import json
|
|
from .kSAT import kSAT
|
|
|
|
class SATquboResult:
|
|
|
|
def __init__(self):
|
|
self.__assignments = set()
|
|
self.__activeBindings = {}
|
|
self.__hasConflicts = False
|
|
self.__occurrences = 1
|
|
self.__satisfiesInstance = False
|
|
self.__assignmentsUpToDate = True
|
|
|
|
|
|
def satisfiesInstance(self):
|
|
return self.__satisfiesInstance
|
|
|
|
def setSatisfiesInstance(self, satInstance):
|
|
evaluation = satInstance.checkAssignment(self.getAssignmentsWithoutPositionIndex())
|
|
self.__satisfiesInstance = evaluation
|
|
|
|
|
|
def addBinding(self, binding, isActive):
|
|
self.__assignmentsUpToDate = False
|
|
clause = binding[0]
|
|
assignment = binding[1]
|
|
varLabel = abs(assignment)
|
|
|
|
if varLabel not in self.__activeBindings:
|
|
self.__activeBindings[varLabel] = []
|
|
|
|
if not isActive:
|
|
return
|
|
|
|
bindingSign = -1 if assignment < 0 else 1
|
|
|
|
self.__activeBindings[varLabel].append((clause, bindingSign))
|
|
self.__checkForConflictAtVar(varLabel)
|
|
|
|
|
|
def __checkForConflictAtVar(self, varLabel):
|
|
if varLabel not in self.__activeBindings:
|
|
return
|
|
|
|
sign = None
|
|
|
|
for assignment in self.__activeBindings[varLabel]:
|
|
if sign != None:
|
|
if sign * assignment[1] < 0:
|
|
self.__hasConflicts = True
|
|
return
|
|
sign = assignment[1]
|
|
|
|
def getAssignments(self):
|
|
if not self.__assignmentsUpToDate:
|
|
self.__updateAssignments()
|
|
|
|
return self.__assignments
|
|
|
|
def __updateAssignments(self):
|
|
self.__assignments = set()
|
|
|
|
for varLabel in self.__activeBindings:
|
|
bindings = self.__activeBindings[varLabel]
|
|
|
|
if not bindings:
|
|
self.__assignments.add(-1 * varLabel)
|
|
|
|
for binding in bindings:
|
|
sign = binding[1]
|
|
self.__assignments.add(sign * varLabel)
|
|
|
|
self.__assignmentsUpToDate = True
|
|
|
|
def getAssignmentsSortedByVarIndex(self):
|
|
return sorted(self.getAssignments(), key=abs)
|
|
|
|
def getAssignmentsWithoutPositionIndex(self):
|
|
assignments = self.getAssignmentsSortedByVarIndex()
|
|
|
|
for i in range(len(assignments)):
|
|
assignments[i] = 0 if assignments[i] < 0 else 1
|
|
|
|
return assignments
|
|
|
|
def getActiveBindings(self):
|
|
return self.__activeBindings
|
|
|
|
def hasConflicts(self):
|
|
return self.__hasConflicts
|
|
|
|
def setOccurrences(self, occurrences):
|
|
self.__occurrences = occurrences
|
|
|
|
def getOccurrences(self):
|
|
return self.__occurrences
|
|
|
|
def toPrimitive(self):
|
|
primitive = {}
|
|
|
|
primitive["assignments"] = self.getAssignmentsSortedByVarIndex()
|
|
primitive["hasConflicts"] = self.__hasConflicts
|
|
primitive["activeBindings"] = self.getActiveBindings()
|
|
primitive["satisfiesInstance"] = self.__satisfiesInstance
|
|
|
|
return primitive
|
|
|
|
def fromPrimitive(self, primitive):
|
|
|
|
for varLabel in primitive["activeBindings"]:
|
|
bindings = primitive["activeBindings"][varLabel]
|
|
|
|
if not bindings:
|
|
self.addBinding((-1, int(varLabel)), False)
|
|
|
|
for binding in bindings:
|
|
clause = binding[0]
|
|
sign = binding[1]
|
|
|
|
self.addBinding((clause, sign * int(varLabel)), True)
|
|
|
|
self.__satisfiesInstance = primitive["satisfiesInstance"]
|
|
|
|
|
|
def readAssignmentsFromFile(resultFilePath):
|
|
resultFile = open(resultFilePath, "r")
|
|
|
|
assignments = []
|
|
|
|
line = resultFile.readline()
|
|
while line:
|
|
|
|
if line.strip():
|
|
assignments.append(__parseAssignmentFromLine(line))
|
|
|
|
|
|
line = resultFile.readline()
|
|
|
|
resultFile.close()
|
|
|
|
return assignments
|
|
|
|
def __parseAssignmentFromLine(line):
|
|
result = json.loads(line)
|
|
|
|
assignment = [None] * abs(max(result["assignments"], key=abs))
|
|
|
|
for varAssignment in result["assignments"]:
|
|
assignment[abs(varAssignment) - 1] = 0 if varAssignment < 0 else 1
|
|
|
|
return assignment
|
|
|
|
def readResultsFromFile(resultFilePath):
|
|
resultFile = open(resultFilePath, "r")
|
|
|
|
results = []
|
|
|
|
line = resultFile.readline()
|
|
while line:
|
|
|
|
if line.strip():
|
|
result = SATquboResult()
|
|
result.fromPrimitive(json.loads(line))
|
|
results.append(result)
|
|
|
|
line = resultFile.readline()
|
|
|
|
return results
|