def bq(fmla): """ Bound the free variables in fmla of uninterpeted sort """ vs = list(sorted(used_variables_ast(fmla))) vs = [v for v in vs if not ivy_logic.is_interpreted_sort(v.sort)] cnsts = [bdv(v) for v in vs] bq_res = ivy_logic.Implies(ivy_logic.And(*cnsts), fmla) if cnsts else fmla return bq_res
def map_fmla(fmla, strat_map): if il.is_binder(fmla): return map_fmla(fmla.body, strat_map) if il.is_variable(fmla): if fmla not in strat_map: res = UFNode() res.variables.add(fmla) strat_map[fmla] = res return strat_map[fmla] nodes = [map_fmla(f, strat_map) for f in fmla.args] if il.is_eq(fmla): unify(*nodes) if il.is_interpreted_sort(fmla.args[0].sort): unify(strat_map[(fmla.rep, 0)], nodes[0]) return None if il.is_ite(fmla): unify(*nodes[1:]) return nodes[1] if il.is_app(fmla): func = fmla.rep if func in symbols_over_universals or True: for idx, node in enumerate(nodes): if node is not None: unify(strat_map[(func, idx)], node) return strat_map[func] return None
def universes(self, numerals=False): # print "sorts: {!r}".format(self.sorts()) if numerals: return dict((s,[c.rename(lambda s:str(i)) for i,c in enumerate(self.sorted_sort_universe(s))] if not ivy_logic.is_interpreted_sort(s) else list(self.sort_universe(s))) for s in self.sorts()) return dict((s,[c.skolem() for c in self.sort_universe(s)]) for s in self.sorts())
def numeral_assign(clauses, h): num_by_sort = defaultdict(list) numerals = [c for c in used_constants_clauses(clauses) if c.is_numeral()] for num in numerals: num_by_sort[num.sort].append(num) # print "num_by_sort: {}".format(numerals) foom = dict() used = set() # print "starting: foom = {}".format(foom) for s in h.sorts(): # print "na sort: {}".format(repr(s)) if ivy_logic.is_interpreted_sort(s): continue # print "sort loop: sort = {}, foom = {}".format(s,foom) for num in num_by_sort[s]: # print "foom = {}".format(foom) numv = h.eval_constant(num) # print "eval: {}:{} = {}".format(num,num.sort,numv) if numv in foom: print "two numerals assigned same value!: {} = {}".format(num, foom[numv]) else: # print "assigning {} to {}".format(num,numv) foom[numv] = num used.add(num) i = 0 for c in h.sorted_sort_universe(s): if c not in foom: while True: num = ivy_logic.Constant(c.rep.rename(lambda s: str(i))) i = i + 1 if num not in used: foom[c.rep] = num break return foom
def map_fmla(fmla,strat_map): if il.is_binder(fmla): return map_fmla(fmla.body,strat_map) if il.is_variable(fmla): if fmla not in strat_map: res = UFNode() res.variables.add(fmla) strat_map[fmla] = res return strat_map[fmla] nodes = [map_fmla(f,strat_map) for f in fmla.args] if il.is_eq(fmla): unify(*nodes) if il.is_interpreted_sort(fmla.args[0].sort): unify(strat_map[(fmla.rep,0)],nodes[0]) return None if il.is_ite(fmla): unify(*nodes[1:]) return nodes[1] if il.is_app(fmla): func = fmla.rep if func in symbols_over_universals or True: for idx,node in enumerate(nodes): if node is not None: unify(strat_map[(func,idx)],node) return strat_map[func] return None
def bq(fmla): """ Bound the free variables in fmla of uninterpeted sort """ vs = list(sorted(used_variables_ast(fmla))) vs = [v for v in vs if not ivy_logic.is_interpreted_sort(v.sort)] cnsts = [bdv(v) for v in vs] bq_res = ivy_logic.Implies(ivy_logic.And(*cnsts),fmla) if cnsts else fmla return bq_res
def numeral_assign(clauses,h): num_by_sort = defaultdict(list) numerals = [c for c in used_constants_clauses(clauses) if c.is_numeral()] for num in numerals: num_by_sort[num.sort].append(num) # print "num_by_sort: {}".format(numerals) foom = dict() used = set() # print "starting: foom = {}".format(foom) for s in h.sorts(): # print "na sort: {}".format(repr(s)) if ivy_logic.is_interpreted_sort(s): continue # print "sort loop: sort = {}, foom = {}".format(s,foom) for num in num_by_sort[s]: # print "foom = {}".format(foom) numv = h.eval_constant(num) # print "eval: {}:{} = {}".format(num,num.sort,numv) if numv in foom: print "two numerals assigned same value!: {} = {}".format(num,foom[numv]) else: # print "assigning {} to {}".format(num,numv) foom[numv] = num used.add(num) i = 0 for c in h.sorted_sort_universe(s): if c not in foom: while True: num = ivy_logic.Constant(c.rep.rename(lambda s:str(i))) i = i + 1 if num not in used: foom[c.rep] = num break return foom
def term_to_z3(term): if ivy_logic.is_boolean(term): return formula_to_z3_int(term) if not term.args: if isinstance(term, ivy_logic.Variable): sorted = hasattr(term, 'sort') sksym = term.rep + ':' + str(term.sort) if sorted else term.rep res = z3_constants.get(sksym) if res is not None: return res # print str(term.sort) sig = lookup_native(term.sort, sorts, "sort") if sorted else S if sig == None: sig = term.sort.to_z3() # if sorted: # print type(term.sort) # print term.sort # print type(sksym) # print sksym # print sig res = z3.Const(sksym, sig) z3_constants[sksym] = res return res res = z3_constants.get(term.rep) if res is None: # if isinstance(term.rep,str): # print "{} : {}".format(term,term.rep) if term.is_numeral(): res = numeral_to_z3(term.rep) elif ivy_logic.is_enumerated( term) and ivy_logic.is_interpreted_sort(term.sort): res = enumerated_to_numeral(term) else: iso = term.rep.sort # TODO: this is dangerous sig = iso.to_z3() if iso is not None else S # print "term: {}, iso : {}, sig = {}".format(term,iso,sig) res = z3.Const(term.rep.name, sig) z3_constants[term.rep] = res elif isinstance(term, ivy_logic.Ite): return z3.If(formula_to_z3_int(term.args[0]), term_to_z3(term.args[1]), term_to_z3(term.args[2])) else: if not hasattr(term, 'rep'): print term print term.lineno fun = z3_functions.get(term.rep) if fun is None: fun = lookup_native(term.rep, functions, "function") if fun is None: sig = term.rep.sort.to_z3() fun = z3.Function(term.rep.name, *sig) z3_functions[term.rep] = fun args = [term_to_z3(arg) for arg in term.args] res = apply_z3_func(fun, args) return res
def recur(expr): if isinstance(expr,il.Ite): cond = recur(expr.args[0]) thenterm = recur(expr.args[1]) elseterm = recur(expr.args[2]) res = [self.sub.ite(cond[0],x,y) for x,y in zip(thenterm,elseterm)] elif il.is_app(expr): sym = expr.rep if sym in il.sig.constructors: m = sym.sort.defines().index(sym.name) res = self.binenc(m,ceillog2(len(sym.sort.defines()))) elif sym.is_numeral() and il.is_interpreted_sort(sym.sort): n = get_encoding_bits(sym.sort) res = self.binenc(int(sym.name),n) elif sym.name in self.ops and il.is_interpreted_sort(sym.sort.dom[0]): args = map(recur,expr.args) res = self.ops[sym.name](expr.args[0].sort,*args) else: assert len(expr.args) == 0 try: res = self.lit(sym) except KeyError: assert getdef is not None, "no definition for {} in aiger output".format(sym) res = getdef(sym) else: args = map(recur,expr.args) if isinstance(expr,il.And): res = self.andl(*args) elif isinstance(expr,il.Or): res = self.orl(*args) elif isinstance(expr,il.Not): res = self.notl(*args) elif isinstance(expr,il.Implies): res = self.implies(*args) elif isinstance(expr,il.Iff): res = self.iff(*args) elif il.is_eq(expr): res = self.encode_equality(expr.args[0].sort,*args) else: assert False,"unimplemented op in aiger output: {}".format(type(expr)) # iu.dbg('expr') # iu.dbg('res') return res
def model_universe_facts(h, sort, upclose): if ivy_logic.is_interpreted_sort(sort): return [] # get universe elements elems = h.sort_universe(sort) # constraint defining universe uc = [] if not upclose: uc = [[ivy_logic._eq_lit(ivy_logic.Variable("X", c.sort), c) for c in elems]] # universe elements are distinct dc = [[ivy_logic._neq_lit(c1, c2)] for (c1, c2) in iu.distinct_unordered_pairs(elems)] return uc + dc
def model_universe_facts(h,sort,upclose): if ivy_logic.is_interpreted_sort(sort): return [] # get universe elements elems = h.sort_universe(sort) # constraint defining universe uc = [] if not upclose: uc = [[ivy_logic._eq_lit(ivy_logic.Variable('X',c.sort),c) for c in elems]] # universe elements are distinct dc = [[ivy_logic._neq_lit(c1,c2)] for (c1,c2) in iu.distinct_unordered_pairs(elems)] return uc+dc
def term_to_z3(term): if ivy_logic.is_boolean(term): return formula_to_z3_int(term) if not term.args: if isinstance(term, ivy_logic.Variable): sorted = hasattr(term, "sort") sksym = term.rep + ":" + str(term.sort) if sorted else term.rep res = z3_constants.get(sksym) if res is not None: return res # print str(term.sort) sig = lookup_native(term.sort, sorts, "sort") if sorted else S if sig == None: sig = term.sort.to_z3() # if sorted: # print type(term.sort) # print term.sort # print type(sksym) # print sksym # print sig res = z3.Const(sksym, sig) z3_constants[sksym] = res return res res = z3_constants.get(term.rep) if res is None: # if isinstance(term.rep,str): # print "{} : {}".format(term,term.rep) if term.is_numeral(): res = numeral_to_z3(term.rep) elif ivy_logic.is_enumerated(term) and ivy_logic.is_interpreted_sort(term.sort): res = enumerated_to_numeral(term) else: iso = term.rep.sort # TODO: this is dangerous sig = iso.to_z3() if iso != None else S # print "term: {}, iso : {}, sig = {}".format(term,iso,sig) res = z3.Const(term.rep.name, sig) z3_constants[term.rep] = res elif isinstance(term, ivy_logic.Ite): return z3.If(formula_to_z3_int(term.args[0]), term_to_z3(term.args[1]), term_to_z3(term.args[2])) else: fun = z3_functions.get(term.rep) if fun is None: fun = lookup_native(term.rep, functions, "function") if fun is None: sig = term.rep.sort.to_z3() fun = z3.Function(term.rep.name, *sig) z3_functions[term.rep] = fun args = [term_to_z3(arg) for arg in term.args] res = apply_z3_func(fun, args) return res
def map_fmla(lineno, fmla, pol): """ Add all of the subterms of `fmla` to the stratification graph. """ global universally_quantified_variables global macro_var_map global macro_dep_map global macro_map global macro_val_map global strat_map global arcs if il.is_binder(fmla): return map_fmla(lineno, fmla.body, pol) if il.is_variable(fmla): if fmla in universally_quantified_variables: if fmla not in strat_map: res = UFNode() strat_map[fmla] = res return strat_map[fmla], set() node, vs = macro_var_map.get(fmla, None), macro_dep_map.get(fmla, set()) return node, vs reses = [ map_fmla(lineno, f, il.polar(fmla, pos, pol)) for pos, f in enumerate(fmla.args) ] nodes, uvs = iu.unzip_pairs(reses) all_uvs = iu.union_of_list(uvs) all_uvs.update(n for n in nodes if n is not None) if il.is_eq(fmla): if not il.is_interpreted_sort(fmla.args[0].sort): S_sigma = strat_map[il.Symbol('=', fmla.args[0])] for x, uv in zip(nodes, uvs): if x is not None: unify(x, S_sigma) arcs.extend((v, S_sigma, fmla, lineno) for v in uv) else: check_interpreted(fmla, nodes, uvs, lineno, pol) return None, all_uvs if il.is_ite(fmla): # S_sigma = strat_map[il.Symbol('=',fmla.args[1])] # for x,uv in zip(nodes[1:],uvs[1:]): # if x is not None: # unify(x,S_sigma) # arcs.extend((v,S_sigma,fmla,lineno) for v in uv) # TODO: treat ite as pseudo-macro: does this work? if nodes[1] and nodes[2]: unify(*nodes[1:]) return nodes[1] or nodes[2], all_uvs if il.is_app(fmla): func = fmla.rep if not il.is_interpreted_symbol(func): if func in macro_value_map: return macro_value_map[func] if func in macro_map: defn, lf = macro_map[func] res = map_fmla(lf.lineno, defn.rhs(), None) macro_value_map[func] = res return res for idx, node in enumerate(nodes): anode = strat_map[(func, idx)] if node is not None: unify(anode, node) arcs.extend((v, anode, fmla, lineno) for v in uvs[idx]) else: check_interpreted(fmla, nodes, uvs, lineno, pol) return None, all_uvs return None, all_uvs