def GenerateFunctionConstraints(spec, localVarConstraintsMap): if not isinstance(spec, list): if isinstance(spec, tuple): (typ, raw_val) = spec return GetValFromType(typ, raw_val) raise SynthException('Improper function call %s'%spec) if logger.IsLogging(): print spec opSym = spec[0] argConstraints = [] for arg in spec[1:]: if arg in localVarConstraintsMap.keys(): argConstraints.append(localVarConstraintsMap[arg]) elif isinstance(arg, tuple): (typ, raw_val) = arg argConstraints.append(GetValFromType(typ, raw_val)) elif arg in funcDefsMap.keys(): funcDef = funcDefsMap[arg] funcFormalArgsList = funcDef[2] funcDefExpr = funcDef[4] if funcFormalArgsList: raise SynthException('Cannot call constant function' + ' with arguments') argConstraints.append(GenerateFunctionConstraints( funcDefExpr, localVarConstraintsMap)) else: funcConstraint = GenerateFunctionConstraints( arg, localVarConstraintsMap) argConstraints.append(funcConstraint) if opSym in funcDefsMap: funcDef = funcDefsMap[opSym] funcFormalArgsList = funcDef[2] funcDefExpr = funcDef[4] newLocalVarConstraintsMap = {} for ii in range(len(funcFormalArgsList)): formalArg = funcFormalArgsList[ii] formalArgName = formalArg[0] newLocalVarConstraintsMap[formalArgName] = argConstraints[ii] return GenerateFunctionConstraints( funcDefExpr, newLocalVarConstraintsMap) elif opSym in synthFunsMap: raise SynthException( 'Synth function call cannot be within a defined function') else: op = theory.GetFunctionFromSymbol(opSym) return op(*argConstraints)
def GetSortFromType(typ): if typ == 'Int': return IntSort() elif typ == 'Bool': return BoolSort() elif isinstance(typ, list): if (len(typ) != 2 or typ[0] != 'BitVec'): raise SynthException('Unknown Type %r' % (typ)) else: intName, size = typ[1] return BitVecSort(size) else: raise SynthException('Unknown Type %r' % (typ))
def GetValFromType(typ, raw_val): srt = GetSortFromType(typ) if srt == IntSort(): return IntVal(raw_val) elif srt == BoolSort(): return BoolVal(raw_val) elif is_bv_sort(srt): sz = srt.size() return BitVecVal(raw_val, sz) else: raise SynthException('Unknown sort')
def GetStringFromType(typ): srt = GetSortFromType(typ) if srt == IntSort(): return 'Int' elif srt == BoolSort(): return 'Bool' elif is_bv_sort(srt): sz = srt.size() return '(BitVec ' + str(sz) + ')' else: raise SynthException('Unknonw sort for string conversion.')
def GenerateCircuitSimilarityConstraints(circuits): constraints = [Bool(True)] numCircuits = len(circuits) for i in range(numCircuits): for j in range(i + 1, numCircuits): circuitX = circuits[i] circuitY = circuits[j] if circuitX.funcName == circuitY.funcName: numComponentsX = len(circuitX.components) numComponentsY = len(circuitY.components) if numComponentsX != numComponentsY: raise SynthException('circuits for same function must' + 'have same number of components') for comp_no in range(numComponentsX): compX = circuitX.components[comp_no] compY = circuitY.components[comp_no] numInputPortsX = len(compX.inputPorts) numInputPortsY = len(compY.inputPorts) if numInputPortsY != numInputPortsX: raise SynthException('similar components must have' + 'same number of input ports') for port_no in range(numInputPortsX): constraints.append( Int(circuitX.PN2LNMap[ compX.inputPorts[port_no].name]) == Int( circuitY.PN2LNMap[ compY.inputPorts[port_no].name])) constraints.append( Int(circuitX.PN2LNMap[compX.outputPort.name]) == Int( circuitY.PN2LNMap[compY.outputPort.name])) return And(constraints)
def GenerateSubexpr(i): (comp, compArgs) = RefinedProgList[i] production = comp.production if isinstance(production, list): opSym = production[0] retVal = '(%s' % opSym for compArg in compArgs: retVal += ' ' retVal += GenerateSubexpr(tmpMap[compArg.outputPort.name]) retVal += ')' return retVal elif isinstance(production, tuple): (constType, constVal) = production return '%s' % GetValFromType(constType, constVal).sexpr() elif isinstance(production, str): return production else: raise SynthException('Unknown type of production')
def GenerateAll(spec, K, localVarConstraintsMap): if logger.IsLogging(): print spec if not isinstance(spec, list): raise SynthException('Improper function call %r' % spec) opSym = spec[0] argConstraints = [] specConnList = [] circuitList = [] for arg in spec[1:]: if arg in localVarConstraintsMap.keys(): argConstraints.append(localVarConstraintsMap[arg]) elif arg in declaredVar2PortMap.keys(): argConstraints.append(declaredVar2PortMap[arg].var) elif isinstance(arg, tuple): (typ, raw_val) = arg argConstraints.append(GetValFromType(typ, raw_val)) # specifically for constant functions elif arg in funcDefsMap.keys(): funcDef = funcDefsMap[arg] funcFormalArgsList = funcDef[2] funcDefExpr = funcDef[4] if funcFormalArgsList: raise SynthException('Cannot call constant function' + ' with arguments') (typ, raw_val) = funcDefExpr argConstraints.append(GetValFromType(typ, raw_val)) else: (funcConstraint, specConns, circuits) = GenerateAll(arg, K, localVarConstraintsMap) argConstraints.append(funcConstraint) specConnList.extend(specConns) circuitList.extend(circuits) if opSym in funcDefsMap: funcDef = funcDefsMap[opSym] funcFormalArgsList = funcDef[2] funcDefExpr = funcDef[4] newLocalVarConstraintsMap = {} for ii in range(len(funcFormalArgsList)): formalArg = funcFormalArgsList[ii] formalArgName = formalArg[0] newLocalVarConstraintsMap[formalArgName] = argConstraints[ii] (funcDefExprConstraint, specConns, circuits) = GenerateAll( funcDefExpr, K, newLocalVarConstraintsMap) specConnList.extend(specConns) circuitList.extend(circuits) return (funcDefExprConstraint, specConnList, circuitList) elif opSym in synthFunsMap: if not localVarConstraintsMap: if spec in [circuitExpr for (circuitExpr, _) in circuitsCache]: circuit = next( circ for (expr, circ) in circuitsCache if expr == spec) return (circuit.outputPort.var, [], []) circuit = GenerateCircuit(synthFunsMap[opSym], K) if not localVarConstraintsMap: circuitsCache.append((spec, circuit)) circuitList.append(circuit) if len(circuit.inputPorts) != len(argConstraints): raise SynthException('Improper function call at %r' % spec) for ii in range(len(circuit.inputPorts)): specConnList.append(circuit.inputPorts[ii].var == argConstraints[ii]) return (circuit.outputPort.var, specConnList, circuitList) else: op = theory.GetFunctionFromSymbol(opSym) return (op(*argConstraints), specConnList, circuitList)
def GenerateCircuit(synthFun, K): # K copies of each component if len(synthFun) != 5: raise SynthException('Wrong synth-fun command') # command = synthFun[0] funcName = synthFun[1] argList = synthFun[2] funcRetType = synthFun[3] funcGrammar = synthFun[4] circuitInputPorts = [ Port('__CIRCUIT_INP_%s' % argName, '__CIRCUIT_%s_%s' % (funcName, argName), GetSortFromType(argType)) for (argName, argType) in argList] circuitOutputPort = Port( '__CIRCUIT_OUT_%s' % funcName, '__CIRCUIT_%s_%s' % (funcName, 'Start'), GetSortFromType(funcRetType)) nonTermTypes = {} for nonTermExpansion in funcGrammar: nonTermTypes[nonTermExpansion[0]] = nonTermExpansion[1] formalArgTypes = {} for arg in argList: formalArgTypes[arg[0]] = arg[1] nonTermTypes.update(formalArgTypes) componentBag = [] for nonTermExpansion in funcGrammar: nonTerm = nonTermExpansion[0] nonTermType = nonTermExpansion[1] productions = nonTermExpansion[2] for production in productions: if isinstance(production, list): if production[0] == 'let': pass else: for copyNum in range(0, K): op = theory.GetFunctionFromSymbol(production[0]) inputPorts = [] for i in range(1, len(production)): inputPorts.append( Port( '%s_%s_i%d_%d' % (nonTerm, production[0], i, copyNum), '__CIRCUIT_%s_%s' % (funcName, production[i]), GetSortFromType( nonTermTypes[ production[i]]))) outputPort = Port( '%s_%s_o_%d' % (nonTerm, production[0], copyNum), '__CIRCUIT_%s_%s' % (funcName, nonTerm), GetSortFromType(nonTermType)) inputPortVars = [ inputPort.var for inputPort in inputPorts] spec = (outputPort.var == op(*inputPortVars)) componentBag.append( Component( inputPorts, outputPort, spec, '%s_%s' % (nonTerm, production[0]), production)) elif isinstance(production, tuple): (constType, constVal) = production inputPorts = [] outputPort = Port('%s_c%s_o_%d' % (nonTerm, str(constVal), 0), '__CIRCUIT_%s_%s' % (funcName, nonTerm), GetSortFromType(nonTermType)) spec = (outputPort.var == GetValFromType(constType, constVal)) componentBag.append(Component(inputPorts, outputPort, spec, '%s_c%s' % ( nonTerm, str(constVal)), production)) elif isinstance(production, str): if production in [arg[0] for arg in argList]: inputPorts = [ Port( '%s_LIT%s_i_%s' % (nonTerm, production, 0), '__CIRCUIT_%s_%s' % (funcName, production), GetSortFromType( formalArgTypes[production]))] outputPort = Port('%s_LIT%s_o_%s' % (nonTerm, production, 0), '__CIRCUIT_%s_%s' % (funcName, nonTerm), GetSortFromType(nonTermType)) spec = (outputPort.var == inputPorts[0].var) componentBag.append(Component(inputPorts, outputPort, spec, '%s_LIT%s' % ( nonTerm, production), production)) elif production in nonTermTypes: for copyNum in range(0, K): op = theory.GetFunctionFromSymbol('_ID') inputPorts = [ Port( '%s_ID_%s_i_%d'% (nonTerm, production, copyNum), '__CIRCUIT__%s_%s' % (funcName, production), GetSortFromType(nonTermTypes[production])) ] outputPort = Port( '%s_ID_%s_o_%d' % (nonTerm, production, copyNum), '__CIRCUIT_%s_%s' % (funcName, nonTerm), GetSortFromType(nonTermType)) spec = (outputPort.var == inputPorts[0].var) componentBag.append(Component(inputPorts, outputPort, spec, '%s_ID_%s' % (nonTerm, production), production)) else: raise SynthException('Invalid parameter in production') else: raise SynthException('Unknown kind of production') return Circuit( funcName, componentBag, circuitInputPorts, circuitOutputPort, synthFun)