5using namespace std::string_literals;
28 if (
auto app =
body()->isa<App>())
29 if (
auto callee =
app->callee()->
isa_mut<Lam>(); callee && callee->is_set())
return callee;
47 auto lam = d->isa_mut<Lam>();
48 if (!lam || !lam->is_set())
return nullptr;
55 if (
auto app = lam->
body()->isa<
App>()) {
57 if (var && app->callee()->has_free_var(var))
return nullptr;
59 if (app->arg() == var || app->arg() == lam->
world().
inhabitant(lam->
dom()))
return app->callee();
65 if (
auto lam = def->isa<
Lam>())
67 if (f->isa_mut())
return f;
69 for (
auto mut : f->local_muts())
80 for (slow = def; slow != fast; slow =
eta_step(slow), fast =
eta_step(fast)) {}
81 return fast == def ? nullptr : fast;
86 auto eta = w.mut_lam(f->type()->as<
Pi>());
87 eta->set(f->dbg_key())->debug_prefix(
"eta_"s);
88 return eta->app(
filter, f, eta->var());
Def * set(size_t i, const Def *)
Successively set from left to right.
World & world() const noexcept
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
constexpr auto reduce(const Def *arg) const
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
std::variant< bool, const Def * > Filter
const Def * filter() const
Lam * forwardee() const
λ x = f arg where f is a mut Lam that is_set();
Lam * set(Filter filter, const Def *body)
static Lam * eta_expand(Filter, const Def *f)
Lam * set_filter(Filter)
Set filter first.
static const Def * eta_reduce(const Def *def)
Fast-forwards def along its chain of η-redexes λ x = f x where x ∉ FV(f).
Lam * branch(Filter filter, const Def *cond, const Def *t, const Def *f, const Def *arg=nullptr)
Set body to an App of (f, t)#cond mem or (f, t)#cond () if mem is nullptr.
Lam * app(Filter filter, const Def *callee, const Def *arg)
Set body to an App of callee and arg.
static const Def * isa_ret_arg(const Def *d)
Yields the y of λ (x, ret) = ret y - the argument d's body hands to its Lam::ret_var.
const Def * ret_var()
Yields the Lam::var of the Lam::ret_pi.
A dependent function type.
auto doms(Projector auto f) const noexcept
Pi(const Def *type, const Def *dom, const Def *codom, bool implicit)
Constructor for an immutable Pi.
static const Pi * isa_basicblock(const Def *d)
const Pi * ret_pi() const
Yields the last Pi::dom, if Pi::isa_basicblock.
nat_t num_doms() const noexcept
Pi * set_dom(const Def *dom)
const Def * inhabitant(const Def *type)
The sole inhabitant of type, if it has exactly one, nullptr otherwise.
const Def * filter(Lam::Filter filter)
const Def * app(const Def *callee, const Def *arg)
fe::View< const Def * > Defs
static const Def * eta_step(const Def *def)
static const Def * eta_callee(const Lam *lam)