Expr* subst(Expr* e, const Subst& sub) { switch (e->kind) { case id_expr: return e; case unit_term: return e; case true_term: return e; case false_term: return e; case if_term: return subst_ternary_term(as<If>(e), sub); case int_term: return e; case and_term: return subst_binary_term(as<And>(e), sub); case or_term: return subst_binary_term(as<Or>(e), sub); case equals_term: return subst_binary_term(as<Equals>(e), sub); case less_term: return subst_binary_term(as<Less>(e), sub); case not_term: return subst_unary_term(as<Not>(e), sub); case succ_term: return subst_unary_term(as<Succ>(e), sub); case pred_term: return subst_unary_term(as<Pred>(e), sub); case iszero_term: return subst_unary_term(as<Iszero>(e), sub); case var_term: return subst_var(as<Var>(e), sub); case abs_term: return subst_binary_term(as<Abs>(e), sub); case app_term: return subst_binary_term(as<App>(e), sub); case ref_term: return subst_ref(as<Ref>(e), sub); case mem_term: return subst_mem(as<Mem>(e), sub); case kind_type: return e; case unit_type: return e; case bool_type: return e; case nat_type: return e; case arrow_type: return e; case record_term: return e; default: break; } lang_unreachable(format("substitution into unkown term '{}'", node_name(e))); }
Expr& operator()(Reference_expr& e) { return subst_ref(cxt, e, sub); }