def match(pat, inst, freesyms, constants): """ Match an instance to a pattern. A match is an assignment sigma to freesyms such that sigma pat =_alpha inst. """ if il.is_quantifier(pat): return match_quants(pat, inst, freesyms, constants) if heads_match(pat, inst, freesyms): matches = [ match(x, y, freesyms, constants) for x, y in zip(pat.args, inst.args) ] matches.extend([ match_sort(x, y, freesyms) for x, y in zip(term_sorts(pat), term_sorts(inst)) ]) if il.is_variable(pat): matches.append({pat: inst}) res = merge_matches(*matches) return res elif il.is_app(pat) and pat.rep in freesyms: B = extract_terms(inst, pat.args) if all(v in constants for v in lu.variables_ast(B)): matches = [{pat.rep: B}] matches.extend([ match_sort(x, y, freesyms) for x, y in zip(term_sorts(pat), lambda_sorts(B)) ]) res = merge_matches(*matches) return res
def formula_to_z3_int(fmla): # print "formula_to_z3_int: {} : {}".format(fmla,type(fmla)) if ivy_logic.is_atom(fmla): return atom_to_z3(fmla) if isinstance(fmla, ivy_logic.Definition) and ivy_logic.is_enumerated(fmla.args[0]) and not use_z3_enums: return encode_equality(*fmla.args) args = [formula_to_z3_int(arg) for arg in fmla.args] if isinstance(fmla, ivy_logic.And): return z3.And(args) if isinstance(fmla, ivy_logic.Or): return z3.Or(args) if isinstance(fmla, ivy_logic.Not): return z3.Not(args[0]) if isinstance(fmla, ivy_logic.Definition): return my_eq(args[0], args[1]) if isinstance(fmla, ivy_logic.Iff): return my_eq(args[0], args[1]) if isinstance(fmla, ivy_logic.Implies): return z3.Implies(args[0], args[1]) if isinstance(fmla, ivy_logic.Ite): return z3.If(args[0], args[1], args[2]) if ivy_logic.is_quantifier(fmla): variables = ivy_logic.quantifier_vars(fmla) q = z3.ForAll if ivy_logic.is_forall(fmla) else z3.Exists res = q([term_to_z3(v) for v in variables], args[0]) # print "res = {}".format(res) return res if ivy_logic.is_individual(fmla): return term_to_z3(fmla) print "bad fmla: {!r}".format(fmla) assert False
def formula_to_z3_int(fmla): # print "formula_to_z3_int: {} : {}".format(fmla,type(fmla)) if ivy_logic.is_atom(fmla): return atom_to_z3(fmla) if isinstance(fmla, ivy_logic.Definition) and ivy_logic.is_enumerated( fmla.args[0]): return encode_equality(*fmla.args) args = [formula_to_z3_int(arg) for arg in fmla.args] if isinstance(fmla, ivy_logic.And): return z3.And(args) if isinstance(fmla, ivy_logic.Or): return z3.Or(args) if isinstance(fmla, ivy_logic.Not): return z3.Not(args[0]) if isinstance(fmla, ivy_logic.Definition): return my_eq(args[0], args[1]) if isinstance(fmla, ivy_logic.Iff): return my_eq(args[0], args[1]) if isinstance(fmla, ivy_logic.Implies): return z3.Implies(args[0], args[1]) if isinstance(fmla, ivy_logic.Ite): return z3.If(args[0], args[1], args[2]) if ivy_logic.is_quantifier(fmla): variables = ivy_logic.quantifier_vars(fmla) q = z3.forall if ivy_logic.is_forall(fmla) else z3.Exists res = q([term_to_z3(v) for v in variables], args[0]) # print "res = {}".format(res) return res if ivy_logic.is_individual(fmla): return term_to_z3(fmla) print "bad fmla: {!r}".format(fmla) assert False
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 heads_match(pat,inst,freesyms): """Returns true if the heads of two terms match. This means they have the same top-level operator and same number of arguments. Quantifiers do not match anything. A function symbol matches if it has the same name and if it agrees on the non-free sorts in its type. """ return (il.is_app(pat) and il.is_app(inst) and funcs_match(pat.rep,inst.rep,freesyms) and pat.rep not in freesyms or not il.is_app(pat) and not il.is_quantifier(pat) and type(pat) is type(inst) and len(pat.args) == len(inst.args))
def heads_match(pat,inst,freesyms): """Returns true if the heads of two terms match. This means they have the same top-level operator and same number of arguments. Quantifiers do not match anything. A function symbol matches if it has the same name and if it agrees on the non-free sorts in its type. """ return (il.is_app(pat) and il.is_app(inst) and funcs_match(pat.rep,inst.rep,freesyms) or not il.is_app(pat) and not il.is_quantifier(pat) and type(pat) is type(inst) and len(pat.args) == len(inst.args))
def fo_match(pat,inst,freesyms,constants): """ Compute a partial first-order match. Matches free FO variables to ground terms, but ignores variable occurrences under free second-order symbols. """ if il.is_variable(pat): if pat in freesyms and all(x in constants for x in lu.variables_ast(inst)): res = {pat:inst} if pat.sort in freesyms: res[pat.sort] = inst.sort return res if pat.sort == inst.sort: return res if il.is_quantifier(pat) and il.is_quantifier(inst): with RemoveSymbols(freesyms,pat.variables): return fo_match(pat.body,inst.body,freesyms,constants) if heads_match(pat,inst,freesyms): matches = [fo_match(x,y,freesyms,constants) for x,y in zip(pat.args,inst.args)] res = merge_matches(*matches) return res return dict()
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 fo_match(pat,inst,freesyms,constants): """ Compute a partial first-order match. Matches free FO variables to ground terms, but ignores variable occurrences under free second-order symbols. """ if il.is_variable(pat): if pat in freesyms and all(x in constants for x in lu.variables_ast(inst)): res = {pat:inst} if pat.sort == inst.sort: return res if pat.sort in freesyms: res[pat.sort] = inst.sort return res if il.is_quantifier(pat) and il.is_quantifier(inst): with RemoveSymbols(freesyms,pat.variables): return fo_match(pat.body,inst.body,freesyms,constants) if heads_match(pat,inst,freesyms): matches = [fo_match(x,y,freesyms,constants) for x,y in zip(pat.args,inst.args)] res = merge_matches(*matches) return res return dict()
def qe(self,expr,sort_constants): if il.is_quantifier(expr): old = self.syms.get(expr,None) if old is not None: return old res = self.fresh(expr) consts = [sort_constants[x.sort] for x in expr.variables] values = itertools.product(*consts) maps = [dict(zip(expr.variables,v)) for v in values] insts = [normalize(il.substitute(expr.body,m)) for m in maps] # for i in insts: # print ' {}'.format(i) for inst in insts: c = il.Implies(res,inst) if il.is_forall(expr) else il.Implies(inst,res) self.fmlas.append(c) return res return clone_normal(expr,[self.qe(e,sort_constants) for e in expr.args])
def match(pat,inst,freesyms,constants): """ Match an instance to a pattern. A match is an assignment sigma to freesyms such that sigma pat =_alpha inst. """ if il.is_quantifier(pat): return match_quants(pat,inst,freesyms,constants) if heads_match(pat,inst,freesyms): matches = [match(x,y,freesyms,constants) for x,y in zip(pat.args,inst.args)] matches.extend([match_sort(x,y,freesyms) for x,y in zip(term_sorts(pat),term_sorts(inst))]) return merge_matches(*matches) if il.is_app(pat) and pat.rep in freesyms: B = extract_terms(inst,pat.args) if all(v in constants for v in lu.variables_ast(B)): return {pat.rep:B}
def mk_prop_abs(expr): if il.is_quantifier(expr) or len(expr.args) > 0 and any(not is_finite_sort(a.sort) for a in expr.args): return new_prop(expr) return expr.clone(map(mk_prop_abs,expr.args))