def applyRestrictUp(self, u, literal): if u.isLeaf(): return (u, resolver.tautologyId) rvar = literal.variable nvar = u.variable phase1 = literal.high == self.leaf1 if rvar < nvar: return (u, resolver.tautologyId) elif rvar == nvar: result = u.high if phase1 else u.low just = u.inferTrueUp if phase1 else u.inferFalseUp return (result, just) key = ("resup", u.id, literal.id) if key in self.operationCache: return self.operationCache[key][:2] ruleIndex = { } uhigh = u.high ruleIndex["UHX"] = u.inferTrueUp ulow = u.low ruleIndex["ULX"] = u.inferFalseUp (vhigh, resHigh) = self.applyRestrictUp(uhigh, literal) ruleIndex["RESH"] = resHigh (vlow, resLow) = self.applyRestrictUp(ulow, literal) ruleIndex["RESL"] = resLow if vhigh == vlow: v = vhigh else: v = self.findOrMake(nvar, vhigh, vlow) ruleIndex["VHX"] = v.inferTrueDown ruleIndex["VLX"] = v.inferFalseDown targetClause = resolver.cleanClause([-rvar.id if phase1 else rvar.id, u.id, -v.id]) if targetClause == resolver.tautologyId: justification, clauseList = resolver.tautologyId, [] else: try: comment = "Justification that %s%s & %s ==> %s" % ("" if phase1 else "!", rvar.name, v.label(), u.label()) justification, clauseList = self.restrictResolver.run(targetClause, ruleIndex, comment) except resolver.ResolveException: targetClause = resolver.cleanClause([u.id, -v.id]) comment = "Degenerate restriction. Justification that %s ==> %s" % (v.label(), u.label()) justification, clauseList = self.restrictResolver.run(targetClause, ruleIndex, comment) # Record this for use by the prover self.prover.restrictDegeneracies.add(justification) self.operationCache[key] = (v, justification,clauseList) self.cacheJustifyAdded += 1 return (v, justification)
def createClause(self, result, antecedent, comment=None, isInput=False): self.comment(comment) result = resolver.cleanClause(result) if result == resolver.tautologyId: return result if result == -resolver.tautologyId: result = [] self.clauseCount += 1 antecedent = list(antecedent) if not self.doLrat: antecedent.sort() middle = [ord('a')] if self.doBinary else [] rest = result + [0] + antecedent + [0] ilist = [self.clauseCount] + middle + rest if self.doBinary: if isInput and self.doLrat: pass else: bytes = stream.CompressArray(ilist).bytes self.file.write(bytes) else: slist = [str(i) for i in ilist] istring = " ".join(slist) if isInput and self.doLrat: self.comment(istring) else: self.file.write(istring + '\n') self.clauseDict[self.clauseCount] = result return self.clauseCount
def createClause(self, result, antecedent = [], comment = None, isInput = False, isUniversal = False, ulit = None): self.comment(comment) result = resolver.cleanClause(result, nosort = isUniversal) if result == resolver.tautologyId: return result self.clauseCount += 1 antecedent = list(antecedent) middle = ['u'] if isUniversal else [] rest = result + [0] if self.mode in [ProverMode.refProof, ProverMode.dualProof] and not self.doQrat: rest += antecedent + [0] ilist = [self.clauseCount] if not self.doQrat else [] ilist += middle + rest slist = [str(i) for i in ilist] istring = " ".join(slist) if isInput: self.comment(istring) else: self.file.write(istring + '\n') if isUniversal and ulit is not None: result = [lit for lit in result if lit != ulit] self.clauseDict[self.clauseCount] = result if len(antecedent) > 0: self.antecedentDict[self.clauseCount] = antecedent return self.clauseCount
def applyAndJustify(self, nodeA, nodeB): self.applyCount += 1 # Constant cases. # No justifications required, since all return one of the arguments if nodeA == self.leaf0 or nodeB == self.leaf0: return (self.leaf0, resolver.tautologyId) if nodeA == self.leaf1: return (nodeB, resolver.tautologyId) if nodeB == self.leaf1: return (nodeA, resolver.tautologyId) if nodeA == nodeB: return (nodeA, resolver.tautologyId) if nodeA.id > nodeB.id: nodeA, nodeB = nodeB, nodeA key = ("and", nodeA.id, nodeB.id) if key in self.operationCache: return self.operationCache[key][:2] # Mapping from rule names to clause numbers ruleIndex = {} # Mapping from variable names to variable numbers splitVar = min(nodeA.variable, nodeB.variable) highA = nodeA.branchHigh(splitVar) lowA = nodeA.branchLow(splitVar) highB = nodeB.branchHigh(splitVar) lowB = nodeB.branchLow(splitVar) if highA != lowA: ruleIndex["UHD"] = nodeA.inferTrueDown ruleIndex["ULD"] = nodeA.inferFalseDown if highB != lowB: ruleIndex["VHD"] = nodeB.inferTrueDown ruleIndex["VLD"] = nodeB.inferFalseDown (newHigh, andHigh) = self.applyAndJustify(highA, highB) ruleIndex["ANDH"] = andHigh (newLow, andLow) = self.applyAndJustify(lowA, lowB) ruleIndex["ANDL"] = andLow if newHigh == newLow: newNode = newHigh else: newNode = self.findOrMake(splitVar, newHigh, newLow) ruleIndex["WHU"] = newNode.inferTrueUp ruleIndex["WLU"] = newNode.inferFalseUp targetClause = resolver.cleanClause([-nodeA.id, -nodeB.id, newNode.id]) if targetClause == resolver.tautologyId: justification, clauseList = resolver.tautologyId, [] else: comment = "Justification that %s & %s ==> %s" % ( nodeA.label(), nodeB.label(), newNode.label()) justification, clauseList = self.andResolver.run( targetClause, ruleIndex, comment) self.operationCache[key] = (newNode, justification, clauseList) self.cacheJustifyAdded += 1 return (newNode, justification)
def justifyImply(self, nodeA, nodeB): self.applyCount += 1 # Special cases if nodeA == nodeB: return (True, resolver.tautologyId) if nodeA == self.leaf0: return (True, resolver.tautologyId) if nodeB == self.leaf1: return (True, resolver.tautologyId) # It would be an error if implication fails if nodeA == self.leaf1: return (False, resolver.tautologyId) if nodeB == self.leaf0: return (False, resolver.tautologyId) key = ("imply", nodeA.id, nodeB.id) if key in self.operationCache: return self.operationCache[key][:2] ruleIndex = {} splitVar = min(nodeA.variable, nodeB.variable) highA = nodeA.branchHigh(splitVar) lowA = nodeA.branchLow(splitVar) highB = nodeB.branchHigh(splitVar) lowB = nodeB.branchLow(splitVar) if highA != lowA: ruleIndex["UHD"] = nodeA.inferTrueDown ruleIndex["ULD"] = nodeA.inferFalseDown if highB != lowB: ruleIndex["VHU"] = nodeB.inferTrueUp ruleIndex["VLU"] = nodeB.inferFalseUp (checkHigh, implyHigh) = self.justifyImply(highA, highB) if implyHigh != resolver.tautologyId: ruleIndex["IMH"] = implyHigh (checkLow, implyLow) = self.justifyImply(lowA, lowB) if implyLow != resolver.tautologyId: ruleIndex["IML"] = implyLow check = checkHigh and checkLow if check: targetClause = resolver.cleanClause([-nodeA.id, nodeB.id]) comment = "Justification that %s ==> %s" % (nodeA.label(), nodeB.label()) justification, clauseList = self.implyResolver.run( targetClause, ruleIndex, comment) else: justification, clauseList = resolver.tautologyId, [] self.operationCache[key] = (check, justification, clauseList) if justification != resolver.tautologyId: self.cacheJustifyAdded += 1 else: self.cacheNoJustifyAdded += 1 return (check, justification)
def proveAdd(self, result, comment = None): result = resolver.cleanClause(result) if result == resolver.tautologyId: self.comment(comment) return result rfields = [str(r) for r in result] fields = ['a'] + rfields + ['0'] stepNumber = self.generateStepQP(fields, True, comment) self.clauseDict[stepNumber] = result if self.doQrat: return self.createClause(result, comment) return stepNumber
def proveAddBlocked(self, clause, blockers, comment = None): result = resolver.cleanClause(clause) if result == resolver.tautologyId: self.comment(comment) return result rfields = [str(r) for r in result] cmd = 'ab' if self.mode in [ProverMode.refProof, ProverMode.dualProof] else 'a' fields = [cmd] + rfields + ['0'] if self.mode in [ProverMode.refProof, ProverMode.dualProof]: bfields = [str(-abs(b)) for b in blockers] fields += bfields + ['0'] stepNumber = self.generateStepQP(fields, True, comment) self.clauseDict[stepNumber] = result var = abs(clause[0]) # Record defining clause qlevel = self.evarQlevels[var] self.qlevelEvars[qlevel][var].append(stepNumber) if self.doQrat: return self.createClause(result, blockers, comment) return stepNumber
def proveAddResolution(self, result, antecedent, comment = None): result = resolver.cleanClause(result) if result == resolver.tautologyId: self.comment(comment) return result rfields = [str(r) for r in result] afields = [str(a) for a in antecedent] cmd = 'ar' if self.mode in [ProverMode.refProof, ProverMode.dualProof] else 'a' fields = [cmd] + rfields + ['0'] if self.mode in [ProverMode.refProof, ProverMode.dualProof]: afields = [str(a) for a in antecedent] fields += afields + ['0'] stepNumber = self.generateStepQP(fields, True, comment) if len(result) > 0 and self.mode in [ProverMode.satProof, ProverMode.refProof, ProverMode.dualProof]: qlevel = max([self.idToQlevel[abs(lit)] for lit in result]) if qlevel in self.qlevelClauses: self.qlevelClauses[qlevel].append(stepNumber) else: self.qlevelClauses[qlevel] = [stepNumber] self.clauseDict[stepNumber] = result self.antecedentDict[stepNumber] = antecedent if self.doQrat: self.file.write(' '.join(rfields) + ' 0\n') return stepNumber
def createClause(self, result, antecedent, comment=None): result = resolver.cleanClause(result) if result == resolver.tautologyId: return result self.clauseCount += 1 return self.clauseCount