Coq theorem proving: Simple fraction law in peano arithmetic
Question
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).
Require Import Arith Even.
So we define:
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.
n, m: nat
en: even n
em: even mNat.div2 n + Nat.div2 m = Nat.div2 (n + m)m: nat
en: even 0
em: even mNat.div2 0 + Nat.div2 m = Nat.div2 (0 + m)n, m: nat
en: even (S n)
em: even m
IHn: even n -> Nat.div2 n + Nat.div2 m = Nat.div2 (n + m)Nat.div2 (S n) + Nat.div2 m = Nat.div2 (S n + m)reflexivity.m: nat
en: even 0
em: even mNat.div2 0 + Nat.div2 m = Nat.div2 (0 + m)n, m: nat
en: even (S n)
em: even m
IHn: even n -> Nat.div2 n + Nat.div2 m = Nat.div2 (n + m)Nat.div2 (S n) + Nat.div2 m = Nat.div2 (S 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.
Answer (Anton Trunov)
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.P: nat -> PropP 0 -> P 1 -> (forall n : nat, P n -> P (S n) -> P (S (S n))) -> forall n : nat, P nnow intros P0 P1 IH n; enough (H : P n /\ P (S n)); [|induction n]; intuition. Qed.P: nat -> PropP 0 -> P 1 -> (forall n : nat, P n -> P (S n) -> P (S (S n))) -> forall n : nat, P n
nat_ind2 can be used as follows:
n, m: nateven n -> even m -> Nat.div2 n + Nat.div2 m = Nat.div2 (n + m)n, m: nateven n -> even m -> Nat.div2 n + Nat.div2 m = Nat.div2 (n + m)(* here goes the rest of the proof *) Admitted.m: nateven 0 -> even m -> Nat.div2 0 + Nat.div2 m = Nat.div2 (0 + m)m: nateven 1 -> even m -> Nat.div2 1 + Nat.div2 m = Nat.div2 (1 + m)n, m: nat
IHn: even n -> even m -> Nat.div2 n + Nat.div2 m = Nat.div2 (n + m)
IHn0: even (S n) -> even m -> Nat.div2 (S n) + Nat.div2 m = Nat.div2 (S n + m)even (S (S n)) -> even m -> Nat.div2 (S (S n)) + Nat.div2 m = Nat.div2 (S (S n) + m)
Answer (larsr)
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.forall n m : nat, Even n -> Even m -> n / 2 + m / 2 = (n + m) / 2n, m: nat
H: Even n
x: nat
H0: n = 2 * x
H1: Even m
x0: nat
H2: m = 2 * x0n / 2 + m / 2 = (n + m) / 2x: nat
H: Even (2 * x)
x0: nat
H1: Even (2 * x0)2 * x / 2 + 2 * x0 / 2 = (2 * x + 2 * x0) / 2x: nat
H: Even (2 * x)
x0: nat
H1: Even (2 * x0)2 * x / 2 + 2 * x0 / 2 = 2 * (x + x0) / 2rewrite ?(div_mul); auto. Qed.x: nat
H: Even (2 * x)
x0: nat
H1: Even (2 * x0)x * 2 / 2 + x0 * 2 / 2 = (x + x0) * 2 / 2
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...