Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
def match_problem(schema, decl):
    """ Creating a matching problem from a schema and a declaration """
    vocab = goal_vocab(schema)
    freesyms = set(vocab.symbols + vocab.sorts + vocab.variables)
    constants = set(v for v in goal_free(decl) if il.is_variable(v))
    return MatchProblem(schema, goal_conc(schema), goal_conc(decl), freesyms,
                        constants)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
 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))
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
0
def create_macro_maps(assumes, asserts, macros):
    global universally_quantified_variables
    global macro_var_map
    global macro_dep_map
    global macro_map
    global macro_value_map
    global strat_map
    macro_map = dict()
    for df, lf in macros:
        macro_map[df.defines()] = (df, lf)
    macro_dep_map = defaultdict(set)
    macro_var_map = dict()
    macro_value_map = dict()

    def var_map_add(w, vn):
        if w in macro_var_map:
            unify(macro_var_map[w], vn)
        else:
            macro_var_map[w] = vn

    for fmla, _ in assumes + asserts + list(reversed(macros)):
        for app in ilu.apps_ast(fmla):
            if app.rep in macro_map:
                mvs = macro_map[app.rep][0].args[0].args
                for v, w in zip(app.args, mvs):
                    if il.is_variable(w):
                        if il.is_variable(v):
                            if v in universally_quantified_variables:
                                var_map_add(w, strat_map[v])
                            if v in macro_var_map:
                                var_map_add(w, macro_var_map[v])
                            if v in macro_dep_map:
                                macro_dep_map[w].update(macro_dep_map[v])
                        else:
                            for u in ilu.used_variables_ast(v):
                                if u in universally_quantified_variables:
                                    macro_dep_map[w].add(strat_map[u])
                                if u in macro_var_map:
                                    macro_dep_map[w].add(macro_var_map[u])
                                if u in macro_dep_map:
                                    macro_dep_map[w].update(macro_var_map[u])
Ejemplo n.º 8
0
def avoid_capture_problem(prob, match):
    """ Rename a match problem to avoid capture when applying a
    match"""
    mrv = match_rhs_vars(match)
    matchnames = set(x.name for x in match_rhs_vars(match))
    used = set(matchnames)
    used.update(x.name for x in goal_defns(prob.schema))
    used.update(v.name for v in goal_free(prob.schema) if il.is_variable(v))
    rn = iu.UniqueRenamer(used=used)
    cmatch = dict((v, v.rename(rn)) for v in prob.freesyms
                  if v.name in matchnames and v not in match)
    rename_problem(cmatch, prob)
Ejemplo n.º 9
0
def apply_match_rec(match,fmla,env):
    args = [apply_match_rec(match,f,env) for f in fmla.args]
    if il.is_app(fmla):
        if fmla.rep in match:
            func = match[fmla.rep]
            return func(*args)
        return apply_match_func(match,fmla.rep)(*args)
    if il.is_variable(fmla) and fmla in match:
        return match[fmla]
    if il.is_binder(fmla):
        with il.BindSymbols(env,fmla.variables):
            fmla = fmla.clone_binder([apply_match_rec(match,v,env) for v in fmla.variables],args[0])
        return fmla
    return fmla.clone(args)
Ejemplo n.º 10
0
def compile_one_match(lhs,rhs,freesyms,constants):
    if il.is_variable(lhs):
        return fo_match(lhs,rhs,freesyms,constants)
    rhsvs = dict((v.name,v) for v in lu.used_variables_ast(rhs))
    vmatches = [{v.sort:rhsvs[v.name].sort} for v in lu.used_variables_ast(lhs)
                  if v.name in rhsvs and v.sort in freesyms]
    vmatch = merge_matches(*vmatches)
    if vmatch is None:
        return None
    lhs = apply_match_alt(vmatch,lhs)
    newfreesyms = apply_match_freesyms(vmatch,freesyms)
    somatch = match(lhs,rhs,newfreesyms,constants)
    somatch = compose_matches(freesyms,vmatch,somatch,vmatch)
    fmatch = merge_matches(vmatch,somatch)
    return fmatch
Ejemplo n.º 11
0
def apply_match(match, fmla):
    """ apply a match to a formula. 

    In effect, substitute all symbols in the match with the
    corresponding lambda terms and apply beta reduction
    """

    args = [apply_match(match, f) for f in fmla.args]
    if il.is_app(fmla):
        if fmla.rep in match:
            func = match[fmla.rep]
            return func(*args)
        return apply_match_func(match, fmla.rep)(*args)
    if il.is_variable(fmla) and fmla in match:
        return match[fmla]
    return fmla.clone(args)
Ejemplo n.º 12
0
def apply_match(match,fmla):
    """ apply a match to a formula. 

    In effect, substitute all symbols in the match with the
    corresponding lambda terms and apply beta reduction
    """

    args = [apply_match(match,f) for f in fmla.args]
    if il.is_app(fmla):
        if fmla.rep in match:
            func = match[fmla.rep]
            return func(*args)
        return apply_match_func(match,fmla.rep)(*args)
    if il.is_variable(fmla) and fmla in match:
        return match[fmla]
    return fmla.clone(args)
Ejemplo n.º 13
0
def apply_match(match,fmla):
    """ apply a match to a formula. 

    In effect, substitute all symbols in the match with the
    corresponding lambda terms and apply beta reduction
    """

    args = [apply_match(match,f) for f in fmla.args]
    if il.is_app(fmla):
        if fmla.rep in match:
            func = match[fmla.rep]
            return func(*args)
    elif il.is_binder(fmla):
        vs = [apply_match(match,v) for v in fmla.variables]
        return fmla.clone_binder(vs,apply_match(match,fmla.body))
    elif il.is_variable(fmla):
        return il.Variable(fmla.name,match.get(fmla.sort,fmla.sort))
    return fmla.clone(args)
Ejemplo n.º 14
0
def apply_match_alt(match,fmla):
    """ apply a match to a formula. 

    In effect, substitute all symbols in the match with the
    corresponding lambda terms and apply beta reduction
    """

    args = [apply_match_alt(match,f) for f in fmla.args]
    if il.is_app(fmla):
        func = apply_match_func(match,fmla.rep)
        if func in match:
            func = match[func]
            return func(*args)
        return func(*args)
    if il.is_variable(fmla):
        fmla = il.Variable(fmla.name,match.get(fmla.sort,fmla.sort))
        fmla = match.get(fmla,fmla)
        return fmla
    return fmla.clone(args)
Ejemplo n.º 15
0
def strip_action(ast, strip_map, strip_binding):
    if isinstance(ast, ia.CallAction):
        name = canon_act(ast.args[0].rep)
        args = [
            strip_action(arg, strip_map, strip_binding)
            for arg in ast.args[0].args
        ]
        strip_params = get_strip_params(name, ast.args[0].args, strip_map,
                                        strip_binding, ast)
        call = ast.args[0].clone(args[len(strip_params):])
        return ast.clone([call] + [
            strip_action(arg, strip_map, strip_binding) for arg in ast.args[1:]
        ])
    if isinstance(ast, ia.AssignAction):
        if ast.args[0].rep.name in ivy_logic.sig.symbols:
            lhs_params = strip_map_lookup(ast.args[0].rep.name, strip_map)
            if len(lhs_params) != num_isolate_params:
                raise iu.IvyError(ast, "assignment may be interfering")
    if (ivy_logic.is_constant(ast)
            or ivy_logic.is_variable(ast)) and ast in strip_binding:
        sname = strip_binding[ast]
        if sname not in ivy_logic.sig.symbols:
            ivy_logic.add_symbol(sname, ast.sort)
            strip_added_symbols.append(ivy_logic.Symbol(sname, ast.sort))
        return ivy_logic.Symbol(sname, ast.sort)
    args = [strip_action(arg, strip_map, strip_binding) for arg in ast.args]
    if ivy_logic.is_app(ast):
        name = ast.rep.name
        strip_params = get_strip_params(name, ast.args, strip_map,
                                        strip_binding, ast)
        if strip_params:
            new_sort = strip_sort(ast.rep.sort, strip_params)
            new_args = args[len(strip_params):]
            new_symbol = ivy_logic.Symbol(name, new_sort)
            return new_symbol(*new_args)
    if isinstance(ast, ivy_ast.Atom):
        name = ast.rep
        strip_params = get_strip_params(name, ast.args, strip_map,
                                        strip_binding, ast)
        if strip_params:
            new_args = args[len(strip_params):]
            return ast.clone(new_args)
    return ast.clone(args)
Ejemplo n.º 16
0
def apply_match_alt_rec(match,fmla,env):
    args = [apply_match_alt_rec(match,f,env) for f in fmla.args]
    if il.is_app(fmla):
        if fmla.rep in match:
            return apply_fun(match_get(match,fmla.rep,env),args)
        func = apply_match_func(match,fmla.rep)
        func = match_get(match,func,env,func)
        return func(*args)
    if il.is_variable(fmla):
        if fmla in match:
            return match_get(match,fmla,env)
        fmla = il.Variable(fmla.name,apply_match_sort(match,fmla.sort))
        fmla = match_get(match,fmla,env,fmla)
        return fmla
    if il.is_binder(fmla):
        with il.BindSymbols(env,fmla.variables):
            fmla = fmla.clone_binder([apply_match_alt_rec(match,v,env) for v in fmla.variables],args[0])
        return fmla
    return fmla.clone(args)
Ejemplo n.º 17
0
def apply_match_alt(match, fmla):
    """ apply a match to a formula. 

    In effect, substitute all symbols in the match with the
    corresponding lambda terms and apply beta reduction
    """

    args = [apply_match_alt(match, f) for f in fmla.args]
    if il.is_app(fmla):
        func = apply_match_func(match, fmla.rep)
        if func in match:
            func = match[func]
            return func(*args)
        return func(*args)
    if il.is_variable(fmla):
        fmla = il.Variable(fmla.name, match.get(fmla.sort, fmla.sort))
        fmla = match.get(fmla, fmla)
        return fmla
    return fmla.clone(args)
Ejemplo n.º 18
0
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()
Ejemplo n.º 19
0
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()
Ejemplo n.º 20
0
def strip_action(ast,strip_map,strip_binding):
    if isinstance(ast,ia.CallAction):
        name = ast.args[0].rep
        args = [strip_action(arg,strip_map,strip_binding) for arg in ast.args[0].args]
        strip_params = get_strip_params(name,ast.args[0].args,strip_map,strip_binding,ast)
        call = ast.args[0].clone(args[len(strip_params):])
        return ast.clone([call]+[strip_action(arg,strip_map,strip_binding) for arg in ast.args[1:]])
    if (ivy_logic.is_constant(ast) or ivy_logic.is_variable(ast)) and ast in strip_binding:
        sname = strip_binding[ast]
        if sname not in ivy_logic.sig.symbols:
            ivy_logic.add_symbol(sname,ast.sort)
        return ivy_logic.Symbol(sname,ast.sort)
    args = [strip_action(arg,strip_map,strip_binding) for arg in ast.args]
    if ivy_logic.is_app(ast):
        name = ast.rep.name
        strip_params = get_strip_params(name,ast.args,strip_map,strip_binding,ast)
        if strip_params:
            new_sort = strip_sort(ast.rep.sort,strip_params)
            new_args = args[len(strip_params):]
            new_symbol = ivy_logic.Symbol(name,new_sort)
            return new_symbol(*new_args)
    return ast.clone(args)
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
def apply_match_sym(match,sym):
    if il.is_variable(sym):
        return il.Variable(sym.name,match.get(sym.sort,sym.sort))
    return match.get(sym,sym) if isinstance(sym,il.UninterpretedSort) else apply_match_func(match,sym)
Ejemplo n.º 23
0
def apply_match_sym(match, sym):
    if il.is_variable(sym):
        return il.Variable(sym.name, match.get(sym.sort, sym.sort))
    return match.get(sym, sym) if isinstance(
        sym, il.UninterpretedSort) else apply_match_func(match, sym)
Ejemplo n.º 24
0
def term_sorts(term):
    """ Returns a list of the domain and range sorts of the head function of a term, if any """
    return func_sorts(term.rep) if il.is_app(
        term) else [term.sort] if il.is_variable(term) else []