sidekick/tests/test_api.ml
Guillaume Bury 4f5bb640ca [WIP] All is setup, remains to have real theories
Architecture is now all setup, but theories for the smt and mcsat
solvers are currently dummy ones that are not doing anything.
2016-09-16 15:49:33 +02:00

175 lines
4.2 KiB
OCaml

(*
MSAT is free software, using the Apache license, see file LICENSE
Copyright 2014 Guillaume Bury
Copyright 2014 Simon Cruanes
*)
(* Tests that require the API *)
module F = Expr_sat
module T = Tseitin.Make(F)
let (|>) x f = f x
let p_check = ref false
let time_limit = ref 300.
let size_limit = ref 1000_000_000.
let error_msg opt arg l =
Format.fprintf Format.str_formatter "'%s' is not a valid argument for '%s', valid arguments are : %a"
arg opt (fun fmt -> List.iter (fun (s, _) -> Format.fprintf fmt "%s, " s)) l;
Format.flush_str_formatter ()
let set_flag opt arg flag l =
try
flag := List.assoc arg l
with Not_found ->
invalid_arg (error_msg opt arg l)
let usage = "Usage : test_api [options]"
let argspec = Arg.align [
"-check", Arg.Set p_check,
" Build, check and print the proof (if output is set), if unsat";
"-v", Arg.Int (fun i -> Log.set_debug i),
"<lvl> Sets the debug verbose level";
]
type solver_res =
| R_sat
| R_unsat
exception Incorrect_model
module type BASIC_SOLVER = sig
val solve : ?assumptions:F.t list -> unit -> solver_res
val assume : ?tag:int -> F.t list list -> unit
end
let mk_solver (): (module BASIC_SOLVER) =
let module S = struct
include Sat.Make(struct end)
let solve ?assumptions ()= match solve ?assumptions() with
| Sat _ ->
R_sat
| Unsat us ->
let p = us.Solver_intf.get_proof () in
Proof.check p;
R_unsat
end
in (module S)
exception Error of string
let error msg = raise (Error msg)
let errorf msg = Format.ksprintf error msg
module Test = struct
type action =
| A_assume of F.t list list
| A_solve of F.t list * [`Expect_sat | `Expect_unsat]
type t = {
name: string;
actions: action list;
}
let mk_test name l = {name; actions=l}
let assume l = A_assume (List.map (List.map F.make) l)
let assume1 c = assume [c]
let solve ?(assumptions=[]) e =
let assumptions = List.map F.make assumptions in
A_solve (assumptions, e)
type result =
| Pass
| Fail of string
let run (t:t): result =
(* Interesting stuff happening *)
let (module S: BASIC_SOLVER) = mk_solver () in
try
List.iter
(function
| A_assume cs ->
S.assume cs
| A_solve (assumptions, expect) ->
match S.solve ~assumptions (), expect with
| R_sat, `Expect_sat
| R_unsat, `Expect_unsat -> ()
| R_unsat, `Expect_sat ->
error "expect sat, got unsat"
| R_sat, `Expect_unsat ->
error "expect unsat, got sat"
)
t.actions;
Pass
with Error msg ->
Fail msg
(* basic test *)
let test1 =
[ assume [[-1;2]; [-1;3]];
solve `Expect_sat;
assume [[-2;4]; [-3;-4]];
solve `Expect_sat;
assume [[1]];
solve `Expect_unsat;
] |> mk_test "test1"
(* same as test1 but with assumptions *)
let test2 =
[ solve `Expect_sat;
assume [[-1;2]; [-1;3]];
solve `Expect_sat;
assume [[-2;4]; [-3;-4]];
solve `Expect_sat;
solve ~assumptions:[1] `Expect_unsat;
solve `Expect_sat;
] |> mk_test "test2"
(* repeat assumptions *)
let test3 =
[ assume [[-1;2]; [-1;3]];
solve `Expect_sat;
assume [[-2;4]; [-3;-4]];
solve `Expect_sat;
solve ~assumptions:[1] `Expect_unsat;
solve `Expect_sat;
solve ~assumptions:[1] `Expect_unsat;
solve `Expect_sat;
solve ~assumptions:[1] `Expect_unsat;
solve `Expect_sat;
solve ~assumptions:[2] `Expect_sat;
assume [[1]];
solve `Expect_unsat;
] |> mk_test "test3"
(* just check that we do create new solvers *)
let test_clean =
[ solve `Expect_sat
] |> mk_test "test_clean"
let suite =
[ test1;
test2;
test3;
test_clean; (* after test3 *)
]
end
let main () =
(* Administrative duties *)
Arg.parse argspec (fun _ -> ()) usage;
let failed = ref false in
List.iter
(fun test ->
Printf.printf "%-10s... %!" test.Test.name;
match Test.run test with
| Test.Pass -> Printf.printf "ok\n%!"
| Test.Fail msg ->
failed := true;
Printf.printf "fail (%s)\n%!" msg)
Test.suite;
if !failed then exit 1
let () = main()