def __init__(self, solver=None, debug=False): if not solver: self.solver = Solver() else: self.solver = solver self.initCommonTypes() self.solver.DEBUG = debug self.variables = {} #keep track of all Pretty Solvers global psolvers, default_psolver psolvers[id(self)]=self if default_psolver == None: default_psolver = id(self)
class PrettySolver(): def __init__(self, solver=None, debug=False): if not solver: self.solver = Solver() else: self.solver = solver self.initCommonTypes() self.solver.DEBUG = debug self.variables = {} #keep track of all Pretty Solvers global psolvers, default_psolver psolvers[id(self)]=self if default_psolver == None: default_psolver = id(self) def setDebug(self, debug): self.solver.DEBUG = debug def initCommonTypes(self): self.bv64bits=self.bvType(64) self.bv32bits=self.bvType(32) self.bv16bits=self.bvType(16) self.bv8bits=self.bvType(8) self.booltype=self.boolType() self.true=self.trueExpr() self.false=self.falseExpr() def createExpression(self, exprstring=None, addr=None, signed=False, lang=0): return Expression(exprstring, self, addr, signed, lang) def assertFormula(self, exp): self.solver.assertFormula(exp.addr) def queryFormula(self, exp): return self.solver.queryFormula(exp.addr) def checkUnsat(self, exp): return self.solver.checkUnsat(exp.addr) def checkSat(self, exp): return self.solver.checkSat(exp.addr) def checkContinue(self): return self.solver.checkContinue() def restart(self, exp): return self.solver.restart(exp.addr) def returnFromCheck(self): self.solver.returnFromCheck() def getCounterExample(self): ret=[] for e in self.solver.getCounterExample(): ret.append(Expression(None, self, e)) return ret def getConcreteModel(self): ret=[] for e in self.solver.getConcreteModel(): ret.append(Expression(None, self, e)) return ret def getUserAssumptions(self): ret=[] for e in self.solver.getUserAssumptions(): ret.append(Expression(None, self, e)) return ret def getInternalAssumptions(self): ret=[] for e in self.solver.getInternalAssumptions(): ret.append(Expression(None, self, e)) return ret def getAssumptions(self): ret=[] for e in self.solver.getAssumptions(): ret.append(Expression(None, self, e)) return ret def getAxioms(self, exp): ret=[] for e in self.solver.getAxioms(exp.addr): ret.append(Expression(None, self, e)) return ret def getIndex(self, exp): return self.solver.getIndex(exp.addr) def getExistential(self, exp): return Expression(None, self, self.solver.getExistential(exp.addr)) def getNumVars(self, exp): return self.solver.getNumVars(exp.addr) def getVar(self, exp, ind): return Expression(None, self, self.solver.getVar(exp.addr, ind)) def getArity(self, exp): return self.solver.getArity(exp.addr) def getChild(self, exp, ind): return Expression(None, self, self.solver.getChild(exp.addr, ind)) def getBody(self, exp): return Expression(None, self, self.solver.getBody(exp.addr)) def getKind(self, exp): return self.solver.getKind(exp.addr) def getClosure(self): return Expression(None, self, self.solver.getClosure()) def isClosure(self, exp): return self.solver.isClosure(exp.addr) def isSkolem(self, exp): return self.solver.isSkolem(exp.addr) def getBoundIndex(self, exp): return self.solver.getBoundIndex(exp.addr) def getFunction(self, exp): return Expression(None, self, self.solver.getFunction(exp.addr)) def incomplete(self): return self.solver.incomplete() def getProof(self): return Expression(None, self, self.solver.getProof()) #Context methods def stackLevel(self): return self.solver.stackLevel() def push(self): return self.solver.push() def pop(self): return self.solver.pop() def popto(self, level): return self.solver.popto(level) #Misc functions def deleteExpr(self,exp): self.solver.deleteExpr(exp.addr) def importExpr(self, exp): return Expression(None, self, self.solver.importExpr(exp.addr), exp.signed) #returns a simplified Expr def simplify(self, exp): return Expression(None, self, self.solver.simplify(exp.addr), exp.signed) def parseFile(self, filename): self.solver.parseFile(filename) #returns a new Bit-Vector Type of <bits> bits def bvType(self, bits=32): return Type(self, self.solver.bvType(bits)) def boolType(self): return Type(self, self.solver.boolType()) def boundVarExpr(self, name, uid, vartype=None, signed=False): if vartype: vartype = vartype.addr return Expression(None, self, self.solver.boundVarExpr(name, uid, vartype), signed) #returns a variable Expr def varExpr(self, name, vartype=None, signed=False): if vartype and isinstance(vartype, Type): vartype = vartype.addr tmp=Expression(None, self, self.solver.varExpr(name, vartype), signed) self.variables[name]=(tmp, vartype) return tmp #returns a variable Expr initialized with a given Expr def varDefExpr(self, name, definition, vartype=None, signed=False): if vartype and isinstance(vartype, Type): vartype = vartype.addr tmp = Expression(None, self, self.solver.varDefExpr(name, definition.addr, vartype), signed) self.variables[name]=(tmp, vartype) return tmp def createTypeFromString(self, typename): return Type(self, self.solver.createTypeFromString(typename)) def lookupVar(self, name): if self.variables.has_key(name): #return cached variables only, this way we maintain signedness vartype = self.variables[name][1] if not isinstance(vartype, Type): vartype = self.solver.bv32bits return (self.variables[name][0], Type(self, vartype)) return False #Utils def compareExpr(self, exp1, exp2): return self.solver.compareExpr(exp1.addr, exp2.addr) def exprFromString(self, stri, signed=False): return Expression(None, self, self.solver.exprFromString(stri), signed) def exprFromStringAndLang(self, stri, lang, signed=False): """ This receives a list of commands, not formulas. """ return Expression(None, self, self.solver.exprFromStringAndLang(stri, lang), signed) def exprString(self, exp, lang=None): if lang == None: lang = exp.lang ret=self.solver.exprString(exp.addr, lang) if not lang: #convert binary numbers to hex ret = ret.split("0bin") out="" out+=ret.pop(0) for b in ret: intbuf="" for idx in xrange(0, len(b)): if b[idx] != "1" and b[idx] != "0": break else: intbuf+=b[idx] if (len(intbuf) % 4) == 0: out+="0hex" out+="%X"%int(intbuf,2) out+=b[len(intbuf):] else: out+="0bin" out+=b ret = out return ret def getType(self, exp): return Type(self, self.solver.getType(exp.addr)) def getName(self, exp): return self.solver.getName(exp.addr) def getUid(self, exp): return self.solver.getUid(exp.addr) def typeString(self, t): return self.solver.typeString(t.addr) def typeStringFromExpr(self, exp): return self.solver.typeStringFromExpr(exp.addr) def getBitSizeFromExpr(self, exp): return self.solver.getBitSizeFromExpr(exp.addr) def getKindString(self, kind): return self.solver.getKindString(kind) def kindString(self, exp): return self.solver.kindString(exp.addr) def getBoolFromBitvector(self, exp): return Expression(None, self, self.solver.getBoolFromBitvector(exp.addr)) def getBitvectorFromBool(self, exp, bits=1): return Expression(None, self, self.solver.getBitvectorFromBool(exp.addr, bits)) def skolemizeVar(self, exp, idx): return Expression(None, self, self.solver.skolemizeVar(exp.addr, idx), exp.signed) def skolemize(self, exp, boundVars, skolemVars): r_boundVars = [] r_skolemVars = [] for e in boundVars: r_boundVars.append(e.addr) for e in skolemVars: r_skolemVars.append(e.addr) return Expression(None, self, self.solver.skolemize(exp.addr, r_boundVars, r_skolemVars), exp.signed) def getInt(self, exp): return self.solver.getInt(exp.addr) #Logic functions def impliesExpr(self, hyp, concl): return Expression(None, self, self.solver.impliesExpr(hyp.addr, concl.addr)) def iffExpr(self, exp1, exp2): return Expression(None, self, self.solver.iffExpr(exp1.addr, exp2.addr)) def distinctExpr(self, arr_expr): tmp=[] for e in arr_expr: tmp.append(e.addr) return Expression(None, self, self.solver.distinctExpr(tmp)) def forallExpr(self, Bvars, exp): tmp=[] for e in Bvars: tmp.append(e.addr) return Expression(None, self, self.solver.forallExpr(tmp, exp.addr)) def existsExpr(self, Bvars, exp): tmp=[] for e in Bvars: tmp.append(e.addr) return Expression(None, self, self.solver.existsExpr(tmp, exp.addr)) def lambdaExpr(self, Bvars, exp): tmp=[] for e in Bvars: tmp.append(e.addr) return Expression(None, self, self.solver.lambdaExpr(tmp, exp.addr)) def iteExpr(self, ifpart, thenpart, elsepart): return Expression(None, self, self.solver.iteExpr(ifpart.addr, thenpart.addr, elsepart.addr)) def trueExpr(self): return Expression(None, self, self.solver.trueExpr()) def falseExpr(self): return Expression(None, self, self.solver.falseExpr()) def boolNotExpr(self, exp): return Expression(None, self, self.solver.boolNotExpr(exp.addr)) def boolAndExpr(self, exp1, exp2): return Expression(None, self, self.solver.boolAndExpr(exp1.addr, exp2.addr)) def boolOrExpr(self, exp1, exp2): return Expression(None, self, self.solver.boolOrExpr(exp1.addr, exp2.addr)) def boolXorExpr(self, exp1, exp2): return Expression(None, self, self.solver.boolXorExpr(exp1.addr, exp2.addr)) #Order functions def ltExpr(self, exp1, exp2): return Expression(None, self, self.solver.ltExpr(exp1.addr, exp2.addr)) def leExpr(self, exp1, exp2): return Expression(None, self, self.solver.leExpr(exp1.addr, exp2.addr)) def gtExpr(self, exp1, exp2): return Expression(None, self, self.solver.gtExpr(exp1.addr, exp2.addr)) def geExpr(self, exp1, exp2): return Expression(None, self, self.solver.geExpr(exp1.addr, exp2.addr)) def sltExpr(self, exp1, exp2): return Expression(None, self, self.solver.sltExpr(exp1.addr, exp2.addr)) def sleExpr(self, exp1, exp2): return Expression(None, self, self.solver.sleExpr(exp1.addr, exp2.addr)) def sgtExpr(self, exp1, exp2): return Expression(None, self, self.solver.sgtExpr(exp1.addr, exp2.addr)) def sgeExpr(self, exp1, exp2): return Expression(None, self, self.solver.sgeExpr(exp1.addr, exp2.addr)) def eqExpr(self, exp1, exp2): return Expression(None, self, self.solver.eqExpr(exp1.addr, exp2.addr)) def neExpr(self, exp1, exp2): return Expression(None, self, self.solver.neExpr(exp1.addr, exp2.addr)) #Bit-Vector functions def UConstFromExpr(self, exp): return self.solver.UConstFromExpr(exp.addr) def constExpr(self, num, bits=32, signed=False): return Expression(None, self, self.solver.constExpr(num, bits), signed) def concatExpr(self, exp1, exp2): return Expression(None, self, self.solver.concatExpr(exp1.addr, exp2.addr)) def extractExpr(self, exp, start, end): return Expression(None, self, self.solver.extractExpr(exp.addr, start, end)) def boolExtractExpr(self, exp, bit): return Expression(None, self, self.solver.boolExtractExpr(exp.addr, bit)) def signExtendExpr(self, exp, bits): return Expression(None, self, self.solver.signExtendExpr(exp.addr, bits)) def zeroExtendExpr(self, exp, bits): return Expression(None, self, self.solver.zeroExtendExpr(exp.addr, bits)) #the <bits> here might be an expression or a constant amount def leftRotateExpr(self, exp, bits): if isinstance(bits, Expression): bits=bits.addr return Expression(None, self, self.solver.leftRotateExpr(exp.addr, bits)) #the <bits> here might be an expression or a constant amount def leftShiftExpr(self, exp, bits, finalsize=None): if isinstance(bits, Expression): bits=bits.addr return Expression(None, self, self.solver.leftShiftExpr(exp.addr, bits, finalsize)) #the <bits> here might be an expression or a constant amount def rightArithmeticShiftExpr(self, exp, bits, finalsize=None): if isinstance(bits, Expression): bits=bits.addr return Expression(None, self, self.solver.rightArithmeticShiftExpr(exp.addr, bits, finalsize), exp.signed) #the <bits> here might be an expression or a constant amount def rightRotateExpr(self, exp, bits): if isinstance(bits, Expression): bits=bits.addr return Expression(None, self, self.solver.rightRotateExpr(exp.addr, bits)) #the <bits> here might be an expression or a constant amount def rightShiftExpr(self, exp, bits, finalsize=None): if isinstance(bits, Expression): bits=bits.addr return Expression(None, self, self.solver.rightShiftExpr(exp.addr, bits, finalsize)) def notExpr(self, exp): return Expression(None, self, self.solver.notExpr(exp.addr)) def andExpr(self, exp1, exp2): return Expression(None, self, self.solver.andExpr(exp1.addr, exp2.addr)) def orExpr(self, exp1, exp2): return Expression(None, self, self.solver.orExpr(exp1.addr, exp2.addr)) def xorExpr(self, exp1, exp2): return Expression(None, self, self.solver.xorExpr(exp1.addr, exp2.addr)) def negExpr(self, exp): return Expression(None, self, self.solver.negExpr(exp.addr)) def addExpr(self, exp1, exp2, bits=None): return Expression(None, self, self.solver.addExpr(exp1.addr, exp2.addr, bits), exp1.signed and exp2.signed) def subExpr(self, exp1, exp2, bits=None): return Expression(None, self, self.solver.subExpr(exp1.addr, exp2.addr, bits), exp1.signed and exp2.signed) def umulExpr(self, exp1, exp2, bits=None): return Expression(None, self, self.solver.umulExpr(exp1.addr, exp2.addr, bits)) def udivExpr(self, exp1, exp2): return Expression(None, self, self.solver.udivExpr(exp1.addr, exp2.addr)) def uremExpr(self, exp1, exp2): return Expression(None, self, self.solver.uremExpr(exp1.addr, exp2.addr)) def sdivExpr(self, exp1, exp2): return Expression(None, self, self.solver.sdivExpr(exp1.addr, exp2.addr), True) def sremExpr(self, exp1, exp2): return Expression(None, self, self.solver.sremExpr(exp1.addr, exp2.addr), True) def smodExpr(self, exp1, exp2): return Expression(None, self, self.solver.smodExpr(exp1.addr, exp2.addr), True) def smulExpr(self, exp1, exp2, bits=None): return Expression(None, self, self.solver.smulExpr(exp1.addr, exp2.addr, bits), True) def assignExpr(self, exp1, exp2, bits=None, endpos=0, pos=0, endbits=None): return Expression(None, self, self.solver.assignExpr(exp1.addr, exp2.addr, bits, endpos, pos, endbits)) def dumpExpr(self, exp, recursive=False, calchash=False): tmp=self.solver.dumpExpr(exp.addr, recursive, calchash) self.crc=self.solver.crc return (tmp, exp.lang, exp.signed) def loadExpr(self, dump, recursive=False, varsdict=None): if varsdict: tmp={} for k,v in varsdict.iteritems(): tmp[k]=v.addr varsdict=tmp tmp = Expression(None, self, self.solver.loadExpr(dump[0], recursive, varsdict)) tmp.lang = dump[1] tmp.signed = dump[2] return tmp def getVarDependency(self, exp, return_name=False): tmp=self.solver.getVarDependency(exp.addr, return_name) if return_name: return tmp ret=[] for e in tmp: ret.append(Expression(None, self, e)) return ret def hashExpr(self, exp): return self.solver.hashExpr(exp.addr) def mergeExpr(self, exp, varsdict): tmp={} for k,v in varsdict.iteritems(): tmp[k]=v.addr return Expression(None, self, self.solver.mergeExpr(exp.addr, tmp), exp.signed) def concreteModelGenerator(self, exp): for item in self.solver.concreteModelGenerator(exp.addr): for x in xrange(0, len(item)): item[x] = Expression(None, self, item[x], False, exp.lang) yield item return