def substitute_apply(t, subs, by_name=False):

    if not isinstance(subs, dict):
        subs = dict(subs)

    _substitute_apply = partial(substitute_apply, subs=subs, by_name=by_name)

    if type(t) in (Var, Const):
        return t

    if type(t) is Apply and t.func in subs:
        terms = tuple(_substitute_apply(x) for x in t.terms)
        result = subs[t.func](*terms)
        fvr = free_variables(result, by_name=by_name)
        fvt = free_variables(*terms, by_name=by_name)
        assert fvr <= fvt, "New free variables!? {}, {}".format(fvr, fvt)
        return result

    elif type(t) in (Apply, Eq, Ite, Not, And, Or, Implies, Iff):
        return type(t)(*(_substitute_apply(x) for x in t))

    elif type(t) in (ForAll, Exists):
        return type(t)(t.variables, _substitute_apply(t.body, subs=dict(
            (k, v) for k, v in subs.iteritems()
            if k not in t.variables
        )))
    else:
        assert False, type(e)
Add a new tag to the handler.
dataset/ETHPy150Open Microsoft/ivy/ivy/logic_util.py/substitute_apply--crossover with--dataset/ETHPy150Open evennia/evennia/evennia/typeclasses/tags.py/TagHandler.add