From e0f199997cfc885926f7fa471563b325e242f8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Wi=C3=9Fmann?= <edu@thorsten-wissmann.de> Date: Tue, 24 Nov 2015 12:52:34 +0100 Subject: [PATCH] Add a lot of comments about cores --- src/lib/CoAlgMisc.ml | 27 ++++++++++++--- src/lib/CoAlgReasoner.ml | 72 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/lib/CoAlgMisc.ml b/src/lib/CoAlgMisc.ml index c103bb7..00174a7 100644 --- a/src/lib/CoAlgMisc.ml +++ b/src/lib/CoAlgMisc.ml @@ -177,14 +177,33 @@ type lht = localFormula LHt.t type fht = Minisat.lit FHt.t type nht = bset NHt.t -type state = { sortS : sort; mutable bsS : bset; mutable statusS : nodeStatus; +type state = { sortS : sort; + mutable bsS : bset; (* a set of formulas who are either literals or + modalities (TODO: also @-formulas?). + the state is satisfiable if /\bsS is satisfiable. + *) + mutable statusS : nodeStatus; mutable parentsS : core list; mutable childrenS : (dependencies * core list) list; mutable constraintsS : csetSet; expandFkt : stateExpander; idx: int } -and core = { sortC : sort; mutable bsC : bset; mutable statusC : nodeStatus; - mutable parentsC : (state * int) list; mutable childrenC : state list; - mutable constraintsC : csetSet; solver : Minisat.solver; fht : fht; +and core = { (* for details, see documentation of newCore *) + sortC : sort; + mutable bsC : bset; (* a set of arbitrary formulas. + the present core is satisfiable if /\ bsC is satisfiable *) + mutable statusC : nodeStatus; + mutable parentsC : (state * int) list; + mutable childrenC : state list; + mutable constraintsC : csetSet; + solver : Minisat.solver; (* a solver to find satisfying assignemnts for bsC. + the solver returns "satisfiable" iff + there is a satisfying assignment of + bsC which is not represented by some state from the + childrenC yet. + *) + fht : fht; (* mapping of boolean subformulas of bsC to their corresponding literals + of the Minisat solver + *) mutable constraintParents : cset list; idx : int } diff --git a/src/lib/CoAlgReasoner.ml b/src/lib/CoAlgReasoner.ml index a17d10e..034d6f2 100644 --- a/src/lib/CoAlgReasoner.ml +++ b/src/lib/CoAlgReasoner.ml @@ -414,58 +414,127 @@ let getLit sort fht solver f = lit let newCore sort bs = + (* when creating a now core from a set of formulas bs + bs = { x_1, ...., x_n } + = "x_1 /\ .... /\ x_n" + Then we do this by: + + 1. creating a new literal in the sat solver for each + "boolean subformula" from the x_i. "boolean subformula" means that + this subformula is not hidden under modalities but only under + boolean connectives (/\, \/). + 2. encoding the relation between a formula and its intermediate boolean + subformulas by a clause: + *) let fht = fhtInit () in let solver = M.new_solver () in let rec addClauses f = + (* step 1: create a literal in the satsolver representing the formula f *) let lf = getLit sort fht solver f in + (* step 2: encode relation to possible subformulas *) match lfGetType sort f with | OrF -> + (* + case 2.(a) f = f1 \/ f2 + fill fht such that it says: + + f |---> lf + f1 |---> lf1 + f2 |---> lf2 + *) let f1 = lfGetDest1 sort f in let f2 = lfGetDest2 sort f in addClauses f1; addClauses f2; let lf1 = fhtMustFind fht f1 in let lf2 = fhtMustFind fht f2 in + (* + encode the structure of f by adding the clause (lf -> lf1 \/ lf2) + *) let okay = M.add_clause solver [M.neg_lit lf; lf1; lf2] in assert (okay) | AndF -> + (* + case 2.(b) f = f1 /\ f2 + fill fht such that it says: + + f |---> lf + f1 |---> lf1 + f2 |---> lf2 + *) let f1 = lfGetDest1 sort f in let f2 = lfGetDest2 sort f in addClauses f1; addClauses f2; let lf1 = fhtMustFind fht f1 in let lf2 = fhtMustFind fht f2 in + (* + encode the structure of f by adding the clauses + (lf -> lf1) /\ (lf -> lf2) + *) let okay1 = M.add_clause solver [M.neg_lit lf; lf1] in assert (okay1); let okay2 = M.add_clause solver [M.neg_lit lf; lf2] in assert (okay2) | _ -> () + (* case 2.(c) + We don't need to do anything except adding f to the fht + *) in bsetIter addClauses bs; coreMake sort bs solver fht let getNextState core = + (* Create a new state, which is obtained by a satisfying assignment of the + literals of the minisat solver. + In addition to that, feed the negation of the satisfying assignment back + to the minisat solver in order to obtain different solutions on successive + minisat calls. + *) let bs = coreGetBs core in let fht = coreGetFht core in let litset = bsetFold (fun f acc -> (fhtMustFind fht f)::acc) bs [] in let solver = coreGetSolver core in let isSat = M.invoke_solver solver litset in + (* Clearly, if the current core is unsatisfiable, no further child state can + be created *) if not isSat then None else let sort = coreGetSort core in + (* create a new set of formulas newbs with the property: + if the conjunction of newbs is satisfiable, then the present core is + satisfiable. + *) let newbs = bsetMake () in + (* if newbs = { l_1, .... l_n }, i.e. + + newbs = l_1 /\ ... /\ l_n + + then we can get essentially different satisfying assignments of bs by + adding another clause + + clause = ¬ newbs = ¬l_1 \/ ... \/ ¬l_n + + By mkExclClause, newbs is filled, and clause is built in the accumulator acc. + *) let rec mkExclClause f acc = + (* f is a formula that is true in the current satisfying assignment *) match lfGetType sort f with | OrF -> + (* if f is true and a disjunction, then one of its disjuncts is true *) let f1 = lfGetDest1 sort f in let lf1 = fhtMustFind fht f1 in + (* if the first disjunct f1 is true, then we need to add subformulas + of f1 to newbs&clause *) if M.literal_status solver lf1 = M.LTRUE then mkExclClause f1 acc else + (* otherwise f2 must be true *) let f2 = lfGetDest2 sort f in let lf2 = fhtMustFind fht f2 in assert (M.literal_status solver lf2 = M.LTRUE); mkExclClause f2 acc | AndF -> + (* if the true f is a conjuction, then both conjunctions must be true *) let f1 = lfGetDest1 sort f in let lf1 = fhtMustFind fht f1 in assert (M.literal_status solver lf1 = M.LTRUE); @@ -475,7 +544,10 @@ let getNextState core = assert (M.literal_status solver lf2 = M.LTRUE); mkExclClause f2 acc1 | _ -> + (* if f is a trivial formula or modality, then add it ... *) + (* ... to newbs *) bsetAdd newbs f; + (* ... and to the new clause *) (M.neg_lit (fhtMustFind fht f))::acc in let clause = bsetFold mkExclClause bs [] in -- GitLab