Advertisement
Guest User

Untitled

a guest
Feb 28th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.79 KB | None | 0 0
  1. module QuickSort.List
  2.  
  3. #set-options "--initial_ifuel 1 --initial_fuel 1 --max_ifuel 1 --max_fuel 1"
  4.  
  5. open FStar.List.Tot
  6.  
  7. (* Specification of sorted according to a comparison function f *)
  8. val sorted: ('a -> 'a -> Tot bool) -> list 'a -> Tot bool
  9. let rec sorted f = function
  10.  | x::y::xs -> f x y && sorted f (y::xs)
  11.  | _ -> true
  12.  
  13. type total_order (a:eqtype) =
  14.  f:(a -> a -> Tot bool) {
  15.      (forall a. f a a) // reflexive
  16.    /\ (forall a1 a2. f a1 a2 /\ f a2 a1 ==> a1 = a2) // anti-symmetric
  17.    /\ (forall a1 a2 a3. f a1 a2 /\ f a2 a3 ==> f a1 a3) // transitive
  18.    /\ (forall a1 a2. f a1 a2 \/ f a2 a1) // total
  19.  }
  20.  
  21. val count: #a:eqtype -> a -> list a -> Tot nat
  22. let rec count #a x = function
  23.  | hd::tl -> (if hd = x then 1 else 0) + count x tl
  24.  | [] -> 0
  25.  
  26.  
  27. val mem_count: #a:eqtype -> x:a -> l:list a ->
  28.  Lemma (requires True)
  29.     (ensures (mem x l = (count x l > 0)))
  30.     (decreases l)
  31.  [SMTPat (mem x l)]
  32. let rec mem_count #a x = function
  33.  | [] -> ()
  34.  | _::tl -> mem_count x tl
  35.  
  36.  
  37. val append_count: #a:eqtype -> l:list a -> m:list a -> x:a ->
  38.  Lemma (requires True)
  39.        (ensures (count x (l @ m) = (count x l + count x m)))
  40.  [SMTPat (count x (l @ m))]
  41. let rec append_count #a l m x =
  42.  match l with
  43.  | [] -> ()
  44.  | hd::tl -> append_count tl m x
  45.  
  46.  
  47. val partition: ('a -> Tot bool) -> list 'a -> Tot (list 'a * list 'a)
  48. let rec partition f = function
  49.  | [] -> [], []
  50.  | hd::tl ->
  51.    let l1, l2 = partition f tl in
  52.    if f hd then (hd::l1, l2) else (l1, hd::l2)
  53.  
  54.  
  55. val partition_lemma: #a:eqtype -> f:(a -> Tot bool) -> l:list a ->
  56.  Lemma (requires True)
  57.        (ensures (let (hi, lo) = partition f l in
  58.                  length l = length hi + length lo
  59.                  /\ (forall x. (mem x hi ==>   f x)
  60.                        /\ (mem x lo ==> ~(f x))
  61.                        /\ (count x l = count x hi + count x lo))))
  62.  [SMTPat (partition f l)]
  63. let rec partition_lemma #a f l = match l with
  64.  | [] -> ()
  65.  | hd::tl ->  partition_lemma f tl
  66.  
  67.  
  68. val sorted_app_lemma: #a:eqtype -> f:total_order a
  69.  -> l1:list a{sorted f l1} -> l2:list a{sorted f l2} -> pivot:a
  70.  -> Lemma (requires (forall y. (mem y l1 ==> ~(f pivot y))
  71.                 /\ (mem y l2 ==>   f pivot y)))
  72.          (ensures (sorted f (l1 @ pivot :: l2)))
  73.  [SMTPat (sorted f (l1 @ pivot::l2))]
  74. let rec sorted_app_lemma #a f l1 l2 pivot =
  75.  match l1 with
  76.  | hd::tl -> sorted_app_lemma f tl l2 pivot
  77.  | _ -> ()
  78.  
  79. type is_permutation (a:eqtype) (l:list a) (m:list a) =
  80.  forall x. count x l = count x m
  81.  
  82. val quicksort: #a:eqtype -> f:total_order a -> l:list a ->
  83.  Tot (m:list a{sorted f m /\ is_permutation a l m})
  84.  (decreases (length l))
  85. let rec quicksort #a f = function
  86.  | [] -> []
  87.  | pivot::tl ->
  88.    let hi, lo = partition (f pivot) tl in
  89.    (quicksort f lo) @ pivot :: quicksort f hi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement