mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 03:05:31 -05:00
Architecture is now all setup, but theories for the smt and mcsat solvers are currently dummy ones that are not doing anything.
175 lines
4.2 KiB
OCaml
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()
|