expr_app::expr_app(expr const & fn, expr const & arg, tag g): expr_composite(expr_kind::App, ::lean::hash(fn.hash(), arg.hash()), fn.has_expr_metavar() || arg.has_expr_metavar(), fn.has_univ_metavar() || arg.has_univ_metavar(), fn.has_local() || arg.has_local(), fn.has_param_univ() || arg.has_param_univ(), inc_weight(add_weight(get_weight(fn), get_weight(arg))), std::max(get_free_var_range(fn), get_free_var_range(arg)), g), m_fn(fn), m_arg(arg) { m_hash = ::lean::hash(m_hash, m_weight); }
expr_let::expr_let(name const & n, expr const & t, expr const & v, expr const & b, tag g): expr_composite(expr_kind::Let, ::lean::hash(::lean::hash(t.hash(), v.hash()), b.hash()), t.has_expr_metavar() || v.has_expr_metavar() || b.has_expr_metavar(), t.has_univ_metavar() || v.has_univ_metavar() || b.has_univ_metavar(), t.has_local() || v.has_local() || b.has_local(), t.has_param_univ() || v.has_param_univ() || b.has_param_univ(), inc_weight(add_weight(add_weight(get_weight(t), get_weight(v)), get_weight(b))), std::max(std::max(get_free_var_range(t), get_free_var_range(v)), dec(get_free_var_range(b))), g), m_name(n), m_type(t), m_value(v), m_body(b) { m_hash = ::lean::hash(m_hash, m_weight); }
expr_binding::expr_binding(expr_kind k, name const & n, expr const & t, expr const & b, binder_info const & i, tag g): expr_composite(k, ::lean::hash(t.hash(), b.hash()), t.has_expr_metavar() || b.has_expr_metavar(), t.has_univ_metavar() || b.has_univ_metavar(), t.has_local() || b.has_local(), t.has_param_univ() || b.has_param_univ(), inc_weight(add_weight(get_weight(t), get_weight(b))), std::max(get_free_var_range(t), dec(get_free_var_range(b))), g), m_binder(n, t, i), m_body(b) { m_hash = ::lean::hash(m_hash, m_weight); lean_assert(k == expr_kind::Lambda || k == expr_kind::Pi); }
// scoped_expr_actions must occur after a Binder/Binders. static void validate_transitions(bool nud, unsigned num, transition const * ts, expr const & a) { unsigned nargs = 0; if (!nud) nargs++; // led tables have an implicit left argument bool found_binder = false; for (unsigned i = 0; i < num; i++) { action const & a = ts[i].get_action(); switch (a.kind()) { case action_kind::Binder: case action_kind::Binders: found_binder = true; break; case action_kind::Expr: case action_kind::Exprs: case action_kind::Ext: case action_kind::LuaExt: nargs++; break; case action_kind::ScopedExpr: if (!found_binder) throw exception("invalid notation declaration, a scoped expression must occur after a binder element"); nargs++; break; case action_kind::Skip: break; } } if (get_free_var_range(a) > nargs) throw exception("invalid notation declaration, expression template has more free variables than arguments"); }
static unsigned get_free_var_range(unsigned num, expr const * args) { unsigned r = 0; for (unsigned i = 0; i < num; i++) { unsigned d = get_free_var_range(args[i]); if (d > r) r = d; } return r; }
action mk_exprs_action(name const & sep, expr const & rec, optional<expr> const & ini, optional<name> const & terminator, bool right, unsigned rbp) { if (get_free_var_range(rec) > 2) throw exception("invalid notation, the expression used to combine a sequence of expressions " "must not contain free variables with de Bruijn indices greater than 1"); expr new_rec = annotate_macro_subterms(rec); optional<expr> new_ini = ini ? some_expr(annotate_macro_subterms(*ini)) : none_expr(); return action(new exprs_action_cell(sep, new_rec, new_ini, terminator, right, rbp)); }
expr_macro::expr_macro(macro_definition const & m, unsigned num, expr const * args, tag g): expr_composite(expr_kind::Macro, lean::hash(num, [&](unsigned i) { return args[i].hash(); }, m.hash()), std::any_of(args, args+num, [](expr const & e) { return e.has_expr_metavar(); }), std::any_of(args, args+num, [](expr const & e) { return e.has_univ_metavar(); }), std::any_of(args, args+num, [](expr const & e) { return e.has_local(); }), std::any_of(args, args+num, [](expr const & e) { return e.has_param_univ(); }), inc_weight(add_weight(num, args)), get_free_var_range(num, args), g), m_definition(m), m_num_args(num) { m_args = new expr[num]; for (unsigned i = 0; i < m_num_args; i++) m_args[i] = args[i]; }
expr_mlocal::expr_mlocal(bool is_meta, name const & n, expr const & t, tag g): expr_composite(is_meta ? expr_kind::Meta : expr_kind::Local, n.hash(), is_meta || t.has_expr_metavar(), t.has_univ_metavar(), !is_meta || t.has_local(), t.has_param_univ(), 1, get_free_var_range(t), g), m_name(n), m_type(t) {}