Require Import PeanoNat.
Check PeanoNat.Nat.add_assoc.
Output:
Nat.add_assoc
: forall n m p : nat, n + (m + p) = n + m + p
So, the theorem is defined.
But when I create a theorem and try to use it, it gives an error:
Theorem a : forall a b c d e f,
a + b + c + d + e = f.
Proof.
intros.
PeanoNat.Nat.add_assoc a (b + c) d.
Error: The reference PeanoNat.Nat.add_assoc was not found in the
current environment.
Why can't it find the theorem?
What comes after Proof. is not the proof itself. It's a series of instructions, called tactics, that tells Coq how to build a proof. add_assoc is a proof, not a tactic that builds a proof. You would use the tactic rewrite (Nat.add_assoc a (b + c) d) to rewrite (any part of) the goal according to the equality
Nat.add_assoc a (b + c) d
: a + (b + c + d) = a + (b + c) + d
However, your goal a + b + c + d + e = f does not contain either of those terms—+ is left associative and your goal is actually (((a + b) + c) + d) + e = f—so this tactic will fail. In fact, your goal is unprovable, but I assume that it's just for example. You may also be interested in the tactic apply [prf]. It takes the conclusion (thing on the right side of all the ->s and foralls) of prf, matches it against the goal, and gives you subgoals for all of its hypotheses. See also: the Coq tactic reference.
Related
In some cases it is easier to instantiate the one existential term before another. In this contrived example, I wish to set c = 3 first, and from that choose, say a = 1 and b = 2.
Lemma three_nats : exists (a : nat) (b : nat) (c : nat),
a + b = c.
Proof.
eexists.
eexists.
exists 3.
(* Now what? *)
Is there a way to use just the simple exists 3 on c first?
You can use that it is enough to prove that there exists c,b,a such that a+b=c.
enough (exists c a b, a + b = c).
Now you have two goals. First, that
exists c a b, a + b = c -> exists a b c, a + b = c.
and second, that
exists c a b, a + b = c.
Btw, you can finish off the first part of the proof quickly with firstorder like this:
enough (exists c a b, a + b = c) by firstorder.
Or if you don't want to repeat the goal, just apply this lemma:
Lemma ex_swap {A B C} {P:A->B->C->Prop}:
(exists c a b, P a b c) -> exists a b c, P a b c.
Proof. firstorder. Qed.
I have a simple question.
I want to teach Coq that there is vec_assoc.
Require Import Coq.Vectors.Vector.
Lemma vec_assoc (A:Type)(a b c:nat): t A ((a+b)+c) = t A (a+(b+c)).
Proof.
f_equal. symmetry. apply Nat.add_assoc. Qed.
Variable a b c:nat.
Variable A B:Type.
Variable I : (t A ((a+b)+c) -> B).
Variable p:t A (a+(b+c)).
Coq returns an error
`The term "p" has type "vector A (a + (b + c))"
while it is expected to have type "vector A (a + b + c)".`
When I execute Compute I p.
How do I teach Coq that associative law of natural number holds?
Well, associativity does not hold with respect to convertibility of Coq terms, it only holds propositionally. What that means is that in a context where a, b c : nat you can build a term pf : a + (b + c) = (a + b) + c but it is not the case that the specific proof eq_refl can be given the type a + (b + c) = (a + b) + c.
In your case, since you already have a proof that t A (a + (b + c)) = t A ((a + b) + c) you could do the application by first transporting p along this equality using eq_rect or the rew vec_assoc A a b c in p syntax from the module EqNotations of the standard library (just add Import EqNotations.).
In any case nothing will compute since both I and p are variables (and the proof vec_assoc is opaque thanks to Qed).
I am a beginner at Coq proof system (about 4 days). I've tried hard, but I am not able to prove the following.
forall a b c : nat, S (S (a + b)) = S (S (a + c)) -> b = c.
As far as I know, we need to prove the bijectivity of +, so that we can somehow use f(b) = f(c) -> b = c. How do I do this ?
As pointed out in Vinz's answer, you can find the bijectivity theorem about plus directly in the Coq standard library. You can also prove it directly using primitive tactics and mathematical induction on a as follows.
Theorem plus_l_bij: forall a b c : nat, a + b = a + c -> b = c.
Proof.
induction a as [|a'].
intros b c H. apply H.
intros b c H. simpl plus in H. inversion H. apply IHa' in H1. apply H1.
Qed.
After induction a, the base case a = 0 is trivial.
The proof for the second case a = S a', rearranges
S a' + b = S a' + c
to
S (a' + b) = S (a' + c)
and then removes the constructor S using its bijectivity. Finally, the induction hypothesis can be applied to finish the proof.
Using SearchAbout plus or SearchPattern (_ + _ = _ + _ -> _) you could check the available lemmas about +. But if you didn't import the correct modules, that could be useless. What I usually do is that I go look at the online documentation. Here is the documentation for plus and you could have a particular look to plus_reg_l and plus_reg_r.
I want to prove in Coq that:
convert l' + 1 + (convert l' + 1) = convert l' + convert l' + 1 + 1
only some parentheses is redundant and do not let me use reflexivity command; so what should I do?
All of the elements are nat (Natural) type so as convert l' is a function that will return a nat number and I do not want to use some powerful tactics like Omega and so on.
Omega is very useful, as it quickly lets you continue with the more interesting parts of the proof, but when one is learning I personally find it helpful to see a "simpler" proof (the omega-generated proof terms tend to be very long and unreadable).
First note that you will need to use associativity and commutativity of plus. Use Coq's search facilities to find useful lemmas. Use _ as a wild card character. You can find lemmas that contain structures that look like associativity like this:
SearchAbout (_ + (_ + _)= (_ + _) + _).
locates five lemmas that contain, among others, this:
plus_assoc: forall n m p : nat, n + (m + p) = n + m + p
In the same way you can find the commutativity lemma with
SearchAbout (_ + _ = _ + _).
And here it is:
plus_comm: forall n m : nat, n + m = m + n
You cannot apply them directly, but instead you can use the rewrite tactic that lets you work on sub-parts of the terms. I recommend that you play around with it to get a feeling for how it works.
Here is a proof of the desired lemma.
Require Import Arith.
Lemma nat_lemma: forall n, n + 1 + (n + 1) = n + n + 1 + 1.
intro n.
repeat rewrite <- plus_assoc. (* n + (1 + (n + 1)) = n + (n + (1 + 1)) *)
rewrite (plus_comm 1 (n+1)). (* uses (1 + (n + 1) = (n + 1) + 1 *)
repeat rewrite plus_assoc.
reflexivity.
Qed.
Now use this lemma to prove your theorem.
You can use the omega tactic. Just do Require Import Omega. at the beginning of your file and you should be good to go.
Does anybody know of a proof in any of the standard libraries of Coq of the following theorem? If there is one, I couldn´t find it.
forall a b c: nat, b >= c -> a + b - c = a + (b - c)
Thanks in advance,
Marcus.
It is unlikely that somewhat specific formulations would be in the standard library. In particular, for regular Presburger arithmetic, there is a powerful tactic that is complete, namely omega:
Require Import Omega.
Theorem t : forall a b c: nat, b >= c -> a + b - c = a + (b - c).
Proof.
intros. omega.
Qed.
There is a very similar lemma in the Coq standard library (checked with version 8.5pl3), it's called
Nat.add_sub_assoc
: forall n m p : nat, p <= m -> n + (m - p) = n + m - p
Here is how it can be used:
Require Import Coq.Arith.Arith.
Goal forall a b c: nat, b >= c -> a + b - c = a + (b - c).
intros a b c H.
apply (eq_sym (Nat.add_sub_assoc _ _ _ H)).
Qed.
You can use Coq's search facilities to discover it:
Require Import Coq.Arith.Arith.
Search (_ + _ - _).