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
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
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
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]
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
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
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]
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
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]:
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))
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
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
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
# 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]: