nus/cs3234/labs/week-04_proving-the-soundness-of-unit-tests.v
2024-02-20 11:31:16 +08:00

168 lines
4.1 KiB
Coq

(* week-04_proving-the-soundness-of-unit-tests.v *)
(* LPP 2024 - CS3234 2023-2024, Sem2 *)
(* Olivier Danvy <danvy@yale-nus.edu.sg> *)
(* Version of 09 Feb 2024 *)
(* ********** *)
Require Import Arith Bool.
(* ********** *)
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)).
(* ********** *)
Check (Nat.eqb 1 2, 1 =? 2).
Definition test_add (candidate : nat -> nat -> nat) :=
(candidate 0 2 =? 2) && (candidate 2 0 =? 2) && (candidate 2 2 =? 4).
(* ********** *)
Theorem soundness_of_test_add_for_the_recursive_specification_of_addition :
forall add : nat -> nat -> nat,
recursive_specification_of_addition add ->
test_add add = true.
Proof.
intro add.
unfold recursive_specification_of_addition.
intros [H_add_O H_add_S].
unfold test_add.
Check (H_add_O 2).
rewrite -> (H_add_O 2).
Search (_ =? _).
Check (beq_nat_refl 2).
rewrite <- (beq_nat_refl 2).
Search (true && _ = _).
Check (forall x y z : bool, x && (y && z) = (x && y) && z).
Check (andb_true_l (add 2 0 =? 2)).
rewrite -> (andb_true_l (add 2 0 =? 2)).
Check (H_add_S 1 0).
Check (H_add_S 1 2).
assert (H_add_2 : forall y : nat, add 2 y = S (S y)).
{ intro y.
rewrite -> (H_add_S 1 y).
rewrite -> (H_add_S 0 y).
rewrite -> (H_add_O y).
reflexivity. }
Check (H_add_2 0).
rewrite -> (H_add_2 0).
rewrite <- (beq_nat_refl 2).
rewrite -> (andb_true_l (add 2 2 =? 4)).
rewrite -> (H_add_2 2).
rewrite <- (beq_nat_refl 4).
reflexivity.
Restart.
intro add.
unfold recursive_specification_of_addition.
intros [H_add_O H_add_S].
unfold test_add.
rewrite -> (H_add_O 2).
assert (H_add_2 : forall y : nat, add 2 y = S (S y)).
{ intro y.
rewrite -> (H_add_S 1 y).
rewrite -> (H_add_S 0 y).
rewrite -> (H_add_O y).
reflexivity. }
rewrite -> (H_add_2 0).
rewrite -> (H_add_2 2).
rewrite <- (beq_nat_refl 2).
rewrite -> (andb_true_l true).
rewrite -> (andb_true_l (4 =? 4)).
rewrite <- (beq_nat_refl 4).
reflexivity.
Restart.
intro add.
unfold recursive_specification_of_addition.
intros [H_add_O H_add_S].
unfold test_add.
rewrite -> (H_add_O 2).
assert (H_add_2 : forall y : nat, add 2 y = S (S y)).
{ intro y.
rewrite -> (H_add_S 1 y).
rewrite -> (H_add_S 0 y).
rewrite -> (H_add_O y).
reflexivity. }
rewrite -> (H_add_2 0).
rewrite -> (H_add_2 2).
compute.
reflexivity.
Restart.
intro add.
unfold recursive_specification_of_addition.
intros [H_add_O H_add_S].
unfold test_add.
compute.
(* Disaster city, that's what it is. *)
Restart.
intro add.
unfold recursive_specification_of_addition.
intros [H_add_O H_add_S].
unfold test_add.
rewrite -> (H_add_O 2).
assert (H_add_2 : forall y : nat, add 2 y = S (S y)).
{ intro y.
rewrite -> (H_add_S 1 y).
rewrite -> (H_add_S 0 y).
rewrite -> (H_add_O y).
reflexivity. }
rewrite -> (H_add_2 0).
rewrite -> (H_add_2 2).
unfold beq_nat. (* "e1 =? e2" is syntactic sugar for "beq_nat e1 e2" *)
unfold andb. (* "e1 && e2" is syntactic sugar for "andb e1 e2" *)
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)).
(* ***** *)
Theorem soundness_of_test_add_for_the_tail_recursive_specification_of_addition :
forall add : nat -> nat -> nat,
tail_recursive_specification_of_addition add ->
test_add add = true.
Proof.
intros add.
unfold tail_recursive_specification_of_addition.
intros [H_add_O H_add_S].
unfold test_add.
rewrite -> (H_add_O 2).
assert (H_add_2 : forall y : nat, add 2 y = S (S y)).
{ intro y.
rewrite -> (H_add_S 1 y).
rewrite -> (H_add_S 0 (S y)).
rewrite -> (H_add_O (S (S y))).
reflexivity.
}
rewrite -> (H_add_2 0).
rewrite -> (H_add_2 2).
unfold beq_nat.
unfold andb.
reflexivity.
Qed.
(* ********** *)
(* end of week-04_proving-the-soundness-of-unit-tests.v *)