def __init__(self, clauses, model, vocab, top_level=True): TraceBase.__init__(self) self.clauses = clauses self.model = model self.vocab = vocab self.top_level = top_level if clauses is not None: ignore = lambda s: islv.solver_name(s) == None mod_clauses = islv.clauses_model_to_clauses(clauses, model=model, numerals=True, ignore=ignore) self.eqs = defaultdict(list) for fmla in mod_clauses.fmlas: if lg.is_eq(fmla): lhs, rhs = fmla.args if lg.is_app(lhs): self.eqs[lhs.rep].append(fmla) elif isinstance(fmla, lg.Not): app = fmla.args[0] if lg.is_app(app): self.eqs[app.rep].append(lg.Equals(app, lg.Or())) else: if lg.is_app(fmla): self.eqs[fmla.rep].append(lg.Equals(fmla, lg.And()))
def __init__(self, clauses, model, vocab): # iu.dbg('clauses') self.clauses = clauses self.model = model self.vocab = vocab self.current = dict() mod_clauses = islv.clauses_model_to_clauses(clauses, model=model, numerals=True) # iu.dbg('mod_clauses') self.eqs = defaultdict(list) for fmla in mod_clauses.fmlas: if lg.is_eq(fmla): lhs, rhs = fmla.args if lg.is_app(lhs): self.eqs[lhs.rep].append(fmla) elif isinstance(fmla, lg.Not): app = fmla.args[0] if lg.is_app(app): self.eqs[app.rep].append(lg.Equals(app, lg.Or())) else: if lg.is_app(fmla): self.eqs[fmla.rep].append(lg.Equals(fmla, lg.And())) # for sym in vocab: # if not itr.is_new(sym) and not itr.is_skolem(sym): # self.show_sym(sym,sym) self.started = False self.renaming = dict() print print 'Trace follows...' print 80 * '*'
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 make_skolems(fmla, ast, pol, univs): global macro_dep_map global strat_map if isinstance(fmla, il.Not): make_skolems(fmla.args[0], ast, not pol, univs) if isinstance(fmla, il.Implies): make_skolems(fmla.args[0], ast, not pol, univs) make_skolems(fmla.args[1], ast, pol, univs) is_e = il.is_exists(fmla) is_a = il.is_forall(fmla) if is_e and pol or is_a and not pol: fvs = set(il.free_variables(fmla)) for u in univs: if u in fvs: for e in il.quantifier_vars(fmla): macro_dep_map[e].add(strat_map[u]) if is_e and not pol or is_a and pol: make_skolems(fmla.args[0], ast, pol, univs + list(il.quantifier_vars(fmla))) for arg in fmla.args: make_skolems(arg, ast, pol, univs) if isinstance(fmla, il.Ite): make_skolems(fmla.args[0], ast, not pol, univs) if isinstance(fmla, il.Iff) or (il.is_eq(fmla) and il.is_boolean(fmla.args[0])): make_skolems(fmla.args[0], ast, not pol, univs) make_skolems(fmla.args[1], ast, not pol, univs)
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 get_qa_arcs(fmla,ast,pol,univs,strat_map): if isinstance(fmla,il.Not): for a in get_qa_arcs(fmla.args[0],ast,not pol,univs,strat_map): yield a return if isinstance(fmla,il.Implies): for a in get_qa_arcs(fmla.args[0],ast,not pol,univs,strat_map): yield a for a in get_qa_arcs(fmla.args[1],ast,pol,univs,strat_map): yield a return is_e = il.is_exists(fmla) is_a = il.is_forall(fmla) if is_e and pol or is_a and not pol: fvs = set(il.free_variables(fmla)) for u in univs: if u in fvs: for e in il.quantifier_vars(fmla): yield (find(strat_map[u]),find(strat_map[e]),ast) if is_e and not pol or is_a and pol: for a in get_qa_arcs(fmla.args[0],ast,pol,univs+list(il.quantifier_vars(fmla)),strat_map): yield a for arg in fmla.args: for a in get_qa_arcs(arg,ast,pol,univs,strat_map): yield a if isinstance(fmla,il.Ite): for a in get_qa_arcs(fmla.args[0],ast,not pol,univs,strat_map): yield a if isinstance(fmla,il.Iff) or (il.is_eq(fmla) and il.is_boolean(fmla.args[0])): for a in get_qa_arcs(fmla.args[0],ast,not pol,univs,strat_map): yield a for a in get_qa_arcs(fmla.args[1],ast,not pol,univs,strat_map): yield a
def match(pat,expr,mp): if il.is_variable(pat): if pat in mp: return expr == mp[pat] mp[pat] = expr return True if il.is_app(pat): return (il.is_app(expr) and pat.rep == expr.rep and all(match(x,y,mp) for x,y in zip(pat.args,expr.args))) if il.is_quantifier(pat): return False if type(pat) is not type(expr): return False if il.is_eq(expr): px,py = pat.args ex,ey = expr.args if px.sort != ex.sort: return False save = mp.copy() if match(px,ex,mp) and match(py,ey,mp): return True mp.clear() mp.update(save) return match(px,ey,mp) and match(py,ex,mp) return all(match(x,y,mp) for x,y in zip(pat.args,expr.args))
def __init__(self, clauses, model, vocab, top_level=True): art.AnalysisGraph.__init__(self) self.clauses = clauses self.model = model self.vocab = vocab mod_clauses = islv.clauses_model_to_clauses(clauses, model=model, numerals=True) self.eqs = defaultdict(list) for fmla in mod_clauses.fmlas: if lg.is_eq(fmla): lhs, rhs = fmla.args if lg.is_app(lhs): self.eqs[lhs.rep].append(fmla) elif isinstance(fmla, lg.Not): app = fmla.args[0] if lg.is_app(app): self.eqs[app.rep].append(lg.Equals(app, lg.Or())) else: if lg.is_app(fmla): self.eqs[fmla.rep].append(lg.Equals(fmla, lg.And())) self.last_action = None self.sub = None self.returned = None self.top_level = top_level
def clone_normal(expr,args): if il.is_eq(expr): x,y = args if x == y: return il.And() to = term_ord(x,y) # print 'term_ord({},{}) = {}'.format(x,y,to) if to == 1: x,y = y,x return expr.clone([x,y]) return expr.clone(args)
def get_trigger(expr,vs): if il.is_quantifier(expr) or il.is_variable(expr): return None for a in expr.args: r = get_trigger(a,vs) if r is not None: return r if il.is_app(expr) or il.is_eq(expr): evs = ilu.used_variables_ast(expr) if all(v in evs for v in vs): return expr
def elim_ite(expr,cnsts): if isinstance(expr,il.Ite): global ite_ctr c,x,y = expr.args if not is_finite_sort(x.sort): v = il.Symbol('__ite[{}]'.format(ite_ctr),x.sort) ite_ctr += 1 cnsts.append(il.Ite(elim_ite(c,cnsts),elim_ite(il.Equals(v,x),cnsts),elim_ite(il.Equals(v,y),cnsts))) return v if il.is_eq(expr): v,e = expr.args if isinstance(e,il.Ite): c,x,y = e.args if not is_finite_sort(x.sort): return il.Ite(elim_ite(c,cnsts),elim_ite(il.Equals(v,x),cnsts),elim_ite(il.Equals(v,y),cnsts)) return expr.clone([elim_ite(e,cnsts) for e in expr.args])
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 is_arithmetic_literal(app, pos, nodes, uvs, pol): """ Given an application `app` of an interpreted symbol, with a variable in argument position `pos`, where `nodes` gives the top-level universals of the arguments and `uvs` gives the lower-level universals, determine whether `app` is an arithmetic literal. As a side effect, if both arguments of an arithmetic literal are universals, we unify them (per the rule in seciont 4 of ibid). """ if ((il.is_inequality_symbol(app.rep) or il.is_eq(app)) and thy.has_integer_interp(app.args[0].sort)): if il.is_strict_inequality_symbol(app.rep, pol): if nodes[1 - pos] is not None: unify(*nodes) return True # If `app` is an integer theory literal and the other argument is ground, we are OK if nodes[1 - pos] is None and not uvs[1 - pos]: return True return False
def unroll(self, card, body=None): cond = self.args[0] while isinstance(cond, And) and len(cond.args) > 0: cond = cond.args[0] if is_app(cond) and cond.rep.name in ['<', '>', '<=', '>=']: idx_sort = cond.args[0].sort elif isinstance(cond, Not) and is_eq(cond.args[0]): idx_sort = cond.args[0].args[0].sort else: raise IvyError(self, 'cannot determine an index sort for loop') cardsort = card(idx_sort) if cardsort is None: raise IvyError( self, 'cannot determine an iteration bound for loop over {}'.format( idx_sort)) res = AssumeAction(Not(self.args[0])) for idx in range(cardsort): res = IfAction(self.args[0], Sequence(body or self.args[1], res)) if hasattr(self, 'formal_params'): res.formal_params = self.formal_params if hasattr(self, 'formal_returns'): res.formal_returns = self.formal_returns return res
def unlikely(fmla): # remove if possible the =constant predicates return ivy_logic.is_eq(fmla) and ivy_logic.is_constant( fmla.args[0])
def unlikely(fmla): # remove if possible the =constant predicates return ivy_logic.is_eq(fmla) and ivy_logic.is_constant(fmla.args[0])
def is_numeral_concept(c): return (len(c.variables) == 1 and il.is_eq(c.formula) and isinstance(c.formula.args[0], il.Variable) and il.is_numeral(c.formula.args[1]))
def can_abbreviate_formula(v,fmla): return (len(fmla.args) == 1 and fmla.args[0] == v or il.is_eq(fmla) and (fmla.args[0] == v or len(fmla.args[0].args) ==1 and fmla.args[0].args[0] == v) and not any(ilu.variables_ast(fmla.args[1])))
def is_numeral_concept(c): return (len(c.variables) == 1 and il.is_eq(c.formula) and isinstance(c.formula.args[0],il.Variable) and il.is_numeral(c.formula.args[1]))
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
def can_abbreviate_formula(v, fmla): return (len(fmla.args) == 1 and fmla.args[0] == v or il.is_eq(fmla) and (fmla.args[0] == v or len(fmla.args[0].args) == 1 and fmla.args[0].args[0] == v) and not any(ilu.variables_ast(fmla.args[1])))