logical-foundations/Induction.v
2024-03-30 16:38:15 -07:00

478 lines
8.9 KiB
Coq

From LF Require Export Basics.
Theorem add_0_r : forall n : nat,
n + 0 = n.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem minus_n_n : forall n,
n - n = 0.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem mul_0_r : forall n : nat,
n * 0 = 0.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem plus_n_Sm : forall n m : nat,
S (n + m) = n + (S m).
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- intros m.
simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem add_comm : forall n m : nat,
n + m = m + n.
Proof.
induction n as [ | n' IHn'].
- intros m.
rewrite add_0_r.
reflexivity.
- intros m.
simpl.
rewrite plus_n_Sm.
rewrite IHn'.
simpl.
rewrite plus_n_Sm.
reflexivity.
Qed.
Theorem sn_eq_sm_n_eq_m : forall n m : nat,
S n = S m -> n = m.
Proof.
intros n m H.
inversion H.
reflexivity.
Qed.
Theorem n_eq_m_sn_eq_sm : forall n m : nat,
n = m -> S n = S m.
Proof.
intros n m H.
rewrite H.
reflexivity.
Qed.
Theorem add_assoc : forall n m p : nat,
n + (m + p) = (n + m) + p.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
intros m p.
apply n_eq_m_sn_eq_sm.
rewrite IHn'.
reflexivity.
Qed.
Fixpoint double (n : nat) :=
match n with
| O => O
| S n' => S (S (double n'))
end.
Lemma double_plus : forall n, double n = n + n.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
apply n_eq_m_sn_eq_sm.
rewrite IHn'.
apply plus_n_Sm.
Qed.
Theorem eqb_refl : forall n : nat,
(n =? n) = true.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem even_S : forall n : nat,
even (S n) = negb (even n).
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- rewrite IHn'.
rewrite negb_involutive.
reflexivity.
Qed.
Theorem mult_0_plus' : forall n m : nat,
(n + 0 + 0) * m = n * m.
Proof.
intros n m.
assert (H : n + 0 + 0 = n).
- rewrite add_comm.
simpl.
rewrite add_comm.
reflexivity.
- rewrite H.
reflexivity.
Qed.
Lemma n_zero_zero : forall n : nat,
n * 0 = 0.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem add_shuffle3 : forall n m p : nat,
n + (m + p) = m + (n + p).
Proof.
intros n m p.
rewrite add_assoc.
assert (H: n + m = m + n).
{ rewrite add_comm. reflexivity. }
rewrite H.
rewrite add_assoc.
reflexivity.
Qed.
Lemma shuffle_4 : forall (a b c d : nat),
(a + b) + (c + d) = (a + c) + (b + d).
Proof.
intros a b c d.
assert (H: a + b + (c + d) = a + ((b + c) + d)).
{ rewrite add_assoc. rewrite add_assoc. rewrite add_assoc. reflexivity. }
rewrite H.
assert (H1: b + c = c + b).
{ rewrite add_comm. reflexivity. }
rewrite H1.
rewrite add_assoc.
rewrite add_assoc.
rewrite add_assoc.
reflexivity.
Qed.
Theorem mult_plus_distr_l : forall (n m k : nat),
n * (m + k) = n * m + n * k.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- intros m k.
simpl.
rewrite IHn'.
rewrite shuffle_4.
reflexivity.
Qed.
Theorem n_one_n : forall n : nat,
n * 1 = n.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem mul_comm : forall m n : nat,
m * n = n * m.
Proof.
induction n as [ | n' IHn'].
- rewrite n_zero_zero.
reflexivity.
- simpl.
assert (H: S n' = n' + 1).
{ rewrite add_comm. reflexivity. }
rewrite H.
rewrite mult_plus_distr_l.
rewrite n_one_n.
rewrite IHn'.
rewrite add_comm.
reflexivity.
Qed.
Theorem plus_leb_compact_l : forall n m p : nat,
n <=? m = true -> (p + n) <=? (p + m) = true.
Proof.
induction p as [ | p' IHp'].
- auto.
- intros H.
simpl.
apply IHp'.
rewrite H.
reflexivity.
Qed.
Theorem leb_refl : forall n : nat,
(n <=? n) = true.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite IHn'.
reflexivity.
Qed.
Theorem zero_neqb_S : forall n : nat,
0 =? (S n) = false.
Proof.
reflexivity.
Qed.
Theorem andb_false_r : forall b : bool,
andb b false = false.
Proof.
intros.
rewrite andb_commutative.
reflexivity.
Qed.
Theorem S_neqb_0 : forall n : nat,
(S n) =? 0 = false.
Proof.
reflexivity.
Qed.
Theorem mult_1_l : forall n : nat, 1 * n = n.
Proof.
intros n.
simpl.
rewrite add_0_r.
reflexivity.
Qed.
Theorem all3_spec : forall b c : bool,
b && c || (negb b || negb c) = true.
Proof.
intros [] [].
- reflexivity.
- reflexivity.
- reflexivity.
- reflexivity.
Qed.
Theorem mult_plus_distr_r : forall n m p : nat,
(n + m) * p = (n * p) + (m * p).
Proof.
induction p as [ | p' IHp'].
- rewrite n_zero_zero.
rewrite n_zero_zero.
rewrite n_zero_zero.
reflexivity.
- rewrite mul_comm.
simpl.
rewrite mul_comm.
rewrite IHp'.
assert (H: forall n', n' * S p' = S p' * n').
{ intros. rewrite mul_comm. reflexivity. }
rewrite H.
rewrite H.
simpl.
rewrite shuffle_4.
assert (H': forall n', p' * n' = n' * p').
{ intros. rewrite mul_comm. reflexivity. }
rewrite H'.
rewrite H'.
reflexivity.
Qed.
Theorem mult_assoc : forall n m p : nat,
n * (m * p) = (n * m) * p.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- intros.
simpl.
rewrite mult_plus_distr_r.
rewrite IHn'.
reflexivity.
Qed.
Theorem add_shuffle3' : forall n m p : nat,
n + (m + p) = m + (n + p).
Proof.
intros.
rewrite add_assoc.
rewrite add_assoc.
replace (n + m) with (m + n).
- reflexivity.
- rewrite add_comm.
reflexivity.
Qed.
Inductive bin : Type :=
| Z
| B0 (n : bin)
| B1 (n : bin).
Fixpoint incr (m : bin) : bin :=
match m with
| Z => B1 Z
| B0 b => B1 b
| B1 b => B0 (incr b)
end.
Fixpoint bin_to_nat (m : bin) : nat :=
match m with
| Z => O
| B0 b => 2 * bin_to_nat b
| B1 b => 1 + 2 * bin_to_nat b
end.
Theorem sn_np1 : forall n : nat,
S n = n + 1.
Proof.
intros.
rewrite add_comm.
reflexivity.
Qed.
Theorem add_both_r : forall n m k : nat,
n = m -> n + k = m + k.
Proof.
intros n m k H.
rewrite H.
reflexivity.
Qed.
Theorem add_cancel_r : forall n m k : nat,
n + k = m + k -> n = m.
Proof.
induction k as [ | k' IHk'].
- rewrite add_0_r.
rewrite add_0_r.
intro H.
rewrite H.
reflexivity.
- simpl.
rewrite <- plus_n_Sm.
rewrite <- plus_n_Sm.
intro H.
inversion H.
apply IHk'.
rewrite H1.
reflexivity.
Qed.
Theorem bin_to_nat_pres_incr : forall b : bin,
bin_to_nat (incr b) = S (bin_to_nat b).
Proof.
induction b as [ | b0 | b1 IHb].
- reflexivity.
- reflexivity.
- simpl.
rewrite add_0_r.
rewrite IHb.
rewrite add_0_r.
rewrite sn_np1.
assert (H: S (S (bin_to_nat b1 + bin_to_nat b1)) = S (bin_to_nat b1 + bin_to_nat b1) + 1).
{ rewrite sn_np1. reflexivity. }
rewrite H.
assert (H1 : S (bin_to_nat b1 + bin_to_nat b1) + 1 = bin_to_nat b1 + bin_to_nat b1 + 1 + 1).
{ rewrite sn_np1. reflexivity. }
rewrite H1.
rewrite shuffle_4.
rewrite add_assoc.
reflexivity.
Qed.
Fixpoint nat_to_bin (n : nat) : bin :=
match n with
| O => Z
| S n' => incr (nat_to_bin n')
end.
Theorem nat_bin_nat : forall n : nat,
bin_to_nat (nat_to_bin n) = n.
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite bin_to_nat_pres_incr.
rewrite IHn'.
reflexivity.
Qed.
Lemma double_incr : forall n : nat,
double (S n) = S (S (double n)).
Proof.
intros [ | n' ].
- reflexivity.
- simpl.
reflexivity.
Qed.
Definition double_bin (b : bin) : bin :=
match b with
| Z => Z
| b' => B0 b'
end.
Lemma double_incr_bin : forall b,
double_bin (incr b) = incr (incr (double_bin b)).
Proof.
intros [ | b0 | b1 ] ; reflexivity.
Qed.
Fixpoint normalize (b : bin) : bin :=
match b with
| B0 Z => Z
| Z => Z
| B0 b' => double_bin (normalize b')
| B1 b' => B1 (normalize b')
end.
Theorem double_natural : forall n : nat,
nat_to_bin (double n) = double_bin (nat_to_bin n).
Proof.
induction n as [ | n' IHn'].
- reflexivity.
- simpl.
rewrite double_incr_bin.
rewrite IHn'.
reflexivity.
Qed.
Lemma incr_double_B1 : forall b,
incr (double_bin b) = B1 b.
Proof.
induction b as [ | b0 IHb0 | b1 IHb1] ; reflexivity.
Qed.
Theorem bin_nat_bin : forall b, nat_to_bin (bin_to_nat b) = normalize b.
induction b as [ | b0 IHb0 | b1 IHb1].
- reflexivity.
- simpl.
rewrite add_0_r.
rewrite <- double_plus.
rewrite double_natural.
rewrite IHb0.
destruct b0 as [ | b0' | b1'] ; reflexivity.
- simpl.
rewrite add_0_r.
rewrite <- double_plus.
rewrite double_natural.
rewrite IHb1.
rewrite incr_double_B1.
reflexivity.
Qed.