mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-10 21:24:06 -05:00
feat: allow optional disabling of proof logging
- goal: do not keep clauses alive after they're gc'd - default is to indeed log proofs
This commit is contained in:
parent
65a8a65095
commit
da24541fa0
4 changed files with 46 additions and 23 deletions
|
|
@ -74,6 +74,7 @@ module Make(Plugin : PLUGIN)
|
||||||
| Local
|
| Local
|
||||||
| Lemma of lemma
|
| Lemma of lemma
|
||||||
| History of clause list
|
| History of clause list
|
||||||
|
| Empty_premise
|
||||||
|
|
||||||
type elt =
|
type elt =
|
||||||
| E_lit of lit
|
| E_lit of lit
|
||||||
|
|
@ -117,6 +118,7 @@ module Make(Plugin : PLUGIN)
|
||||||
| Lemma _ -> "T" ^ string_of_int c.name
|
| Lemma _ -> "T" ^ string_of_int c.name
|
||||||
| Local -> "L" ^ string_of_int c.name
|
| Local -> "L" ^ string_of_int c.name
|
||||||
| History _ -> "C" ^ string_of_int c.name
|
| History _ -> "C" ^ string_of_int c.name
|
||||||
|
| Empty_premise -> string_of_int c.name
|
||||||
|
|
||||||
module Lit = struct
|
module Lit = struct
|
||||||
type t = lit
|
type t = lit
|
||||||
|
|
@ -396,6 +398,7 @@ module Make(Plugin : PLUGIN)
|
||||||
| Local -> Format.fprintf out "local"
|
| Local -> Format.fprintf out "local"
|
||||||
| History v ->
|
| History v ->
|
||||||
List.iter (fun c -> Format.fprintf out "%s,@ " (name_of_clause c)) v
|
List.iter (fun c -> Format.fprintf out "%s,@ " (name_of_clause c)) v
|
||||||
|
| Empty_premise -> Format.fprintf out "<no premise>"
|
||||||
|
|
||||||
let debug out ({atoms=arr; cpremise=cp;_}as c) =
|
let debug out ({atoms=arr; cpremise=cp;_}as c) =
|
||||||
Format.fprintf out "%s@[<hov>{@[<hov>%a@]}@ cpremise={@[<hov>%a@]}@]"
|
Format.fprintf out "%s@[<hov>{@[<hov>%a@]}@ cpremise={@[<hov>%a@]}@]"
|
||||||
|
|
@ -478,9 +481,11 @@ module Make(Plugin : PLUGIN)
|
||||||
in
|
in
|
||||||
aux (c, d)
|
aux (c, d)
|
||||||
|
|
||||||
let[@inline] prove conclusion =
|
let prove conclusion =
|
||||||
assert (conclusion.cpremise <> History []);
|
match conclusion.cpremise with
|
||||||
conclusion
|
| History [] -> assert false
|
||||||
|
| Empty_premise -> raise Solver_intf.No_proof
|
||||||
|
| _ -> conclusion
|
||||||
|
|
||||||
let rec set_atom_proof a =
|
let rec set_atom_proof a =
|
||||||
let aux acc b =
|
let aux acc b =
|
||||||
|
|
@ -582,6 +587,7 @@ module Make(Plugin : PLUGIN)
|
||||||
conclusion.cpremise <- History [c'; d'];
|
conclusion.cpremise <- History [c'; d'];
|
||||||
assert (cmp_cl l (to_list conclusion) = 0);
|
assert (cmp_cl l (to_list conclusion) = 0);
|
||||||
{ conclusion; step = Resolution (c', d', a); }
|
{ conclusion; step = Resolution (c', d', a); }
|
||||||
|
| Empty_premise -> raise Solver_intf.No_proof
|
||||||
|
|
||||||
(* Proof nodes manipulation *)
|
(* Proof nodes manipulation *)
|
||||||
let is_leaf = function
|
let is_leaf = function
|
||||||
|
|
@ -615,6 +621,7 @@ module Make(Plugin : PLUGIN)
|
||||||
if not @@ Clause.visited c then (
|
if not @@ Clause.visited c then (
|
||||||
Clause.set_visited c true;
|
Clause.set_visited c true;
|
||||||
match c.cpremise with
|
match c.cpremise with
|
||||||
|
| Empty_premise -> raise Solver_intf.No_proof
|
||||||
| Hyp _ | Lemma _ | Local -> aux (c :: res) acc r
|
| Hyp _ | Lemma _ | Local -> aux (c :: res) acc r
|
||||||
| History h ->
|
| History h ->
|
||||||
let l = List.fold_left (fun acc c ->
|
let l = List.fold_left (fun acc c ->
|
||||||
|
|
@ -712,6 +719,8 @@ module Make(Plugin : PLUGIN)
|
||||||
st : st;
|
st : st;
|
||||||
th: theory;
|
th: theory;
|
||||||
|
|
||||||
|
log_proof: bool; (* do we store proofs? *)
|
||||||
|
|
||||||
(* Clauses are simplified for eficiency purposes. In the following
|
(* Clauses are simplified for eficiency purposes. In the following
|
||||||
vectors, the comments actually refer to the original non-simplified
|
vectors, the comments actually refer to the original non-simplified
|
||||||
clause. *)
|
clause. *)
|
||||||
|
|
@ -778,7 +787,7 @@ module Make(Plugin : PLUGIN)
|
||||||
type solver = t
|
type solver = t
|
||||||
|
|
||||||
(* Starting environment. *)
|
(* Starting environment. *)
|
||||||
let create_ ~st (th:theory) : t = {
|
let create_ ~st ~log_proof (th:theory) : t = {
|
||||||
st; th;
|
st; th;
|
||||||
unsat_at_0=None;
|
unsat_at_0=None;
|
||||||
next_decision = None;
|
next_decision = None;
|
||||||
|
|
@ -800,15 +809,16 @@ module Make(Plugin : PLUGIN)
|
||||||
|
|
||||||
var_incr = 1.;
|
var_incr = 1.;
|
||||||
clause_incr = 1.;
|
clause_incr = 1.;
|
||||||
|
log_proof;
|
||||||
|
|
||||||
restart_first = 100;
|
restart_first = 100;
|
||||||
|
|
||||||
learntsize_factor = 1. /. 3. ;
|
learntsize_factor = 1. /. 3. ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let create ?(size=`Big) (th:theory) : t =
|
let create ?(log_proof=true) ?(size=`Big) (th:theory) : t =
|
||||||
let st = create_st ~size () in
|
let st = create_st ~size () in
|
||||||
create_ ~st th
|
create_ ~st ~log_proof th
|
||||||
|
|
||||||
let[@inline] st t = t.st
|
let[@inline] st t = t.st
|
||||||
let[@inline] nb_clauses st = Vec.size st.clauses_hyps
|
let[@inline] nb_clauses st = Vec.size st.clauses_hyps
|
||||||
|
|
@ -1317,10 +1327,9 @@ module Make(Plugin : PLUGIN)
|
||||||
Log.debug debug "(@[sat.analyze-conflict: skipping resolution for semantic propagation@])"
|
Log.debug debug "(@[sat.analyze-conflict: skipping resolution for semantic propagation@])"
|
||||||
| Some clause ->
|
| Some clause ->
|
||||||
Log.debugf debug (fun k->k"(@[sat.analyze-conflict.resolve@ %a@])" Clause.debug clause);
|
Log.debugf debug (fun k->k"(@[sat.analyze-conflict.resolve@ %a@])" Clause.debug clause);
|
||||||
begin match clause.cpremise with
|
if Clause.learnt clause then (
|
||||||
| History _ -> clause_bump_activity st clause
|
clause_bump_activity st clause;
|
||||||
| Hyp _ | Local | Lemma _ -> ()
|
);
|
||||||
end;
|
|
||||||
history := clause :: !history;
|
history := clause :: !history;
|
||||||
(* visit the current predecessors *)
|
(* visit the current predecessors *)
|
||||||
for j = 0 to Array.length clause.atoms - 1 do
|
for j = 0 to Array.length clause.atoms - 1 do
|
||||||
|
|
@ -1393,6 +1402,7 @@ module Make(Plugin : PLUGIN)
|
||||||
|
|
||||||
(* add the learnt clause to the clause database, propagate, etc. *)
|
(* add the learnt clause to the clause database, propagate, etc. *)
|
||||||
let record_learnt_clause st (confl:clause) (cr:conflict_res): unit =
|
let record_learnt_clause st (confl:clause) (cr:conflict_res): unit =
|
||||||
|
let proof = if st.log_proof then History cr.cr_history else Empty_premise in
|
||||||
begin match cr.cr_learnt with
|
begin match cr.cr_learnt with
|
||||||
| [] -> assert false
|
| [] -> assert false
|
||||||
| [fuip] ->
|
| [fuip] ->
|
||||||
|
|
@ -1401,13 +1411,13 @@ module Make(Plugin : PLUGIN)
|
||||||
(* incompatible at level 0 *)
|
(* incompatible at level 0 *)
|
||||||
report_unsat st (US_false confl)
|
report_unsat st (US_false confl)
|
||||||
) else (
|
) else (
|
||||||
let uclause = Clause.make cr.cr_learnt (History cr.cr_history) in
|
let uclause = Clause.make cr.cr_learnt proof in
|
||||||
(* no need to attach [uclause], it is true at level 0 *)
|
(* no need to attach [uclause], it is true at level 0 *)
|
||||||
Clause.set_learnt uclause true;
|
Clause.set_learnt uclause true;
|
||||||
enqueue_bool st fuip ~level:0 (Bcp uclause)
|
enqueue_bool st fuip ~level:0 (Bcp uclause)
|
||||||
)
|
)
|
||||||
| fuip :: _ ->
|
| fuip :: _ ->
|
||||||
let lclause = Clause.make cr.cr_learnt (History cr.cr_history) in
|
let lclause = Clause.make cr.cr_learnt proof in
|
||||||
Clause.set_learnt lclause true;
|
Clause.set_learnt lclause true;
|
||||||
if Array.length lclause.atoms > 2 then (
|
if Array.length lclause.atoms > 2 then (
|
||||||
Vec.push st.clauses_learnt lclause; (* potentially gc'able *)
|
Vec.push st.clauses_learnt lclause; (* potentially gc'able *)
|
||||||
|
|
@ -1459,13 +1469,14 @@ module Make(Plugin : PLUGIN)
|
||||||
Log.debugf debug (fun k -> k "(@[sat.dups-removed@ %a@])" Clause.debug c);
|
Log.debugf debug (fun k -> k "(@[sat.dups-removed@ %a@])" Clause.debug c);
|
||||||
let atoms, history = partition c.atoms in
|
let atoms, history = partition c.atoms in
|
||||||
let clause =
|
let clause =
|
||||||
if history = []
|
if history = [] then (
|
||||||
then (
|
(* just update order of atoms *)
|
||||||
(* update order of atoms *)
|
|
||||||
List.iteri (fun i a -> c.atoms.(i) <- a) atoms;
|
List.iteri (fun i a -> c.atoms.(i) <- a) atoms;
|
||||||
c
|
c
|
||||||
|
) else (
|
||||||
|
let proof = if st.log_proof then History (c::history) else Empty_premise in
|
||||||
|
Clause.make atoms proof
|
||||||
)
|
)
|
||||||
else Clause.make atoms (History (c :: history))
|
|
||||||
in
|
in
|
||||||
Log.debugf info (fun k->k "(@[sat.new-clause@ @[<hov>%a@]@])" Clause.debug clause);
|
Log.debugf info (fun k->k "(@[sat.new-clause@ @[<hov>%a@]@])" Clause.debug clause);
|
||||||
match atoms with
|
match atoms with
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,8 @@ type ('a, 'b) gadt_eq = GADT_EQ : ('a, 'a) gadt_eq
|
||||||
type void = (unit,bool) gadt_eq
|
type void = (unit,bool) gadt_eq
|
||||||
(** A provably empty type *)
|
(** A provably empty type *)
|
||||||
|
|
||||||
|
exception No_proof
|
||||||
|
|
||||||
module type FORMULA = sig
|
module type FORMULA = sig
|
||||||
(** formulas *)
|
(** formulas *)
|
||||||
|
|
||||||
|
|
@ -408,9 +410,15 @@ module type S = sig
|
||||||
type t = solver
|
type t = solver
|
||||||
(** Main solver type, containing all state for solving. *)
|
(** Main solver type, containing all state for solving. *)
|
||||||
|
|
||||||
val create : ?size:[`Tiny|`Small|`Big] -> theory -> t
|
val create :
|
||||||
|
?log_proof:bool ->
|
||||||
|
?size:[`Tiny|`Small|`Big] ->
|
||||||
|
theory ->
|
||||||
|
t
|
||||||
(** Create new solver
|
(** Create new solver
|
||||||
@param theory the theory
|
@param theory the theory
|
||||||
|
@param log_proof if true, stores proof (default [true]). Otherwise
|
||||||
|
the functions that return proofs will fail with [No_proof]
|
||||||
@param size the initial size of internal data structures. The bigger,
|
@param size the initial size of internal data structures. The bigger,
|
||||||
the faster, but also the more RAM it uses. *)
|
the faster, but also the more RAM it uses. *)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,16 @@ let p_dot_proof = ref ""
|
||||||
let p_proof_print = ref false
|
let p_proof_print = ref false
|
||||||
let time_limit = ref 300.
|
let time_limit = ref 300.
|
||||||
let size_limit = ref 1000_000_000.
|
let size_limit = ref 1000_000_000.
|
||||||
|
let no_proof = ref false
|
||||||
|
|
||||||
module S = Msat_sat
|
module S = Msat_sat
|
||||||
|
|
||||||
module Process = struct
|
module Process() = struct
|
||||||
module D = Msat_backend.Dot.Make(S)(Msat_backend.Dot.Default(S))
|
module D = Msat_backend.Dot.Make(S)(Msat_backend.Dot.Default(S))
|
||||||
|
|
||||||
let hyps = ref []
|
let hyps = ref []
|
||||||
|
|
||||||
let st = S.create ~size:`Big ()
|
let st = S.create ~log_proof:(not !no_proof) ~size:`Big ()
|
||||||
|
|
||||||
let check_model sat =
|
let check_model sat =
|
||||||
let check_clause c =
|
let check_clause c =
|
||||||
|
|
@ -63,7 +64,7 @@ module Process = struct
|
||||||
|
|
||||||
let add_clauses cs =
|
let add_clauses cs =
|
||||||
S.assume st (CCList.map conv_c cs) ()
|
S.assume st (CCList.map conv_c cs) ()
|
||||||
end
|
end[@@inline]
|
||||||
|
|
||||||
let parse_file f =
|
let parse_file f =
|
||||||
let module L = Lexing in
|
let module L = Lexing in
|
||||||
|
|
@ -126,6 +127,7 @@ let argspec = Arg.align [
|
||||||
"<t>[smhd] Sets the time limit for the sat solver";
|
"<t>[smhd] Sets the time limit for the sat solver";
|
||||||
"-v", Arg.Int (fun i -> Log.set_debug i),
|
"-v", Arg.Int (fun i -> Log.set_debug i),
|
||||||
"<lvl> Sets the debug verbose level";
|
"<lvl> Sets the debug verbose level";
|
||||||
|
"-no-proof", Arg.Set no_proof, " disable proof logging";
|
||||||
]
|
]
|
||||||
|
|
||||||
(* Limits alarm *)
|
(* Limits alarm *)
|
||||||
|
|
@ -147,10 +149,12 @@ let main () =
|
||||||
);
|
);
|
||||||
let al = Gc.create_alarm check in
|
let al = Gc.create_alarm check in
|
||||||
|
|
||||||
|
let module P = Process() in
|
||||||
|
|
||||||
(* Interesting stuff happening *)
|
(* Interesting stuff happening *)
|
||||||
let clauses = parse_file !file in
|
let clauses = parse_file !file in
|
||||||
Process.add_clauses clauses;
|
P.add_clauses clauses;
|
||||||
Process.prove ~assumptions:[] ();
|
P.prove ~assumptions:[] ();
|
||||||
Gc.delete_alarm al;
|
Gc.delete_alarm al;
|
||||||
()
|
()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ end = struct
|
||||||
r
|
r
|
||||||
|
|
||||||
let create g : t =
|
let create g : t =
|
||||||
{ solver=S.create (Theory.create g); grid0=g }
|
{ solver=S.create ~log_proof:false (Theory.create g); grid0=g }
|
||||||
end
|
end
|
||||||
|
|
||||||
let solve_grid (g:Grid.t) : Grid.t option =
|
let solve_grid (g:Grid.t) : Grid.t option =
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue