Lemma cannot be used as a hint - coq

Why doesn't Coq accept this lemma as a hint?
Lemma contr : forall p1 : Prop, False -> p1.
Proof. tauto. Qed.
Hint Resolve contr : Hints.
Or other lemmas that end with a Prop variable?

Looking at the documentation for Hint Resolve ( http://coq.inria.fr/distrib/V8.4/refman/Reference-Manual011.html##command232 ):
term cannot be used as a hint
The type of term contains products over variables which do not appear in the conclusion. A typical example is a transitivity axiom. In that case the apply tactic fails, and thus is useless.
However, it does not seem (to me) to be the case here, as the only product is over p1 which does appear in the conclusion.
The problem here seems to be that your conclusion have absolutely no shape at all. auto seems to work by matching the shape of your goal with the shape of the return type of the hint database. Here, it might be upset by the fact that your goal is just a quantified variable. I am not sure whether this is a reasonable thing to trip over, but this particular instance might be the only case where you might have such a shapeless return type (with obviously the same case for Set and Type), so it's not a big deal.
So, you probably don't need this as a hint?... just use tactics such as tauto, intuition or perform any kind of elimination/destruction/inversion on the value of type False in your environment... not very satisfactory but eh :\

Related

What is a concrete example of the type `Set` and what is the meaning of `Set`?

I've been trying to understand what Set is after encountering it in Adam Chlipala's book in addition to this great discussion in SO. His first example definition binary ops using Set:
Inductive binop : Set := Plus | Times.
in that book he says:
Second, there is the : Set fragment, which declares that we are defining a datatype that should be thought of as a constituent of programs.
Which confuses me. What does Adam mean here?
In addition, I thought that some additional concrete examples would help my understanding. I am not an expert of Coq so I am not sure what type of examples would help but something simple and very concrete/grounded might be useful.
Note, I have seen that Set is the first "type set" in a the type hierarchy e.g. Set = Type(0) <= Type = Type(1) <= Type(2) <= ... . I guess this sort of makes sense intuitively like I'd assume nat \in Type and all usual programming types to be in it but not sure what would be in Type that wouldn't be in Set. Perhaps recursive types? Not sure if that is the right example but I am trying to wrap my head around what this concept means and it's conceptual (& practical) usefulness.
Though Set and Type are different in Coq, this is mostly due to historical reasons. Nowadays, most developments do not rely on Set being different from Type. In particular, Adam's comment would also make sense if you replace Set by Type everywhere. The main point is that, when you want to define a datatype that you can compute with during execution (e.g. a number), you want to put it in Set or Type rather than Prop. This is because things that live in Prop are erased when you extract programs from Coq, so something defined in Prop would end up not computing anything.
As for your second question: Set is something that lives in Type, but not in Set, as the following snippet shows.
Check Set : Type. (* This works *)
Fail Check Set : Set.
(* The command has indeed failed with message: *)
(* The term "Set" has type "Type" while it is expected to have type *)
(* "Set" (universe inconsistency: Cannot enforce Set+1 <= Set). *)
This restriction is in place to prevent paradoxes in the theory. This is pretty much the only difference you see between Set and Type by default. You can also make them more different by invoking Coq with the -impredicative-set option:
(* Needs -impredicative-set; otherwise, the first line will also fail.*)
Check (forall A : Set, A -> A) : Set.
Universe u.
Fail Check (forall A : Type#{u}, A -> A) : Type#{u}.
(* The command has indeed failed with message: *)
(* The term "forall A : Type, A -> A" has type "Type#{u+1}" *)
(* while it is expected to have type "Type#{u}" (universe inconsistency: Cannot enforce *)
(* u < u because u = u). *)
Note that I had to add the Universe u. declaration to force the two occurrences of Type to be at the same level. Without this declaration, Coq would silently put the two Types at different universe levels, and the command would be accepted. (This would not mean that Type would have the same behavior as Set in this example, since Type#{u} and Type#{v} are different things when u and v are different!)
If you're wondering why this feature is useful, it is not by chance. The overwhelming majority of Coq developments does not rely on it. It is turned off by default because it is incompatible with a few axioms that are generally considered more useful in Coq developments, such as the strong law of the excluded middle:
forall A : Prop, {A} + {~ A}
With -impredicative-set turned on, this axiom yields a paradox, while it is safe to use by default.

Proving technology of Coq's kernel

Isabelle bases its kernel proof power in resolution coupled with higher-order unification.
How are theorems proven by Coq's kernel?
The question arises from reading Paulson's "The foundation of a generic theorem prover":
Propositions-as-types could consume excessive space; and what would take the place of Huet's unification procedure for higher-order logic?
There are two kinds of technology in most provers: the "proving" part (responsible for building a proof, since it is often too tedious for the user) and the "checking" part (responsible for verifying that a proof is well-formed and matches a given theorem statement). In both Isabelle and Coq, the kernel is only responsible for the "checking" part.
In the case of Coq, the propositions-as-types paradigm is indeed used for checking proofs. In other words, a proof is a lambda-term of the Calculus of Inductive Constructions (CIC) whose type is compared to the theorem statement seen as a type.
How are theorems proven by Coq's kernel?
As explained above, theorems are not proven by Coq's kernel, only checked.
That check is done as usual with type checking: If the term is an application, check (recursively) that the arguments has the right type, and that the function return type matches the type. For example, to prove that a + f(b) has type nat, you must check that plus has type nat -> nat -> nat, that f has type A -> nat, that a has type nat and b has type A.
The proof has to be constructed by the user. The proof itself is a lambda term. The theorem proposition is the type of the lambda term.
Because it may be difficult to create the right lambda term directly, Coq does not force the user to write the whole term in one go. One can instead leave "holes" in the term to be filled in later, either by hand or with tactics. Tactics are small programs that try to fill in a piece of the proof (which may or may not be the right piece...).
Once the entire lambda term has been constructed, the proof is checked by Coq by checking that the lambda term really has the type of the proposition that one wishes to prove.

How to prove that "Type <> Set" (i.e. Type is not equal to Set) in Coq?

Is there an equality or inequality relation between Type and Set in Coq ?
I am learning about Coq's type system and understand that the type of Set is Type#{Set+1}, and that the type of Type#{k} is Type#{k+1}. I tried to prove that Type = Set, and then tried to prove Type <> Set, but I failed in both cases.
I started with
Lemma set_is_type : Type = Set.
Proof.
reflexivity.
which gives an error message saying that Unable to unify "Set" with "Type#{Top.74}".
Then I tried
Lemma set_is_not_type : Type <> Set.
Proof.
intros contra.
At this point I do not know how to proceed. The tactic discriminate did not work, neither inversion contra.
Which one of the above two lemmas can be proved?
This actually isn't an entirely trivial theorem. To show that Type = Set results in a paradox (and hence that having separate levels of Type is necessary), you'll need to use a standard result akin to Russell's paradox from set theory. Specifically, you'll need Hurken's paradox, which essentially says that smaller Types can't be on equal footing to larger Types (remember that Type is polymorphic in Coq, and in particular, Set is the lowest level (or second lowest if you include Prop)).
The particular theorem we want can be found in the standard library.
Require Logic.Hurkens.
Import Logic.Hurkens.TypeNeqSmallType.
Check paradox.
paradox has the type signature forall A : Type, Type = A -> False. This is pretty much what we want to prove, since Set: Type (at least if Type is large enough).
Lemma set_is_not_type: Type <> Set.
Proof.
intro F.
exact (paradox _ F).
Defined.
Coq automatically sets restrictions on the Type in this lemma to ensure that Set: Type.
On the other hand, Set is equal to some level of Type, so we should be able to prove that Type = Set with some different constraints on this Type. The easiest way I found to do this was to prove that Type = Type, but then instantiate this theorem with Set. For whatever reason, as you found, reflexivity can't enforce universe constraints by itself. To do this, we need to make both the lemmas universe polymorphic so that they can be instantiated with a particular universe level.
Polymorphic Lemma type_is_type: Type = Type.
Proof.
reflexivity.
Defined.
Polymorphic Lemma type_is_set: Type = Set.
Proof.
apply type_is_type.
Defined.
The easier way to make everything universe polymorphic is to put Set Universe Polymorphism. before everything.

General Advice about When to Use Prop and When to use bool

I am formalizing a grammar which is essentially one over boolean expressions. In coq, you can get boolean-like things in Prop or more explicitly in bool.
So for example, I could write:
true && true
Or
True /\ True
The problem is that in proofs (which is what I really care about) I can do a case analysis in domain bool, but in Prop this is not possible (since all members are not enumerable, I suppose). Giving up this tactic and similar rewriting tactics seems like a huge drawback even for very simple proofs.
In general, what situations would one choose Prop over bool for formalizing? I realize this is a broad question, but I feel like this is not addressed in the Coq manual sufficiently. I am interested in real world experience people have had going down both routes.
There are lots of different opinions on this. My personal take is that you are often better off not making this choice: it makes sense to have two versions of a property, one in Prop, the other one in bool.
Why would you want this? As you pointed out, booleans support case analysis in proofs and functions, which general propositions do not. However, Prop is more convenient to use in certain cases. Suppose you have a type T with finitely many values. We can write a procedure
all : (T -> bool) -> bool
that decides whether a boolean property P : T -> bool holds of all elements of T. Imagine that we know that all P = true, for some property P. We might want to use this fact to conclude that P x = true for some value x. To do this, we need to prove a lemma about all:
allP : forall P : T -> bool,
all P = true <-> (forall x : T, P x = true)
This lemma connects two different formulations of the same property: a boolean one and a propositional one. When reasoning about all in a proof, we can invoke allP to convert freely between the two. We can also have different conversion lemmas:
allPn : forall P,
all P = false <-> (exists x, P x = false)
In fact, we are free to choose any Coq proposition whatsoever to relate to a boolean computation (as long, of course, as we can prove that the two are logically equivalent). For instance, if we would like to have a custom induction principle associated with a boolean property, we can look for an equivalent formulation as an inductively defined proposition.
The Mathematical Components library is a good example of development that follows this style. Indeed, because it is so pervasive there, the library provides a special view mechanism for writing conversion lemmas like the one above and applying them. In plain Coq, we can also use the rewrite tactic to apply logical equivalences more conveniently.
Of course, there are many situations where it does not make sense to have two formulations of the same property. Sometimes, you are forced to use Prop, because the property you care about is undecidable. Sometimes, you might feel that you wouldn't gain anything by writing your property in Prop, and may keep it only as a boolean.
In addition to the Software Foundations chapter linked above, this answer discusses the difference between bool and Prop in more depth.

Finish proof with false hypothesis in Coq

So I have a false hypothesis in a subgoal. It's an equality between different constructors. How do I finish the subgoal?
H: List.Not_Empty Bit.Bit Bit.Zero (List.Empty Bit.Bit) = List.Empty Bit.Bit
This doesn't look like the Coq List I'm used to from the standard library, so it will be hard to help you without knowing the definitions of List.Not_Empty and List.Empty. If I guess correctly that List.Empty stands for nil and List.Not_empty stands for cons, then it's just a matter of showing that the two constructors are not equal. You can for instance do:
congruence.
or simply:
inversion H.
However, if it's something more involved, these two might fail. So you'd want to either:
SearchAbout List.Not_Empty.
to see if lemmas exist about it, or to:
unfold List.Not_Empty, List.Empty in H.
to unfold definitions and work out the details (possibly saving this subproof as a lemma if it does not exist, as it seems useful).