46 return lam->var(lam->num_vars(),
env_param(lam->type()->as<
Pi>()));
52 if (!fn_isa_lam ||
fnc->isa<
Lam>())
return ClosLit(tpl);
54 return ClosLit(
nullptr);
60 auto& w = env->
world();
61 auto pi = fn->
type()->as<
Pi>();
63 assert(env->
type() == pi->dom(pi->num_doms(), ep));
65 return w.tuple(ct, {env->
type(), fn, env})->as<Tuple>();
70 auto [env_type, fn, env] = c->projs<3>();
71 return {env_type, fn, env};
75 auto& w = closure->
world();
77 auto pi = fn->type()->as<
Pi>();
79 return w.app(fn,
DefVec(pi->num_doms(), [&](
auto i) { return clos_insert_env(ep, i, env, args); }));
87 auto& w = def->
world();
89 if (!sig || sig->num_ops() < 3 || sig->op(0_u64) != w.type())
return nullptr;
90 auto var = sig->
var(sig->num_ops(), 0);
91 if (sig->op(2_u64) != var)
return nullptr;
92 auto pi = sig->
op(1_u64)->isa<
Pi>();
93 if (!pi || !
Pi::isa_cn(pi) || pi->num_ops() <= 1_u64)
return nullptr;
94 return (pi->dom(pi->num_doms(),
env_param(pi)) == var) ? sig :
nullptr;
98 auto& w = pi->
world();
99 auto doms = pi->
doms();
105 auto& w = ct->
world();
106 auto pi = ct->
op(1_u64)->as<
Pi>();
109 return w.cn(new_dom);
117 return (i == ep) ? env : f(
shift_env(ep, i));
125 auto sigma = w.mut_sigma(w.type(), 3_u64)->set(
"Clos");
126 sigma->set(0_u64, w.type());
127 sigma->set(1_u64,
ctype(w, doms, sigma->var(3, 0)));
128 sigma->set(2_u64, sigma->var(3, 0));
131 return w.cn(
DefVec(doms.size() + 1,
132 [&](
auto i) { return clos_insert_env(ep, i, env_type, [&](auto j) { return doms[j]; }); }));
static const Def * peel(const Def *def)
Peel off all Id Axms from def.
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
World & world() const noexcept
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
const Def * op(size_t i) const noexcept
const Def * var(nat_t a, nat_t i) noexcept
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
static void hook(Flags2Phases &phases)
A dependent function type.
auto doms(Projector auto f) const noexcept
static const Pi * isa_cn(const Def *d)
Data constructor for a Sigma.
The World represents the whole program and manages creation of MimIR nodes (Defs).
const Def * env_var() const
friend ClosLit isa_clos_lit(const Def *, bool)
Tries to match a closure literal.
static void reg_phases(Flags2Phases &phases)
void register_normalizers(Normalizers &normalizers)
const Def * clos_sub_env(size_t ep, const Def *tup_or_sig, const Def *new_env)
const Def * clos_remove_env(size_t ep, size_t i, std::function< const Def *(size_t)> f)
Sigma * clos_type(const Pi *pi)
Creates a typed closure type from pi.
size_t shift_env(size_t ep, size_t i)
Adjust the index of an argument to account for the env param.
const Def * ctype(World &w, Defs doms, const Def *env_type=nullptr)
Builds a closure type from the domains doms of a Cn.
const Def * clos_insert_env(size_t ep, size_t i, const Def *env, std::function< const Def *(size_t)> f)
const Pi * clos_type_to_pi(const Def *ct, const Def *new_env_type=nullptr)
Convert a closure type to a Pi, where the environment type has been removed or replaced by new_env_ty...
std::tuple< const Def *, const Def *, const Def * > clos_unpack(const Def *c)
Deconstruct a closure into (env_type, function, env).
size_t skip_env(size_t ep, size_t i)
Same as shift_env, but skips the env param instead.
const Def * clos_pack(const Def *env, const Def *fn, const Def *ct=nullptr)
Pack a typed closure.
const Def * clos_apply(const Def *closure, const Def *args)
Apply a closure to arguments.
const Sigma * isa_clos_type(const Def *def)
size_t env_param(Defs doms)
Describes where the environment is placed in the argument list: right after a leading mem....
fe::View< const Def * > Defs
fe::Vector< const Def * > DefVec
ankerl::unordered_dense::map< flags_t, std::function< std::unique_ptr< Phase >(World &)> > Flags2Phases
Maps an axiom of a Phase to a function that creates one.
#define MIM_PLUGIN_ENTRY(p)
Defines a Plugin's entry point; the body fills in the plugin handed to it, as in MIM_PLUGIN_ENTRY(dem...