I have a proof for this that doesn't use mathcomp, but it is not even remotely idiomatic Coq.
It uses even induction.
It also uses opose proof
from JoJoModding's answer to one of my earlier questions to wire up the even induction. This tactic is not in the Coq standard library, but rather stdpp from this library.
Also, I use even z
to mean $\exists w \mathop. w + w = z$ not $\exists w \mathop. 2w = z$ for convenience. I use even'
with the latter definition.
From stdpp Require Import tactics.
From Coq Require Import Lia.
Ltac finisher := intuition ; firstorder ; (lia || idtac) ; eauto ; simpl.
Definition even x := exists z, z + z = x.
Lemma bool_lem : forall b, b = true \/ b = false.
Proof.
intro b.
induction b.
- finisher.
- finisher.
Qed.
Fixpoint even_func x :=
match x with
| O => true
| S O => false
| S (S x) => even_func x
end
.
Fixpoint even_induction (f : nat -> Type) (case0 : f 0) (case1 : f 1) (i : forall x, f x -> f (S (S x))) y :=
match y with
| O => case0
| S O => case1
| S (S w) => (i w) (even_induction f case0 case1 i w)
end
.
Lemma even_iff_even_func : forall x, even x <-> even_func x = true.
Proof.
opose proof (even_induction (fun x => even x <-> even_func x = true) _ _ _).
- simpl. assert (0 + 0 = 0) by finisher. unfold even. now finisher.
- simpl.
assert ((even 1 <-> false = true) <-> not (even 1)) by finisher.
apply H.
unfold even.
finisher.
- intro x.
intro H.
assert (even_func (S (S x)) = even_func x) by finisher.
rewrite H0.
assert (even_func x = true \/ even_func x = false) by now pose proof bool_lem (even_func x).
destruct H1.
+ assert (even x) by finisher.
intuition.
unfold even in H.
firstorder.
unfold even.
assert (S x0 + S x0 = S (S x)) by finisher.
finisher.
+ intuition.
* unfold even in H.
destruct H.
induction x0.
-- finisher.
-- assert (exists w, w + w = x).
++ assert (x0 + x0 = x) by finisher. finisher.
++ now pose proof H2 H4.
* unfold even in H4.
destruct H4.
assert (S x0 + S x0 = S (S x)) by finisher.
unfold even.
now finisher.
- finisher.
Qed.
Lemma even_iff_even_double_successor : forall x, even x <-> even (S (S x)).
Proof.
intro x.
enough (even_func x = even_func (S (S x))).
- pose proof even_iff_even_func x.
pose proof even_iff_even_func (S (S x)).
now finisher.
- now finisher.
Qed.
Lemma evenness_lemma_1 : forall x, even (3 * S (S x)) <-> even (3 * x).
Proof.
intro x.
pose proof even_iff_even_func (3 * S (S x)).
pose proof even_iff_even_func (3 * x).
enough (even_func (3 * (S (S x))) = even_func (3 * x)).
- now finisher.
- opose proof (even_induction (fun x => even_func (3 * (S (S x))) = even_func (3 * x)) _ _ _).
+ finisher.
+ finisher.
+ intro w.
intro I.
assert (3 * w = w + w + w) by finisher.
assert (3 * S( S( w)) = S( S( S( S( S( S( w + w + w ))))))) by finisher.
rewrite H1 in I.
rewrite H2 in I.
rewrite H2.
clear H1 H2.
assert (3 * S( S( S( S( w )))) = S(S(S(S( S(S(S(S( S(S(S(S(w + w + w))))))))))))) by finisher.
rewrite H1.
clear H1.
now finisher.
+ now finisher.
Qed.
Lemma evenness_lemma_2 : forall x, even (3 * x) <-> even x.
Proof.
intro x.
pose proof even_iff_even_func (3 * x).
pose proof even_iff_even_func x.
enough (even_func (3 * x) = even_func x).
- finisher.
- opose proof (even_induction (fun x => even_func (3 * x) = even_func x) _ _ _).
+ now finisher.
+ now finisher.
+ intro w.
intro I.
assert (3 * w = w + w + w) by finisher.
rewrite H1 in I.
clear H1.
assert (3 * S(S(w)) = S(S(S(S(S(S(w + w + w))))))) by finisher.
rewrite H1.
now clear H1.
+ now finisher.
Qed.
Theorem two_m_eq_3_n : forall m n, 2 * m = 3 * n -> even n.
Proof.
intro m.
intro n.
opose proof (even_induction (fun x => 2 * m = 3 * x -> even x) _ _ _).
- unfold even. now finisher.
- now finisher.
- finisher.
pose proof even_iff_even_double_successor x.
apply H1. clear H1.
assert (2 * m = m + m) by finisher.
assert (m + m = 3 * S (S x)) by finisher.
assert (even (3 * S (S x))) by finisher.
clear H0 H1 H2.
pose proof evenness_lemma_1 x.
assert (even (3 * x)) by finisher.
pose proof evenness_lemma_2 x.
now finisher.
- finisher.
Qed.
So yeah, it can be done with basically brute force.