Prove that n < m + n or that 0 < m in COQ - coq

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.

Related

How to prove `plus_le_compat_l : forall n m p, n <= m -> p + n <= p + m.`

another problem from SFv1 which got me stuck.
The theorem is as follows:
Theorem plus_le_compat_l : forall n m p,
n <= m ->
p + n <= p + m.
I have tried several avenues so far, the one that got me the furthest was to introduce n and start induction on it. The base case is rather trivial (intros m p H. rewrite add_0_r. apply le_plus_l.).
As for the inductive step, I have tried to destruct p, which gives me two subcases. For the first where p = O, it's super easy to prove by applying H. When p = S n I get stuck. Here's the full proof so far:
Theorem plus_le_compat_l : forall n m p,
n <= m ->
p + n <= p + m.
Proof.
intros n.
induction n as [| n' IHn'].
- intros m p H. rewrite add_0_r. apply le_plus_l.
- destruct p eqn:E.
+ intros H. simpl. apply H.
+ intros H. simpl. apply n_le_m__Sn_le_Sm.
And my current goal:
n' : nat
IHn' : forall m p : nat, n' <= m -> p + n' <= p + m
m, p, n : nat
E : p = S n
H : S n' <= m
============================
n + S n' <= n + m
I tried a trivial manipulation to turn the LHS of the inequality into n' + S n which lets me rewrite the S n as p, but that also doesn't take me anywhere.
Any hints here are highly appreciated :-)
Thanks
PS: I have tried to apply a previously proved theorem without success:
Theorem add_le_cases : forall n m p q,
n + m <= p + q -> n <= p \/ m <= q.
I think in this case using induction on p is the way to go, and both goals should be quite ok to prove – the induction one by a use of le_n_S.

Coq theorem proving: Simple fraction law in peano arithmetic

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...

I want to do induction on Peano nats but I want to prove a property P over nats 1 ... n. Does Coq provide a tactic/tool to do this?

I want to prove something for natural numbers not including 0. So my base case for property P would be P 1 instead of P 0.
I'm considering using n >= 0 as a hypothesis in the goal, but is there another way to do this in Coq?
Consider shifting the property to become a property on all nats.
Definition P' (n : nat) := P (S n).
So forall n, n >= 1 -> P n is equivalent to forall n, P' n.
Just add n > 0 or n <> 0 as an assumption. Example:
Require Import Arith.
Goal forall n, n > 0 -> forall a, a = n - 1 -> a + 1 = n.
induction n; intros H.
- now apply Nat.nlt_0_r in H. (* This case, 0 > 0, is simply impossible *)
- intros a H1.
now rewrite H1; simpl; rewrite Nat.sub_0_r, Nat.add_comm.
Qed.
One possible variant is to perform directly a proof by induction on the property 0 <= n.
Require Import Arith.
Goal forall n, 1 <= n -> forall a, a = n - 1 -> a + 1 = n.
induction 1.
(* first case being considered is P 1. *)
now intros a a0; rewrite a0.
now simpl; intros a a_m; rewrite a_m, Nat.add_1_r, Nat.sub_0_r.
Qed.
This behavior is granted by the fact that the order _ <= _ is actually defined as an inductive relation.

Preserving structure with inductions on 2 variables

I've been learning about Coq's tactics and familiarizing myself with the system by reproving basic facts about natural numbers.
I've been trying to avoid using the theorems that are already proven in the library, and reproving things like the associativity of multiplication, etc.
However, I've been stymied in a couple of cases, where I have a property for n m:nat that I want to prove, but when I try to do induction on both n and m, the structure of the inductive hypothesises is useless for trying to prove the property.
I proved n = m -> o * n = o * m very easily:
Theorem times_alg_left : forall n m o:nat, n = m -> o * n = o * m.
intros n m o H.
rewrite H; reflexivity.
Defined.
But trying to prove S o * n = S o * m -> n = m completely flumoxed me. I decided, after considerable struggles, to try to prove 2 * n = 2 * m -> n = m, but that was no easier.
I end up with situations like this:
Theorem m2_eq : forall n m:nat, 2 * n = 2 * m -> n = m.
intros n m H.
induction n.
destruct m.
reflexivity.
discriminate.
induction m.
discriminate.
1 subgoal
n, m : nat
H : 2 * S n = 2 * S m
IHn : 2 * n = 2 * S m -> n = S m
IHm : 2 * S n = 2 * m -> (2 * n = 2 * m -> n = m) -> S n = m
______________________________________(1/1)
S n = S m
I've got 2 * S n = 2 * S m, but my inductive premises are talking about 2 * n = 2 * S m and 2 * S n = 2 * m.
I can't make anything happen from this situation.
Similarly, I started trying to proof things about Nat.sub and less than or equal to get around this limitation, but I ran into the same situation.
Theorem sub0_imp_le : forall n m:nat, n - m = 0 -> n <= m.
intros n m H.
induction n; induction m.
apply le_n.
apply le_0.
rewrite sub0 in H.
discriminate.
1 subgoal
n, m : nat
H : S n - S m = 0
IHn : n - S m = 0 -> n <= S m
IHm : S n - m = 0 -> (n - m = 0 -> n <= m) -> S n <= m
______________________________________(1/1)
S n <= S m
But I'm in the same pickle where my inductive premises are worthless.
How do I structure my tactics to solve these type of theorems, with 2 nat variables, and some kind of equality or subtraction situation going on?
You need to do induct on one number while generalizing the other, using the generalize dependent tactic, for instance. This is explained in detail in the Software Foundations book.
Using the Software Foundations book Arthur mentioned, I found the exmaple in question. I need to not introduce m before doing induction on n. I needed to do induction on n first instead, then introduce m.
https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html#lab143
Theorem times_alg_rem_left : forall n o m:nat, (S o) * n = (S o) * m -> n = m.
intros n o.
induction n.
simpl.
intros m eq.
destruct m.
reflexivity.
rewrite (timesz o) in eq.
simpl in eq.
discriminate.
intros m eq.
destruct m.
rewrite (timesz (S o)) in eq.
inversion eq.
apply f_equal.
apply IHn.
rewrite (times_nSm (S o) n) in eq.
rewrite (times_nSm (S o) m) in eq.
apply plus_alg_rem_right in eq.
assumption.
Defined.

even (n + m) -> even n /\ even m \/ odd n /\ odd m

How can I prove this lemma:
Lemma even_plus_split n m :
even (n + m) -> even n /\ even m \/ odd n /\ odd m.
These are the only libraries and definition that can be used:
Require Import Arith.
Require Import Coq.omega.Omega.
Definition even (n: nat) := exists k, n = 2 * k.
Definition odd (n: nat) := exists k, n = 2 * k + 1.
I am new to Coq and confused about it. Can you give me a solution? Thanks in advance!
the code so far:
Lemma even_plus_split n m :
even (n + m) -> even n /\ even m \/ odd n /\ odd m.
Proof.
intros.
unfold even.
unfold even in H.
destruct H as [k H].
unfold odd.
exists (1/2*k).
result so far:
1 subgoal
n, m, k : nat
H : n + m = 2 * k
______________________________________(1/1)
(exists k0 : nat, n = 2 * k0) /\ (exists k0 : nat, m = 2 * k0) \/
(exists k0 : nat, n = 2 * k0 + 1) /\ (exists k0 : nat, m = 2 * k0 + 1)
I just want to make k0 equals to 1/2*k, and therefore I suppose it would make sense, but I can't do that.
I just want to make k0 equals to 1/2*k, and therefore I suppose it would make sense, but I can't do that.
There is a function called Nat.div2, which divides a natural number by 2. Running Search Nat.div2.
Nat.le_div2: forall n : nat, Nat.div2 (S n) <= n
Nat.lt_div2: forall n : nat, 0 < n -> Nat.div2 n < n
Nat.div2_decr: forall a n : nat, a <= S n -> Nat.div2 a <= n
Nat.div2_wd: Morphisms.Proper (Morphisms.respectful eq eq) Nat.div2
Nat.div2_spec: forall a : nat, Nat.div2 a = Nat.shiftr a 1
Nnat.N2Nat.inj_div2: forall a : N, N.to_nat (N.div2 a) = Nat.div2 (N.to_nat a)
Nnat.Nat2N.inj_div2: forall n : nat, N.of_nat (Nat.div2 n) = N.div2 (N.of_nat n)
Nat.div2_double: forall n : nat, Nat.div2 (2 * n) = n
Nat.div2_div: forall a : nat, Nat.div2 a = a / 2
Nat.div2_succ_double: forall n : nat, Nat.div2 (S (2 * n)) = n
Nat.div2_odd: forall a : nat, a = 2 * Nat.div2 a + Nat.b2n (Nat.odd a)
Nat.div2_bitwise:
forall (op : bool -> bool -> bool) (n a b : nat),
Nat.div2 (Nat.bitwise op (S n) a b) = Nat.bitwise op n (Nat.div2 a) (Nat.div2 b)
Of these, the most promising seems to be Nat.div2_odd: forall a : nat, a = 2 * Nat.div2 a + Nat.b2n (Nat.odd a). If you pose proof this lemma, you can destruct (Nat.odd a) and use simpl to get that either a = 2 * Nat.div2 a or a = 2 * Nat.div2 a + 1, for whichever a you choose.
This may not give you a solution directly (I am not convinced that setting k0 to k / 2 is the right decision), but if it does not, you should make sure that you can figure out how to prove this fact on paper before you try it in Coq. Coq is very good at making sure that you don't make any jumps of logic that you're not allowed to make; it's extremely bad at helping you figure out how to prove a fact that you don't yet know how to prove.
Everybody who tries to answer seems to be dancing around the fact that you actually chose a wrong direction for this proof. Here is a example:
if n = 601 and m = 399, then n + m = 2 * 500,
n = 2 * 300 + 1, and m = 2 * 199 + 1.
Between 500, 300, and 199, the 1/2 ratio does not appear anywhere.
Still the statement (even n /\ even m) / (odd n /\ odd m) is definitely true.
So for now, you have more a math problem than a Coq problem.
You have to make a proof for universally quantified numbers n and m, but somehow this proof should also work for specific choices of these numbers. So in a sense you can make the mental exercise of testing your proof on examples.