I some times see this syntax in Coq to represent certain types/sets such as in printing information about existential variables:
?T : [ |- Set]
?T0 : [ x : ?T |- Set ]
I don't know how to search for this syntax.
What does it mean?
Is the first one the same as
? T : Set
?
Suppose we have a term with a certain type.
Variable B : nat -> nat.
Check B.
(*
B
: nat -> nat
*)
If we create another term using B it may or may not type check, i.e. B true is not typeable.
Fail Check B true.
(*
Error message:
The term "true" has type "bool" while it is expected to have type "nat".
*)
Coq allows wildcards in terms and then tries to figure out the type itself.
Check B _.
(*
B ?n
: nat
where
?n : [ |- nat]
*)
Here Coq says that the type of B _ is nat, but only
under the assumption that the argument
(named ?n) is of type nat. Or otherwise put, "under the assumption that one can infer that the type of ?n is nat from the empty context".
Sometimes more stuff is found on the left side of the "turnstile" symbol |-.
Variable x:nat.
Check _ x.
(*
?y x
: ?T#{x:=x}
where
?y : [ |- forall x : nat, ?T]
?T : [x : nat |- Type]
*)
Above the underscore is called ?y and the type of (?y x) is a dependent type ?T that depends on x. ?T is only typable (to a Type) in a context where x is a nat.
If x is not a nat, then ?T is not typable.
I might be mistaken, but the first one should be read as "the existential variable named T is of type Set" and the second should be read as "the existential variable named T0 is of type Set, in a context where the variable x is of type ?T", meaning that the term which will fill the second hole might depend on some variable named x.
Related
The Ltac chapter of CPDT, shows a "faulty" tactic:
Theorem t1' : forall x : nat, x = x.
match goal with
| [ |- forall x, ?P ] => trivial
end.
The book then explains
The problem is that unification variables may not contain locally bound variables.
In this case, [?P] would need to be bound to [x = x], which contains the local quantified
variable [x]. By using a wildcard in the earlier version, we avoided this restriction.
However, the tactic above actually works in Coq 8.11!
Can unification variables now contain locally-bound variables? If so, is there any difference between the above and
Theorem t1' : forall x : nat, x = x.
match goal with
| [ |- forall x, _ ] => trivial
end.
(where we replaced ?P by _)?
The difference between ?P and _ is that you can actually refer to P in the branch. Unfortunately, P is an open term, so it might quickly end up being ill-formed, so there is not much you can do with it. So, I would not rely on it. It is better to use forall x, #?P x as a pattern, so that P is a closed term.
The book provides some more info later on:
Actually, the behavior demonstrated here applies to Coq version 8.4,
but not 8.4pl1. The latter version will allow regular Ltac pattern
variables to match terms that contain locally bound variables, but a
tactic failure occurs if that variable is later used as a Gallina term.
This means that in
Ltac dummy :=
match goal with
| [ H: forall x, ?P |- _ ] => assert True
end.
Lemma foo (a x : nat) :
(forall n, n = 42) ->
True.
Proof.
intros.
dummy.
the dummy tactic can be applied (because we match ?P but don't refer to it later on), but if we change dummy to be
Ltac dummy :=
match goal with
| [ H: forall x, ?P |- _ ] => assert ?P
end.
then that'll fail because we're referring to ?P, which is potentially an open term.
I am working with a definition in coq which need to yield something from a Theorem, but cannot destruct in the definition.
Theorem sp : forall (X : Type) (T : X -> Prop)..... , exists (a : X), T a.
Definition yield_sp : (X : Type) (T : X -> Prop) (H : sp X T .....)..... : X.
When I try to destruct H, coq warns that
Case analysis on sort Type is not allowed for inductive definition ex.
I would like to know the reason for it, and further, how to use definition to yield an element from an "exists" proposition.
You cannot extract the witness out of an existence proof. There are a few options:
Change the statement of the proof to {x : T | P x}, which behaves more-or-less like the existential quantifier, but supports a projection function proj1_sig : {x : T | P x} -> T.
Assume a choice axiom, as in https://coq.inria.fr/library/Coq.Logic.ClassicalChoice.html
If you are quantifying over a countable type and your proposition is decidable, you can use the trick in this question to extract the witness.
For a simple inductive type like the natural numbers nat, it is easy to prove that the two constructors (zero and successor) give all possible natural numbers,
Lemma nat_destruct (n : nat) : n = O \/ exists m : nat, n = S m.
Proof.
destruct n. left. reflexivity. right. exists n. reflexivity.
Qed.
However I hear it is not so simple for equality proofs. There is only one equality constructor, eq_refl, but Coq cannot prove that
eq_destruct : forall (A : Type) (x : A) (prEq : x = x), prEq = eq_refl
What exactly blocks this proof ? Probably a first problem is that equality is not just a type, but a type family eq : forall A : Type, A -> A -> Prop. Is there a simpler type family where such a proof is impossible ? With 1 or 2 arguments instead of 3 maybe ?
I wrote about this issue in a blog post. In general, this arises when you define a type family over a type that does not have decidable equality. For example, consider the following type:
Inductive foo : Type -> Type :=
| Foo : foo unit.
It is not possible to show (I am pretty sure) that every inhabitant of foo unit is of the form Foo.
This phenomenon is easier to see at the level of proof terms. When you destruct a term of such a family, you must generalize over the index of the family. You can only relate this index to a known shape such as unit if the type has decidable equality.
In Coq, propositions are types and proofs are values. For example we may write a simple proof like this, which proves 0=0.
Definition test : (eq 0 0) := eq_refl 0.
Interestingly, when checking the type of eq_refl, it shows
eq_refl
: ?x = ?x
where
?A : [ |- Type]
?x : [ |- ?A]
That means all the arguments of eq_refl are implicit. In Coq, implicit arguments are usually not allowed to determined explicitly, unless using #.
To prove 0=0, we can write explicitly #eq_refl nat 0 or just eq_refl as nat and 0 can be deduced. But in the example at beginning, eq_refl 0 also works. Why?
This thing does not work in general, e.g.
Definition foobar {A : Type -> Type} {T : Type} : list (A T) := [].
Definition test : list (list nat) := foobar.
Fail Definition test' : list (list nat) := foobar nat.
Implicit arguments structures of constants may sometimes rely on several
Arguments directives, as can be seen in the file $COQLIB/theories/Init/Logic.v, lines 309 and 310, reproduced here:
Arguments eq {A} x _.
Arguments eq_refl {A x} , [A] x.
The use of the Arguments command is documented here, but I did not see it mentioned that several implicit arguments configuration are accepted.
On the other hand, the command Print Implicit eq_refl. returns precise information about the fact that two methods of understanding implicit arguments can be used, one when the functions receives 1 argument, and when the function receives 0 arguments.
Writing
Inductive Foo : Type -> Type :=
| foo : Foo Bar
with
Bar := .
gives
Error: Non strictly positive occurrence of "Bar" in "Foo Bar".
I know the standard example of why strict positivity is necessary; if I have
Inductive Fix :=
| fFix : (Fix -> Fix) -> Fix.
with an eliminator
Fix_rect : forall (P : Fix -> Type) (v : forall f, (forall x, P (f x)) -> P (fFix f)) (f : Fix), P f
then I can prove absurdity with
Fix_rect (fun _ => False) (fun f H => H (fFix id)) (fFix id) : False
(Aside: Does anything go wrong if instead the eliminator is
Fix_rect : forall (P : Fix -> Type) (v : forall f, (forall x, P x -> P (f x)) -> P (fFix f)) (f : Fix), P f
?)
However, I don't see a way to make use of occurrences that appear only in indices. Is there a way to derive a similar contradiction if non-strictly-positive occurrences are permitted in type indices?
This doesn't seem to be a positivity issue, contrary to the error message. Rather, since you have mutual indexing, this is an inductive-inductive type (a weird "large" one at that), which Coq doesn't support.
You could try defining non-indexed types, and separate recursively defined "well-formedness" relations which encode correct indexing. E. g.
Inductive PreFoo : Type :=
| foo : PreFoo.
Inductive Bar : Type :=.
Fixpoint FooWf (f : PreFoo) (t : Type) : Prop :=
match f with
| foo => (t = Bar)
end.
Definition Foo (t : Type) := sig (fun f => FooWf f t).
This is analogous to how you might have indexed intrinsic syntaxes for type theories or extrinsic presyntaxes with separate typing relations.