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.