 ### new examples: tree_of_array and binary_sort

parent 7d8d2baf
 (** Binary sort Binary sort is a variant of insertion sort where binary search is used to find the insertion point. This lowers the number of comparisons (from N^2 to N log(N)) and thus is useful when comparisons are costly. For instance, Binary sort is used as an ingredient in Java 8's TimSort implementation (which is the library sort for Object[]). Author: Jean-Christophe Filliâtre (CNRS) *) module BinarySort use import int.Int use import int.ComputerDivision use import ref.Ref use import array.Array use import array.ArrayPermut let lemma occ_shift (m1 m2: M.map int 'a) (mid k: int) (x: 'a) : unit requires { 0 <= mid <= k } requires { forall i. mid < i <= k -> M.get m2 i = M.get m1 (i - 1) } requires { M.get m2 mid = M.get m1 k } ensures { M.Occ.occ x m1 mid (k+1) = M.Occ.occ x m2 mid (k+1) } = for i = mid to Int.(-) k 1 do invariant { M.Occ.occ x m1 mid i = M.Occ.occ x m2 (mid+1) (i+1) } () done; assert { M.Occ.occ (M.get m1 k) m1 mid (k+1) = 1 + M.Occ.occ (M.get m1 k) m1 mid k }; assert { M.Occ.occ (M.get m1 k) m2 mid (k+1) = 1 + M.Occ.occ (M.get m1 k) m2 (mid+1) (k+1) }; assert { M.Occ.occ x m1 mid (k+1) = M.Occ.occ x m2 mid (k+1) by x = M.get m1 k \/ x <> M.get m1 k } let binary_sort (a: array int) : unit ensures { forall i j. 0 <= i <= j < length a -> a[i] <= a[j] } ensures { permut_sub (old a) a 0 (length a) } = 'Init: for k = 1 to length a - 1 do (* a[0..k-1) is sorted; insert a[k] *) invariant { forall i j. 0 <= i <= j < k -> a[i] <= a[j] } invariant { permut_sub (at a 'Init) a 0 (length a) } let v = a[k] in let left = ref 0 in let right = ref k in while !left < !right do invariant { 0 <= !left <= !right <= k } invariant { forall i. 0 <= i < !left -> a[i] <= v } invariant { forall i. !right <= i < k -> v < a[i] } variant { !right - !left } let mid = !left + div (!right - !left) 2 in if v < a[mid] then right := mid else left := mid + 1 done; (* !left is the place where to insert value v so we move a[!left..k) one position to the right *) 'L: for l = k downto !left + 1 do invariant { forall i. l < i <= k -> a[i] = (at a 'L)[i - 1] } invariant { forall i. 0 <= i <= l -> a[i] = (at a 'L)[i] } invariant { forall i. k < i < length a -> a[i] = (at a 'L)[i] } a[l] <- a[l - 1] done; a[!left] <- v; assert { permut_sub (at a 'L) a !left (k + 1) }; assert { permut_sub (at a 'L) a 0 (length a) }; done end

File added
 ... ... @@ -13,20 +13,20 @@ module BubbleSort let bubble_sort (a: array int) ensures { permut_all (old a) a } ensures { permut_all (old a) a } ensures { sorted a } = 'Init: for i = length a - 1 downto 1 do invariant { permut_all (at a 'Init) a } invariant { sorted_sub a i (length a) } invariant { forall k1 k2: int. 0 <= k1 <= i < k2 < length a -> a[k1] <= a[k2] invariant { forall k1 k2: int. 0 <= k1 <= i < k2 < length a -> a[k1] <= a[k2] } for j = 0 to i - 1 do invariant { permut_all (at a 'Init) a } invariant { sorted_sub a i (length a) } invariant { forall k1 k2: int. 0 <= k1 <= i < k2 < length a -> a[k1] <= a[k2] invariant { forall k1 k2: int. 0 <= k1 <= i < k2 < length a -> a[k1] <= a[k2] } invariant { forall k. 0 <= k <= j -> a[k] <= a[j] } if a[j] > a[j+1] then swap a j (j+1); ... ... @@ -35,7 +35,7 @@ module BubbleSort let test1 () = let a = make 3 0 in a <- 7; a <- 3; a <- 1; a <- 7; a <- 3; a <- 1; bubble_sort a; a ... ...
 ... ... @@ -4,14 +4,16 @@ ... ... @@ -20,7 +22,7 @@ ... ... @@ -51,7 +53,7 @@ ... ... @@ -64,10 +66,10 @@ ... ... @@ -102,5 +104,73 @@
No preview for this file type
 (** Build a tree of logarithmic height from an array, in linear time, while preserving the order of elements Author: Jean-Christophe Filliâtre (CNRS) *) module TreeOfArray use import int.Int use import int.ComputerDivision use import int.Power use import array.Array use import array.ToList use import bintree.Tree use import bintree.Size use import bintree.Inorder use import bintree.Height let rec tree_of_array_aux (a: array 'a) (lo hi: int) : tree 'a requires { 0 <= lo <= hi <= length a } variant { hi - lo } ensures { let n = hi - lo in size result = n && inorder result = to_list a lo hi && (n > 0 -> let h = height result in power 2 (h-1) <= n < power 2 h) } = if hi = lo then Empty else let mid = lo + div (hi - lo) 2 in let left = tree_of_array_aux a lo mid in let right = tree_of_array_aux a (mid + 1) hi in Node left a[mid] right let tree_of_array (a: array 'a) : tree 'a ensures { inorder result = to_list a 0 (length a) } ensures { size result > 0 -> let h = height result in power 2 (h-1) <= size result < power 2 h } = tree_of_array_aux a 0 (length a) end

 ... ... @@ -295,6 +295,12 @@ module ToList forall a: array 'a, l u: int. l < u -> to_list a l u = Cons a[l] (to_list a (l+1) u) use import list.Append lemma to_list_append: forall a: array 'a, l m u: int. l <= m <= u -> to_list a l m ++ to_list a m u = to_list a l u val to_list (a: array 'a) (l u: int) : list 'a requires { 0 <= l && u <= length a } ensures { result = to_list a l u } ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment