Progressing on new theory interface

This commit is contained in:
Guillaume Bury 2014-11-12 16:24:08 +01:00
parent 68a1249527
commit 35ce540684
4 changed files with 64 additions and 70 deletions

View file

@ -69,12 +69,12 @@ module Tsat = struct
start : int; start : int;
length : int; length : int;
get : int -> formula; get : int -> formula;
push : formula -> unit; push : formula -> formula list -> proof -> unit;
} }
type res = type res =
| Sat of level | Sat of level
| Unsat of formula list | Unsat of formula list * proof
let dummy = () let dummy = ()
let current_level () = () let current_level () = ()

View file

@ -352,20 +352,35 @@ module Make (F : Formula_intf.S)
Vec.shrink watched dead_part Vec.shrink watched dead_part
(* Propagation (boolean and theory *) (* Propagation (boolean and theory *)
let slice_get i = (Vec.get env.trail i).lit
let slice_push lit l lemma =
let atoms = List.rev_map add_atom (lit :: (List.rev_map F.neg l)) in
let c = St.make_clause (St.fresh_name ()) atoms (List.length atoms) true [] in
enqueue (St.add_atom lit) (decision_level ()) (Some c)
let current_slice () = Th.({ let current_slice () = Th.({
start = env.tatoms_qhead; start = env.tatoms_qhead;
length = (Vec.size env.trail) - env.tatoms_qhead; length = (Vec.size env.trail) - env.tatoms_qhead;
get = (function i -> (Vec.get env.trail i).lit); get = slice_get;
push = (function lit -> enqueue (St.add_atom lit) (decision_level ()) None); push = slice_push;
(* TODO: modify reasons to allow for theory reason *)
}) })
let rec theory_propagate () = None let rec theory_propagate () =
match Th.assume (current_slice ()) with
| Th.Sat _ ->
env.tatoms_qhead <- Vec.size env.trail;
propagate ()
| Th.Unsat (l, p) ->
let l = List.rev_map St.add_atom l in
let c = St.make_clause (St.fresh_name ()) l (List.length l) true [] in
Some c
and propagate () = and propagate () =
if env.qhead = Vec.size env.trail then
None
else begin
let num_props = ref 0 in let num_props = ref 0 in
let res = ref None in let res = ref None in
(*assert (Queue.is_empty env.tqueue);*)
while env.qhead < Vec.size env.trail do while env.qhead < Vec.size env.trail do
let a = Vec.get env.trail env.qhead in let a = Vec.get env.trail env.qhead in
env.qhead <- env.qhead + 1; env.qhead <- env.qhead + 1;
@ -374,7 +389,10 @@ module Make (F : Formula_intf.S)
done; done;
env.propagations <- env.propagations + !num_props; env.propagations <- env.propagations + !num_props;
env.simpDB_props <- env.simpDB_props - !num_props; env.simpDB_props <- env.simpDB_props - !num_props;
!res match !res with
| None -> theory_propagate ()
| _ -> !res
end
(* conflict analysis *) (* conflict analysis *)
let analyze c_clause = let analyze c_clause =
@ -481,24 +499,17 @@ module Make (F : Formula_intf.S)
(struct type t = clause let equal = (==) let hash = Hashtbl.hash end) (struct type t = clause let equal = (==) let hash = Hashtbl.hash end)
let report_b_unsat ({atoms=atoms} as confl) = let report_unsat ({atoms=atoms} as confl) =
env.unsat_conflict <- Some confl; env.unsat_conflict <- Some confl;
env.is_unsat <- true; env.is_unsat <- true;
raise Unsat raise Unsat
let report_t_unsat dep =
env.is_unsat <- true;
raise Unsat
let simplify () = let simplify () =
assert (decision_level () = 0); assert (decision_level () = 0);
if env.is_unsat then raise Unsat; if env.is_unsat then raise Unsat;
begin begin
match propagate () with match propagate () with
| Some confl -> report_b_unsat confl | Some confl -> report_unsat confl
| None ->
match theory_propagate () with
Some dep -> report_t_unsat dep
| None -> () | None -> ()
end; end;
if nb_assigns() <> env.simpDB_assigns && env.simpDB_props <= 0 then begin if nb_assigns() <> env.simpDB_assigns && env.simpDB_props <= 0 then begin
@ -533,8 +544,8 @@ module Make (F : Formula_intf.S)
clause_decay_activity () clause_decay_activity ()
let theory_analyze dep = 0, [], [], 1
(* (*
let theory_analyze dep = 0, [], [], 1
let atoms, sz, max_lvl, c_hist = let atoms, sz, max_lvl, c_hist =
Ex.fold_atoms Ex.fold_atoms
(fun a (acc, sz, max_lvl, c_hist) -> (fun a (acc, sz, max_lvl, c_hist) ->
@ -603,7 +614,7 @@ module Make (F : Formula_intf.S)
let add_boolean_conflict confl = let add_boolean_conflict confl =
env.conflicts <- env.conflicts + 1; env.conflicts <- env.conflicts + 1;
if decision_level() = 0 then report_b_unsat confl; (* Top-level conflict *) if decision_level() = 0 then report_unsat confl; (* Top-level conflict *)
let blevel, learnt, history, size = analyze confl in let blevel, learnt, history, size = analyze confl in
cancel_until blevel; cancel_until blevel;
record_learnt_clause blevel learnt history size record_learnt_clause blevel learnt history size
@ -618,16 +629,6 @@ module Make (F : Formula_intf.S)
add_boolean_conflict confl add_boolean_conflict confl
| None -> (* No Conflict *) | None -> (* No Conflict *)
match theory_propagate () with
| Some dep ->
incr conflictC;
env.conflicts <- env.conflicts + 1;
if decision_level() = 0 then report_t_unsat dep; (* T-L conflict *)
let blevel, learnt, history, size = theory_analyze dep in
cancel_until blevel;
record_learnt_clause blevel learnt history size
| None ->
if nb_assigns() = env.nb_init_vars then raise Sat; if nb_assigns() = env.nb_init_vars then raise Sat;
if n_of_conflicts >= 0 && !conflictC >= n_of_conflicts then if n_of_conflicts >= 0 && !conflictC >= n_of_conflicts then
begin begin
@ -727,7 +728,7 @@ module Make (F : Formula_intf.S)
let size = List.length atoms in let size = List.length atoms in
match atoms with match atoms with
| [] -> | [] ->
report_b_unsat init0; report_unsat init0;
| a::_::_ -> | a::_::_ ->
let name = fresh_name () in let name = fresh_name () in
@ -745,13 +746,11 @@ module Make (F : Formula_intf.S)
a.var.vpremise <- init; a.var.vpremise <- init;
enqueue a 0 None; enqueue a 0 None;
match propagate () with match propagate () with
None -> () | Some confl -> report_b_unsat confl None -> () | Some confl -> report_unsat confl
with Trivial -> () with Trivial -> ()
let add_clauses cnf ~cnumber = let add_clauses cnf ~cnumber =
List.iter (add_clause ~cnumber) cnf; List.iter (add_clause ~cnumber) cnf
match theory_propagate () with
None -> () | Some dep -> report_t_unsat dep
let init_solver cnf ~cnumber = let init_solver cnf ~cnumber =
let nbv = made_vars_info env.vars in let nbv = made_vars_info env.vars in

View file

@ -25,7 +25,7 @@ module type S = sig
start : int; start : int;
length : int; length : int;
get : int -> formula; get : int -> formula;
push : formula -> unit; push : formula -> formula list -> proof -> unit;
} }
type level type level
@ -33,7 +33,7 @@ module type S = sig
type res = type res =
| Sat of level | Sat of level
| Unsat of formula list | Unsat of formula list * proof
(** Type returned by the theory, either the current set of assumptions is satisfiable, (** Type returned by the theory, either the current set of assumptions is satisfiable,
or it is not, in which case an unsatisfiable clause (hopefully minimal) is returned. or it is not, in which case an unsatisfiable clause (hopefully minimal) is returned.
Formulas in the unsat clause must come from the current set of assumptions. *) Formulas in the unsat clause must come from the current set of assumptions. *)

View file

@ -39,11 +39,6 @@ module Make (F : Formula_intf.S) = struct
let make comb l = Comb (comb, l) let make comb l = Comb (comb, l)
let value env c =
if List.mem c env then Some true
else if List.mem (make Not [c]) env then Some false
else None
let make_atom p = Lit p let make_atom p = Lit p
let atomic_true = F.fresh () let atomic_true = F.fresh ()