I have the last subgoal to prove a theorem.
and it's:
1 subgoal
b, d : nat
H : 0 <= b
H0 : 0 <= d
m : nat
H1 : 0 <= m
H2 : S m = d
______________________________________(1/1)
b <= b + S m
I think I need an assumption like n <= n + Sm for this.
Anyone can help me out?? Thanks a lot!
The lia tactic, which stands for "Linear Integer Arithmetic", can solve this and many similar goals. E.g.:
Require Import Lia.
Goal forall b m, b <= b + S m.
Proof. intros. lia. Qed.
This is lemma le_plus_l of the standard library.
It might be a good time for you to get familiar with the Search command. It is very useful to find theorems, and quite powerful once you get the hand of it. Here for instance I simply used Search (?x <= ?x + _) and got exactly the thing you were looking for.
Related
I am learning coq and am trying to prove equalities in peano arithmetic.
I got stuck on a simple fraction law.
We know that (n + m) / 2 = n / 2 + m / 2 from primary school.
In peano arithmetic this does only hold if n and m are even (because then division produces correct results).
Compute (3 / 2) + (5 / 2). (*3*)
Compute (3 + 5) / 2. (*4*)
So we define:
Theorem fraction_addition: forall n m: nat ,
even n -> even m -> Nat.div2 n + Nat.div2 m = Nat.div2 (n + m).
From my understanding this is a correct and provable theorem.
I tried an inductive proof, e.g.
intros n m en em.
induction n.
- reflexivity.
- ???
Which gets me into the situation that
en = even (S n)
and IHn : even n -> Nat.div2 n + Nat.div2 m = Nat.div2 (n + m), so i don't find a way to apply the induction hypothesis.
After long research of the standard library and documentation, i don't find an answer.
You need to strengthen your induction hypothesis in cases like this.
One way of doing this is by proving an induction principle like this one:
From Coq Require Import Arith Even.
Lemma nat_ind2 (P : nat -> Prop) :
P 0 ->
P 1 ->
(forall n, P n -> P (S n) -> P (S (S n))) ->
forall n, P n.
Proof.
now intros P0 P1 IH n; enough (H : P n /\ P (S n)); [|induction n]; intuition.
Qed.
nat_ind2 can be used as follows:
Theorem fraction_addition n m :
even n -> even m ->
Nat.div2 n + Nat.div2 m = Nat.div2 (n + m).
Proof.
induction n using nat_ind2.
(* here goes the rest of the proof *)
Qed.
You can also prove your theorem without induction if you are ok with using the standard library.
If you use Even m in your hypothesis (which says exists n, m = 2*m) then you can use simple algebraic rewrites with lemmas from the standard library.
Require Import PeanoNat.
Import Nat.
Goal forall n m, Even n -> Even m -> n / 2 + m / 2 = (n+m)/2.
inversion 1; inversion 1.
subst.
rewrite <- mul_add_distr_l.
rewrite ?(mul_comm 2).
rewrite ?div_mul; auto.
Qed.
The question mark just means "rewrite as many (zero or more) times as possible".
inversion 1 does inversion on the first inductive hypothesis in the goal, in this case first Even n and then Even m. It gives us n = 2 * x and m = 2 * x0 in the context, which we then substitute.
Also note even_spec: forall n : nat, even n = true <-> Even n, so you can use even if you prefer that, just rewrite with even_spec first...
(** **** Exercise: 3 stars, standard, optional (ev_plus_plus)
This exercise just requires applying existing lemmas. No
induction or even case analysis is needed, though some of the
rewriting may be tedious. *)
Theorem ev_plus_plus : forall n m p,
even (n+m) -> even (n+p) -> even (m+p).
Proof.
intros n m p H1 H2.
Here is what I got:
1 subgoal (ID 89)
n, m, p : nat
H1 : even (n + m)
H2 : even (n + p)
============================
even (m + p)
I have proven the previous theorem:
Theorem ev_ev__ev : forall n m,
even (n+m) -> even n -> even m.
And wanted to apply it to H1, but
apply ev_ev__ev in H1.
gives an error:
Error: Unable to find an instance for the variable m.
Why can't it find "m" in the expression even (n + m)? How to fix?
Update
apply ev_ev__ev with (m:=m) in H1.
gives a very strange result:
2 subgoals (ID 90)
n, m, p : nat
H1 : even m
H2 : even (n + p)
============================
even (m + p)
subgoal 2 (ID 92) is:
even (n + m + m)
I thought that it will transform H1 to 2 hypothesis:
H11 : even n
H12 : even m
But instead it gave 2 subgoals, the second that we need to prove is more complicated than the initial one:
even (n + m + m)
What's happening here?
The statement forall n m, even (n+m) -> even n -> even m. does not mean "if we have that (n + m) is even then we have both that n is even and that m is even" (this is false, consider n = m = 1). Instead it means "if we have that (n+m) is even, and we have that n is even, then we have that m is even".
There is no way to get H11 : even n and H12 : even m just from H1 : even (n + m) without assuming a contradiction. I would suggest figuring out how to prove your theorem with pen and paper before trying to prove it in Coq.
Because Coq can't figure out what value it should give for m. You can apply the tactic eapply ev_ev__ev in H1. and see the goals
n, m, p : nat
H2 : even (n + p)
H1 : even ?m
============================
even (m + p)
subgoal 2 (ID 17) is:
even (n + m + ?m)
Coq has instantiated the m with a meta variable ?m, and you need to give a witness for this meta variable in the end to finish the proof.
Second approach is just apply the tactic with instantiating the value of m apply ev_ev__ev with (m := m) in H1.
You can see more on apply with tactics in software-foundations https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html
The thing that is happening is that Coq unifies H1 with the even n argument of ev_ev__ev instead of the even (n+m).
You can tell Coq exactly where you want H1 to go, and use _ wildcards for the places where you let Coq work out the details.
You probably wanted this the term ev_ev__ev n m H1 with type even n -> even m but your apply produced the term ev_ev__ev (n+m) m _ H1 which also left you with some more stuff to prove. To take a look at the proof context, do
Check ev_ev__ev (n+m) m _ H1.
I'm trying to use a lemma for a bigger proof, but I can't find a way to prove one of those two things. Can somebody help me? Here is the proof so far:
Lemma less_r : (forall m n p : nat, n + m < p + n + m).
Proof.
intros.
apply PeanoNat.Nat.add_lt_mono_r.
apply PeanoNat.Nat.lt_add_pos_l.
admit.
Qed.
Your statement cannot be proved because it does not hold. For instance, if we take n = m = p = 0, it implies 0 < 0, a clear contradiction.
Is there a way to admit asserts in Coq ?
Suppose I have a theorem like this:
Theorem test : forall m n : nat,
m * n = n * m.
Proof.
intros n m.
assert (H1: m + m * n = m * S n). { Admitted. }
Abort.
The above assert doesn't seem to work for me.
The error I receive is:
Error: No focused proof (No proof-editing in progress).
What I want is something like undefined in Haskell. Baiscally, I will come back to this later and prove it. Is there something like that in Coq to achieve it ?
In general the tactic admit (lower-case first letter) admits the current subgoal. Thus assert <your assertion>. admit. should work in your case.
Or in its full glory as follows.
Theorem test : forall m n : nat,
m * n = n * m.
Proof.
intros n m.
assert (H1: m + m * n = m * S n). admit.
Abort.
Edit: The version with ; is nonsense, because you do not want to admit all subgoals.
Let's say that I know certain natural numbers are good. I know 1 is good, if n is good then 3n is, and if n is good then n+5 is, and those are only ways of constructing good numbers. It seems to me that the adequate formalization of this in Coq is
Inductive good : nat -> Prop :=
| g1 : good 1
| g3 : forall n, good n -> good (n * 3)
| g5 : forall n, good n -> good (n + 5).
However, despite being obvious, the fact that 0 is not good seems not being provable using this definition (because when I invert, in case of g3 I only get the same thing in the hypothesis).
Now it isn't so obvious what exactly are good numbers. And it really seems that I don't need to characterize them totally in order to know that 0 is not good. For example, I can know that 2 is not good just by doing few inversions.
Indeed g3 can be applied an unbounded number of times when trying to disprove good 0. That is why we can think this proof requires induction (and we can see that the auxiliary lemma needed in the solution of #AntonTrunov uses induction). The same idea is used in theorem loop_never_stop of http://www.cis.upenn.edu/~bcpierce/sf/current/Imp.html#lab428.
Require Import Omega.
Example not_good_0 : ~ good 0.
Proof.
intros contra. remember 0 as n. induction contra.
discriminate. apply IHcontra. omega. omega.
Qed.
This problem needs induction. And induction needs some predicate P : nat -> Prop to work with. A primitive (constant) predicate like (fun n => ~good 0) doesn't give you much: you won't be able to prove the base case for 1 (which corresponds to the constructor g1), because the predicate "forgets" its argument.
So you need to prove some logically equivalent (or stronger) statement which readily will give you the necessary predicate.
An example of such equivalent statement is forall n, good n -> n > 0, which you can later use to disprove good 0. The corresponding predicate P is (fun n => n > 0).
Require Import Coq.Arith.Arith.
Require Import Coq.omega.Omega.
Inductive good : nat -> Prop :=
| g1 : good 1
| g3 : forall n, good n -> good (n * 3)
| g5 : forall n, good n -> good (n + 5).
Lemma good_gt_O: forall n, good n -> n > 0.
Proof.
intros n H. induction H; omega.
Qed.
Goal ~ good 0.
intro H. now apply good_ge_O in H.
Qed.
Here is a proof of the aforementioned equivalence:
Lemma not_good0_gt_zero_equiv_not_good0 :
(forall n, good n -> n > 0) <-> ~ good 0.
Proof.
split; intros; firstorder.
destruct n; [tauto | omega].
Qed.
And it's easy to show that forall n, n = 0 -> ~ good n which implicitly appears in #eponier's answer is equivalent to ~ good 0 too.
Lemma not_good0_eq_zero_equiv_not_good0 :
(forall n, n = 0 -> ~ good n) <-> ~ good 0.
Proof.
split; intros; subst; auto.
Qed.
Now, the corresponding predicate used to prove forall n, n = 0 -> ~ good n is fun n => n = 0 -> False. This can be shown by using manual application of the goal_ind induction principle, automatically generated by Coq:
Example not_good_0_manual : forall n, n = 0 -> ~ good n.
Proof.
intros n Eq contra.
generalize Eq.
refine (good_ind (fun n => n = 0 -> False) _ _ _ _ _);
try eassumption; intros; omega.
Qed.
generalize Eq. introduces n = 0 as a premise to the current goal. Without it the goal to prove would be False and the corresponding predicate would be the boring fun n => False again.