def getConflictClause(minimize=False): if minimize: Monosat().minimizeConflictClause() conf_clause = Monosat().getConflictClause() if conf_clause is None: return None else: vars = [] for v in conf_clause: vars.append(Var(v)) return vars
def minimize(bitvector_or_literals,weights=None): if isinstance(bitvector_or_literals,Var): bitvector_or_literals = [bitvector_or_literals] if isinstance(weights,int): weights = [weights] if isinstance(bitvector_or_literals,int): Monosat().minimizeBV(bitvector_or_literals) else: lit_ints = [l.getLit() for l in bitvector_or_literals] if weights is None: Monosat().minimizeLits(lit_ints) else: Monosat().minimizeWeightedLits(lit_ints,weights)
def _checkBVs(bvs): for bv in bvs: assert (isinstance(bv, BitVector)) if (bv.mgr._solver != Monosat().getSolver()): raise RuntimeError( 'Bitvector %s does not belong to current solver, aborting (use setSolver() to correct this)' % (str(bv)))
def minimizeUnsatCore(assumptions): assumption_ints = [a.lit for a in assumptions] conf_clause = Monosat().minimizeUnsatCore(assumption_ints) assert conf_clause is not None vars = [] for v in conf_clause: vars.append(Var(v)) return vars
def getConflictClause(): conf_clause = Monosat().getConflictClause() if conf_clause is None: return None else: vars = [] for v in conf_clause: vars.append(Var(v)) return vars
def Solve(assumptions=None, preprocessing=True, bvs_to_minimize=None, time_limit_seconds=None, memory_limit_mb=None, conflict_limit=None): WriteConstraints() if time_limit_seconds is None or time_limit_seconds <= 0: time_limit_seconds = -1 if memory_limit_mb is None or memory_limit_mb <= 0: memory_limit_mb = -1 if conflict_limit is None or conflict_limit <= 0: conflict_limit = -1 Monosat().setTimeLimit(time_limit_seconds) Monosat().setMemoryLimit(memory_limit_mb) Monosat().setConflictLimit(conflict_limit) #if preprocessing: # Monosat().preprocess(); print("Solving in Monosat...") t = time.clock() if isinstance(assumptions, Var): assumptions = [assumptions] elif assumptions is None: assumptions = [] if isinstance(bvs_to_minimize, BitVector): bvs_to_minimize = [bvs_to_minimize] elif bvs_to_minimize is None: bvs_to_minimize = [] r = Monosat().solveLimited([x.getLit() for x in assumptions], [bv.getID() for bv in bvs_to_minimize]) if r is None: raise RuntimeError( "MonoSAT aborted before solving (possibly do to a time or memory limit)" ) Monosat().elapsed_time += time.clock() - t return r
def Solve(assumptions=None, preprocessing=True, bvs_to_minimize=None, time_limit_seconds=None, memory_limit_mb=None, conflict_limit=None): WriteConstraints() if time_limit_seconds is None or time_limit_seconds <= 0: time_limit_seconds = -1 if memory_limit_mb is None or memory_limit_mb <= 0: memory_limit_mb = -1 if conflict_limit is None or conflict_limit <= 0: conflict_limit = -1 Monosat().setTimeLimit(time_limit_seconds) Monosat().setMemoryLimit(memory_limit_mb) Monosat().setConflictLimit(conflict_limit) #if preprocessing: # Monosat().preprocess(); print("Solving in Monosat...") t = time.clock() if isinstance(assumptions, Var): assumptions = [assumptions] elif assumptions is None: assumptions = [] if isinstance(bvs_to_minimize, BitVector): bvs_to_minimize = [bvs_to_minimize] elif bvs_to_minimize is None: bvs_to_minimize = [] for bv in bvs_to_minimize: bvID = bv.getID() Monosat().minimizeBV(bvID) r = Monosat().solveLimited([x.getLit() for x in assumptions]) if r is None: raise SolveException( "MonoSAT aborted before solving (possibly do to a time or memory limit)" ) Monosat().elapsed_time += time.clock() - t found_optimal = Monosat().lastSolutionWasOptimal() if r is None: raise SolveException( "MonoSAT aborted before solving (possibly due to a time or memory limit)" ) elif r and not found_optimal: print( "MonoSAT found a satisfying solution, but it might not be optimal (due to a time or memory limit)" ) return r
def __init__(self, mgr, width=None, op=None, args=None): assigned_bits = None if isinstance(mgr, int): # Shift the arguments over 1 args = op op = width width = mgr mgr = BVManager() elif isinstance(mgr, collections.Iterable): assigned_bits = list(mgr) mgr = BVManager() # Build this bitvector from a list of elements assert op is None assert args is None if width is not None: assert width == len(assigned_bits) width = len(assigned_bits) assert mgr._solver == Monosat().getSolver() assert width is not None self.mgr = mgr self._bv = None self.symbol = None self._width = width self._constant = None self.pid = None if args is None and isinstance(op, (int, float)): val = int(op) originalval = val if val < 0: val += 1 << width # val=0 # print("Warning: negative bitvectors not yet supported, setting to 0", file=sys.stderr) if val >= (1 << width): val = (1 << width) - 1 print( "Warning: value %d is too large to represent with a width-%d bitvector, setting to %d" % (originalval, width, val), file=sys.stderr, ) self._constant = val # if(val>0): # print("Warning: value %d is too large to represent with a width-%d bitvector, setting to %d"%(originalval,width, (1<<width)-1), file=sys.stderr) op = None args = None if not mgr._hasConstant(val, width): self.pid = mgr._monosat.newBitvector_const(width, val) mgr._setConstant(val, width, self) else: self.pid = mgr._getConstant(val, width).pid self._bv = [None] * width # fill bv with constants, for convenience elsewhere for i in range(width - 1, -1, -1): v = 1 << i if val >= v: val -= v self._bv[i] = true() else: self._bv[i] = false() elif (args is None and op == "anon") or op == "~": # create an anomymous bitvector (has no literals) self.pid = mgr._monosat.newBitvector_anon(width) else: self._bv = [] if assigned_bits is None: for _ in range(width): self._bv.append(Var()) else: # Can't do this, because Monosat doesn't support multiple theories on the same variable # self._bv = assigned_bits for i in range(width): v = Var() self._bv.append(v) AssertEq(v, assigned_bits[i]) # arr = (c_int*width)() # for i,v in enumerate(self._bv): # arr[i]=c_int(v.getLit()//2) bits = [v.getLit() // 2 for v in self._bv] self.pid = mgr._monosat.newBitvector(bits) if op == "+": assert len(args) == 2 _checkBVs((self, args[0], args[1])) if not mgr.bitblast_addition: mgr._monosat.bv_addition(args[0].getID(), args[1].getID(), self.getID()) if mgr.bitblast_addition or mgr.bitblast_addition_shadow: carry = false() for i, (a, b, out) in enumerate(zip(args[0], args[1], self)): r, carry2 = Add(a, b, carry) AssertEq(out, r) carry = carry2 Assert(Not(carry)) # disallow overflow. elif op == "-": _checkBVs((self, args[0], args[1])) # mgr._monosat.bv_addition(self.getID(), args[1].getID(), args[0].getID()) mgr._monosat.bv_subtraction(args[0].getID(), args[1].getID(), self.getID()) elif op == "*": mgr._monosat.bv_multiply(args[0].getID(), args[1].getID(), self.getID()) elif op == "/": mgr._monosat.bv_divide(args[0].getID(), args[1].getID(), self.getID()) elif op == "~": _checkBVs((self, args[0])) mgr._monosat.bv_not(args[0].getID(), self.getID()) elif op == "&": _checkBVs((self, args[0])) mgr._monosat.bv_and(args[0].getID(), args[1].getID(), self.getID()) elif op == "~&": _checkBVs((self, args[0])) mgr._monosat.bv_nand(args[0].getID(), args[1].getID(), self.getID()) elif op == "|": _checkBVs((self, args[0])) mgr._monosat.bv_or(args[0].getID(), args[1].getID(), self.getID()) elif op == "~|": _checkBVs((self, args[0])) mgr._monosat.bv_nor(args[0].getID(), args[1].getID(), self.getID()) elif op == "^": _checkBVs((self, args[0])) mgr._monosat.bv_xor(args[0].getID(), args[1].getID(), self.getID()) elif op == "~^": _checkBVs((self, args[0])) mgr._monosat.bv_xnor(args[0].getID(), args[1].getID(), self.getID()) elif op == "slice": _checkBVs((self, args[0])) mgr._monosat.bv_slice(args[0].getID(), args[1], args[2], self.getID()) elif op == "concat": _checkBVs((self, args[0], args[1])) mgr._monosat.bv_concat(args[0].getID(), args[1].getID(), self.getID()) elif op == "min": _checkBVs((self,)) _checkBVs((args)) mgr._monosat.bv_min([x.getID() for x in args], self.getID()) elif op == "max": _checkBVs((self,)) _checkBVs((args)) mgr._monosat.bv_max([x.getID() for x in args], self.getID()) elif op == "popcount": mgr._monosat.bv_popcount((l.getLit() for l in args), self.getID())
def clearOptimizationObjectives(): Monosat().clearOptimizationObjectives()
def FoundOptimal(): return Monosat().lastSolutionWasOptimal();
def __call__(cls, *args, **kwargs): if cls not in Monosat()._getManagers(): inst = super(Manager, cls).__call__(*args, **kwargs) inst._solver = Monosat().getSolver() Monosat()._getManagers()[cls] = inst return Monosat()._getManagers()[cls]
from monosat.monosat_c import Monosat from monosat.logic import * from monosat.bvtheory import BitVector from monosat.graphtheory import Graph from monosat.pbtheory import PBManager import time _monosat = Monosat() _pbm = PBManager() _pbm.elapsed_time = 0 _monosat.elapsed_time = 0 def Solve(assumptions=None, preprocessing=True): #first, write any pseudoboolean constraints _writePBCosntraints() #if preprocessing: # _monosat.preprocess(); print("Solving in Monosat...") t = time.clock() if assumptions is not None: r = _monosat.solveAssumptions([x.getLit() for x in assumptions]) else: r = _monosat.solve() _monosat.elapsed_time += time.clock() - t return r def _writePBCosntraints(): if not _pbm.hasConstraints():
#NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, #DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT #OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import os import shutil from tempfile import NamedTemporaryFile import time from monosat.logic import * from monosat.monosat_c import Monosat, dimacs from monosat.singleton import Singleton debug=False _monosat = Monosat() #Collects a set of graphs to encode together into a formula class PBManager(metaclass=Singleton): def setPB(self,pb): self.pb = pb def __init__(self): self.pb = MinisatPlus() self.import_time=0 def clear(self): if(self.pb): self.pb.clear()