Guest User

Chapter "Introduction" of Software Foundations in F*

a guest
Jan 27th, 2016
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 8.31 KB | None | 0 0
  1. module Basics
  2.  
  3. (* Days of the Week *)
  4.  
  5. type day =
  6.   | Monday: day
  7.   | Tuesday: day
  8.   | Wednesday: day
  9.   | Thursday: day
  10.   | Friday: day
  11.   | Saturday: day
  12.   | Sunday: day
  13.  
  14. let next_weekday (d: day): day =
  15.   match d with
  16.   | Monday -> Tuesday
  17.   | Tuesday -> Wednesday
  18.   | Wednesday -> Thursday
  19.   | Thursday -> Friday
  20.   | Friday -> Monday
  21.   | Saturday -> Monday
  22.   | Sunday -> Monday
  23.  
  24. val test_next_weekday: unit ->
  25.   Lemma (next_weekday (next_weekday Saturday) = Tuesday)
  26. let test_next_weekday () = ()
  27.  
  28.  
  29. (* Booleans *)
  30.  
  31. let negb (b: bool): bool =
  32.   match b with
  33.   | true -> false
  34.   | false -> true
  35.  
  36. let andb (b1: bool) (b2: bool): bool =
  37.   match b1 with
  38.   | true -> b2
  39.   | false -> false
  40.  
  41. let orb (b1: bool) (b2: bool): bool =
  42.   match b1 with
  43.   | true -> true
  44.   | false -> b2
  45.  
  46. val test_orb1: unit -> Lemma (orb true false = true)
  47. let test_orb1 () = ()
  48. val test_orb2: unit -> Lemma (orb false false = false)
  49. let test_orb2 () = ()
  50. val test_orb3: unit -> Lemma (orb false true = true)
  51. let test_orb3 () = ()
  52. val test_orb4: unit -> Lemma (orb true true = true)
  53. let test_orb4 () = ()
  54.  
  55.  
  56. (* Exercise: 1 star (nandb) *)
  57. let nandb (b1: bool) (b2: bool): bool =
  58.   match b1, b2 with
  59.   | true, true -> false
  60.   | _, _ -> true
  61.  
  62. val test_nandb1: unit -> Lemma (nandb true false = true)
  63. let test_nandb1 () = ()
  64. val test_nandb2: unit -> Lemma (nandb false false = true)
  65. let test_nandb2 () = ()
  66. val test_nandb3: unit -> Lemma (nandb false true = true)
  67. let test_nandb3 () = ()
  68. val test_nandb4: unit -> Lemma (nandb true true = false)
  69. let test_nandb4 () = ()
  70.  
  71.  
  72. (* Exercise: 1 star (andb3) *)
  73. let andb3 (b1: bool) (b2: bool) (b3: bool): bool =
  74.   andb (andb b1 b2) b3
  75.  
  76. val test_andb31: unit -> Lemma (andb3 true true true = true)
  77. let test_andb31 () = ()
  78. val test_andb32: unit -> Lemma (andb3 false true true = false)
  79. let test_andb32 () = ()
  80. val test_andb33: unit -> Lemma (andb3 true false true = false)
  81. let test_andb33 () = ()
  82. val test_andb34: unit -> Lemma (andb3 true true false = false)
  83. let test_andb34 () = ()
  84.  
  85.  
  86. (* Numbers *)
  87.  
  88. type nat =
  89.   | O: nat
  90.   | S: n:nat -> nat
  91.  
  92. let pred (n: nat): nat =
  93.   match n with
  94.   | O -> O
  95.   | S n' -> n'
  96.  
  97. let minustwo (n: nat): nat =
  98.   match n with
  99.   | O -> O
  100.   | S O -> O
  101.   | S (S n') -> n'
  102.  
  103. val evenb: n: nat -> Tot bool
  104. let rec evenb n =
  105.   match n with
  106.   | O -> true
  107.   | S O -> false
  108.   | S (S n') -> evenb n'
  109.  
  110. val oddb: n: nat -> Tot bool
  111. let oddb n = negb (evenb n)
  112.  
  113. val test_oddb1: unit -> Lemma (oddb (S O) = true)
  114. let test_oddb1 () = ()
  115. val test_oddb2: unit -> Lemma (oddb (S (S (S (S O)))) = false)
  116. let test_oddb2 () = ()
  117.  
  118. val plus: n: nat -> m: nat -> Tot nat
  119. let rec plus n m =
  120.   match n with
  121.   | O -> m
  122.   | S n' -> S (plus n' m)
  123.  
  124. val mult: n: nat -> m: nat -> Tot nat
  125. let rec mult n m =
  126.   match n with
  127.   | O -> O
  128.   | S n' -> plus m (mult n' m)
  129.  
  130. val minus: n: nat -> m: nat -> Tot nat
  131. let rec minus n m =
  132.   match n, m with
  133.   | O, _ -> O
  134.   | S _, O -> n
  135.   | S n', S m' -> minus n' m'
  136.  
  137. val exp: base: nat -> power: nat -> Tot nat
  138. let rec exp base power =
  139.   match power with
  140.   | O -> S O
  141.   | S p -> mult base (exp base p)
  142.  
  143.  
  144. (* Auxiliaries for converting between our nats and F*'s nats. *)
  145.  
  146. val to_nat: i: int{i >= 0} -> Tot nat
  147. let rec to_nat i =
  148.   if i = 0 then O else S (to_nat (i-1))
  149.  
  150. val of_nat: n: nat -> Tot (i: int{i >= 0})
  151. let rec of_nat n =
  152.   match n with
  153.   | O -> 0
  154.   | S n' -> 1 + of_nat n'
  155.  
  156. val to_nat_of_nat: i: int{i >= 0} -> Lemma (of_nat (to_nat i) = i)
  157. let rec to_nat_of_nat i =
  158.   if i = 0 then () else to_nat_of_nat (i-1)
  159.  
  160. val of_nat_to_nat: n: nat -> Lemma (to_nat (of_nat n) = n)
  161. let rec of_nat_to_nat n = by_induction_on n of_nat_to_nat
  162.  
  163.  
  164. (* Exercise: 1 star (factorial) *)
  165.  
  166. val factorial: n: nat -> Tot nat
  167. let rec factorial n =
  168.   match n with
  169.   | O -> S O
  170.   | S n' -> mult n (factorial n')
  171.  
  172. val test_factorial1: unit -> Lemma (of_nat (factorial (to_nat 3)) = 6)
  173. let test_factorial1 () = ()
  174. val test_factorial1': unit -> Lemma (factorial (to_nat 3) = to_nat 6)
  175. let test_factorial1' () = ()
  176.  
  177. val test_factorial2: unit ->
  178.   Lemma (factorial (to_nat 5) = mult (to_nat 10) (to_nat 12))
  179. let test_factorial2 () = (* FIXME! *) admit ()
  180.  
  181.  
  182. val beq_nat: n: nat -> m: nat -> Tot bool
  183. let rec beq_nat n m =
  184.   match n with
  185.   | O -> (match m with
  186.           | O -> true
  187.           | S m' -> false)
  188.  | S n' -> (match m with
  189.              | O -> false
  190.              | S m' -> beq_nat n' m')
  191.  
  192. val ble_nat: n: nat -> m: nat -> Tot bool
  193. let rec ble_nat n m =
  194.  match n with
  195.  | O -> true
  196.  | S n' ->
  197.     match m with
  198.     | O -> false
  199.     | S m' -> ble_nat n' m'
  200.  
  201. val test_ble_nat1: unit -> Lemma (ble_nat (to_nat 2) (to_nat 2) = true)
  202. let test_ble_nat1 () = ()
  203. val test_ble_nat2: unit -> Lemma (ble_nat (to_nat 2) (to_nat 4) = true)
  204. let test_ble_nat2 () = ()
  205. val test_ble_nat3: unit -> Lemma (ble_nat (to_nat 4) (to_nat 2) = false)
  206. let test_ble_nat3 () = ()
  207.  
  208.  
  209. (* Exercise: 2 stars (blt_nat) *)
  210.  
  211. val blt_nat: n: nat -> m: nat -> Tot bool
  212. let blt_nat n m = ble_nat (S n) m
  213.  
  214. val test_blt_nat1: unit -> Lemma (blt_nat (to_nat 2) (to_nat 2) = false)
  215. let test_blt_nat1 () = ()
  216. val test_blt_nat2: unit -> Lemma (blt_nat (to_nat 2) (to_nat 4) = true)
  217. let test_blt_nat2 () = ()
  218. val test_blt_nat3: unit -> Lemma (blt_nat (to_nat 4) (to_nat 2) = false)
  219. let test_blt_nat3 () = ()
  220.  
  221.  
  222. (* Proof by Simplification *)
  223.  
  224. val plus_O_n: n: nat -> Lemma (plus O n = n)
  225. let plus_O_n n = ()
  226.  
  227. val plus_1_l: n: nat -> Lemma (plus (S O) n = S n)
  228. let plus_1_l n = ()
  229.  
  230. val mult_0_l: n: nat -> Lemma (mult O n = O)
  231. let mult_0_l n = ()
  232.  
  233.  
  234. (* Proof by Rewriting *)
  235.  
  236. val plus_id_example: n: nat -> m: nat -> Lemma (n = m ==> plus n n = plus m m)
  237. let plus_id_example n m = ()
  238.  
  239.  
  240. (* Exercise: 1 star (plus_id_exercise) *)
  241.  
  242. val plus_id_exercise:
  243.  n: nat -> m: nat -> o: nat ->
  244.  Lemma (n = m /\ m = o ==> plus n m = plus m o)
  245. let plus_id_exercise n m o = ()
  246.  
  247.  
  248. val mult_0_plus: n: nat -> m: nat -> Lemma (mult (plus O n) m = mult n m)
  249. let mult_0_plus n m = plus_O_n n  (* not really necessary *)
  250.  
  251.  
  252. (* Exercise: 2 stars (mult_S_1) *)
  253.  
  254. val mult_S_1:
  255.  n: nat -> m: nat ->
  256.  Lemma (m = S n ==> mult m (plus (S O) n) = mult m m)
  257. let mult_S_1 n m = ()  (* could call plus_1_l n, but it's not needed *)
  258.  
  259.  
  260. (* Proof by Case Analysis *)
  261.  
  262. val plus_1_neq_0: n: nat -> Lemma (beq_nat (plus n (S O)) O = false)
  263. let plus_1_neq_0 n = ()
  264.  
  265. val negb_involutive: b: bool -> Lemma (negb (negb b) = b)
  266. let negb_involutive b = ()
  267.  
  268.  
  269. (* Exercise: 1 star (zero_nbeq_plus_1) *)
  270.  
  271. val zero_nbeq_plus_1: n: nat -> Lemma (beq_nat O (plus n (S O)) = false)
  272. let zero_nbeq_plus_1 n = ()
  273.  
  274.  
  275. (* More Exercises *)
  276.  
  277. (* Exercise: 2 stars (boolean_functions) *)
  278.  
  279. val identity_fn_applied_twice:
  280.   f: (bool -> Tot bool) ->
  281.   Lemma ((forall (x: bool). f x = x) ==> (forall (b: bool). f (f b) = b))
  282. let identity_fn_applied_twice f = ()
  283.  
  284. val negation_fn_applied_twice:
  285.   f: (bool -> Tot bool) ->
  286.   Lemma ((forall (x: bool). f x = negb x) ==> (forall (b: bool). f (f b) = b))
  287. let negation_fn_applied_twice f = ()
  288.  
  289.  
  290. (* Exercise: 2 stars (andb_eq_orb) *)
  291.  
  292. val andb_eq_orb: b: bool -> c: bool -> Lemma (andb b c = orb b c ==> b = c)
  293. let andb_eq_orb b c = ()
  294.  
  295.  
  296. (* Exercise: 3 stars (binary) *)
  297.  
  298. type bin =
  299.   | BZ
  300.   | B0: b: bin -> bin
  301.   | B1: b: bin -> bin
  302.  
  303. val incr: b: bin -> Tot bin
  304. let rec incr b =
  305.   match b with
  306.   | BZ -> B1 BZ
  307.   | B0 b' -> B1 b'
  308.   | B1 b' -> B0 (incr b')
  309.  
  310. val bin_to_nat: b: bin -> Tot nat
  311. let rec bin_to_nat b =
  312.   match b with
  313.   | BZ -> O
  314.   | B0 b' -> mult (S (S O)) (bin_to_nat b')
  315.   | B1 b' -> plus (S O) (mult (S (S O)) (bin_to_nat b'))
  316.  
  317. val test_bin_incr1: unit -> Lemma (bin_to_nat (incr BZ) = S O)
  318. let test_bin_incr1 () = ()
  319.  
  320. val test_bin_incr2:
  321.   b: bin ->
  322.   Lemma (bin_to_nat (B1 b) = plus (S O) (bin_to_nat (B0 b)))
  323. let test_bin_incr2 b = ()
  324.  
  325. val test_bin_incr3:
  326.   b: bin ->
  327.   Lemma (bin_to_nat (B0 b) = mult (S (S O)) (bin_to_nat b))
  328. let test_bin_incr3 b = ()
  329.  
  330. val test_bin_incr4:
  331.   b: bin ->
  332.   Lemma (bin_to_nat (incr (B1 b)) = mult (S (S O)) (plus (S O) (bin_to_nat b)))
  333. let rec test_bin_incr4 b =
  334.   match b with
  335.   | BZ -> ()
  336.   | B0 b' -> test_bin_incr4 b'
  337.   | B1 b' -> (* FIXME *) admit ()
  338.  
  339. val test_bin_incr5:
  340.  b: bin ->
  341.  Lemma (bin_to_nat (incr b) = plus (S O) (bin_to_nat b))
  342. let rec test_bin_incr5 b =
  343.  match b with
  344.  | BZ -> ()
  345.  | B0 b' -> test_bin_incr5 b'
  346.  | B1 b' -> (* FIXME *) admit ()
Add Comment
Please, Sign In to add comment