3#include <fe/worklist.h>
14 auto queue = fe::BFSWorklist<DefSet>();
15 auto pinned = fe::BFSWorklist<DefSet>();
16 for (
auto mut :
old_world().externals().muts())
19 while (!queue.empty()) {
20 auto def = queue.pop();
24 if (
auto app = def->isa<
App>();
26 for (
auto arg : app->arg()->projs())
27 if (
auto lam = arg->isa_mut<
Lam>()) pinned.push(lam);
29 for (
auto d : def->deps())
33 while (!pinned.empty()) {
34 auto def = pinned.pop();
35 if (
auto lam = def->isa_mut<
Lam>()) preserved_.emplace(lam);
36 for (
auto d : def->deps())
53 if (curr_mem_ && !preserving_) {
59 tuple && std::ranges::any_of(
tuple->ops(), [](
const Def* op) { return isa_mem(op); }))
65 if (curr_mem_ && !preserving_ && !old_def->
isa_mut() && old_def->
type() &&
isa_mem(old_def))
return curr_mem_;
71 if (preserving_)
return new_pi;
77 auto dom = new_pi->dom();
83 if (
auto [sigma, old_var] = dom->isa_binder<
Sigma>(); sigma) {
84 auto n = sigma->num_ops();
85 auto new_sigma = w.mut_sigma(sigma->type(), n + 1);
86 new_sigma->set(0,
mem);
89 for (
size_t i = 0; i != n; ++i) {
90 auto shift = w.tuple(
DefVec(n, [&](
size_t j) {
return j < i ? new_sigma->var(n + 1, j + 1) :
mem; }));
92 new_sigma->set(i + 1, rw.rewrite(sigma->op(i)));
94 return w.cn(new_sigma);
106 if (preserved_.contains(old_lam)) {
107 auto _ = fe::Restore(preserving_,
true);
112 map(old_lam, new_lam);
115 if (
auto n = old_lam->
num_vars(); n != 0) {
116 auto offset = new_lam->num_doms() - old_lam->
num_doms();
117 auto new_n = new_lam->num_vars();
118 for (
size_t i = 0; i != n; ++i)
126 if (!old_lam->
is_set())
return new_lam;
142 auto [_, k] = app->
args<2>();
143 return w.app(
rewrite(k), curr_mem_);
150 auto mem = curr_mem_;
154 auto new_pi = new_callee->
type()->isa<
Pi>();
155 if (old_pi && new_pi && new_pi->
num_doms() == old_pi->num_doms() + 1) {
157 new_arg = w.tuple(
Def::cat(
mem, new_arg->projs(old_pi->num_doms())));
160 auto new_app = w.app(new_callee, new_arg);
161 advance_mem(new_app);
176 auto rank = [](
const Def* op) {
177 if (!op->type())
return 0;
182 auto n =
tuple->num_ops();
184 for (
int r = 0; r != 3; ++r)
185 for (
size_t i = 0; i != n; ++i)
190void AddMem::advance_mem(
const Def* def) {
191 if (
auto m =
mem_def(def)) curr_mem_ = m;
auto args(Projector auto f) const noexcept
const Def * callee() const
A (possibly paramterized) Array.
static auto isa(const Def *def)
Def * set(size_t i, const Def *)
Successively set from left to right.
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
static DefVec cat(Defs a, Defs b)
DbgKey dbg_key() const
Cheap handle for other->set(this->dbg_key()).
const Def * var(nat_t a, nat_t i) noexcept
nat_t num_vars() noexcept
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
const T * isa_imm() const
const Def * filter() const
Lam * set(Filter filter, const Def *body)
nat_t num_doms() const noexcept
A dependent function type.
static const Pi * isa_cn(const Def *d)
nat_t num_doms() const noexcept
World & new_world()
Create new Defs into this.
World & old_world()
Get old Defs from here.
virtual const Def * rewrite_imm_Seq(const Seq *seq)
virtual const Def * rewrite_imm_Tuple(const Tuple *)
const Def * map(const Def *old_def, const Def *new_def)
virtual const Def * rewrite_mut_Lam(Lam *)
virtual const Def * rewrite_imm_Sigma(const Sigma *)
virtual const Def * rewrite_imm_Pi(const Pi *)
virtual const Def * rewrite(const Def *)
virtual const Def * rewrite_imm_App(const App *)
Data constructor for a Sigma.
VarRewriter(World &world)
Lam * mut_lam(const Pi *pi)
bool analyze() final
Runs the optional pre-analysis on old_world(), typically to a fixed point, before rewriting begins.
const Def * rewrite_imm_Tuple(const Tuple *) override
const Def * rewrite_imm_Pi(const Pi *) override
const Def * rewrite(const Def *) override
const Def * rewrite_mut_Lam(Lam *) override
const Def * rewrite_imm_App(const App *) override
bool has_leading_mem(const Pi *pi)
Does pi already thread memory - a leading mem.M, either directly or grouped as the first component of...
const Def * mem_var(Lam *lam)
Returns the memory argument of a function if it has one.
const Def * mem_def(const Def *def)
Returns the (first) element of type mem.M a from the given tuple.
const App * isa_mem(const Def *def)
If def is a mem.M-typed value, yields its memory type mem.M a; otherwise nullptr.
fe::Vector< const Def * > DefVec