MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
rewrite.cpp
Go to the documentation of this file.
1#include "mim/rewrite.h"
2
3#include <fe/assert.h>
4
5#include "mim/driver.h"
6#include "mim/world.h"
7
8// Don't use fancy C++-lambdas; it's way too annoying stepping through them in a debugger.
9
10namespace mim {
11
12/*
13 * Rewriter
14 */
15
17 : world_(&world) {
18 push(); // create root map
19}
20
21Rewriter::~Rewriter() = default;
22
24 pop();
25 assert(scopes_.empty());
26 push();
27}
28
29const Def* Rewriter::map(const Def* old_def, const Def* new_def) {
30 for (size_t i = scopes_.size(); i-- != 1;)
31 if (auto& scope = scopes_[i];
32 old_def->has_free_vars_in(scope.old_vars) || new_def->has_free_vars_in(scope.new_vars)) {
33 // A binder rebuilt in here takes its Var - and what depends on it - along.
34 if (auto var = old_def->has_var()) scope.old_vars = old_def->world().vars().insert(scope.old_vars, var);
35 return scope.old2new[old_def] = new_def;
36 }
37 return scopes_.front().old2new[old_def] = new_def;
38}
39
40void Rewriter::bind_old(const Var* var) {
41 if (var) scopes_.back().old_vars = var->world().vars().insert(scopes_.back().old_vars, var);
42}
43
44void Rewriter::bind_new(const Var* var) {
45 if (var) scopes_.back().new_vars = var->world().vars().insert(scopes_.back().new_vars, var);
46}
47
48const Def* Rewriter::map(const Def* old_def, Defs new_defs) {
49 auto new_tuple = world().tuple(new_defs);
50 return map(old_def, new_tuple);
51}
52const Def* Rewriter::map(Defs old_defs, const Def* new_def) {
53 auto old_tuple = world().tuple(old_defs);
54 return map(old_tuple, new_def);
55}
56const Def* Rewriter::map(Defs old_defs, Defs new_defs) {
57 auto old_tuple = world().tuple(old_defs);
58 auto new_tuple = world().tuple(new_defs);
59 return map(old_tuple, new_tuple);
60}
61
62const Def* Rewriter::rewrite(const Def* old_def) {
63 if (auto new_def = lookup(old_def)) return new_def;
64
65 auto new_def = old_def->isa_mut() ? rewrite_mut((Def*)old_def) : rewrite_imm(old_def);
66 return new_def->set(old_def->dbg_key());
67}
68
69// clang-format off
70#define CODE_MUT(N) case Node::N: new_def = rewrite_mut_##N(old_mut->as<N>()); break;
71#define CODE_IMM(N) case Node::N: new_def = rewrite_imm_##N(old_def->as<N>()); break;
72// clang-format on
73
74const Def* Rewriter::rewrite_imm(const Def* old_def) {
75 const Def* new_def;
76 switch (old_def->node()) {
78 default: std::unreachable();
79 }
80 return map(old_def, new_def);
81}
82
83const Def* Rewriter::rewrite_mut(Def* old_mut) {
84 const Def* new_def;
85 switch (old_mut->node()) {
87 default: std::unreachable();
88 }
89 return new_def;
90}
91
92#undef CODE_MUT
93#undef CODE_IMM
94
96 auto new_ops = DefVec(ops.size());
97 for (size_t i = 0, e = ops.size(); i != e; ++i)
98 new_ops[i] = rewrite(ops[i]);
99 return new_ops;
100}
101
102#ifndef DOXYGEN
103// clang-format off
104const Def* Rewriter::rewrite_imm_Idx (const Idx* ) { return world().type_idx(); }
105const Def* Rewriter::rewrite_imm_Nat (const Nat* ) { return world().type_nat(); }
106const Def* Rewriter::rewrite_imm_Level (const Level* ) { return world().type_level(); }
107const Def* Rewriter::rewrite_imm_Lit (const Lit* d) { return world().lit (rewrite(d->type()), d->get()); }
108const Def* Rewriter::rewrite_imm_Match (const Match* d) { return world().match (rewrite(d->ops())); }
109const Def* Rewriter::rewrite_imm_Reform (const Reform* d) { return world().reform (rewrite(d->dom())); }
110const Def* Rewriter::rewrite_imm_Sigma (const Sigma* d) { return world().sigma (rewrite(d->ops())); }
111const Def* Rewriter::rewrite_imm_Type (const Type* d) { return world().type (rewrite(d->level())); }
112const Def* Rewriter::rewrite_imm_LSucc (const LSucc* d) { return world().lsucc (rewrite(d->op()), d->offset()); }
113const Def* Rewriter::rewrite_imm_LMax (const LMax* d) { return world().lmax (rewrite(d->ops())); }
114const Def* Rewriter::rewrite_imm_Single (const Single* d) { return world().single (rewrite(d->op())); }
115const Def* Rewriter::rewrite_imm_Wrap (const Wrap* d) { return world().wrap (rewrite(d->op())); }
116const Def* Rewriter::rewrite_imm_Nom (const Nom* d) { return world().nom (d->key(), rewrite(d->op())); }
117const Def* Rewriter::rewrite_imm_Name (const Name* d) { return world().name (rewrite(d->nom()), rewrite(d->op())); }
118const Def* Rewriter::rewrite_imm_Struc (const Struc* d) { return world().struc (rewrite(d->op())); }
119const Def* Rewriter::rewrite_imm_Var (const Var* d) { return world().var (rewrite(d->binder())->as_mut()); }
120const Def* Rewriter::rewrite_imm_Top (const Top* d) { return world().top (rewrite(d->type())); }
121const Def* Rewriter::rewrite_imm_Bot (const Bot* d) { return world().bot (rewrite(d->type())); }
122const Def* Rewriter::rewrite_imm_Join (const Join* d) { return world().join (rewrite(d->ops())); }
123const Def* Rewriter::rewrite_imm_Variant(const Variant* d) { return world().variant(rewrite(d->ops())); }
124
125const Def* Rewriter::rewrite_imm_Arr (const Arr* d) { return rewrite_imm_Seq(d); }
126const Def* Rewriter::rewrite_imm_Pack(const Pack* d) { return rewrite_imm_Seq(d); }
127const Def* Rewriter::rewrite_mut_Arr ( Arr* d) { return rewrite_mut_Seq(d); }
128const Def* Rewriter::rewrite_mut_Pack( Pack* d) { return rewrite_mut_Seq(d); }
129// clang-format on
130
131const Def* Rewriter::rewrite_imm_App(const App* d) {
132 // Rewrite the arg before the callee:
133 // the callee may be a recursive mutable that, when rewritten first, eagerly expands its body before the concrete
134 // argument is available to specialize it, breaking partial-evaluation termination
135 auto new_arg = rewrite(d->arg());
136 auto new_callee = rewrite(d->callee());
137 return world().app(new_callee, new_arg);
138}
139
140const Def* Rewriter::rewrite_imm_Inj(const Inj* d) {
141 auto new_type = rewrite(d->type());
142 auto new_value = rewrite(d->value());
143 if (d->type()->isa<Variant>()) return world().inj(new_type, d->index(), new_value);
144 return world().inj(new_type, new_value);
145}
146
147const Def* Rewriter::rewrite_imm_Insert(const Insert* d) {
148 auto new_tuple = rewrite(d->tuple());
149 auto new_index = rewrite(d->index());
150 auto new_value = rewrite(d->value());
151 return world().insert(new_tuple, new_index, new_value);
152}
153
154const Def* Rewriter::rewrite_imm_Lam(const Lam* d) {
155 auto new_type = rewrite(d->type())->as<Pi>();
156 auto new_filter = rewrite(d->filter());
157 auto new_body = rewrite(d->body());
158 return world().lam(new_type, new_filter, new_body);
159}
160
161const Def* Rewriter::rewrite_imm_Pi(const Pi* d) {
162 auto new_dom = rewrite(d->dom());
163 auto new_codom = rewrite(d->codom());
164 return world().pi(new_dom, new_codom, d->is_implicit());
165}
166
167const Def* Rewriter::rewrite_imm_Proxy(const Proxy* d) {
168 auto new_type = rewrite(d->type());
169 auto new_ops = rewrite(d->ops());
170 return world().proxy(new_type, new_ops, d->tag(), d->tracks_vars(), d->tracks_muts());
171}
172
173const Def* Rewriter::rewrite_imm_Rule(const Rule* d) {
174 auto new_type = rewrite(d->type())->as<Reform>();
175 auto new_lhs = rewrite(d->lhs());
176 auto new_rhs = rewrite(d->rhs());
177 auto new_guard = rewrite(d->guard());
178 return world().rule(new_type, new_lhs, new_rhs, new_guard);
179}
180
181const Def* Rewriter::rewrite_imm_Tuple(const Tuple* d) {
182 auto new_type = rewrite(d->type());
183 auto new_ops = rewrite(d->ops());
184 return world().tuple(new_type, new_ops);
185}
186
187const Def* Rewriter::rewrite_mut_Lam(Lam* d) { return rewrite_stub(d, world().mut_lam(rewrite(d->type())->as<Pi>())); }
189 return rewrite_stub(d, world().mut_rule(rewrite(d->type())->as<Reform>()));
190}
191
193 return rewrite_stub(d, world().mut_pi(rewrite(d->type()), d->is_implicit()));
194}
195
197 return rewrite_stub(d, world().mut_sigma(rewrite(d->type()), d->num_ops()));
198}
199
201 return rewrite_stub(d, world().mut_variant(rewrite(d->type()), d->num_ops()));
202}
203
204const Def* Rewriter::rewrite_imm_Axm(const Axm* a) {
205 if (&a->world() != &world()) {
206 auto type = rewrite(a->type());
207 return world().axm(a->normalizer(), a->curry(), a->trip(), type, a->plugin(), a->tag(), a->sub());
208 }
209 return a;
210}
211
212const Def* Rewriter::rewrite_imm_Extract(const Extract* ex) {
213 auto new_index = rewrite(ex->index());
214 if (auto index = Lit::isa(new_index)) {
215 if (auto tuple = ex->tuple()->isa<Tuple>()) return rewrite(tuple->op(*index));
216 if (auto pack = ex->tuple()->isa_imm<Pack>(); pack && pack->arity()->is_closed()) return rewrite(pack->body());
217 }
218
219 auto new_tuple = rewrite(ex->tuple());
220 return world().extract(new_tuple, new_index);
221}
222
223const Def* Rewriter::rewrite_mut_Hole(Hole* hole) {
224 auto [last, op] = hole->find();
225 return op ? rewrite(op) : rewrite_stub(last, world().mut_hole(rewrite(last->type())));
226}
227
228#endif
229
231 auto new_shape = rewrite(*seq->shape());
232 if (auto l = Lit::isa(new_shape); l && *l == 0) return world().prod(seq->is_intro());
233 return world().seq(seq->is_intro(), new_shape, rewrite(seq->body()));
234}
235
237 if (!seq->is_set()) return rewrite_stub(seq, world().mut_seq(seq->is_intro(), rewrite(seq->type())));
238
239 auto new_shape = rewrite(*seq->shape())->zonk();
240 auto l = seq->shape().is_fused() ? std::nullopt : Lit::isa(new_shape);
241 if (l && *l == 0) return world().prod(seq->is_intro());
242
243 if (auto var = seq->has_var(); var && l && *l < world().flags().scalarize_threshold) {
244 auto new_ops = fe::Vector<const Def*, 32>(*l);
245 for (size_t i = 0, e = *l; i != e; ++i) {
246 push(Vars(var));
247 map(var, world().lit_idx(e, i));
248 new_ops[i] = rewrite(seq->body());
249 pop();
250 }
251 return map(seq, world().prod(seq->is_intro(), new_ops));
252 }
253
254 return rewrite_stub(seq, world().mut_seq(seq->is_intro(), rewrite(seq->type())));
255}
256
257const Def* Rewriter::rewrite_stub(Def* old_mut, Def* new_mut) {
258 map(old_mut, new_mut);
259 if (!old_mut->is_set()) return new_mut;
260
261 auto _ = enter(old_mut);
262 for (size_t i = 0, e = old_mut->num_ops(); i != e; ++i)
263 new_mut->set(i, rewrite(old_mut->op(i)));
264
265 return seal(old_mut, new_mut);
266}
267
268const Def* Rewriter::rewrite_stub(Def* old_mut, Def* new_mut, fe::View<size_t> new2old) {
269 assert(new_mut->num_ops() == new2old.size());
270 map(old_mut, new_mut);
271 if (!old_mut->is_set()) return new_mut;
272
273 auto _ = enter(old_mut);
274 for (size_t i = 0, e = new2old.size(); i != e; ++i)
275 new_mut->set(i, rewrite(old_mut->op(new2old[i])));
276
277 return seal(old_mut, new_mut);
278}
279
280const Def* Rewriter::seal(Def* old_mut, Def* new_mut) {
281 // A stub that something already captured must stay, or the capture and its users disagree on which Def it is.
282 if (new_mut->users().empty() && new_mut->is_immutabilizable())
283 if (auto new_imm = new_mut->immutabilize()) return map(old_mut, new_imm);
284 return new_mut;
285}
286
287/*
288 * VarRewriter
289 */
290
291const Def* VarRewriter::rewrite(const Def* old_def) {
292 // Only Vars, mutables and non-ground immutables are ever mapped, so a ground immutable needs no lookup.
293 if (!old_def->isa_mut() && old_def->local_vars().empty() && old_def->local_muts().empty()) return old_def;
294 if (auto new_def = lookup(old_def)) return new_def;
295
296 if (auto old_mut = old_def->isa_mut())
297 return has_intersection(old_mut) ? rewrite_mut(old_mut)->set(old_mut->dbg_key()) : old_mut;
298
299 return has_intersection(old_def) ? rewrite_imm(old_def)->set(old_def->dbg_key()) : old_def;
300}
301
303 bind_old(mut->has_var());
304 return Rewriter::rewrite_mut(mut);
305}
306
307/*
308 * Zonker
309 */
310
311const Def* Zonker::lookup(const Def* old_def) {
312 // Holes only ever get set, so a cached result goes stale once a Hole within it got set since.
313 // A self-map is a fixpoint, though: e.g. `binder#i` keeps a set Hole in its type until the binder is rewired.
314 if (auto new_def = fe::lookup(old2new(), old_def);
315 new_def && (new_def == old_def || new_def->isa_mut() || !new_def->needs_zonk()))
316 return new_def;
317 return nullptr;
318}
319
320const Def* Zonker::rewrite(const Def* def) {
321 if (auto hole = def->isa_mut<Hole>()) {
322 auto [last, op] = hole->find();
323 def = op ? op : last;
324 }
325
326 return def->needs_zonk() ? Rewriter::rewrite(def) : def;
327}
328
330 map(mut, mut);
331
332 auto old_type = mut->type();
333 auto old_ops = DefVec(mut->ops().begin(), mut->ops().end());
334
335 mut->unset()->set_type(rewrite(old_type));
336
337 for (size_t i = 0, e = mut->num_ops(); i != e; ++i)
338 mut->set(i, rewrite(old_ops[i]));
339
340 if (auto new_imm = mut->immutabilize()) return map(mut, new_imm);
341
342 return mut;
343}
344
345/*
346 * Importer
347 */
348
349const Def* Importer::rewrite(const Def* def) {
350 if (auto new_def = lookup(def)) return new_def;
351 if (auto flags = world().driver().library()->annexes().flags(def)) return map(def, world().annex(*flags));
352 return Rewriter::rewrite(def);
353}
354
355} // namespace mim
A (possibly paramterized) Array.
Definition tuple.h:305
Definition axm.h:9
Base class for all Defs.
Definition def.h:289
bool is_set() const
Definition def.h:396
constexpr Node node() const noexcept
Definition def.h:315
Def * set(size_t i, const Def *)
Successively set from left to right.
Definition def.cpp:188
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition def.h:597
const Def * zonk() const
If Holes have been filled, reconstruct the program without them.
Definition check.cpp:20
World & world() const noexcept
Definition def.h:1105
Def * set_type(const Def *)
Update type.
Definition def.cpp:199
bool is_intro() const noexcept
Definition def.h:347
constexpr auto ops() const noexcept
Definition def.h:374
Vars local_vars() const
Vars reachable by following immutable deps().
Definition def.h:527
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:588
const Def * op(size_t i) const noexcept
Definition def.h:377
DbgKey dbg_key() const
Cheap handle for other->set(this->dbg_key()).
Definition def.h:631
bool is_immutabilizable()
Definition def.cpp:131
Muts local_muts() const
Mutables reachable by following immutable deps(); mut->local_muts() is by definition the set { mut }...
Definition def.h:520
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:1119
const Def * immutabilize()
Definition def.cpp:567
Def * unset()
Unsets all Def::ops; works even, if not set at all or only partially set.
Definition def.cpp:205
bool needs_zonk() const
Yields true, if Def::local_muts() contain a Hole that is set.
Definition check.cpp:11
Muts users()
Set of mutables where this mutable is locally referenced.
Definition def.h:533
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
Definition def.h:496
bool has_free_vars_in(Vars) const
Same as vars.has_intersection(free_vars()).
Definition def.cpp:285
constexpr size_t num_ops() const noexcept
Definition def.h:378
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:360
This node is a hole in the IR that is inferred by its context later on.
Definition check.h:16
A built-in constant of type Nat -> *.
Definition def.h:1013
const Def * rewrite(const Def *) final
Definition rewrite.cpp:349
Constructs a Join or Variant value.
Definition union.h:60
Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
Definition tuple.h:385
A union type whose ops are sorted and deduplicated: T ∪ T is T.
Definition union.h:44
A function.
Definition lam.h:91
static std::optional< T > isa(const Def *def)
Definition def.h:976
Scrutinize Match::scrutinee() and dispatch to Match::arms.
Definition union.h:123
Nominal newtype term introduction.
Definition nom.h:34
Nominal newtype formation.
Definition nom.h:11
A (possibly paramterized) Tuple.
Definition tuple.h:332
A dependent function type.
Definition lam.h:14
Used as intermediate value during optimizatinos such as Analysis.
Definition def.h:1065
Type formation of a rewrite Rule.
Definition rule.h:9
fe::Vector< Scope > scopes_
Definition rewrite.h:127
bool has_intersection(const Def *old_def)
Does old_def depend on the old Vars of any scope?
Definition rewrite.h:107
virtual const Def * rewrite_imm_Top(const Top *)
virtual const Def * rewrite_imm_Join(const Join *)
virtual const Def * rewrite_imm_Match(const Match *)
void bind_old(const Var *var)
Adds the old var - if any - to the innermost scope.
Definition rewrite.cpp:40
void pop()
Definition rewrite.h:41
virtual const Def * rewrite_imm_Seq(const Seq *seq)
Definition rewrite.cpp:230
virtual const Def * rewrite_imm_Extract(const Extract *)
virtual const Def * rewrite_imm_LSucc(const LSucc *)
virtual const Def * rewrite_imm_Wrap(const Wrap *)
virtual const Def * rewrite_mut_Sigma(Sigma *)
virtual const Def * rewrite_imm_Arr(const Arr *)
virtual const Def * rewrite_imm_Insert(const Insert *)
virtual const Def * rewrite_imm_Pack(const Pack *)
virtual const Def * rewrite_mut_Seq(Seq *seq)
Definition rewrite.cpp:236
World & world()
Definition rewrite.h:33
virtual const Def * rewrite_mut(Def *)
Definition rewrite.cpp:83
virtual const Def * rewrite_mut_Variant(Variant *)
virtual const Def * rewrite_mut_Hole(Hole *)
virtual const Def * rewrite_imm_Proxy(const Proxy *)
virtual const Def * rewrite_imm_Name(const Name *)
virtual const Def * rewrite_imm_Tuple(const Tuple *)
virtual const Def * rewrite_stub(Def *, Def *)
Definition rewrite.cpp:257
const Def * map(const Def *old_def, const Def *new_def)
Definition rewrite.cpp:29
virtual const Def * rewrite_mut_Lam(Lam *)
virtual const Def * rewrite_imm_Struc(const Struc *)
Rewriter(World &world)
Definition rewrite.cpp:16
virtual ~Rewriter()
virtual const Def * rewrite_imm_Axm(const Axm *)
virtual const Def * rewrite_imm_Sigma(const Sigma *)
void bind_new(const Var *var)
Adds the new var - if any - to the innermost scope.
Definition rewrite.cpp:44
virtual const Def * rewrite_imm_Nom(const Nom *)
virtual const Def * rewrite_imm_Type(const Type *)
virtual const Def * rewrite_mut_Arr(Arr *)
virtual const Def * rewrite_imm_Single(const Single *)
virtual const Def * rewrite_imm_Var(const Var *)
virtual const Def * rewrite_imm_Reform(const Reform *)
virtual const Def * rewrite_imm_Pi(const Pi *)
virtual const Def * rewrite_imm_Inj(const Inj *)
const Def * seal(Def *old_mut, Def *new_mut)
The tail of rewrite_stub: immutabilizes new_mut in hindsight, as rewriting may have made it vacuous.
Definition rewrite.cpp:280
void reset()
Definition rewrite.cpp:23
virtual const Def * rewrite_mut_Pack(Pack *)
virtual const Def * rewrite_imm_Bot(const Bot *)
virtual const Def * rewrite_imm(const Def *)
Definition rewrite.cpp:74
virtual const Def * rewrite_imm_Idx(const Idx *)
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:62
virtual const Def * rewrite_imm_App(const App *)
virtual const Def * rewrite_imm_LMax(const LMax *)
auto enter(Def *new_mut)
Updates curr_mut() to new_mut and restores it at the end of the scope.
Definition rewrite.h:115
virtual const Def * rewrite_mut_Rule(Rule *)
virtual const Def * rewrite_imm_Level(const Level *)
void push(Vars old_vars={}, Vars new_vars={})
Definition rewrite.h:40
Def2Def & old2new()
The map of the innermost push() scope.
Definition rewrite.h:104
virtual const Def * rewrite_imm_Nat(const Nat *)
virtual const Def * lookup(const Def *old_def)
Lookup old_def by searching in reverse through the stack of maps.
Definition rewrite.h:66
virtual const Def * rewrite_imm_Lit(const Lit *)
virtual const Def * rewrite_imm_Rule(const Rule *)
virtual const Def * rewrite_mut_Pi(Pi *)
virtual const Def * rewrite_imm_Lam(const Lam *)
virtual const Def * rewrite_imm_Variant(const Variant *)
A rewrite rule.
Definition rule.h:40
Base class for Arr and Pack.
Definition tuple.h:267
const Def * body() const
Definition tuple.h:280
Shape shape() const
Definition tuple.h:279
bool is_fused() const
Does this span several axes? Also true for a dynamic rank.
Definition tuple.h:211
A dependent tuple type.
Definition tuple.h:39
Singleton type formation.
Definition single.h:10
Nominal newtype term elimination.
Definition nom.h:56
Data constructor for a Sigma.
Definition tuple.h:84
const Def * rewrite_mut(Def *) final
Definition rewrite.cpp:302
const Def * rewrite(const Def *) final
Definition rewrite.cpp:291
A variable introduced by a binder (mutable).
Definition def.h:857
A sum type whose cases are positional: unlike a Join, they are neither sorted nor deduplicated.
Definition union.h:86
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:43
const Def * insert(const Def *d, const Def *i, const Def *val)
Definition world.cpp:802
const Def * variant(Defs ops)
Definition world.cpp:1023
const Lit * lit(const Def *type, u64 val)
Definition world.cpp:919
const Def * struc(const Def *nom)
Get the structural part of a nominal.
Definition world.cpp:1150
const Type * type(const Def *level)
Definition world.cpp:235
const Def * lsucc(const Def *op, level_t offset=1)
Definition world.cpp:247
const Def * sigma(Defs ops)
Definition world.cpp:506
const Def * app(const Def *callee, const Def *arg)
Definition world.cpp:416
const Def * match(Defs)
Definition world.cpp:1030
const Def * seq(bool is_pack, Shape shape, const Def *body)
Definition world.cpp:887
const Pi * pi(const Def *dom, const Def *codom, bool implicit=false)
Definition world.h:386
const Def * bot(const Def *type)
Definition world.h:604
const Def * single(const Def *)
Singleton type formation.
Definition world.cpp:1114
const Idx * type_idx()
Definition world.h:623
Sym name() const
Definition world.h:113
const Reform * reform(const Def *dom)
Definition world.h:442
const Nat * type_nat()
Definition world.h:622
const Lam * lam(const Pi *pi, Lam::Filter f, const Def *body)
Definition world.h:414
const Def * tuple(Defs ops)
Definition world.cpp:516
const Def * lmax(Defs levels)
Definition world.cpp:260
const Def * inj(const Def *type, const Def *value)
Definition world.cpp:975
const Axm * axm(NormalizeFn n, u8 curry, u8 trip, const Def *type, plugin_t p, tag_t t, sub_t s)
Definition world.h:368
const Def * extract(const Def *d, const Def *i)
Definition world.cpp:598
const Proxy * proxy(const Def *type, Defs ops, u32 tag, bool vars=false, bool muts=false)
Definition world.h:357
const Def * join(Defs ops)
Definition world.cpp:948
const Def * var(Def *mut)
Definition world.cpp:392
const Nom * nom(flags_t key, const Def *type)
Make type Nominal under key.
Definition world.cpp:1134
const Def * prod(bool term, Defs ops)
Definition world.h:497
const Def * wrap(const Def *)
Singleton term introduction.
Definition world.cpp:1123
const Def * top(const Def *type)
Definition world.h:605
auto & vars()
Definition world.h:714
const Rule * rule(const Reform *type, const Def *lhs, const Def *rhs, const Def *guard)
Definition world.h:444
const Level * type_level()
Definition world.h:319
Singleton term introduction.
Definition single.h:32
const Def * rewire_mut(Def *)
Definition rewrite.cpp:329
const Def * lookup(const Def *old_def) final
Lookup old_def by searching in reverse through the stack of maps.
Definition rewrite.cpp:311
const Def * rewrite(const Def *) final
Definition rewrite.cpp:320
#define MIM_MUT_NODE(X)
Definition def.h:65
#define MIM_IMM_NODE(X)
Definition def.h:47
Definition ast.h:16
fe::View< const Def * > Defs
Definition def.h:96
TExt< true > Top
Definition union.h:40
fe::Vector< const Def * > DefVec
Definition def.h:98
fe::Patricia< const Var, DefKey >::Set Vars
Definition def.h:115
TExt< false > Bot
Definition union.h:39
@ Pi
Definition def.h:125
@ Reform
Definition def.h:125
#define CODE_MUT(N)
Definition phase.h:288
#define CODE_IMM(N)
Definition rewrite.h:86