class SATModerno_fromFormula: def __init__(self): self.cnf = CNF() def runPySAT_fromFormula(self, formula): list_clauses = [] relationAndClauses = self.cnf.formulaToCNFClauses(formula) clauses = list(relationAndClauses.get("clauses")) glucose = Glucose3() for clause in clauses: list_clauses.append(list(clause)) glucose.append_formula(list_clauses) return glucose.solve()
class DPLL: def __init__(self): self.cnf = CNF() def runFromFile(self, filePath): clauses = self.cnf.readCNFFile(filePath) return self.__dpllRecursion(clauses, set()) def runFromFormula(self, formula): relationAndClauses = self.cnf.formulaToCNFClauses(formula) relation = relationAndClauses.get("relation") clauses = relationAndClauses.get("clauses") result = self.__dpllRecursion(clauses, set()) if not result: return result valuation = dict() for literal in result: if literal > 0: valuation[relation.get(literal)] = True else: valuation[relation.get(abs(literal))] = False return valuation def __dpllRecursion(self, clauses, valuation): clauses, valuation = self.__unitPropagation(clauses, valuation) if len(clauses) == 0: return valuation if self.__hasEmptyClause(clauses): return False literal = self.__getLiteral(clauses) clausesFirstCase = clauses.union({frozenset([literal])}) clausesSecondCase = clauses.union({frozenset([literal * -1])}) result = self.__dpllRecursion(clausesFirstCase, valuation) if result: return result return self.__dpllRecursion(clausesSecondCase, valuation) def __unitPropagation(self, clauses, valuation): unitaryClause = self.__getUnitaryClause(clauses) while unitaryClause is not None: clauses.remove(unitaryClause) valuation = valuation.union(unitaryClause) literal = list(unitaryClause)[0] toRemove = set() newCalsues = set() for clause in clauses: if literal in clause: toRemove.add(clause) continue inversedLiteral = literal * -1 if inversedLiteral in clause: # print(literal) newClause = clause.difference({inversedLiteral}) # print(clause, newClause) newCalsues.add(frozenset(newClause)) if len(newClause) == 0: clauses = clauses.difference(toRemove).union( newCalsues) return clauses, valuation clauses = clauses.difference(toRemove).union(newCalsues) toRemove.clear() newCalsues.clear() unitaryClause = self.__getUnitaryClause(clauses) return clauses, valuation def __getUnitaryClause(self, clauses): for clause in clauses: if len(clause) == 1: return clause return None def __hasEmptyClause(self, clauses): for clause in clauses: if len(clause) == 0: return True return False def __getLiteral(self, clauses): smaller = None for clause in clauses: if smaller is None: smaller = clause continue if len(clause) < len(smaller): smaller = clause return list(smaller)[0]
class Resolution: def __init__(self): self.cnf = CNF() def runFromFile(self, filePath): clauses = self.cnf.readCNFFile(filePath) return self.__resolutionMethod(clauses) def runFromFormula(self, formula): clause = self.cnf.formulaToCNFClauses(formula) return self.__resolutionMethod(clauses) def __resolutionMethod(self, clauses): clauses = self.__removeTrivialClauses(clauses) for currentClause in clauses: for clause in clauses: if currentClause == clause: continue trivialLiteral = self.__getTrivialLiteral( currentClause, clause) if trivialLiteral: currentClauseCopy = set(currentClause) currentClauseCopy.remove(trivialLiteral) clauseCopy = set(clause) clauseCopy.remove((trivialLiteral * -1)) newClause = frozenset(currentClauseCopy.union(clauseCopy)) if not len(newClause): return False setClauses = set(clauses) setClauses.add(newClause) clauses = list(setClauses) if len(clauses) > 0: return set(clauses) return True def __removeTrivialClauses(self, clauses): for clause in clauses: if self.__isTivialClause(clause): clauses.remove(clause) return clauses def __isTrivialClause(self, clause): for literal in clause: if (literal * -1) in clause: return True return False def __getTrivialLiteral(self, currentClause, clause): trivialLiteral = None for literal in currentClause: if (literal * -1) in clause: if trivialLiteral is None: trivialLiteral = literal else: trivialLiteral = None break return trivialLiteral