ContainersAndHOFs tips
Unfolding not
~ P in Coq stands for not P, and is defined as P -> False, so to
prove ~ P, it sometimes helps to do unfold not. intro.
forall P : Prop, P -> ~ P -> Falseforall P : Prop, P -> ~ P -> FalseP: Prop
HP: P
HnP: ~ PFalseP: Prop
HP: P
HnP: P -> FalseFalse
As HnP is of type P -> False, we can apply it to the hypothesis HP: P to get a hypothesis of type False.
P: Prop
HP: P
HnP: P -> False
HFalse: FalseFalse
We can then solve the goal using HFalse.
apply HFalse. Qed.
Behavior of simpl on fixpoints
Some students have been running into a situation where simpl doesn't behave as they expect.
This hint explores the behavior of simpl on Fixpoint definitions.
Here's a simple Fixpoint definition always_true : nat -> bool that deserves its name:
Note that the syntax {struct x} is a hint to Coq that our definition structurally recurses on the x
argument (the only argument). Of course, there isn't any recursion at all here! So indeed, every
recursive call (of which there are none) passes a structurally smaller x argument to always_true.
Now, suppose we try to prove the following theorem:
forall x : nat, always_true x = trueforall x : nat, always_true x = truex: natalways_true x = truex: natalways_true x = truex: natalways_true x = true
That's surprising, isn't it?
Here's a key fact to understanding how simpl works on Fixpoint definitions:
simpl only reduces the application of Fixpoint definitions when the argument
on which it structurally recurses (according to Coq) is in the form of a constructor application.
That's a mouthful. A trivial way to remedy this is to use destruct on the argument
for which the fixpoint is known to be structurally recursive:
destruct x; reflexivity. Qed.
Another possible solution for our example here is to just define always_true as a Definition,
rather than a Fixpoint; then reflexivity will work as expected.
In the exercise set, you may run into a Fixpoint that can be viewed as structurally recursive
on two different arguments, and by using the "{struct}" syntax seen above, you can choose which
- one may be more convenient with respect to simpl's behavior as noted in the bolded statement above.
Finally, since Coq usually infers which argument a fixpoint is structurally
decreasing on, you can run Print f. for any fixpoint f to see which argument Coq chose.