feat: 3234 week 3
This commit is contained in:
parent
01ffa3b6aa
commit
14e3095632
581
cs3234/labs/week-03_specifications.v
Normal file
581
cs3234/labs/week-03_specifications.v
Normal file
@ -0,0 +1,581 @@
|
||||
(* week-03_specifications.v *)
|
||||
(* LPP 2023 - CS3234 2023-2024, Sem2 *)
|
||||
(* Olivier Danvy <danvy@yale-nus.edu.sg> *)
|
||||
(* Version of 01 Feb 2024 *)
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Paraphernalia: *)
|
||||
|
||||
Require Import Arith.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Definition recursive_specification_of_addition (add : nat -> nat -> nat) :=
|
||||
(forall y : nat,
|
||||
add O y = y)
|
||||
/\
|
||||
(forall x' y : nat,
|
||||
add (S x') y = S (add x' y)).
|
||||
|
||||
Definition lambda_dropped_recursive_specification_of_addition (add : nat -> nat -> nat) :=
|
||||
(forall y : nat,
|
||||
add 0 y = y
|
||||
/\ forall x' : nat,
|
||||
add (S x') y = S (add x' y)).
|
||||
|
||||
Proposition there_is_at_most_one_recursive_addition :
|
||||
forall add1 add2 : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add1 ->
|
||||
recursive_specification_of_addition add2 ->
|
||||
forall x y : nat,
|
||||
add1 x y = add2 x y.
|
||||
Proof.
|
||||
intros add1 add2.
|
||||
unfold recursive_specification_of_addition.
|
||||
intros [H_add1_0 H_add1_S].
|
||||
intros [H_add2_0 H_add2_S].
|
||||
intro x.
|
||||
induction x as [| x' IHx].
|
||||
- intro y.
|
||||
rewrite H_add1_0.
|
||||
rewrite H_add2_0.
|
||||
reflexivity.
|
||||
- intro y.
|
||||
rewrite H_add1_S.
|
||||
rewrite H_add2_S.
|
||||
rewrite IHx.
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
intros add1 add2.
|
||||
unfold recursive_specification_of_addition.
|
||||
intros [H_add1_O H_add1_S] [H_add2_O H_add2_S].
|
||||
intro x.
|
||||
|
||||
induction x as [| x' IHx'].
|
||||
- intro y.
|
||||
rewrite -> (H_add2_O y).
|
||||
Check (H_add1_O y).
|
||||
exact (H_add1_O y).
|
||||
- intro y.
|
||||
rewrite -> (H_add1_S x' y).
|
||||
rewrite -> (H_add2_S x' y).
|
||||
|
||||
Check (IHx' y).
|
||||
rewrite -> (IHx' y).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Definition tail_recursive_specification_of_addition (add : nat -> nat -> nat) :=
|
||||
(forall y : nat,
|
||||
add O y = y)
|
||||
/\
|
||||
(forall x' y : nat,
|
||||
add (S x') y = add x' (S y)).
|
||||
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 01 *)
|
||||
|
||||
Proposition there_is_at_most_one_tail_recursive_addition :
|
||||
forall add1 add2 : nat -> nat -> nat,
|
||||
tail_recursive_specification_of_addition add1 ->
|
||||
tail_recursive_specification_of_addition add2 ->
|
||||
forall x y : nat,
|
||||
add1 x y = add2 x y.
|
||||
Proof.
|
||||
intros add1 add2.
|
||||
unfold tail_recursive_specification_of_addition.
|
||||
intros [H_add1_O H_add1_S] [H_add2_O H_add2_S].
|
||||
intros x y.
|
||||
induction x as [| x' IHx'].
|
||||
- rewrite -> (H_add2_O y).
|
||||
exact (H_add1_O y).
|
||||
|
||||
- rewrite -> (H_add1_S x' y).
|
||||
rewrite -> (H_add2_S x' y).
|
||||
(* rewrite -> (IHx' (S y)). *)
|
||||
|
||||
Restart.
|
||||
intros add1 add2.
|
||||
unfold tail_recursive_specification_of_addition.
|
||||
intros [H_add1_O H_add1_S] [H_add2_O H_add2_S].
|
||||
intro x.
|
||||
induction x as [| x' IHx'].
|
||||
- intro y.
|
||||
rewrite -> (H_add2_O y).
|
||||
exact (H_add1_O y).
|
||||
- intro y.
|
||||
rewrite -> (H_add1_S x' y).
|
||||
rewrite -> (H_add2_S x' y).
|
||||
rewrite -> (IHx' (S y)).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Definition specification_of_the_predecessor_function (pred : nat -> nat) :=
|
||||
forall n : nat,
|
||||
pred (S n) = n.
|
||||
|
||||
Proposition there_is_at_most_one_predecessor_function :
|
||||
forall pred1 pred2 : nat -> nat,
|
||||
specification_of_the_predecessor_function pred1 ->
|
||||
specification_of_the_predecessor_function pred2 ->
|
||||
forall n : nat,
|
||||
pred1 n = pred2 n.
|
||||
Proof.
|
||||
intros pred1 pred2.
|
||||
unfold specification_of_the_predecessor_function.
|
||||
intros H_pred1_S H_pred2_S.
|
||||
intro n.
|
||||
induction n as [ | n' IHn'].
|
||||
Abort.
|
||||
|
||||
Definition make_predecessor_function (zero n : nat) :=
|
||||
match n with
|
||||
| 0 => zero
|
||||
| S n' => n'
|
||||
end.
|
||||
|
||||
Lemma about_make_predecessor_function :
|
||||
forall zero : nat,
|
||||
specification_of_the_predecessor_function (make_predecessor_function zero).
|
||||
Proof.
|
||||
intro zero.
|
||||
unfold specification_of_the_predecessor_function.
|
||||
induction n as [| n' IHn' ].
|
||||
|
||||
- unfold make_predecessor_function.
|
||||
reflexivity.
|
||||
- unfold make_predecessor_function.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem there_are_at_least_two_predecessor_functions :
|
||||
exists pred1 pred2 : nat -> nat,
|
||||
specification_of_the_predecessor_function pred1 /\
|
||||
specification_of_the_predecessor_function pred2 /\
|
||||
exists n : nat,
|
||||
pred1 n <> pred2 n.
|
||||
Proof.
|
||||
exists (make_predecessor_function 0).
|
||||
exists (make_predecessor_function 1).
|
||||
split.
|
||||
|
||||
- exact (about_make_predecessor_function 0).
|
||||
|
||||
- split.
|
||||
|
||||
-- exact (about_make_predecessor_function 0).
|
||||
|
||||
|
||||
-- exists 0.
|
||||
unfold make_predecessor_function.
|
||||
Search (_ <> S _).
|
||||
Check (n_Sn 0).
|
||||
exact (n_Sn 0).
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Definition specification_of_the_total_predecessor_function (pred : nat -> option nat) :=
|
||||
(pred 0 = None)
|
||||
/\
|
||||
(forall n : nat,
|
||||
pred (S n) = Some n).
|
||||
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 02 *)
|
||||
|
||||
Proposition there_is_at_most_one_total_predecessor_function :
|
||||
forall pred1 pred2 : nat -> option nat,
|
||||
specification_of_the_total_predecessor_function pred1 ->
|
||||
specification_of_the_total_predecessor_function pred2 ->
|
||||
forall n : nat,
|
||||
pred1 n = pred2 n.
|
||||
Proof.
|
||||
intros pred1 pred2.
|
||||
unfold specification_of_the_total_predecessor_function.
|
||||
intros [H_pred1_O H_pred1_S] [H_pred2_O H_pred2_S].
|
||||
intro n.
|
||||
induction n as [ | n' IHn'].
|
||||
|
||||
- rewrite -> H_pred2_O.
|
||||
exact H_pred1_O.
|
||||
|
||||
- rewrite -> (H_pred2_S n').
|
||||
exact (H_pred1_S n').
|
||||
|
||||
Restart.
|
||||
|
||||
intros pred1 pred2.
|
||||
unfold specification_of_the_total_predecessor_function.
|
||||
intros [H_pred1_O H_pred1_S] [H_pred2_O H_pred2_S].
|
||||
intros [ | n'].
|
||||
|
||||
- rewrite -> H_pred2_O.
|
||||
exact H_pred1_O.
|
||||
|
||||
- rewrite -> (H_pred2_S n').
|
||||
exact (H_pred1_S n').
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Definition specification_of_the_predecessor_and_successor_function (ps : nat -> nat) :=
|
||||
(forall n : nat,
|
||||
ps (S n) = n)
|
||||
/\
|
||||
(forall n : nat,
|
||||
ps n = (S n)).
|
||||
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 03 *)
|
||||
|
||||
Theorem there_is_at_most_one_predecessor_and_successor_function :
|
||||
forall ps1 ps2 : nat -> nat,
|
||||
specification_of_the_predecessor_and_successor_function ps1 ->
|
||||
specification_of_the_predecessor_and_successor_function ps2 ->
|
||||
forall n : nat,
|
||||
ps1 n = ps2 n.
|
||||
Proof.
|
||||
intros ps1 ps2.
|
||||
unfold specification_of_the_predecessor_and_successor_function.
|
||||
intros [H_ps1_Sn_n H_ps1_n_Sn] [H_ps2_Sn_n H_ps2_n_Sn].
|
||||
induction n as [| n' IHn'].
|
||||
- Check (H_ps1_n_Sn 0).
|
||||
rewrite (H_ps1_n_Sn 0).
|
||||
rewrite (H_ps2_n_Sn 0).
|
||||
reflexivity.
|
||||
- rewrite -> (H_ps1_Sn_n n').
|
||||
rewrite -> (H_ps2_Sn_n n').
|
||||
reflexivity.
|
||||
|
||||
Abort.
|
||||
|
||||
(* ***** *)
|
||||
|
||||
Lemma a_contradictory_aspect_of_the_predecessor_and_successor_function :
|
||||
forall ps : nat -> nat,
|
||||
specification_of_the_predecessor_and_successor_function ps ->
|
||||
ps 1 = 0 /\ ps 1 = 2.
|
||||
Proof.
|
||||
intro ps.
|
||||
unfold specification_of_the_predecessor_and_successor_function.
|
||||
intros [H_ps_S H_ps].
|
||||
split.
|
||||
|
||||
- rewrite -> (H_ps_S 0).
|
||||
reflexivity.
|
||||
|
||||
- rewrite -> (H_ps 1).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem there_are_zero_predecessor_and_successor_functions :
|
||||
forall ps : nat -> nat,
|
||||
specification_of_the_predecessor_and_successor_function ps ->
|
||||
exists n : nat,
|
||||
ps n <> ps n.
|
||||
Proof.
|
||||
intros ps S_ps.
|
||||
Check (a_contradictory_aspect_of_the_predecessor_and_successor_function ps S_ps).
|
||||
destruct (a_contradictory_aspect_of_the_predecessor_and_successor_function ps S_ps) as [H_ps_0 H_ps_2].
|
||||
exists 1.
|
||||
rewrite -> H_ps_0.
|
||||
|
||||
Restart.
|
||||
|
||||
intros ps S_ps.
|
||||
Check (a_contradictory_aspect_of_the_predecessor_and_successor_function ps S_ps).
|
||||
destruct (a_contradictory_aspect_of_the_predecessor_and_successor_function ps S_ps) as [H_ps_0 H_ps_2].
|
||||
exists 1.
|
||||
rewrite -> H_ps_0 at 1.
|
||||
rewrite -> H_ps_2.
|
||||
Search (0 <> S _).
|
||||
Check (O_S 1).
|
||||
exact (O_S 1).
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Theorem the_resident_addition_function_satisfies_the_recursive_specification_of_addition :
|
||||
recursive_specification_of_addition Nat.add.
|
||||
Proof.
|
||||
unfold recursive_specification_of_addition.
|
||||
split.
|
||||
- intro y.
|
||||
Search (0 + _ = _).
|
||||
exact (Nat.add_0_l y).
|
||||
- intros x' y.
|
||||
Search (S _ + _ = S (_ + _)).
|
||||
exact (Nat.add_succ_l x' y).
|
||||
Qed.
|
||||
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 04 *)
|
||||
|
||||
Theorem the_resident_addition_function_satisfies_the_tail_recursive_specification_of_addition :
|
||||
tail_recursive_specification_of_addition Nat.add.
|
||||
Proof.
|
||||
unfold tail_recursive_specification_of_addition.
|
||||
split.
|
||||
- intro y.
|
||||
exact (Nat.add_0_l y).
|
||||
- intros x' y.
|
||||
Search (S _ + _ = _ + S _).
|
||||
exact (Nat.add_succ_comm x' y).
|
||||
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Exercise 05 *)
|
||||
|
||||
Theorem the_two_specifications_of_addition_are_equivalent :
|
||||
forall add : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add <-> tail_recursive_specification_of_addition add.
|
||||
Proof.
|
||||
intro add.
|
||||
unfold recursive_specification_of_addition.
|
||||
unfold tail_recursive_specification_of_addition.
|
||||
split.
|
||||
- intros [H_add_O H_add_S].
|
||||
split.
|
||||
* exact H_add_O.
|
||||
* intros x'.
|
||||
induction x' as [| x'' IHx''].
|
||||
+ intro y.
|
||||
Check (H_add_S 0 y).
|
||||
rewrite -> (H_add_S 0 y).
|
||||
rewrite -> (H_add_O y).
|
||||
rewrite -> (H_add_O (S y)).
|
||||
reflexivity.
|
||||
+ intro y.
|
||||
rewrite -> (H_add_S (S x'') y).
|
||||
rewrite -> (H_add_S x'' (S y)).
|
||||
rewrite IHx''.
|
||||
reflexivity.
|
||||
- intros [H_add_O H_add_S].
|
||||
split.
|
||||
* exact H_add_O.
|
||||
* intro x'.
|
||||
induction x' as [| x'' IHx''].
|
||||
+ intro y.
|
||||
rewrite -> (H_add_O y).
|
||||
rewrite -> (H_add_S 0 y).
|
||||
rewrite -> (H_add_O (S y)).
|
||||
reflexivity.
|
||||
+ intro y.
|
||||
rewrite -> (H_add_S (S x'') y).
|
||||
rewrite -> (IHx'' (S y)).
|
||||
rewrite <- (H_add_S x'' y).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Exercise 06a *)
|
||||
|
||||
Theorem associativity_of_recursive_addition :
|
||||
forall add : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add ->
|
||||
forall n1 n2 n3 : nat,
|
||||
add n1 (add n2 n3) = add (add n1 n2) n3.
|
||||
Proof.
|
||||
intro add.
|
||||
unfold recursive_specification_of_addition.
|
||||
intros [H_add_O H_add_S].
|
||||
intros x.
|
||||
induction x as [| x' IHx'].
|
||||
- intros y z.
|
||||
rewrite (H_add_O (add y z)).
|
||||
rewrite (H_add_O y).
|
||||
reflexivity.
|
||||
- intros y z.
|
||||
rewrite -> (H_add_S x' (add y z)).
|
||||
rewrite -> (H_add_S x' y).
|
||||
rewrite -> (H_add_S (add x' y) z).
|
||||
rewrite -> IHx'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
Lemma about_the_tail_recursive_addition_function :
|
||||
forall add: nat -> nat -> nat,
|
||||
tail_recursive_specification_of_addition add ->
|
||||
forall x y : nat,
|
||||
add (S x) y = S (add x y).
|
||||
Proof.
|
||||
intro add.
|
||||
unfold tail_recursive_specification_of_addition.
|
||||
intros [H_add_O H_add_S].
|
||||
intro x.
|
||||
induction x as [| x' IHx'].
|
||||
- intro y.
|
||||
rewrite -> (H_add_O y).
|
||||
rewrite -> (H_add_S 0 y).
|
||||
rewrite -> (H_add_O (S y)).
|
||||
reflexivity.
|
||||
- intro y.
|
||||
rewrite -> (H_add_S x' y).
|
||||
rewrite <- (IHx' (S y)).
|
||||
rewrite -> (H_add_S (S x') y).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem associativity_of_tail_recursive_addition :
|
||||
forall add : nat -> nat -> nat,
|
||||
tail_recursive_specification_of_addition add ->
|
||||
forall n1 n2 n3 : nat,
|
||||
add n1 (add n2 n3) = add (add n1 n2) n3.
|
||||
Proof.
|
||||
intros add H_add.
|
||||
assert (H_tmp := H_add).
|
||||
destruct H_tmp as [H_add_O H_add_S].
|
||||
intros x.
|
||||
induction x as [| x' IHx'].
|
||||
- intros y z.
|
||||
rewrite (H_add_O (add y z)).
|
||||
rewrite (H_add_O y).
|
||||
reflexivity.
|
||||
- intros y z.
|
||||
rewrite -> (H_add_S x' (add y z)).
|
||||
rewrite -> (H_add_S x' y).
|
||||
rewrite <- (IHx' (S y) z).
|
||||
rewrite -> (about_the_tail_recursive_addition_function add H_add y z).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Exercise 07 *)
|
||||
|
||||
Lemma commutativity_of_recursive_addition_O :
|
||||
forall add : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add ->
|
||||
forall n : nat,
|
||||
add n O = n.
|
||||
Proof.
|
||||
intro add.
|
||||
unfold recursive_specification_of_addition.
|
||||
intros [H_add_O H_add_S].
|
||||
intro n.
|
||||
induction n as [| n' IHn'].
|
||||
- exact (H_add_O 0).
|
||||
- rewrite -> (H_add_S n' 0).
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma commutativity_of_recursive_addition_S :
|
||||
forall add : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add ->
|
||||
forall n1 n2 : nat,
|
||||
add n1 (S n2) = S (add n1 n2).
|
||||
Proof.
|
||||
intros add H_add.
|
||||
assert (H_tmp := H_add).
|
||||
unfold recursive_specification_of_addition.
|
||||
destruct H_tmp as [H_add_O H_add_S].
|
||||
intro x.
|
||||
induction x as [| x' IHx'].
|
||||
- intro y.
|
||||
rewrite (H_add_O (S y)).
|
||||
rewrite (H_add_O y).
|
||||
reflexivity.
|
||||
- intro y.
|
||||
rewrite -> (H_add_S x' (S y)).
|
||||
rewrite -> (IHx' y).
|
||||
rewrite -> (H_add_S x' y).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem commutativity_of_recursive_addition :
|
||||
forall add : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add ->
|
||||
forall n1 n2 : nat,
|
||||
add n1 n2 = add n2 n1.
|
||||
Proof.
|
||||
intros add S_add.
|
||||
assert (H_add_O := commutativity_of_recursive_addition_O add S_add).
|
||||
assert (H_add_S := commutativity_of_recursive_addition_S add S_add).
|
||||
unfold recursive_specification_of_addition in S_add.
|
||||
destruct S_add as [S_add_O S_add_S].
|
||||
intro x.
|
||||
induction x as [| x' IHx'].
|
||||
- intro y.
|
||||
rewrite -> (S_add_O y).
|
||||
rewrite -> (H_add_O y).
|
||||
reflexivity.
|
||||
- intro y.
|
||||
rewrite -> (S_add_S x' y).
|
||||
rewrite -> (H_add_S y).
|
||||
rewrite -> (IHx' y).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Exercise 08a *)
|
||||
|
||||
Theorem O_is_left_neutral_for_recursive_addition :
|
||||
forall add : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add ->
|
||||
forall n : nat,
|
||||
add 0 n = n.
|
||||
Proof.
|
||||
intros add.
|
||||
unfold recursive_specification_of_addition.
|
||||
intros [H_add_O _].
|
||||
exact H_add_O.
|
||||
Qed.
|
||||
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 08b *)
|
||||
|
||||
Theorem O_is_right_neutral_for_recursive_addition :
|
||||
forall add : nat -> nat -> nat,
|
||||
recursive_specification_of_addition add ->
|
||||
forall n : nat,
|
||||
add n 0 = n.
|
||||
Proof.
|
||||
intros add S_add.
|
||||
unfold recursive_specification_of_addition in S_add.
|
||||
intro n.
|
||||
rewrite -> (commutativity_of_recursive_addition add S_add n).
|
||||
rewrite -> (O_is_left_neutral_for_recursive_addition add S_add n).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 08c *)
|
||||
Theorem O_is_left_neutral_for_tail_recursive_addition :
|
||||
forall add : nat -> nat -> nat,
|
||||
tail_recursive_specification_of_addition add ->
|
||||
forall n : nat,
|
||||
add 0 n = n.
|
||||
Proof.
|
||||
intros add.
|
||||
unfold tail_recursive_specification_of_addition.
|
||||
intros [H_add_O _].
|
||||
exact H_add_O.
|
||||
Qed.
|
||||
Theorem O_is_right_neutral_for_tail_recursive_addition :
|
||||
forall add : nat -> nat -> nat,
|
||||
tail_recursive_specification_of_addition add ->
|
||||
forall n: nat,
|
||||
add n 0 = n.
|
||||
Proof.
|
||||
Admitted.
|
||||
(* end of week-03_specifications.v *)
|
134
cs3234/labs/week-03_structural-induction-over-Peano-numbers.v
Normal file
134
cs3234/labs/week-03_structural-induction-over-Peano-numbers.v
Normal file
@ -0,0 +1,134 @@
|
||||
(* week-03_structural-induction-over-Peano-numbers.v *)
|
||||
(* LPP 2023 - CS3234 2023-2024, Sem2 *)
|
||||
(* Olivier Danvy <danvy@yale-nus.edu.sg> *)
|
||||
(* Version of 05 Feb 2024, with a revisitation of Proposition add_0_r_v0 that uses the induction tactic *)
|
||||
(* was: *)
|
||||
(* Version of 02 Feb 2024 *)
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Definition specification_of_the_addition_function_1 (add : nat -> nat -> nat) :=
|
||||
(forall j : nat,
|
||||
add O j = j)
|
||||
/\
|
||||
(forall i' j : nat,
|
||||
add (S i') j = S (add i' j)).
|
||||
|
||||
Check nat_ind.
|
||||
(*
|
||||
nat_ind
|
||||
: forall P : nat -> Prop, P 0 -> (forall n : nat, P n -> P (S n)) -> forall n : nat, P n
|
||||
*)
|
||||
|
||||
Proposition add_0_r_v0 :
|
||||
forall add : nat -> nat -> nat,
|
||||
specification_of_the_addition_function_1 add ->
|
||||
forall n : nat,
|
||||
add n 0 = n.
|
||||
Proof.
|
||||
intro add.
|
||||
unfold specification_of_the_addition_function_1.
|
||||
intros [S_add_O S_add_S].
|
||||
Check nat_ind.
|
||||
Check (nat_ind
|
||||
(fun n => add n 0 = n)).
|
||||
Check (S_add_O 0).
|
||||
Check (nat_ind
|
||||
(fun n => add n 0 = n)
|
||||
(S_add_O 0)).
|
||||
apply (nat_ind
|
||||
(fun n => add n 0 = n)
|
||||
(S_add_O 0)).
|
||||
intro n'.
|
||||
intro IHn'.
|
||||
Check (S_add_S n' 0).
|
||||
rewrite -> (S_add_S n' 0).
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Search (0 + _ = _).
|
||||
(* plus_O_n: forall n : nat, 0 + n = n *)
|
||||
Search (S _ + _ = _).
|
||||
(* plus_Sn_m: forall n m : nat, S n + m = S (n + m) *)
|
||||
|
||||
Proposition add_0_r_v1 :
|
||||
forall n : nat,
|
||||
n + 0 = n.
|
||||
Proof.
|
||||
Check nat_ind.
|
||||
Check (nat_ind
|
||||
(fun n => n + 0 = n)).
|
||||
Check plus_O_n.
|
||||
Check (plus_O_n 0).
|
||||
Check (nat_ind
|
||||
(fun n => n + 0 = n)
|
||||
(plus_O_n 0)).
|
||||
apply (nat_ind
|
||||
(fun n => n + 0 = n)
|
||||
(plus_O_n 0)).
|
||||
intros n'.
|
||||
intros IHn'.
|
||||
|
||||
Check (plus_Sn_m n' 0).
|
||||
rewrite -> (plus_Sn_m n' 0).
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intro n.
|
||||
induction n using nat_ind.
|
||||
- Check (plus_O_n 0).
|
||||
exact (plus_O_n 0).
|
||||
- revert n IHn.
|
||||
intros n' IHn'.
|
||||
Check (plus_Sn_m n' 0).
|
||||
rewrite -> (plus_Sn_m n' 0).
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intro n.
|
||||
induction n as [ | n' IHn'] using nat_ind.
|
||||
- Check (plus_O_n 0).
|
||||
exact (plus_O_n 0).
|
||||
- Check (plus_Sn_m n' 0).
|
||||
rewrite -> (plus_Sn_m n' 0).
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intro n.
|
||||
induction n as [ | n' IHn'].
|
||||
- Check (plus_O_n 0).
|
||||
exact (plus_O_n 0).
|
||||
- Check (plus_Sn_m n' 0).
|
||||
rewrite -> (plus_Sn_m n' 0).
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Proposition add_0_r_v0_revisited :
|
||||
forall add : nat -> nat -> nat,
|
||||
specification_of_the_addition_function_1 add ->
|
||||
forall n : nat,
|
||||
add n 0 = n.
|
||||
Proof.
|
||||
intro add.
|
||||
unfold specification_of_the_addition_function_1.
|
||||
intros [S_add_O S_add_S].
|
||||
intro n.
|
||||
induction n as [ | n' IHn'].
|
||||
- exact (S_add_O 0).
|
||||
- rewrite -> (S_add_S n' 0).
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* end of week-03_structural-induction-over-Peano-numbers.v *)
|
||||
|
389
cs3234/labs/week-03_structural-induction-over-binary-trees.v
Normal file
389
cs3234/labs/week-03_structural-induction-over-binary-trees.v
Normal file
@ -0,0 +1,389 @@
|
||||
(* week-03_induction-over-binary-trees.v *)
|
||||
(* LPP 2023 - CS3234 2023-2024, Sem2 *)
|
||||
(* Olivier Danvy <danvy@yale-nus.edu.sg> *)
|
||||
(* Version of 01 Feb 2024 *)
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Inductive binary_tree (V : Type) : Type :=
|
||||
Leaf : V -> binary_tree V
|
||||
| Node : binary_tree V -> binary_tree V -> binary_tree V.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Check binary_tree_ind.
|
||||
|
||||
Definition specification_of_mirror (mirror : forall V : Type, binary_tree V -> binary_tree V) : Prop :=
|
||||
(forall (V : Type)
|
||||
(v : V),
|
||||
mirror V (Leaf V v) =
|
||||
Leaf V v)
|
||||
/\
|
||||
(forall (V : Type)
|
||||
(t1 t2 : binary_tree V),
|
||||
mirror V (Node V t1 t2) =
|
||||
Node V (mirror V t2) (mirror V t1)).
|
||||
|
||||
Definition specification_of_number_of_nodes (number_of_nodes : forall V: Type, binary_tree V -> nat) : Prop :=
|
||||
(forall (V : Type) (v: V),
|
||||
number_of_nodes V (Leaf V v) = 0)
|
||||
/\
|
||||
(forall (V : Type) (t1 t2 : binary_tree V),
|
||||
number_of_nodes V (Node V t1 t2) =
|
||||
S (number_of_nodes V t1 + number_of_nodes V t2)).
|
||||
|
||||
Definition specification_of_number_of_leaves (number_of_leaves : forall V: Type, binary_tree V -> nat) : Prop :=
|
||||
(forall (V : Type) (v: V),
|
||||
number_of_leaves V (Leaf V v) = 1)
|
||||
/\
|
||||
(forall (V : Type) (t1 t2 : binary_tree V),
|
||||
number_of_leaves V (Node V t1 t2) =
|
||||
number_of_leaves V t1 + number_of_leaves V t2).
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 09a *)
|
||||
|
||||
Proposition there_is_at_most_one_mirror_function :
|
||||
forall mirror1 mirror2 : forall V : Type, binary_tree V -> binary_tree V,
|
||||
specification_of_mirror mirror1 ->
|
||||
specification_of_mirror mirror2 ->
|
||||
forall (V : Type)
|
||||
(t : binary_tree V),
|
||||
mirror1 V t = mirror2 V t.
|
||||
Proof.
|
||||
intros mirror1 mirror2.
|
||||
unfold specification_of_mirror.
|
||||
intros [S_Leaf1 S_Node1].
|
||||
intros [S_Leaf2 S_Node2].
|
||||
intros V t.
|
||||
induction t as [| t1 IHt1 t2 IHt2].
|
||||
- rewrite -> (S_Leaf1 V v).
|
||||
rewrite -> (S_Leaf2 V v).
|
||||
reflexivity.
|
||||
- rewrite -> (S_Node1 V t1 t2).
|
||||
rewrite -> (S_Node2 V t1 t2).
|
||||
rewrite -> IHt1.
|
||||
rewrite -> IHt2.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* Exercise 09b *)
|
||||
Proposition there_is_at_most_one_number_of_nodes_function :
|
||||
forall number_of_nodes1 number_of_nodes2 : forall V : Type, binary_tree V -> nat,
|
||||
specification_of_number_of_nodes number_of_nodes1 ->
|
||||
specification_of_number_of_nodes number_of_nodes2 ->
|
||||
forall (V : Type)
|
||||
(t : binary_tree V),
|
||||
number_of_nodes1 V t = number_of_nodes2 V t.
|
||||
Proof.
|
||||
intros number_of_nodes1 number_of_nodes2.
|
||||
unfold specification_of_number_of_nodes.
|
||||
intros [S_Leaf1 S_Node1].
|
||||
intros [S_Leaf2 S_Node2].
|
||||
intros V t.
|
||||
induction t as [| t1 IHt1 t2 IHt2].
|
||||
- rewrite -> (S_Leaf1 V v).
|
||||
rewrite -> (S_Leaf2 V v).
|
||||
reflexivity.
|
||||
- rewrite -> (S_Node1 V t1 t2).
|
||||
rewrite -> (S_Node2 V t1 t2).
|
||||
rewrite -> IHt1.
|
||||
rewrite -> IHt2.
|
||||
reflexivity.
|
||||
|
||||
Qed.
|
||||
|
||||
(* Exercise 09c *)
|
||||
Proposition there_is_at_most_one_number_of_leaves_function :
|
||||
forall number_of_leaves1 number_of_leaves2 : forall V : Type, binary_tree V -> nat,
|
||||
specification_of_number_of_leaves number_of_leaves1 ->
|
||||
specification_of_number_of_leaves number_of_leaves2 ->
|
||||
forall (V : Type)
|
||||
(t : binary_tree V),
|
||||
number_of_leaves1 V t = number_of_leaves2 V t.
|
||||
Proof.
|
||||
intros number_of_leaves1 number_of_leaves2.
|
||||
unfold specification_of_number_of_leaves.
|
||||
intros [S_Leaf1 S_Node1].
|
||||
intros [S_Leaf2 S_Node2].
|
||||
intros V t.
|
||||
induction t as [v | t1 IHt1 t2 IHt2].
|
||||
- rewrite -> (S_Leaf1 V v).
|
||||
rewrite -> (S_Leaf2 V v).
|
||||
reflexivity.
|
||||
- rewrite -> (S_Node1 V t1 t2).
|
||||
rewrite -> (S_Node2 V t1 t2).
|
||||
rewrite -> IHt1.
|
||||
rewrite -> IHt2.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
|
||||
(* ***** *)
|
||||
|
||||
Theorem mirror_is_involutory :
|
||||
forall mirror : forall V : Type, binary_tree V -> binary_tree V,
|
||||
specification_of_mirror mirror ->
|
||||
forall (V : Type)
|
||||
(t : binary_tree V),
|
||||
mirror V (mirror V t) = t.
|
||||
Proof.
|
||||
intro mirror.
|
||||
unfold specification_of_mirror.
|
||||
intros [S_Leaf S_Node].
|
||||
intros V t.
|
||||
induction t as [v | t1 IHt1 t2 IHt2].
|
||||
- revert V v.
|
||||
intros V v.
|
||||
Check (S_Leaf V v).
|
||||
rewrite -> (S_Leaf V v).
|
||||
Check (S_Leaf V v).
|
||||
(*
|
||||
exact (S_Leaf V v).
|
||||
*)
|
||||
rewrite -> (S_Leaf V v).
|
||||
reflexivity.
|
||||
- revert IHt2.
|
||||
revert t2.
|
||||
revert IHt1.
|
||||
revert t1.
|
||||
intros t1 IHt1 t2 IHt2.
|
||||
Check (S_Node V t1 t2).
|
||||
rewrite -> (S_Node V t1 t2).
|
||||
Check (S_Node V (mirror V t2) (mirror V t1)).
|
||||
rewrite -> (S_Node V (mirror V t2) (mirror V t1)).
|
||||
rewrite -> IHt1.
|
||||
rewrite -> IHt2.
|
||||
reflexivity.
|
||||
|
||||
Restart. (* now for a less verbose proof: *)
|
||||
|
||||
intros mirror S_mirror V t.
|
||||
induction t as [ v | t1 IHt1 t2 IHt2].
|
||||
- unfold specification_of_mirror in S_mirror.
|
||||
destruct S_mirror as [S_Leaf _].
|
||||
Check (S_Leaf V v).
|
||||
rewrite -> (S_Leaf V v).
|
||||
Check (S_Leaf V v).
|
||||
exact (S_Leaf V v).
|
||||
- unfold specification_of_mirror in S_mirror.
|
||||
destruct S_mirror as [_ S_Node].
|
||||
Check (S_Node V t1 t2).
|
||||
rewrite -> (S_Node V t1 t2).
|
||||
Check (S_Node V (mirror V t2) (mirror V t1)).
|
||||
rewrite -> (S_Node V (mirror V t2) (mirror V t1)).
|
||||
rewrite -> IHt1.
|
||||
rewrite -> IHt2.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Exercise 10 *)
|
||||
Proposition mirror_reverses_itself :
|
||||
forall mirror : forall V : Type, binary_tree V -> binary_tree V,
|
||||
specification_of_mirror mirror ->
|
||||
forall (V : Type)
|
||||
(t t' : binary_tree V),
|
||||
mirror V t = t' ->
|
||||
mirror V t' = t.
|
||||
Proof.
|
||||
intros mirror S_mirror.
|
||||
assert (S_tmp :=S_mirror).
|
||||
unfold specification_of_mirror in S_tmp.
|
||||
destruct S_tmp as [S_Leaf S_Node].
|
||||
intros V t t' M_t_t'.
|
||||
induction t' as [v | t1 IHt1 t2 IHt2].
|
||||
- rewrite <- M_t_t'.
|
||||
rewrite -> (mirror_is_involutory mirror S_mirror V t).
|
||||
reflexivity.
|
||||
- rewrite -> (S_Node V t1 t2).
|
||||
Check (mirror_is_involutory mirror S_mirror V t1).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Proposition mirror_reverses_itself :
|
||||
forall mirror : forall V : Type, binary_tree V -> binary_tree V,
|
||||
specification_of_mirror mirror ->
|
||||
forall (V : Type)
|
||||
(t t' : binary_tree V),
|
||||
mirror V t = t' ->
|
||||
mirror V t' = t.
|
||||
Proof.
|
||||
intros mirror S_mirror V t t' M_t_t'.
|
||||
|
||||
assert (f_equal :
|
||||
forall t1 t2 : binary_tree V,
|
||||
t1 = t2 ->
|
||||
mirror V t1 = mirror V t2).
|
||||
{ intros t1 t2 eq_t1_t2.
|
||||
rewrite -> eq_t1_t2.
|
||||
reflexivity. }
|
||||
Check (f_equal (mirror V t) t').
|
||||
Check (f_equal (mirror V t) t' M_t_t').
|
||||
assert (H_tmp := f_equal (mirror V t) t' M_t_t').
|
||||
|
||||
rewrite <- H_tmp.
|
||||
Check (mirror_is_involutory mirror S_mirror V t).
|
||||
rewrite -> (mirror_is_involutory mirror S_mirror V t).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Definition specification_of_number_of_leaves (number_of_leaves : forall V : Type, binary_tree V -> nat) : Prop :=
|
||||
(forall (V : Type)
|
||||
(v : V),
|
||||
number_of_leaves V (Leaf V v) =
|
||||
1)
|
||||
/\
|
||||
(forall (V : Type)
|
||||
(t1 t2 : binary_tree V),
|
||||
number_of_leaves V (Node V t1 t2) =
|
||||
number_of_leaves V t1 + number_of_leaves V t2).
|
||||
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 09b *)
|
||||
|
||||
Proposition there_is_at_most_one_number_of_leaves_function :
|
||||
forall number_of_leaves1 number_of_leaves2 : forall V : Type, binary_tree V -> nat,
|
||||
specification_of_number_of_leaves number_of_leaves1 ->
|
||||
specification_of_number_of_leaves number_of_leaves2 ->
|
||||
forall (V : Type)
|
||||
(t : binary_tree V),
|
||||
number_of_leaves1 V t = number_of_leaves2 V t.
|
||||
Proof.
|
||||
Abort.
|
||||
|
||||
(* ***** *)
|
||||
|
||||
Definition specification_of_number_of_nodes (number_of_nodes : forall V : Type, binary_tree V -> nat) : Prop :=
|
||||
(forall (V : Type)
|
||||
(v : V),
|
||||
number_of_nodes V (Leaf V v) =
|
||||
0)
|
||||
/\
|
||||
(forall (V : Type)
|
||||
(t1 t2 : binary_tree V),
|
||||
number_of_nodes V (Node V t1 t2) =
|
||||
S (number_of_nodes V t1 + number_of_nodes V t2)).
|
||||
|
||||
(* ***** *)
|
||||
|
||||
(* Exercise 09c *)
|
||||
|
||||
Proposition there_is_at_most_one_number_of_nodes_function :
|
||||
forall number_of_nodes1 number_of_nodes2 : forall V : Type, binary_tree V -> nat,
|
||||
specification_of_number_of_nodes number_of_nodes1 ->
|
||||
specification_of_number_of_nodes number_of_nodes2 ->
|
||||
forall (V : Type)
|
||||
(t : binary_tree V),
|
||||
number_of_nodes1 V t = number_of_nodes2 V t.
|
||||
Proof.
|
||||
Abort.
|
||||
|
||||
(* ***** *)
|
||||
|
||||
Theorem about_the_relative_number_of_leaves_and_nodes_in_a_tree :
|
||||
forall number_of_leaves : forall V : Type, binary_tree V -> nat,
|
||||
specification_of_number_of_leaves number_of_leaves ->
|
||||
forall number_of_nodes : forall V : Type, binary_tree V -> nat,
|
||||
specification_of_number_of_nodes number_of_nodes ->
|
||||
forall (V : Type)
|
||||
(t : binary_tree V),
|
||||
number_of_leaves V t = S (number_of_nodes V t).
|
||||
Proof.
|
||||
intro number_of_leaves.
|
||||
unfold specification_of_number_of_leaves.
|
||||
intros [S_nol_Leaf S_nol_Node].
|
||||
intro number_of_nodes.
|
||||
unfold specification_of_number_of_nodes.
|
||||
intros [S_non_Leaf S_non_Node].
|
||||
|
||||
Restart. (* with less clutter among the assumptions *)
|
||||
|
||||
intros nol S_nol non S_non V t.
|
||||
induction t as [v | t1 IHt1 t2 IHt2].
|
||||
- unfold specification_of_number_of_leaves in S_nol.
|
||||
destruct S_nol as [S_nol_Leaf _].
|
||||
unfold specification_of_number_of_nodes in S_non.
|
||||
destruct S_non as [S_non_Leaf _].
|
||||
Check (S_non_Leaf V v).
|
||||
rewrite -> (S_non_Leaf V v).
|
||||
Check (S_nol_Leaf V v).
|
||||
exact (S_nol_Leaf V v).
|
||||
- unfold specification_of_number_of_leaves in S_nol.
|
||||
destruct S_nol as [_ S_nol_Node].
|
||||
unfold specification_of_number_of_nodes in S_non.
|
||||
destruct S_non as [_ S_non_Node].
|
||||
Check (S_nol_Node V t1 t2).
|
||||
rewrite -> (S_nol_Node V t1 t2).
|
||||
Check (S_non_Node V t1 t2).
|
||||
rewrite -> (S_non_Node V t1 t2).
|
||||
rewrite -> IHt1.
|
||||
rewrite -> IHt2.
|
||||
Search (S _ + _).
|
||||
Check (plus_Sn_m (non V t1) (S (non V t2))).
|
||||
rewrite -> (plus_Sn_m (non V t1) (S (non V t2))).
|
||||
Search (_ + S _ = _).
|
||||
Search (_ = _ + S _).
|
||||
Check (plus_n_Sm (non V t1) (non V t2)).
|
||||
rewrite <- (plus_n_Sm (non V t1) (non V t2)).
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intros nol S_nol non S_non.
|
||||
Check binary_tree_ind.
|
||||
intro V.
|
||||
Check (binary_tree_ind
|
||||
V).
|
||||
Check (binary_tree_ind
|
||||
V
|
||||
(fun t : binary_tree V => nol V t = S (non V t))).
|
||||
assert (wanted_Leaf :
|
||||
forall v : V, nol V (Leaf V v) = S (non V (Leaf V v))).
|
||||
{ intro v.
|
||||
unfold specification_of_number_of_leaves in S_nol.
|
||||
destruct S_nol as [S_nol_Leaf _].
|
||||
unfold specification_of_number_of_nodes in S_non.
|
||||
destruct S_non as [S_non_Leaf _].
|
||||
Check (S_non_Leaf V v).
|
||||
rewrite -> (S_non_Leaf V v).
|
||||
Check (S_nol_Leaf V v).
|
||||
exact (S_nol_Leaf V v). }
|
||||
Check (binary_tree_ind
|
||||
V
|
||||
(fun t : binary_tree V => nol V t = S (non V t))
|
||||
wanted_Leaf).
|
||||
apply (binary_tree_ind
|
||||
V
|
||||
(fun t : binary_tree V => nol V t = S (non V t))
|
||||
wanted_Leaf).
|
||||
intros t1 IHt1 t2 IHt2.
|
||||
unfold specification_of_number_of_leaves in S_nol.
|
||||
destruct S_nol as [_ S_nol_Node].
|
||||
unfold specification_of_number_of_nodes in S_non.
|
||||
destruct S_non as [_ S_non_Node].
|
||||
Check (S_nol_Node V t1 t2).
|
||||
rewrite -> (S_nol_Node V t1 t2).
|
||||
Check (S_non_Node V t1 t2).
|
||||
rewrite -> (S_non_Node V t1 t2).
|
||||
rewrite -> IHt1.
|
||||
rewrite -> IHt2.
|
||||
Search (S _ + _).
|
||||
Check (plus_Sn_m (non V t1) (S (non V t2))).
|
||||
rewrite -> (plus_Sn_m (non V t1) (S (non V t2))).
|
||||
Search (_ + S _ = _).
|
||||
Search (_ = _ + S _).
|
||||
Check (plus_n_Sm (non V t1) (non V t2)).
|
||||
rewrite <- (plus_n_Sm (non V t1) (non V t2)).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* end of week-03_induction-over-binary-trees.v *)
|
79
cs3234/labs/week-03_the-exists-tactic.v
Normal file
79
cs3234/labs/week-03_the-exists-tactic.v
Normal file
@ -0,0 +1,79 @@
|
||||
(* week-03_the-exists-tactic.v *)
|
||||
(* LPP 2024 - CS3234 2023-2024, Sem2 *)
|
||||
(* Olivier Danvy <danvy@yale-nus.edu.sg> *)
|
||||
(* Version of 01 Feb 2024 *)
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Paraphernalia: *)
|
||||
|
||||
Require Import Arith.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Lemma proving_an_existential_example_0 :
|
||||
exists n : nat,
|
||||
n = 0.
|
||||
Proof.
|
||||
exists 0.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Lemma proving_an_existential_example_1 :
|
||||
forall n : nat,
|
||||
exists m : nat,
|
||||
S m = n + 1.
|
||||
Proof.
|
||||
intros n.
|
||||
exists n.
|
||||
Search (_ + S _).
|
||||
Check (plus_n_Sm n 0).
|
||||
rewrite <- (plus_n_Sm n 0).
|
||||
Check Nat.add_0_r.
|
||||
rewrite -> (Nat.add_0_r n).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Lemma proving_an_existential_example_2 :
|
||||
forall n : nat,
|
||||
exists f : nat -> nat,
|
||||
f n = n + 1.
|
||||
Proof.
|
||||
intro n.
|
||||
exists S.
|
||||
rewrite <- (plus_n_Sm n 0).
|
||||
rewrite -> (Nat.add_0_r n).
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intro n.
|
||||
exists (fun n => S n).
|
||||
rewrite <- (plus_n_Sm n 0).
|
||||
rewrite -> (Nat.add_0_r n).
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intro n.
|
||||
exists (fun n => n + 1).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma proving_an_existential_example_3:
|
||||
forall n : nat,
|
||||
exists f : nat -> nat,
|
||||
f n = n + 2.
|
||||
Proof.
|
||||
intro n.
|
||||
exists (fun n => n + 2).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* end of week-03_the-exists-tactic.v *)
|
204
cs3234/labs/week-03_the-rewrite-tactic.v
Normal file
204
cs3234/labs/week-03_the-rewrite-tactic.v
Normal file
@ -0,0 +1,204 @@
|
||||
(* week-03_the-rewrite-tactic.v *)
|
||||
(* LPP 2024 - CS3234 2023-2024, Sem2 *)
|
||||
(* Olivier Danvy <danvy@yale-nus.edu.sg> *)
|
||||
(* Version of 01 Feb 2024 *)
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Require Import Arith Bool.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Rewriting from left to right in the current goal *)
|
||||
|
||||
Proposition p1 :
|
||||
forall i j : nat,
|
||||
i = j ->
|
||||
forall f : nat -> nat,
|
||||
f i = f j.
|
||||
Proof.
|
||||
intros i j H_i_j f.
|
||||
rewrite <- H_i_j.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Rewriting a specific occurrence from left to right in the current goal *)
|
||||
|
||||
Proposition silly :
|
||||
forall x y : nat,
|
||||
x = y ->
|
||||
x + x * y + (y + y) = y + y * x + (x + x).
|
||||
Proof.
|
||||
intros x y H_x_y.
|
||||
rewrite -> H_x_y.
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intros x y H_x_y.
|
||||
rewrite -> H_x_y at 4.
|
||||
rewrite -> H_x_y at 1.
|
||||
rewrite -> H_x_y at 1.
|
||||
rewrite -> H_x_y at 1.
|
||||
rewrite -> H_x_y at 1.
|
||||
reflexivity.
|
||||
|
||||
Restart.
|
||||
|
||||
intros x y H_x_y.
|
||||
rewrite -> H_x_y at 4.
|
||||
rewrite ->3 H_x_y at 1.
|
||||
rewrite -> H_x_y.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Proposition p2 :
|
||||
forall x : nat,
|
||||
x = 0 ->
|
||||
x = 1 ->
|
||||
x <> x. (* i.e., not (x = x), or again ~(x = x), or again x = x -> False *)
|
||||
Proof.
|
||||
intros x H_x0 H_x1.
|
||||
rewrite -> H_x0 at 1.
|
||||
rewrite -> H_x1.
|
||||
Search (0 <> S _).
|
||||
Check (Nat.neq_0_succ 0).
|
||||
exact (Nat.neq_0_succ 0).
|
||||
|
||||
Restart.
|
||||
|
||||
intros x H_x0 H_x1.
|
||||
rewrite -> H_x1 at 2.
|
||||
rewrite -> H_x0.
|
||||
exact (Nat.neq_0_succ 0).
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Rewriting from left to right in an assumption *)
|
||||
|
||||
Proposition p3 : (* transitivity of Leibniz equality *)
|
||||
forall a b c : nat,
|
||||
a = b ->
|
||||
b = c ->
|
||||
a = c.
|
||||
Proof.
|
||||
intros a b c H_ab H_bc.
|
||||
rewrite -> H_ab.
|
||||
exact H_bc.
|
||||
|
||||
Restart.
|
||||
|
||||
intros a b c H_ab H_bc.
|
||||
rewrite -> H_bc in H_ab.
|
||||
exact H_ab.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Rewriting a specific occurrence from left to right in an assumption *)
|
||||
|
||||
Proposition p4 :
|
||||
forall x : nat,
|
||||
x = 0 ->
|
||||
x = 1 ->
|
||||
x <> x. (* i.e., not (x = x), or again ~(x = x), or again x = x -> False *)
|
||||
Proof.
|
||||
unfold not.
|
||||
intros x H_x0 H_x1 H_xx.
|
||||
rewrite -> H_x0 in H_xx at 1.
|
||||
rewrite -> H_x1 in H_xx.
|
||||
Search (0 <> S _).
|
||||
Check Nat.neq_0_succ 0.
|
||||
assert (H_absurd := Nat.neq_0_succ 0).
|
||||
unfold not in H_absurd.
|
||||
Check (H_absurd H_xx).
|
||||
exact (H_absurd H_xx).
|
||||
|
||||
Restart.
|
||||
|
||||
unfold not.
|
||||
intros x H_x0 H_x1 H_xx.
|
||||
rewrite -> H_x1 in H_xx at 2.
|
||||
rewrite -> H_x0 in H_xx.
|
||||
assert (H_absurd := Nat.neq_0_succ 0).
|
||||
unfold not in H_absurd.
|
||||
exact (H_absurd H_xx).
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* Rewriting from right to left *)
|
||||
|
||||
Proposition p1' :
|
||||
forall i j : nat,
|
||||
i = j ->
|
||||
forall f : nat -> nat,
|
||||
f i = f j.
|
||||
Proof.
|
||||
intros i j H_i_j f.
|
||||
rewrite <- H_i_j.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
Check plus_Sn_m. (* : forall n m : nat, S n + m = S (n + m) *)
|
||||
|
||||
Check plus_n_Sm. (* : forall n m : nat, S (n + m) = n + S m *)
|
||||
|
||||
Proposition p5 :
|
||||
forall i j : nat,
|
||||
S i + j = i + S j.
|
||||
Proof.
|
||||
intros i j.
|
||||
Check (plus_Sn_m i j).
|
||||
rewrite -> (plus_Sn_m i j).
|
||||
Check (plus_n_Sm i j).
|
||||
rewrite <- (plus_n_Sm i j).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Proposition p6 :
|
||||
forall n : nat,
|
||||
0 + n = n + 0 ->
|
||||
1 + n = n + 1.
|
||||
Proof.
|
||||
intros n H_n.
|
||||
rewrite -> (plus_Sn_m 0 n).
|
||||
rewrite <- (plus_n_Sm n 0).
|
||||
rewrite -> H_n.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Proposition p7 :
|
||||
forall n : nat,
|
||||
0 + n = n + 0 ->
|
||||
2 + n = n + 2.
|
||||
Proof.
|
||||
intros n H_n.
|
||||
rewrite -> (plus_Sn_m 1 n).
|
||||
rewrite <- (plus_n_Sm n 1).
|
||||
Check (p6 n H_n).
|
||||
rewrite -> (p6 n H_n).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Proposition p8 :
|
||||
forall n : nat,
|
||||
0 + n = n + 0 ->
|
||||
3 + n = n + 3.
|
||||
Proof.
|
||||
intros n H_n.
|
||||
rewrite -> (plus_Sn_m 2 n).
|
||||
rewrite <- (plus_n_Sm n 2).
|
||||
Check (p7 n H_n).
|
||||
rewrite -> (p7 n H_n).
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(* ********** *)
|
||||
|
||||
(* end of week-03_the-rewrite-tactic.v *)
|
Loading…
Reference in New Issue
Block a user