New function to export a problem to dimacs format

This commit is contained in:
Guillaume Bury 2016-08-18 18:19:14 +02:00
parent 56f98d9a82
commit 119f3a8566
6 changed files with 63 additions and 0 deletions

View file

@ -93,4 +93,28 @@ module Make
let get_tag cl = St.(cl.tag) let get_tag cl = St.(cl.tag)
let export_dimacs fmt () =
let n = St.nb_elt () in
let tmp = S.temp () in
let hyps = S.hyps () in
let learnt = S.history () in
let m = Vec.size hyps + Vec.size learnt in
let aux fmt c =
let c' = match c.St.cpremise with
| St.Hyp | St.Lemma _ -> c
| St.History ( { St.cpremise = (St.Hyp | St.Lemma _) } as d :: _) -> d
| _ -> assert false
in
St.pp_dimacs fmt c'
in
let pp s fmt vec =
Format.fprintf fmt "c %s@\n%a" s (Vec.print ~sep:"\n" aux) vec
in
Format.fprintf fmt
"p cnf %d %d@\n%a%a%a"
n m
(pp "Local assumptions") tmp
(pp "Hypotheses") hyps
(pp "Learnt") learnt
end end

View file

@ -33,6 +33,9 @@ module Make
(* clauses assumed (subject to user levels) *) (* clauses assumed (subject to user levels) *)
clauses_learnt : clause Vec.t; clauses_learnt : clause Vec.t;
(* learnt clauses (tautologies true at any time, whatever the user level) *) (* learnt clauses (tautologies true at any time, whatever the user level) *)
clauses_temp : clause Vec.t;
(* Temp clauses, corresponding to the local assumptions. This vec is used
only to have an efficient way to access the list of local assumptions. *)
clauses_to_add : clause Stack.t; clauses_to_add : clause Stack.t;
(* Clauses either assumed or pushed by the theory, waiting to be added. *) (* Clauses either assumed or pushed by the theory, waiting to be added. *)
@ -124,6 +127,8 @@ module Make
clauses_hyps = Vec.make 0 dummy_clause; clauses_hyps = Vec.make 0 dummy_clause;
clauses_learnt = Vec.make 0 dummy_clause; clauses_learnt = Vec.make 0 dummy_clause;
clauses_temp = Vec.make 0 dummy_clause;
clauses_to_add = Stack.create (); clauses_to_add = Stack.create ();
th_head = 0; th_head = 0;
@ -1135,6 +1140,16 @@ module Make
assert (env.base_level > 0); assert (env.base_level > 0);
env.unsat_conflict <- None; env.unsat_conflict <- None;
env.base_level <- env.base_level - 1; (* before the [cancel_until]! *) env.base_level <- env.base_level - 1; (* before the [cancel_until]! *)
(* remove from env.clauses_temp the now invalid caluses. *)
let i = ref (Vec.size env.clauses_temp - 1) in
while !i >= 0 &&
(Vec.get env.clauses_temp !i).atoms.(0).var.v_level > env.base_level do
decr i
done;
Vec.shrink env.clauses_temp (Vec.size env.clauses_temp - !i - 1);
assert (Vec.for_all (fun c ->
Array.length c.atoms = 1 &&
c.atoms.(0).var.v_level <= env.base_level) env.clauses_temp);
cancel_until env.base_level cancel_until env.base_level
end end
@ -1147,6 +1162,7 @@ module Make
if a.is_true then () if a.is_true then ()
else else
let c = make_clause (fresh_hname ()) [a] Local in let c = make_clause (fresh_hname ()) [a] Local in
Vec.push env.clauses_temp c;
if a.neg.is_true then begin if a.neg.is_true then begin
(* conflict between assumptions: UNSAT *) (* conflict between assumptions: UNSAT *)
report_unsat c; report_unsat c;
@ -1166,5 +1182,8 @@ module Make
let hyps () = env.clauses_hyps let hyps () = env.clauses_hyps
let history () = env.clauses_learnt let history () = env.clauses_learnt
let temp () = env.clauses_temp
end end

View file

@ -56,6 +56,10 @@ module Make
(** Returns the vector of assumptions used by the solver. May be slightly different (** Returns the vector of assumptions used by the solver. May be slightly different
from the clauses assumed because of top-level simplification of clauses. *) from the clauses assumed because of top-level simplification of clauses. *)
val temp : unit -> St.clause Vec.t
(** Returns the clauses coreesponding to the local assumptions.
All clauses in this vec are assured to be unit clauses. *)
val history : unit -> St.clause Vec.t val history : unit -> St.clause Vec.t
(** Returns the history of learnt clauses, with no guarantees on order. *) (** Returns the history of learnt clauses, with no guarantees on order. *)
@ -65,5 +69,6 @@ module Make
val model : unit -> (St.term * St.term) list val model : unit -> (St.term * St.term) list
(** Returns the model found if the formula is satisfiable. *) (** Returns the model found if the formula is satisfiable. *)
end end

View file

@ -69,5 +69,9 @@ module type S = sig
val get_tag : St.clause -> int option val get_tag : St.clause -> int option
(** Recover tag from a clause, if any *) (** Recover tag from a clause, if any *)
val export_dimacs : Format.formatter -> unit -> unit
(** Prints the entire set of clauses in the input problem
(including hypothesis, lemmas and local assumptions),
in the dimacs format. *)
end end

View file

@ -301,6 +301,16 @@ module McMake (E : Expr_intf.S)(Dummy : sig end) = struct
Format.fprintf out "%s@[<hov>{@[<hov>%a@]}@ cpremise={@[<hov>%a@]}@]" Format.fprintf out "%s@[<hov>{@[<hov>%a@]}@ cpremise={@[<hov>%a@]}@]"
name pp_atoms_vec arr pp_premise cp name pp_atoms_vec arr pp_premise cp
let pp_dimacs fmt { atoms; } =
let aux fmt a =
Array.iter (fun p ->
Format.fprintf fmt "%s%d "
(if p == p.var.pa then "-" else "")
(p.var.vid+1)
) a
in
Format.fprintf fmt "%a0" aux atoms
end end

View file

@ -142,6 +142,7 @@ module type S = sig
val pp_lit : Format.formatter -> lit -> unit val pp_lit : Format.formatter -> lit -> unit
val pp_atom : Format.formatter -> atom -> unit val pp_atom : Format.formatter -> atom -> unit
val pp_clause : Format.formatter -> clause -> unit val pp_clause : Format.formatter -> clause -> unit
val pp_dimacs : Format.formatter -> clause -> unit
(** Debug function for atoms and clauses (very verbose) *) (** Debug function for atoms and clauses (very verbose) *)
end end