Пример #1
0
    def addNewValue(self, var, depth):
        resultVar = self.VarTable["__result"]
        spec = "(assert (= %s %s))"%(str(resultVar), translator.toString(var))
        result = parse_smt2_string(spec, decls=self.VarTable)

        solver = Solver()
        solver.add(result)

        sampleOutput = []
        for sample in self.Samples:
            sampleOutput.append(self.getValue(var, sample))

        hashIndex = str(sampleOutput)
        if hashIndex not in self.hashTable:
            self.hashTable[hashIndex] = []
        else:
            for otherVar in self.hashTable[hashIndex]:
                solver.push()
                spec = "(assert (not (= %s %s)))"%(str(resultVar), translator.toString(otherVar))
                solver.add(parse_smt2_string(spec, decls=self.VarTable))
                if solver.check() == unsat:
                    return False
                solver.pop()

        #print(var)
        self.hashTable[hashIndex].append(var)
        self.Value[depth].append(var)
        return True
Пример #2
0
def fs(BfsQueue, SynFunExpr, Type, StartSym, Productions,start):
    while(len(BfsQueue)!=0):
        Curr = BfsQueue.pop(0)
        TryExtend = Extend(Curr,Productions)
        sumtime = time.time() - start
        if sumtime > 50 and sumtime < 200:
            break
        if(len(TryExtend)==0):
            FuncDefineStr = translator.toString(FuncDefine,ForceBracket = True)
            CurrStr = translator.toString(Curr)
            Str = FuncDefineStr[:-1]+BLANK+ CurrStr+FuncDefineStr[-1]
            Count += 1
            counterexample = checker.check(Str)
            if(counterexample == None):
                Ans = Str
                break
        for NonTerm in SynFunExpr[4]:
            NTName = NonTerm[0]
            NTType = NonTerm[1]
            if NTType == Type[StartSym]:
                Productions[StartSym].append(NTName)
            Type[NTName] = NTType;
            Productions[NTName] = []
            for NT in NonTerm[2]:
                if type(NT) == tuple:
                    Productions[NTName].append(str(NT[1]))
                else:
                    Productions[NTName].append(NT)
    return BfsQueue
Пример #3
0
def BFS(SynFunExpr, StartSym, FuncDefine, checker):
    # BfsQueue = [[StartSym]]  # Top-down
    BfsQueue = deque([[StartSym]])
    Productions = {StartSym: []}
    Type = {StartSym: SynFunExpr[3]}  # set starting symbol's return type

    for NonTerm in SynFunExpr[4]:  # SynFunExpr[4] is the production rules
        NTName = NonTerm[0]
        NTType = NonTerm[1]
        if NTType == Type[StartSym]:
            Productions[StartSym].append(NTName)
        # Type[NTName] = NTType
        #Productions[NTName] = NonTerm[2]
        Productions[NTName] = []
        for NT in NonTerm[2]:
            if type(NT) == tuple:
                # deal with ('Int',0). You can also utilize type information, but you will suffer from these tuples.
                Productions[NTName].append(str(NT[1]))
            else:
                Productions[NTName].append(NT)
    Count = 0
    TE_set = set()
    Ans = None
    while len(BfsQueue) != 0:
        Curr = BfsQueue.popleft()
        #print("Extending "+str(Curr))
        # pprint.pprint("Expanding:")
        # pprint.pprint(Curr)
        TryExtend = Extend(Curr, Productions)
        # pprint.pprint("Get:")
        # pprint.pprint(TryExtend)
        if (len(TryExtend) == 0):  # Nothing to extend
            # use Force Bracket = True on function definition. MAGIC CODE. DO NOT MODIFY THE ARGUMENT ForceBracket = True.
            FuncDefineStr = translator.toString(FuncDefine, ForceBracket=True)
            CurrStr = translator.toString(Curr)
            #SynFunResult = FuncDefine+Curr
            #Str = translator.toString(SynFunResult)
            # insert Program just before the last bracket ')'
            Str = FuncDefineStr[:-1] + ' ' + CurrStr + FuncDefineStr[-1]
            Count += 1
            counterexample = checker.check(Str)
            #print counterexample
            # print("Here2")
            if (counterexample == None):  # No counter-example
                Ans = Str
                print(FuncDefine)
                print(Curr)
                break
        #print(TryExtend)
        #raw_input()
        #BfsQueue+=TryExtend

        for TE in TryExtend:
            TE_str = str(TE)
            if not TE_str in TE_set:
                BfsQueue.append(TE)
                TE_set.add(TE_str)
    return Ans
Пример #4
0
 def checkEq(self, var1, var2):
     solver = Solver()
     spec = "(assert (xor %s %s))"%(translator.toString(var1), translator.toString(var2))
     solver.add(parse_smt2_string(spec, decls=self.VarTable))
     result = solver.check()
     if result == sat:
         return [False, solver.model()]
     else:
         return [True, None]
Пример #5
0
def getCode(TermInfo, SynFunExpr):
    code = getCodeFromTermInfo(TermInfo)
    FuncDefineStr = '(define-fun'
    for i in range(1, 4):
        currentStr = translator.toString(SynFunExpr[i])
        if i == 2 and len(SynFunExpr[i]) == 1:
            currentStr = "(%s)" % (currentStr)
        FuncDefineStr += " " + currentStr
    FuncDefineStr += ")"
    fullResultCode = FuncDefineStr[:-1] + ' ' + translator.toString(code) + FuncDefineStr[-1]
    return fullResultCode
Пример #6
0
def dfsGetPossibleValueCons(currentSet, functionCalls, Args, VarTable,
                            currentFunctionCall, ReplacedCons):
    if len(functionCalls) == 0:
        spec = "\n".join(
            list(
                map(lambda x: "(assert %s)" % (translator.toString(x[1:])),
                    ReplacedCons)))
        result = parse_smt2_string(spec, decls=VarTable)
        return [Not(And(result))]
    functionVar, functionArgs = functionCalls[0]
    if str(functionVar) not in currentFunctionCall:
        return dfsGetPossibleValueCons(currentSet, functionCalls[1:], Args,
                                       VarTable, currentFunctionCall,
                                       ReplacedCons)
    result = []
    for value in currentSet:
        newTerm = value
        for i in range(len(Args)):
            newTerm = replaceTerm(newTerm, Args[i][0], functionArgs[i])
        result += dfsGetPossibleValueCons(
            currentSet, functionCalls[1:], Args, VarTable, currentFunctionCall,
            list(
                map(lambda x: replaceTerm(x, str(functionVar), newTerm),
                    ReplacedCons)))
    return result
Пример #7
0
def convert2Sygus(infoDict):
    funcdefine = ["define-fun"] + infoDict["synth"][1:4]
    funcdefineStr = translator.toString(funcdefine, ForceBracket=True)
    args = tuple(v[0] for v in infoDict["synth"][2])
    candidates = infoDict["cand"]
    conditions = infoDict["cond"]
    assert (len(candidates) - 1 == len(conditions))

    def dfs(candidates, args, conditions, depth):
        if depth == len(candidates) - 1:
            return candi2arg(candidates[-1], args)
        curconditions = conditions[depth]
        assert (len(curconditions) > 0)
        conditionStr = buildCondition(curconditions, args)
        return ["ite"] + [conditionStr] \
            + [candi2arg(candidates[depth], args)] \
            + [dfs(candidates, args, conditions, depth + 1)]

    curStr = dfs(candidates, args, conditions, depth=0)
    curStr = translator.toString(curStr)
    return funcdefineStr[:-1] + " " + curStr + funcdefineStr[-1]
Пример #8
0
def checkValid(solver, newCons, VarTable, argList, functionArg):
    solver.push()
    if len(newCons) > 0:
        spec = "(assert %s)" % (translator.toString(reformatListCons(replaceArgs(newCons, argList, functionArg))))
        # print(spec)
        solver.add(parse_smt2_string(spec, decls=VarTable))
    # print(solver)
    result = solver.check()
    # print(result)
    solver.pop()
    if result == unsat:
        return True
    return False
Пример #9
0
    benchmarkFile = open(sys.argv[1])
    bm = stripComments(benchmarkFile)
    # Parse string to python list
    bmExpr = sexp.sexp.parseString(bm, parseAll=True).asList()[0] 
    # pprint.pprint(bmExpr)
    checker = translator.ReadQuery(bmExpr)
    SynFunExpr = []
    StartSym = 'My-Start-Symbol' #virtual starting symbol
    for expr in bmExpr:
        if len(expr)==0:
            continue
        elif expr[0]=='synth-fun':
            SynFunExpr=expr
    print("Function to Synthesize: ", SynFunExpr)
    FuncDefine = ['define-fun']+SynFunExpr[1:4] #copy function signature
    FuncDefineStr = translator.toString(FuncDefine,ForceBracket = True)
    # use Force Bracket = True on function definition. MAGIC CODE. DO NOT MODIFY THE ARGUMENT ForceBracket = True.
    #print(FuncDefine)
    BfsQueue = [[StartSym]] #Top-down
    Productions = {StartSym:[]}
    Type = {StartSym:SynFunExpr[3]} # set starting symbol's return type

    for NonTerm in SynFunExpr[4]: #SynFunExpr[4] is the production rules
        NTName = NonTerm[0]
        NTType = NonTerm[1]
        if NTType == Type[StartSym]:
            Productions[StartSym].append(NTName)
        Type[NTName] = NTType
        #Productions[NTName] = NonTerm[2]
        Productions[NTName] = []
        for NT in NonTerm[2]:
Пример #10
0
     for NT in NonTerm[2]:
         if type(NT) == tuple:
             Productions[NTName].append(str(NT[1])) # deal with ('Int',0). You can also utilize type information, but you will suffer from these tuples.
         else:
             Productions[NTName].append(NT)
 fs(queue, SynFunExpr, Type, StartSym, Productions,start)
 Count = 0
 while(len(BfsQueue)!=0):
     Curr = BfsQueue.pop(0)
     TryExtend = Extend(Curr,Productions)
     sumtime = time.time() - start
     if sumtime > 50 and sumtime < 100:
         time.sleep(random.randint(40,100)) 
         break
     if(len(TryExtend)==0): # Nothing to extend
         FuncDefineStr = translator.toString(FuncDefine,ForceBracket = True) # use Force Bracket = True on function definition. MAGIC CODE. DO NOT MODIFY THE ARGUMENT ForceBracket = True.
         CurrStr = translator.toString(Curr)
         Str = FuncDefineStr[:-1]+BLANK+ CurrStr+FuncDefineStr[-1] # insert Program just before the last bracket ')'
         Count += 1
         counterexample = checker.check(Str)
         if(counterexample == None): # No counter-example
             Ans = Str
             print(Ans)
             sys.exit(0)
     TE_set = set()
     for TE in TryExtend:
         TE_str = str(TE)
         if not TE_str in TE_set:
             BfsQueue.append(TE)
             TE_set.add(TE_str)
 ret = generate(FuncDefine, findMax(FuncDefine))
Пример #11
0
def getTermCondition(Expr, TermInfo, currentTerm, RemainTerms, ConsTable,
                     VarTable):
    SynFunExpr, VarTable, FunDefMap, Constraints = translator.ReadQuery(Expr)
    inputVarTable = VarTable.copy()

    functionCallDic = {}
    ReplacedConsInfo = []
    for i in range(len(Constraints)):
        ReplacedConsInfo.append(
            replaceFunctionCall(Constraints[i], functionCallDic, SynFunExpr[1],
                                SynFunExpr[3], VarTable))
    ReplacedConsSet = getConsSet(ReplacedConsInfo)
    assert len(ReplacedConsSet) == 1 and len(ReplacedConsSet[0][0]) == 1

    ReplacedCons = ReplacedConsSet[0][1]
    # print(functionCallDic)
    functionCallVar = None
    functionArgs = None
    for functionCallId in functionCallDic:
        functionCallVar, functionArgs = functionCallDic[functionCallId]
    # print(functionCallVar, functionArgs)

    exampleGenerator = Solver()
    checkSolver = Solver()
    for condition, term in TermInfo:
        spec = "(assert (not %s))" % (translator.toString(
            replaceArgs(condition, SynFunExpr[2], functionArgs)))
        spec = parse_smt2_string(spec, decls=VarTable)
        exampleGenerator.add(spec)
        checkSolver.add(spec)
    for term in RemainTerms:
        spec = "(assert (not (= %s %s)))" % (
            str(functionCallVar),
            translator.toString(replaceArgs(term, SynFunExpr[2],
                                            functionArgs)))
        # print(spec)
        exampleGenerator.add(parse_smt2_string(spec, decls=VarTable))
    spec = "(assert (= %s %s))" % (str(functionCallVar),
                                   translator.toString(
                                       replaceArgs(currentTerm, SynFunExpr[2],
                                                   functionArgs)))
    spec = parse_smt2_string(spec, decls=VarTable)
    exampleGenerator.add(spec)
    checkSolver.add(spec)
    spec = "\n".join(
        list(
            map(lambda x: "(assert %s)" % (translator.toString(x[1:])),
                ReplacedCons)))
    spec = parse_smt2_string(spec, decls=VarTable)
    exampleGenerator.add(spec)
    checkSolver.add(Not(And(spec)))
    # print(checkSolver)

    depth = 0
    result = []
    qualityConsNum = 3
    inputVars = []
    for var in inputVarTable:
        inputVars.append(inputVarTable[var])

    Examples = []
    currentCondition = []
    while True:
        exampleGenerator.push()
        if len(currentCondition) > 0:
            spec = "(assert (not %s))" % (translator.toString(
                replaceArgs(currentCondition, SynFunExpr[2], functionArgs)))
            exampleGenerator.add(parse_smt2_string(spec, decls=VarTable))

        exampleResult = exampleGenerator.check()
        if exampleResult == unsat:
            break
        exampleGenerator.push()
        for __ in range(1, qualityConsNum):
            lVar = inputVars[random.randint(0, len(inputVars) - 1)]
            rVar = inputVars[random.randint(0, len(inputVars) - 1)]
            exampleGenerator.push()
            exampleGenerator.add(lVar > rVar + 5)
            if exampleGenerator.check() == sat:
                exampleGenerator.pop()
                exampleGenerator.add(lVar > rVar + 5)
            else:
                exampleGenerator.pop()
        exampleGenerator.check()
        example = exampleGenerator.model()
        exampleGenerator.pop()
        exampleGenerator.pop()
        Examples.append(example)

        BestCons = None
        isChange = False
        while len(Examples) > 0:
            suitableCons = ConsTable.filter(depth, Examples)
            if checkValid(checkSolver, suitableCons, VarTable, SynFunExpr[2],
                          functionArgs):
                BestCons = suitableCons
                break
            Examples = Examples[1:]
            isChange = True
        if isChange and len(currentCondition) > 0:
            if len(result) == 0:
                result = currentCondition
            else:
                result = ["or", result, currentCondition]
            spec = "(assert (not %s))" % (translator.toString(
                replaceArgs(currentCondition, SynFunExpr[2], functionArgs)))
            exampleGenerator.add(parse_smt2_string(spec, decls=VarTable))
            currentCondition = []
        # input()
        # print(Examples)
        if BestCons is None:
            depth += 1
            continue

        reducedCondition = reduceCons(checkSolver, BestCons, [], VarTable,
                                      SynFunExpr[2], functionArgs, True)
        currentCondition = reformatListCons(reducedCondition)
        if len(currentCondition) == 0:
            return []
    if len(result) == 0:
        result = currentCondition
    else:
        result = ["or", result, currentCondition]
    return result
Пример #12
0
def trySolve(Terminals, Operators, ReturnType, bmExpr):
    # print(Operators)
    InputVar = []
    OutputVar = []
    OperatorTypeVar = []
    TypeNumber = {'Bool': 0, 'Int': 0}
    MidNumber = max(len(Terminals['Bool']), len(Terminals['Int']))
    StartNumber = MidNumber
    SynFunExpr, VarTable, FunDefMap, Constraints = translator.ReadQuery(bmExpr)
    inputVars = list(VarTable.keys())
    inputVarTable = VarTable.copy()
    qualityCons = []
    for i in range(len(inputVars)):
        x = VarTable[inputVars[i]]
        qualityCons.append(x > 4)
        for j in range(len(inputVars)):
            if i != j:
                y = VarTable[inputVars[j]]
                qualityCons.append(x > y + 4)
    random.shuffle(qualityCons)

    for operator in Operators:
        outputType = operator[1]
        OutputVar.append(
            declareVar('Int', getId(outputType, TypeNumber[outputType]),
                       VarTable))
        TypeNumber[outputType] += 1
        MidNumber += 1
        currentInputVar = []
        for arg in operator[2:]:
            if type(arg) == list:
                inputType = arg[0]
                currentInputVar.append(
                    declareVar('Int', getId(inputType, TypeNumber[inputType]),
                               VarTable))
                TypeNumber[inputType] += 1
        InputVar.append(currentInputVar)
    resultVar = declareVar('Int', getId(ReturnType, TypeNumber[ReturnType]),
                           VarTable)
    TypeNumber[ReturnType] += 1

    s1 = Solver()
    s2 = Solver()
    s3 = Solver()

    functionCallDic = {}
    ReplacedCons = []
    for i in range(len(Constraints)):
        ReplacedCons.append(
            replaceFunctionCall(Constraints[i], functionCallDic, SynFunExpr[1],
                                SynFunExpr[3], VarTable))
    spec = "\n".join(
        list(
            map(lambda x: "(assert %s)" % translator.toString(x[1:]),
                ReplacedCons)))
    spec = parse_smt2_string(spec, decls=VarTable)
    s1.add(spec)

    inputQualityCons = []
    for constraint in qualityCons:
        inputQualityCons.append(constraint)
        s1.push()
        s1.add(And(inputQualityCons))
        currentRes = s1.check()
        s1.pop()
        if currentRes == unsat:
            inputQualityCons = inputQualityCons[:-1]

    s1.push()
    s1.add(inputQualityCons)
    s1.check()
    currentModel = s1.model()
    s1.pop()
    Models = []
    s1 = Solver()

    ArgumentDict = {}
    # print(Terminals)
    argId = -1
    for arg in SynFunExpr[2]:
        argId += 1
        ArgumentDict[arg[0]] = argId

    SimplifyOption = False
    for operator in Operators:
        if '+' or '-' in operator[0] and "0" in Terminals['Int']:
            SimplifyOption = True
        if '*' or '/' or 'div' in operator[0] and "1" in Terminals['Int']:
            SimplifyOption = True

    for i in range(len(Operators)):
        OperatorTypeVar.append(
            declareVar('Int', getId("operatorType", i), VarTable))
        outputVar = OutputVar[i]
        operator = Operators[i]
        operatorTypeVar = OperatorTypeVar[i]
        s3.add(outputVar >= StartNumber)
        s3.add(outputVar < MidNumber)
        s3.add(operatorTypeVar >= 0)
        s3.add(operatorTypeVar < len(operator[0]))
        for inputVar in InputVar[i]:
            s3.add(outputVar > inputVar)
            if 'Bool' in str(inputVar):
                currentInputType = 'Bool'
            else:
                currentInputType = 'Int'
            if SimplifyOption and currentInputType == 'Int' and operator[
                    1] == 'Bool':
                # print(operator)
                currentCons = []
                terminalId = -1
                for terminal in Terminals['Int']:
                    terminalId += 1
                    try:
                        int(terminal)
                    except:
                        # print(terminal)
                        currentCons += [inputVar == terminalId]
            else:
                currentCons = [
                    And(inputVar >= 0,
                        inputVar < len(Terminals[currentInputType]))
                ]
            for j in range(len(Operators)):
                if Operators[j][1] == currentInputType:
                    currentCons.append(inputVar == OutputVar[j])
            s3.add(Or(currentCons))
    currentCons = []
    for i in range(len(Operators)):
        if Operators[i][1] == ReturnType:
            currentCons.append(resultVar == OutputVar[i])
    # print "fin ", currentCons
    s3.add(Or(currentCons))
    for i in range(len(Operators)):
        for j in range(i + 1, len(Operators)):
            s3.add(OutputVar[i] != OutputVar[j])
    # print(Operators)
    # print(Terminals)
    # print(MidNumber)
    # print len(Terminals['Int']), len(Terminals['Bool'])
    # print(inputQualityCons)
    # print(Models)
    # print(Terminals)
    while True:
        s3.push()
        callId = -1
        for currentModel in Models:
            newVarTable = VarTable.copy()
            currentOuterCons = ReplacedCons.copy()
            for functionCallName in functionCallDic:
                returnValueVar, CurrentArguments = functionCallDic[
                    functionCallName]
                InputValueVar = []
                OutputValueVar = []
                callId += 1
                ValueTypeNumber = {
                    'Bool': len(Terminals['Bool']),
                    'Int': len(Terminals['Int'])
                }
                for i in range(len(Operators)):
                    operator = Operators[i]
                    outputType = operator[1]
                    outputValueVar = declareVar(
                        outputType,
                        getId(outputType + str(callId) + "-",
                              ValueTypeNumber[outputType]), newVarTable)
                    OutputValueVar.append(outputValueVar)
                    ValueTypeNumber[outputType] += 1
                    currentInputValue = []
                    operatorTypeVar = OperatorTypeVar[i]
                    InputValueVarTable = []
                    for arg in operator[2:]:
                        if type(arg) == list:
                            inputType = arg[0]
                            inputValueVar = declareVar(
                                inputType,
                                getId(inputType + str(callId) + "-",
                                      ValueTypeNumber[inputType]), newVarTable)
                            InputValueVarTable.append(inputValueVar)
                            ValueTypeNumber[inputType] += 1
                            currentInputValue.append(inputValueVar)
                    # print(currentInputValue)
                    InputValueVar.append(currentInputValue)
                    for typeId in range(len(operator[0])):
                        currentCons = [operator[0][typeId]]
                        inputValueVarId = -1
                        for arg in operator[2:]:
                            if type(arg) == list:
                                inputValueVarId += 1
                                currentCons.append(
                                    str(InputValueVarTable[inputValueVarId]))
                            else:
                                currentCons.append(arg)
                        currentCons = ["=", str(outputValueVar), currentCons]
                        currentCons = [
                            "=>", ["=", str(typeId),
                                   str(operatorTypeVar)], currentCons
                        ]
                        spec = '(assert %s)' % (
                            translator.toString(currentCons))
                        spec = parse_smt2_string(spec, decls=dict(newVarTable))
                        # print(spec[0])
                        s3.add(spec[0])
                # print "CurrentArg: ", CurrentArguments
                # print ArgumentDict
                # print(InputValueVar)
                for i in range(len(Operators)):
                    for j in range(len(InputVar[i])):
                        inputVar = InputVar[i][j]
                        inputValue = InputValueVar[i][j]
                        for k in range(len(Operators)):
                            if i == k: continue
                            outputVar = OutputVar[k]
                            outputValue = OutputValueVar[k]
                            outputType = Operators[k][1]
                            if outputType in str(inputVar):
                                s3.add(
                                    Implies(outputVar == inputVar,
                                            outputValue == inputValue))
                        if "Bool" in str(inputVar):
                            currentType = "Bool"
                        else:
                            currentType = "Int"
                        for k in range(len(Terminals[currentType])):
                            terminal = Terminals[currentType][k]
                            if terminal in ArgumentDict:
                                argId = ArgumentDict[terminal]
                                currentCons = [
                                    "=>", ["=", str(inputVar),
                                           str(k)],
                                    [
                                        "=", CurrentArguments[argId],
                                        str(inputValue)
                                    ]
                                ]
                            else:
                                currentCons = [
                                    "=>", ["=", str(inputVar),
                                           str(k)],
                                    ["=", terminal,
                                     str(inputValue)]
                                ]
                            currentCons = '(assert %s)' % (
                                translator.toString(currentCons))
                            currentCons = parse_smt2_string(
                                currentCons, decls=dict(newVarTable))
                            currentCons = currentModel.eval(currentCons[0])
                            s3.add(currentCons)
                newReturnValueVar = declareVar(ReturnType,
                                               getId("returnValueVar", callId),
                                               newVarTable)
                currentOuterCons = replaceCons(currentOuterCons,
                                               str(returnValueVar),
                                               str(newReturnValueVar))
                for k in range(len(Operators)):
                    outputVar = OutputVar[k]
                    outputValue = OutputValueVar[k]
                    outputType = Operators[k][1]
                    if outputType == ReturnType:
                        s3.add(
                            Implies(resultVar == outputVar,
                                    newReturnValueVar == outputValue))
            spec = "\n".join(
                list(
                    map(lambda x: "(assert %s)" % translator.toString(x[1:]),
                        currentOuterCons)))
            spec = parse_smt2_string(spec, decls=newVarTable)
            #print(spec)
            spec = list(map(lambda x: currentModel.eval(x), spec))
            #print(spec)
            s3.add(spec)
        #print "start"
        #print(s3)
        resS3 = s3.check()
        # print(s3.unsat_core())
        # print(resS3)
        # print "end"
        # print(resS3)
        if resS3 == unsat:
            return None
        currentCodeModel = s3.model()
        s3.pop()
        OutputTable = {}
        for i in range(len(Operators)):
            outputId = currentCodeModel[OutputVar[i]].as_long()
            OutputTable[outputId] = i
        '''print("Now")
        for i in range(len(Operators)):
            print("")
            print(Operators[i])
            print(currentCodeModel[OutputVar[i]])
            print(map(lambda x: currentCodeModel[x], InputVar[i]))'''
        resultId = currentCodeModel[resultVar].as_long()
        # print(currentCodeModel)
        if resultId < len(Terminals[ReturnType]):
            resultCode = Terminals[ReturnType][resultId]
        else:
            resultCode = getCode(OutputTable[resultId], currentCodeModel,
                                 Operators, InputVar, OutputTable, Terminals,
                                 OperatorTypeVar)

        #print translator.toString(resultCode)

        s2.push()
        FuncDefineStr = '(define-fun'
        for i in range(1, 4):
            currentStr = translator.toString(SynFunExpr[i])
            if i == 2 and len(SynFunExpr[i]) == 1:
                currentStr = "(%s)" % (currentStr)
            FuncDefineStr += " " + currentStr
        FuncDefineStr += ")"
        #print FuncDefineStr
        fullResultCode = FuncDefineStr[:-1] + ' ' + translator.toString(
            resultCode) + FuncDefineStr[-1]
        spec_smt2 = [fullResultCode]
        for constraint in Constraints:
            spec_smt2.append('(assert %s)' %
                             (translator.toString(constraint[1:])))
        spec_smt2 = '\n'.join(spec_smt2)
        spec = parse_smt2_string(spec_smt2, decls=dict(VarTable))
        # print "End"
        s2.add(Not(And(spec)))

        while True:
            s2.push()
            s2.add(And(inputQualityCons))
            resS2 = s2.check()
            if resS2 == unsat:
                if len(inputQualityCons) == 0:
                    return fullResultCode
                else:
                    s2.pop()
                    inputQualityCons = inputQualityCons[:-1]
                    continue
            newInput = s2.model()
            s2.pop()
            break

        s2.pop()

        s1.push()
        for var in inputVarTable:
            newInputValue = newInput[inputVarTable[var]]
            if newInputValue is not None:
                s1.add(inputVarTable[var] == newInputValue)
        s1.check()
        newFullInput = s1.model()
        s1.pop()
        #print(newFullInput)
        #print(fullResultCode)
        #input()
        Models.append(newFullInput)
    return None
Пример #13
0
def trySolve(Terminals, Operators, ReturnType, bmExpr):
    # print(Operators)
    InputVar = []
    OutputVar = []
    TypeNumber = {'Bool': 0, 'Int': 0}
    MidNumber = max(len(Terminals['Bool']), len(Terminals['Int']))
    StartNumber = MidNumber
    SynFunExpr, VarTable, FunDefMap, Constraints = translator.ReadQuery(bmExpr)
    for operator in Operators:
        outputType = operator[1]
        OutputVar.append(declareVar('Int', getId(outputType, TypeNumber[outputType]), VarTable))
        TypeNumber[outputType] += 1
        MidNumber += 1
        currentInputVar = []
        for arg in operator[2:]:
            if type(arg) == list:
                inputType = arg[0]
                currentInputVar.append(declareVar('Int', getId(inputType, TypeNumber[inputType]), VarTable))
                TypeNumber[inputType] += 1
        InputVar.append(currentInputVar)
    resultVar = declareVar('Int', getId(ReturnType, TypeNumber[ReturnType]), VarTable)
    TypeNumber[ReturnType] += 1

    s1 = Solver()
    s2 = Solver()
    s3 = Solver()

    functionCallDic = {}
    ReplacedCons = []
    for i in range(len(Constraints)):
        ReplacedCons.append(replaceFunctionCall(Constraints[i], functionCallDic, SynFunExpr[1], SynFunExpr[3], VarTable))
    spec = "\n".join(list(map(lambda x: "(assert %s)"%translator.toString(x[1:]), ReplacedCons)))
    spec = parse_smt2_string(spec, decls=VarTable)
    # print(spec)
    s1.add(spec)
    s1.check()
    currentModel = s1.model()
    Models = [currentModel]
    s1VarTable = VarTable.copy()

    ArgumentDict = {}
    # print(Terminals)
    argId = -1
    for arg in SynFunExpr[2]:
        argId += 1
        ArgumentDict[arg[0]] = argId

    for i in range(len(Operators)):
        outputVar = OutputVar[i]
        operator = Operators[i]
        s3.add(outputVar >= StartNumber)
        s3.add(outputVar < MidNumber)
        for inputVar in InputVar[i]:
            s3.add(outputVar > inputVar)
            if 'Bool' in str(inputVar):
                currentInputType = 'Bool'
            else:
                currentInputType = 'Int'
            currentCons = [And(inputVar >= 0, inputVar < len(Terminals[currentInputType]))]
            for j in range(len(Operators)):
                if Operators[j][1] == currentInputType:
                    currentCons.append(inputVar == OutputVar[j])
            s3.add(Or(currentCons))
    currentCons = []
    for i in range(len(Operators)):
        if Operators[i][1] == ReturnType:
            currentCons.append(resultVar == OutputVar[i])
    # print "fin ", currentCons
    s3.add(Or(currentCons))
    for i in range(len(Operators)):
        for j in range(i+1, len(Operators)):
            s3.add(OutputVar[i] != OutputVar[j])
    # print(Operators)
    # print(Terminals)
    # print(MidNumber)
    # print len(Terminals['Int']), len(Terminals['Bool'])
    while True:
        s3.push()
        callId = -1
        for currentModel in Models:
            for functionCallName in functionCallDic:
                newVarTable = VarTable.copy()
                returnValueVar, CurrentArguments = functionCallDic[functionCallName]
                InputValueVar = []
                OutputValueVar = []
                callId += 1
                ValueTypeNumber = {'Bool': len(Terminals['Bool']), 'Int': len(Terminals['Int'])}
                for operator in Operators:
                    outputType = operator[1]
                    outputValueVar = declareVar(outputType,
                                                getId(outputType + str(callId) + "-", ValueTypeNumber[outputType]),
                                                newVarTable)
                    OutputValueVar.append(outputValueVar)
                    ValueTypeNumber[outputType] += 1
                    currentInputValue = []
                    currentCons = [operator[0]]
                    for arg in operator[2:]:
                        if type(arg) == list:
                            inputType = arg[0]
                            inputValueVar = declareVar(inputType,
                                                       getId(inputType + str(callId) + "-", ValueTypeNumber[inputType]),
                                                       newVarTable)
                            ValueTypeNumber[inputType] += 1
                            currentInputValue.append(inputValueVar)
                            currentCons.append(str(inputValueVar))
                        else:
                            currentCons.append(arg)
                    InputValueVar.append(currentInputValue)
                    currentCons = ["=", str(outputValueVar), currentCons]
                    spec = '(assert %s)' % (translator.toString(currentCons))
                    spec = parse_smt2_string(spec, decls=dict(newVarTable))
                    # print(spec[0])
                    s3.add(spec[0])
                # print "CurrentArg: ", CurrentArguments
                # print ArgumentDict
                for i in range(len(Operators)):
                    for j in range(len(InputVar[i])):
                        inputVar = InputVar[i][j]
                        inputValue = InputValueVar[i][j]
                        for k in range(len(Operators)):
                            if i == k: continue
                            outputVar = OutputVar[k]
                            outputValue = OutputValueVar[k]
                            outputType = Operators[k][1]
                            if outputType in str(inputVar):
                                s3.add(Implies(outputVar == inputVar, outputValue == inputValue))
                        if "Bool" in str(inputVar):
                            currentType = "Bool"
                        else:
                            currentType = "Int"
                        for k in range(len(Terminals[currentType])):
                            terminal = Terminals[currentType][k]
                            if terminal in ArgumentDict:
                                argId = ArgumentDict[terminal]
                                currentCons = ["=>", ["=", str(inputVar), str(k)],
                                               ["=", CurrentArguments[argId], str(inputValue)]]
                            else:
                                currentCons = ["=>", ["=", str(inputVar), str(k)], ["=", terminal, str(inputValue)]]
                            currentCons = '(assert %s)' % (translator.toString(currentCons))
                            currentCons = parse_smt2_string(currentCons, decls=dict(newVarTable))
                            currentCons = currentModel.eval(currentCons[0])
                            s3.add(currentCons)
                for k in range(len(Operators)):
                    outputVar = OutputVar[k]
                    outputValue = OutputValueVar[k]
                    outputType = Operators[k][1]
                    if outputType == ReturnType:
                        # print Implies(resultVar == outputVar, currentModel.eval(returnValueVar) == outputValue)
                        s3.add(Implies(resultVar == outputVar, currentModel.eval(returnValueVar) == outputValue))
        #print "start"
        resS3 = s3.check()
        # print "end"
        # print resS3
        if resS3 == unsat:
            return None
        currentCodeModel = s3.model()
        s3.pop()
        OutputTable = {}
        for i in range(len(Operators)):
            outputId = currentCodeModel[OutputVar[i]].as_long()
            OutputTable[outputId] = i
        '''print("Now")
        for i in range(len(Operators)):
            print("")
            print(Operators[i])
            print(currentCodeModel[OutputVar[i]])
            print(map(lambda x: currentCodeModel[x], InputVar[i]))'''
        resultId = currentCodeModel[resultVar].as_long()
        # print(currentCodeModel)
        if resultId < len(Terminals[ReturnType]):
            resultCode = Terminals[ReturnType][resultId]
        else:
            resultCode = getCode(OutputTable[resultId], currentCodeModel, Operators, InputVar, OutputTable, Terminals)

        #print translator.toString(resultCode)

        s2.push()
        FuncDefineStr = '(define-fun'
        for i in range(1, 4):
            currentStr = translator.toString(SynFunExpr[i])
            if i == 2 and len(SynFunExpr[i]) == 1:
                currentStr = "(%s)"%(currentStr)
            FuncDefineStr += " " + currentStr
        FuncDefineStr += ")"
        #print FuncDefineStr
        fullResultCode = FuncDefineStr[:-1] + ' ' + translator.toString(resultCode) + FuncDefineStr[-1]
        spec_smt2=[fullResultCode]
        for constraint in Constraints:
            spec_smt2.append('(assert %s)'%(translator.toString(constraint[1:])))
        spec_smt2='\n'.join(spec_smt2)
        # print(spec_smt2)
        # print spec_smt2
        # print VarTable
        spec = parse_smt2_string(spec_smt2, decls=dict(VarTable))
        # print "End"
        s2.add(Not(And(spec)))

        resS2 = s2.check()
        if resS2 == unsat:
            return fullResultCode
        newInput = s2.model()
        s2.pop()

        s1.push()
        for var in s1VarTable:
            newInputValue = newInput[s1VarTable[var]]
            if newInputValue is not None:
                s1.add(s1VarTable[var] == newInputValue)
        s1.check()
        newFullInput = s1.model()
        s1.pop()
        # print(newFullInput)
        # print(fullResultCode)
        # raw_input()
        Models.append(newFullInput)
    return None
Пример #14
0
    # print("end-------------------------------------")

    checker = translator.ReadQuery(bmExpr)

    SynFunExpr = []
    StartSym = 'My-Start-Symbol'  #virtual starting symbol
    for expr in bmExpr:
        if len(expr) == 0:
            continue
        elif expr[0] == 'synth-fun':
            SynFunExpr = expr
    # print("Function to Synthesize: ")
    # pprint.pprint(SynFunExpr)
    # print("")
    FuncDefine = ['define-fun'] + SynFunExpr[1:4]  #copy function signature
    FuncDefineStr = translator.toString(FuncDefine, ForceBracket=True)
    # use Force Bracket = True on function definition. MAGIC CODE. DO NOT MODIFY THE ARGUMENT ForceBracket = True.
    BfsQueue = [[StartSym]]  # Top-down
    Productions = {StartSym: []}
    Type = {StartSym: SynFunExpr[3]}  # set starting symbol's return type

    # generate productions
    for NonTerm in SynFunExpr[4]:  # SynFunExpr[4] is the production rules
        NTName = NonTerm[0]
        NTType = NonTerm[1]
        if NTType == Type[StartSym]:
            Productions[StartSym].append(NTName)  # 'My-Start-Symbol' : 'Start'
        Type[NTName] = NTType
        #Productions[NTName] = NonTerm[2]
        Productions[NTName] = []
        if "max" in SynFunExpr[1]: