def joinWithParent(arg): instances = arg.getInstances(nonsupered=True) newInstances = {} for (sort, index) in instances.keys(): (expr, pol) = instances[(sort, index)] if pol == Common.DEFINITELY_OFF: continue (lower, upper, _) = sort.instanceRanges[index] for i in range(lower, min(sort.parentInstances, upper + 1)): (old_expr, old_pol) = newInstances.get( (sort.parent, i), (SMTLib.SMT_BoolConst(False), Common.DEFINITELY_OFF)) if pol == Common.DEFINITELY_ON and lower == upper: new_pol = Common.DEFINITELY_ON new_expr = SMTLib.SMT_BoolConst(True) else: new_pol = Common.aggregate_polarity(old_pol, Common.UNKNOWN) new_expr = mOr( old_expr, mAnd( expr, SMTLib.SMT_EQ(sort.instances[index], SMTLib.SMT_IntConst(i)))) newInstances[(sort.parent, i)] = (new_expr, new_pol) return ExprArg(newInstances, nonsupered=True)
def mOr(*args): ''' Similar to mAnd ''' args = list(args) newArgs = [] while (args): i = args.pop() if isinstance(i, SMTLib.SMT_Or): #print(i) for j in i.children(): #print(j) args.append(j) continue if i: if isinstance(i, SMTLib.SMT_BoolConst): if str(i) == "False": continue else: return SMTLib.SMT_BoolConst(True) newArgs.append(i) if len(newArgs) == 0: return SMTLib.SMT_BoolConst(False) elif len(newArgs) == 1: return newArgs[0] else: return SMTLib.SMT_Or(*newArgs)
def flattenInstances(instances): ''' sets the new polarities to corresponding ternary values ''' for (sort, index) in instances.keys(): final_expr = mOr(SMTLib.SMT_BoolConst(False)) (l, h, _) = sort.instanceRanges[index] (exprs, pols) = instances[(sort, index)] final_polarity = Common.DEFINITELY_OFF all_on = True for i in range(l, h + 1): currExpr = exprs.get(i) currPol = pols.get(i) if not (i in pols.keys()) or currPol == Common.DEFINITELY_OFF: all_on = False continue elif currPol == Common.UNKNOWN: all_on = False final_polarity = Common.UNKNOWN final_expr = mOr(final_expr, currExpr) else: final_polarity = Common.UNKNOWN final_expr = mOr(final_expr, currExpr) if all_on: final_polarity = Common.DEFINITELY_ON final_expr = SMTLib.SMT_BoolConst(True) instances[(sort, index)] = (final_expr, final_polarity) return instances
def mAnd(*args): ''' Short for MaybeAnd. Helper Function to simplify formulas passed to Z3, but mostly to make debugging output more comprehensible. Only applies the And function if there are actually multiple arguments. ''' args = list(args) newArgs = [] while (args): i = args.pop() if isinstance(i, SMTLib.SMT_And): for j in i.children(): args.append(j) continue if i: if str(i) == "True": continue if str(i) == "False": return SMTLib.SMT_BoolConst(False) newArgs.append(i) if len(newArgs) == 0: return SMTLib.SMT_BoolConst(True) elif len(newArgs) == 1: return newArgs[0] else: return SMTLib.SMT_And(*newArgs)
def addBasedOnPolarity(self, sort, index, expr): #DOES NOT SUPER polarity = sort.known_polarity(index) if polarity == Common.DEFINITELY_ON: self.clafers[(sort, index)] = (SMTLib.SMT_BoolConst(True), polarity) elif polarity == Common.UNKNOWN: self.clafers[(sort, index)] = (expr, polarity) else: #if definitely off, do not add return
def getInstances(self, nonsupered=False): if nonsupered or self.hasBeenSupered: return self.clafers else: newClafers = {} for (sort, index) in self.clafers.keys(): (expr, polarity) = self.clafers[(sort, index)] if polarity == Common.DEFINITELY_OFF: continue key = (sort.highestSuperSort, sort.indexInHighestSuper + index) if polarity == Common.DEFINITELY_ON: newClafers[key] = (SMTLib.SMT_BoolConst(True), Common.DEFINITELY_ON) continue (currEntry, currPolarity) = newClafers.get( key, (SMTLib.SMT_BoolConst(False), Common.DEFINITELY_OFF)) currEntry = mOr(currEntry, expr) newClafers[key] = (currEntry, Common.aggregate_polarity( currPolarity, polarity)) self.clafers = newClafers self.hasBeenSupered = True return self.clafers
def getQuantifierConditionList(exprs): ''' Iterates over all values in all masks, and returns a list of Booleans, indicating whether each instance is on (or true), or not. ''' finalList = [] for i in exprs: for expr in i: if isinstance(expr, BoolArg): finalList.append(expr.getBool()) continue condList = [] for k in expr.getInstances().values(): (e, pol) = k if pol != Common.DEFINITELY_ON: condList.append(e) else: condList.append(SMTLib.SMT_BoolConst(True)) break finalList.append(mOr(*condList)) return finalList
def preventSameModel(cfr, solver, model): block = [] for i in cfr.cfr_sorts.values(): for j in i.instances: block.append( SMTLib.SMT_NE(j, SMTLib.SMT_IntConst(int(str(model[j.var]))))) if i.refs: for j in i.refs: try: val = model[j.var] except: #happens if a primitive ref is totally unrestricted continue if not val: continue else: block.append(SMTLib.SMT_NE(j, SMTLib.SMT_IntConst(val))) if block == []: solver.add(SMTLib.SMT_BoolConst(False)) else: solver.add(SMTLib.SMT_Or(*block))
def joinWithClaferRef(arg): instances = arg.getInstances(nonsupered=True) newArg = ExprArg(nonsupered=True) for (sort, index) in instances.keys(): (expr, pol) = instances[(sort, index)] while not sort.refSort: (sort, index) = joinWithSuper(sort, index) if isinstance(sort.refSort, PrimitiveType): joinWithPrimitive(newArg, sort, index, expr, pol) else: for i in range(sort.refSort.numInstances): (prev_expr, _) = newArg.getInstances(nonsupered=True).get( (sort.refSort, i), (SMTLib.SMT_BoolConst(False), Common.DEFINITELY_OFF)) newArg.getInstances(nonsupered=True)[(sort.refSort, i)] = (mOr( prev_expr, mAnd( expr, SMTLib.SMT_EQ( sort.refs[index], SMTLib.SMT_IntConst(i)))), Common.UNKNOWN) return newArg
def addMatchValues(matches, instances, left=True): ''' Ignores PrimitiveSorts ''' for (sort, index) in instances.keys(): (expr, polarity) = instances[(sort, index)] #!!! default = (SMTLib.SMT_BoolConst(False), Common.DEFINITELY_OFF) (prev_left, prev_right) = matches.get((sort, index), (default, default)) if left: (prev_expr, prev_pol) = prev_left new_left = (mOr(expr, prev_expr), Common.aggregate_polarity(polarity, prev_pol)) new_right = prev_right else: (prev_expr, prev_pol) = prev_right new_left = prev_left new_right = (mOr(expr, prev_expr), Common.aggregate_polarity(polarity, prev_pol)) matches[(sort, index)] = (new_left, new_right) return matches
def no_split(z3inst, module, num_split): return [SMTLib.SMT_BoolConst(True) for _ in range(num_split)]