Commit 312f137e by Jean-Christophe Filliâtre

### gallery: some experiments in vstte10_queens to count solutions

parent 20cdf859
 ... ... @@ -111,4 +111,121 @@ module NQueens with Solution -> a end (** variant: counting solutions (not part of the competition) TODO: prove soundness i.e. we indeed count the number of solutions *) use import ref.Refint let rec count_bt_queens (board: array int) (n: int) (pos: int) : int variant { n - pos } requires { length board = n /\ 0 <= pos <= n /\ solution board pos } ensures { eq_board board (old board) pos } = 'Init: if pos = n then 1 else begin let s = ref 0 in for i = 0 to n - 1 do invariant { eq_board board (at board 'Init) pos } board[pos] <- i; if check_is_consistent board pos then s += count_bt_queens board n (pos+1) done; !s end let count_queens (board: array int) (n: int) : int requires { length board = n } ensures { true } = count_bt_queens board n 0 let test_count_8 () = let a = Array.make 8 0 in count_queens a 8 end (** counting solutions with machine integers *) module MachineArithmetic use import ref.Refint use import mach.array.Array63 use import mach.int.Int63 predicate is_board (board: array int63) (pos: int) = forall q: int. 0 <= q < pos -> 0 <= to_int board[q] < to_int (length board) exception MInconsistent int63 let mcheck_is_consistent (board: array int63) (pos: int63) requires { 0 <= to_int pos < to_int (length board) } requires { is_board board (to_int pos + 1) } = try let rec forloop q (* for q = 0 to pos-1 do *) = requires { 0 <= to_int q <= to_int pos } requires { is_board board (to_int pos + 1) } variant { to_int pos - to_int q } raises { MInconsistent -> true } if q < pos then begin let bq = board[q] in let bpos = board[pos] in if bq = bpos then raise (MInconsistent q); if bq - bpos = pos - q then raise (MInconsistent q); if bpos - bq = pos - q then raise (MInconsistent q); forloop (q + of_int 1) end in forloop (of_int 0); True with MInconsistent _ -> False end use mach.onetime.OneTime as O (*** let rec mcount_bt_queens (board: array int63) (n: int63) (pos: int63) : O.t requires { to_int (length board) = to_int n } requires { 0 <= to_int pos <= to_int n } requires { is_board board (to_int pos) } variant { to_int n - to_int pos } ensures { is_board board (to_int pos) } = if eq pos n then O.succ (O.zero ()) else begin let s = ref (O.zero ()) in let rec forloop (i: int63) = (* for i = 0 to n-1 do *) requires { 0 <= to_int i <= to_int n } requires { is_board board (to_int pos) } variant { to_int n - to_int i } ensures { is_board board (to_int pos) } if i < n then begin board[pos] <- i; if mcheck_is_consistent board pos then s := O.add !s (mcount_bt_queens board n (pos + of_int 1)); (* let _ = O.add !s (mcount_bt_queens board n (pos + of_int 1)) in (); *) forloop (i + of_int 1) end in forloop (of_int 0); !s end let mcount_queens (board: array int63) (n: int63) : O.t requires { to_int (length board) = to_int n } ensures { true } = mcount_bt_queens board n (of_int 0) let test_mcount_8 () = let n = of_int 8 in let a = Array63.make n (of_int 0) in mcount_queens a n ***) end
 ... ... @@ -2,43 +2,149 @@ ... ...
No preview for this file type
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!