|
|
- #!/usr/bin/env python3
-
- import numpy as np
-
- class kSAT:
- def __init__(self):
- self.__clauses = []
- self.__numVariables = 0
-
- def getBindings(self):
- return self.__clauses
-
- def getNumberOfClauses(self):
- return len(self.__clauses)
-
- def getClause(self, clauseIndex):
- return self.__clauses[clauseIndex]
-
- def addClause(self, clause):
- #counting variables (assuming variables are assigned
- # consistently from 1 to numTotalVars)
- for varBinding in clause:
- if np.absolute(varBinding) > self.__numVariables:
- self.__numVariables = np.absolute(varBinding)
-
- self.__clauses.append(clause)
-
- def getDegreesOfVariables(self):
- degrees = {}
-
- for clause in self.__clauses:
- for binding in clause:
- varLabel = abs(binding)
-
- if varLabel not in degrees:
- degrees[varLabel] = 1
- else:
- degrees[varLabel] += 1
-
- return degrees
-
-
- def evaluate(satInstance, assignments):
- evaluations = []
-
- for assignment in assignments:
- evaluations.append(satInstance.checkAssignment(assignment))
-
- return evaluations
-
- def checkAssignment(self, assignment):
-
- if not self.__assignmentIsComplete(assignment):
- print("wrong number of variables in assignment")
- return False
-
- for clause in self.__clauses:
- clauseResult = False
-
- for binding in clause:
-
- varIndex = np.absolute(binding) - 1
-
- if ((binding > 0 and assignment[varIndex] == True) or
- (binding < 0 and assignment[varIndex] == False)):
- clauseResult = True
-
- if clauseResult == False:
- return False
-
- return True
-
- def __assignmentIsComplete(self, assignment):
- if (len(assignment) != self.getNumberOfVariables() or
- None in assignment):
- return False
-
- return True
-
- def getNumberOfVariables(self):
- return self.__numVariables
-
- def toString(self):
- kSATString = ""
-
- for clauseIndex in range(len(self.__clauses) - 1):
- kSATString += self.__kSATClauseToString(clauseIndex)
- kSATString += " * "
-
- kSATString += self.__kSATClauseToString(len(self.__clauses) - 1)
-
- return kSATString
-
- def getLableOfBinding(self, clauseIndex, binding):
- #return label = "%d%d" % (clauseIndex
- # self.__clauses[clauseIndex][varInClauseIndex])
- return (clauseIndex, binding)
-
- def getConflicts(self):
- conflicts = []
-
- for clauseIndex in range(len(self.__clauses)):
- clause = self.__clauses[clauseIndex]
-
- for binding in clause:
-
- clauseToCheckIndex = 0
-
- #search for conflict with binding
- for clauseToCheckIndex in range(clauseIndex, len(self.__clauses)):
-
- for bindingToCheck in self.__clauses[clauseToCheckIndex]:
- if binding == bindingToCheck * -1:
- conflLable1 = self.getLableOfBinding(clauseIndex,
- binding)
- conflLable2 = self.getLableOfBinding(clauseToCheckIndex,
- bindingToCheck)
- conflicts.append((conflLable1, conflLable2))
-
-
- return conflicts
-
- def writeDIMACS(self, path):
- outputFile = open(path, "w")
- outputFile.write("c A SAT instance\n")
- outputFile.write("p cnf %d %d \n" % (self.getNumberOfVariables(),
- self.getNumberOfClauses()))
-
- for clause in self.getBindings():
- for binding in clause:
- outputFile.write("%d " % binding)
-
- outputFile.write("0\n")
-
- outputFile.close()
-
- def readDIMACS(self, path):
- inputFile = open(path, "r")
-
- line = inputFile.readline()
-
- self.reset()
-
- while line != "":
- if line[0] != "c" and line[0] != "p":
- bindings = [int(binding) for binding in line.split()]
-
- self.addClause(bindings[:len(bindings) -1])
-
- line = inputFile.readline()
-
- inputFile.close()
-
- def writeJSONLike(self):
- jsonLike = {}
-
- jsonLike["clauses"] = self.__clauses
-
- return jsonLike
-
- def readJSONLike(self, jsonLike):
- self.reset()
-
- for clause in jsonLike["clauses"]:
- self.addClause(clause)
-
-
- def reset(self):
- self.__clauses = []
- self.__numVariables = 0
-
- def __kSATClauseToString(self, clauseIndex):
- clause = self.__clauses[clauseIndex]
- varCount = 0
- isFirstVar = True;
-
- clauseString = "(";
-
- for weight in clause:
- varCount += 1
-
- if not isFirstVar:
- clauseString += " + "
-
- clauseString += self.__kSATVariableToString(weight)
-
- isFirstVar = False
-
- clauseString += ")"
-
- return clauseString
-
- def __kSATVariableToString(self, weight):
- name = "x%d" % np.absolute(weight)
-
- if weight < 0:
- return "!" + name
- else:
- return name
|