Guest User

Chapter "Induction" of Software Foundations in F*

a guest
Jan 27th, 2016
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 3.73 KB | None | 0 0
  1. (*--build-config
  2.     other-files: basics.fst
  3.   --*)
  4.  
  5. module Induction
  6.  
  7. open Basics
  8.  
  9.  
  10. (* Naming Cases *)
  11.  
  12. val andb_true_elim1:
  13.   b: bool -> c: bool ->
  14.   Lemma (andb b c = true ==> b = true)
  15. let andb_true_elim1 b c = ()
  16.  
  17.  
  18. (* Exercise: 2 stars (andb_true_elim2) *)
  19.  
  20. val andb_true_elim2:
  21.   b: bool -> c: bool ->
  22.   Lemma (andb b c = true ==> b = true)
  23. let andb_true_elim2 b c = ()
  24.  
  25.  
  26. (* Proof by Induction *)
  27.  
  28. val plus_0_r: n: nat -> Lemma (plus n O = n)
  29. let rec plus_0_r n = by_induction_on n plus_0_r
  30.  
  31. val minus_diag: n: nat -> Lemma (minus n n = O)
  32. let rec minus_diag n = by_induction_on n minus_diag
  33.  
  34.  
  35. (* Exercise: 2 stars (basic_induction) *)
  36.  
  37. val mult_0_r: n: nat -> Lemma (mult n O = O)
  38. let rec mult_0_r n = by_induction_on n mult_0_r
  39.  
  40. val plus_n_Sm: n: nat -> m: nat -> Lemma (S (plus n m) = plus n (S m))
  41. let rec plus_n_Sm n m =
  42.   match n with
  43.   | O -> ()
  44.   | S n' -> plus_n_Sm n' m
  45.  
  46. val plus_comm: n: nat -> m: nat -> Lemma (plus n m = plus m n)
  47. let rec plus_comm n m =
  48.   match n with
  49.   | O -> plus_0_r m
  50.   | S n' ->
  51.       (* plus (S n') m = S (plus n' m) = S (plus m n') by induction *)
  52.       plus_comm n' m;
  53.       (* S (plus m n') = plus m (S n') *)
  54.       plus_n_Sm m n'
  55.  
  56. val plus_assoc:
  57.   n: nat -> m: nat -> p: nat ->
  58.   Lemma (plus n (plus m p) = plus (plus n m) p)
  59. let rec plus_assoc n m p =
  60.   match n with
  61.   | O -> ()
  62.   | S n' -> plus_assoc n' m p
  63.  
  64.  
  65. (* Exercise: 2 stars (double_plus) *)
  66.  
  67. val double: n: nat -> Tot nat
  68. let rec double n =
  69.   match n with
  70.   | O -> O
  71.   | S n' -> S (S (double n'))
  72.  
  73. val double_plus: n: nat -> Lemma (double n = plus n n)
  74. let rec double_plus n =
  75.   match n with
  76.   | O -> ()
  77.   | S n' -> plus_n_Sm n' (S n'); plus_comm n' (S (S n')); double_plus n'
  78.  
  79.  
  80. (* Proofs Within Proofs *)
  81.  
  82. val mult_0_plus':
  83.   n: nat -> m: nat ->
  84.   Lemma (mult (plus O n) m = mult n m)
  85. let mult_0_plus' n m =
  86.   let h: unit -> Lemma (plus O n = n) = (fun _ -> ()) in
  87.   h()
  88.  
  89. val plus_rearrange:
  90.   n: nat -> m: nat -> p: nat -> q: nat ->
  91.   Lemma (plus (plus n m) (plus p q) = plus (plus m n) (plus p q))
  92. let plus_rearrange n m p q =
  93.   let h: unit -> Lemma (plus n m = plus m n) =
  94.     (fun _ -> plus_comm n m; ())
  95.   in
  96.   h()
  97.  
  98.  
  99. (* Exercise: 4 stars (mult_comm) *)
  100.  
  101. val plus_swap:
  102.   n: nat -> m: nat -> p: nat ->
  103.   Lemma (plus n (plus m p) = plus m (plus n p))
  104. let plus_swap n m p =
  105.   plus_assoc n m p; plus_comm n m; plus_assoc m n p
  106.  
  107. (* Proof of mult_comm using these lemmas inspired by Lindsey Kuper's proof
  108.  * at https://github.com/lkuper/software-foundations/blob/master/Induction.v
  109.  *)
  110. val plus_elim: n: nat -> m: nat -> Lemma (plus n (mult n m) = mult n (S m))
  111. let rec plus_elim n m =
  112.   match n with
  113.   | O -> ()
  114.   | S n' ->
  115.       (* plus (S n') (mult (S n') m) = S (plus n' (plus m (mult n' m))) *)
  116.       plus_swap n' m (mult n' m);  (* = S (plus m (plus n' (mult n' m))) *)
  117.       plus_elim n' m;              (* = S (plus m (mult n' (S m))) *)
  118.       ()             (* = plus (S m) (mult n' (S m)) = mult (S n') (S m) *)
  119.  
  120. val mult_m_Sn: m: nat -> n: nat -> Lemma (mult m (S n) = plus m (mult n m))
  121. let rec mult_m_Sn m n =
  122.   match m with
  123.   | O -> mult_0_r n
  124.   | S m' ->
  125.       (* mult (S m') (S n) = plus (S n) (mult m' (S n)) *)
  126.       mult_m_Sn m' n;     (* = plus (S n) (plus (m' (mult n m))) *)
  127.       plus_swap n m' (mult (S n) m');
  128.                           (* = plus m' (plus (S n) (mult (S n) m')) *)
  129.       plus_elim (S n) m'  (* = plus m' (mult (S n) (S m')) *)
  130.  
  131. val mult_comm: m: nat -> n: nat -> Lemma (mult m n = mult n m)
  132. let rec mult_comm m n =
  133.   match n with
  134.   | O -> mult_0_r m
  135.   | S n' ->
  136.       mult_m_Sn m (S n');  (* mult m (S n') = plus m (mult n' m) *)
  137.       mult_comm m n';      (* = plus m (mult m n') *)
  138.       plus_elim m n'       (* = mult m (S n') *)
Add Comment
Please, Sign In to add comment