I want to prove the following theorem on two pairs of type TR:
Definition s:= nat.
Definition d:= nat.
Definition c:= nat.
Definition p:= nat.
Inductive rt: Set :=
|al : rt
|bl : rt.
Definition TR: Set :=
rt* s*d* c* p.
Implicit Types m n : TR.
Theorem eq_TR_dec : forall n m, {n = m} + {n <> m}.
For now, the proof of this theorem begins by intros n. destruct n. destruct m. But I cannot figure out the best tactic to prove this theorem. Any idea how should I prove this theorem? Thank you
As mentionned in the comments, you can use decide equality which basically solve these goals (check the documentation here to learn more).
In this case, just apply it as many times as needed and it works :
Theorem eq_TR_dec : forall n m, {n = m} + {n <> m}.
Proof.
decide equality.
- decide equality.
- decide equality.
* decide equality.
* decide equality.
+ decide equality.
+ {
decide equality.
- decide equality.
- decide equality.
}
Qed.
or more simply using the repeat tactic (as also mentionned in eponier's comment), which basically applies (reccursively in the subgoal generated) the tactic you give it until it fails:
Theorem eq_TR_dec : forall n m, {n = m} + {n <> m}.
Proof.
repeat decide equality.
Qed.
As we saw in the first case, here you only need to solve apply decide equality enough times, so repeat is particularly efficient !
Related
I defined the dependent type and trivial lemma as you can see below.
Require Import Coq.Reals.Reals.
Inductive Euc :nat -> Type:=
|RO : Euc 0
|Rn : forall {n:nat}, R -> Euc n -> Euc (S n).
Lemma ROEuc : forall t:(Euc 0), t = RO.
Proof.
intros. Admitted.
I don't know how to prove it.
Euc 0 is not an inductive type, so I can not use destruct t or induction t.
Please tell me how to prove it.
You should find it easy to prove the more simply-typed theorem
Lemma ROEuc' : forall n (t : Euc n), n = 0 -> existT Euc n t = existT Euc 0 RO.
You can simply destruct t, giving you one trivial case, and one absurd case that can be discharged with congruence.
To derive your lemma from this one, you will need four tools:
The inversion_sigma tactic to turn an equality of existT s into dependent equalities
The fact UIP_dec from Coq.Logic.Eqdep_dec to prove that all proofs of 0 = 0 are equal to eq_refl under the assumption that equality of nat is decidable
The fact that equality of nat is decidable, which you can either take from some lemma in Coq.Arith.Arith (use Search after Require Import Coq.Arith.Arith to find the name of the lemma with the right type) or prove from scratch using the decide equality tactic
subst + simpl to see that your dependent equality will now reduce to the theorem you want to prove
Alternatively, you can Require Import Coq.Program.Tactics and use dependent destruction t, but beware that this often introduces needless dependencies on axioms (visible with Print Assumptions)
In this case, Coq is actually smart enough to do the dependent pattern matching for you.
The magic tactic to use here is refine (match t in Euc 0 with RO => _), which leaves you with a single trivial goal (there may be a variant of destruct that does this, but I don't know what it would be). Here the clause in Euc 0 tells Coq that you are only interested in 0-length vectors, and since 0 is a nat built from constructors, Coq is able to work out that the RS case is impossible by disjointness of constructors.
The full proof:
Lemma ROEuc : forall t:(Euc 0), t = RO.
Proof.
intros.
refine (match t in Euc 0 with RO => _ end).
reflexivity.
Qed.
The proof term generated by this match is actually rather complicated, but understanding it might be helpful if you need to write other proofs about dependent types where Coq's pattern matching isn't powerful enough to help you.
Given the inductive definition of evenness, how is it best proved that, say, 1024 is an even number?
Repeating apply even_S down to zero is certainly not the right approach.
As HTNW pointed out, you can use Ltac automation to produce such a proof. This has the disadvantage of producing a large proof term even_S (even_S ... even_O), thus slowing down proofs. In this case, it is better to reformulate the goal using a boolean decision procedure:
Fixpoint evenb (n : nat) : bool :=
match n with
| 0 => true
| 1 => false
| S (S m) => evenb m
end.
Lemma evenb_correct : forall n, evenb n = true <-> even n.
(* Fun exercise! *)
Coq can prove that evenb 1024 = true simply by evaluating the left-hand side:
Goal (even 1024). apply evenb_correct. reflexivity. Qed.
Repeating apply even_S is not the way. repeat apply even_S is. If even_S is a constructor, there's also repeat constructor.
Inductive even : nat -> Prop :=
| even_O : even O
| even_S : forall n, even n -> even (S (S n)).
Goal (even 1024). repeat apply even_S. exact even_O. Qed.
Goal (even 1024). repeat constructor. Qed. (* also finds even_O, would leave as goal otherwise *)
I wanted to see a few hands on examples of Coq proofs of the form:
\exists A(x1,...,xn)
essentially where the Goal had an existential quantifier. I was having issues manipulating the goal in meaningful ways to make progress in my proof and wanted to see a few examples of common tactics to manipulate.
What are some good existential quantifiers examples in Coq to prove?
My specific example I had:
Theorem Big_Small_ForwardImpl :
forall (P : Program) (S' : State),
(BigStepR (B_PgmConf P) (B_StateConf S')) -> (ConfigEquivR (S_PgmConf P) (S_BlkConf EmptyBlk S')).
Proof.
intros.
induction P.
unfold ConfigEquivR.
refine (ex_intro _ _ _) .
my context and goals was:
1 subgoal
l : list string
s : Statement
S' : State
H : BigStepR (B_PgmConf (Pgm l s)) (B_StateConf S')
______________________________________(1/1)
exists N : nat, NSmallSteps N (S_PgmConf (Pgm l s)) (S_BlkConf EmptyBlk S')
but then changed to:
1 subgoal
l : list string
s : Statement
S' : State
H : BigStepR (B_PgmConf (Pgm l s)) (B_StateConf S')
______________________________________(1/1)
NSmallSteps ?Goal (S_PgmConf (Pgm l s)) (S_BlkConf EmptyBlk S')
after using the refine (ex_intro _ _ _) tactic. Since I am not sure what is going on I was hoping some simpler examples could show me how to manipulate existential quantifiers in my Coq goal.
helpful comment:
The ?Goal was introduced by Coq as a placeholder for some N that will have to be deduced later in the proof.
The following example is based on the code provided in this answer.
Suppose we have a type T and a binary relation R on elements of type T. For the purpose of this example, we can define those as follows.
Variable T : Type.
Variable R : T -> T -> Prop.
Let us prove the following simple theorem.
Theorem test : forall x y, R x y -> exists t, R x t.
Here is a possible solution.
Proof.
intros. exists y. apply H.
Qed.
Instead of explicitly specifying that y is the element we are looking for, we can rely on Coq's powerful automatic proof mechanisms in order to automatically deduce which variable satisfies R x t:
Proof.
intros.
eexists. (* Introduce a temporary placeholder of the form ?t *)
apply H. (* Coq can deduce from the hypothesis H that ?t must be y *)
Qed.
There exist numerous tactics that make ise of the same automated deduction mechanisms, such as eexists, eapply, eauto, etc.
Note that their names often correspond to usual tactics prefixed with an e.
I have the following Lemma with an incomplete proof:
Lemma s_is_plus_one : forall n:nat, S n = n + 1.
Proof.
intros.
reflexivity.
Qed.
This proof fails with
Unable to unify "n + 1" with "S n".
It seems like eq_S would be the way to prove this, but I can't apply it (it doesn't recognize n + 1 as S n: Error: Unable to find an instance for the variable y.). I've also tried ring, but it can't find a relation. When I use rewrite, it just reduces to the same final goal.
How can I finish this proof?
This is related to the way (+) is defined. You can access (+)'s underlying definition by turning notations off (in CoqIDE that's in View > Display notations), seeing that the notation (+) corresponds to the function Nat.add and then calling Print Nat.add which gives you:
Nat.add =
fix add (n m : nat) {struct n} : nat :=
match n with
| O => m
| S p => S (add p m)
end
You can see that (+) is defined by matching on its first argument which in n + 1 is the variable n. Because n does not start with either O or S (it's not "constructor-headed"), the match cannot reduce. Which means you won't be able to prove the equality just by saying that the two things compute to the same normal form (which is what reflexivity claims).
Instead you need to explain to coq why it is the case that for any n the equality will hold true. A classic move in the case of a recursive function like Nat.add is to proceed with a proof by induction. And it does indeed do the job here:
Lemma s_is_plus_one : forall n:nat, S n = n + 1.
Proof.
intros. induction n.
- reflexivity.
- simpl. rewrite <- IHn. reflexivity.
Qed.
Another thing you can do is notice that 1 on the other hand is constructor-headed which means that the match would fire if only you had 1 + n rather than n + 1. Well, we're in luck because in the standard library someone already has proven that Nat.add is commutative so we can just use that:
Lemma s_is_plus_one : forall n:nat, S n = n + 1.
Proof.
intros.
rewrite (Nat.add_comm n 1).
reflexivity.
Qed.
A last alternative: using SearchAbout (?n + 1), we can find all the theorems talking about the pattern ?n + 1 for some variable ?n (the question mark is important here). The first result is the really relevant lemma:
Nat.add_1_r: forall n : nat, n + 1 = S n
Given any programming language, whenever a standard library function exists, we should most likely use it rather than write our own code. One would think that this advice applies equally to Coq. However, I recently forced myself to use the same_relation predicate of the Relation module, and I am left with the feeling of being worse off. So I must be missing something, hence my question. To illustrate what I mean let us consider to possible relations:
Require Import Relations. (* same_relation *)
Require Import Setoids.Setoid. (* seems to be needed for rewrite *)
Inductive rel1 {A:Type} : A -> A -> Prop :=
| rel1_refl : forall x:A, rel1 x x. (* for example *)
Inductive rel2 {A:Type} : A -> A -> Prop :=
| rel2_refl : forall x:A, rel2 x x. (* for example *)
The specific details of these relations do not matter here, as long as rel1 and rel2 are equivalent. Now, if I want to ignore the Coq library, I could simply state:
Lemma L1: forall (A:Type)(x y:A), rel1 x y <-> rel2 x y.
Proof.
(* some proof *)
Qed.
and if I want to follow my instinct and use the Coq library:
Lemma L2: forall (A:Type), same_relation A rel1 rel2.
Proof.
(* some proof *)
Qed.
In the simplest of cases, it seems that having proven lemma L1 or Lemma L2 is equally beneficial:
Lemma application1: forall (A:Type) (x y:A),
rel1 x y -> rel2 x y (* for example *)
Proof.
intros A x y H. apply L1 (* or L2 *) . exact H.
Qed.
Whether I decide to use apply L1 or apply L2 makes no difference...
However in practice, we are likely to be faced with a more complicated goal:
Lemma application2: forall (A:Type) (x y:A) (p:Prop),
p /\ rel1 x y -> p /\ rel2 x y.
Proof.
intros A x y p H. rewrite <- L1. exact H.
Qed.
My point here is that replacing rewrite <- L1 by rewrite <- L2 will fail. This is also true of the previous example, but at least I was able to use apply rather than rewrite. I cannot use apply in this case (unless I go through the trouble of splitting my goal). So it seems that I have lost the convenience of using rewrite, if I only have Lemma L2.
Using rewrite on results which are an equivalence (not just an equality) is very convenient. It seems that wrapping an equivalence into the predicate same_relation takes away this convenience. Was I right to follow my instinct and force myself to use same_relation? More generally, is it so true that if a construct is defined in the standard Coq library, I should use it, rather than define my own version of it?
You pose two questions, I try to answer separately:
Regarding your rewrite problem, this problem is natural as the definition of same_relation goes as double inclusion. I agree that maybe a definition using iff would be more convenient. It would really depend on the kind of goals you have. A possible solution for your problem is to define a view:
Lemma L1 {A:Type} {x y:A} : rel1 x y <-> rel2 x y.
Proof.
Admitted.
Lemma L2 {A:Type} : same_relation A rel1 rel2.
Proof.
Admitted.
Lemma U {T} {R1 R2 : relation T} :
same_relation _ R1 R2 -> forall x y, R1 x y <-> R2 x y.
Proof. now destruct 1; intros x y; split; auto. Qed.
Lemma application2 {A:Type} {x y:A} {p:Prop} :
p /\ rel1 x y -> p /\ rel2 x y.
Proof. now rewrite (U L2). Qed.
Note also that rewriting with a <-> relation is not really based on equality, but on "setoid rewriting". In fact, the following doesn't hold in Coq A <-> B -> A = B.
Regarding your second question, whether to use the Coq standard library is a highly subjective topic. I personally rarely use it, I prefer a different library called math-comp, but YMMV. Regarding relations, mathcomp is mostly specialized into boolean relations rel x y = x -> y -> bool, thus, equivalence is simply defined as equality, typically, given r1 r2 you'd write r1 =2 r2.
IMHO in the end, such choices are highly dependent on your application domain.
[edit]: Note that the Relation library is dated:
Naive set theory in Coq. Coq V6.1. This work was started in July 1993 by F. Prost.
So indeed, it may not be the best modern base to build Coq developments on.