Example #1
0
 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)
Example #2
0
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