MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
world.cpp
Go to the documentation of this file.
1#include "mim/world.h"
2
3#include <string>
4
5#include "mim/check.h"
6#include "mim/def.h"
7#include "mim/driver.h"
8#include "mim/rewrite.h"
9#include "mim/tuple.h"
10
11#include "mim/util/util.h"
12
13namespace mim {
14
15namespace {
16bool is_shape(const Def* s) {
17 if (s->isa<Nat>()) return true;
18 if (auto arr = s->isa<Arr>()) return arr->body()->isa<Nat>();
19 if (auto sig = s->isa_imm<Sigma>())
20 return std::ranges::all_of(sig->ops(), [](const Def* op) { return op->isa<Nat>(); });
21
22 return false;
23}
24
25} // namespace
26
27/*
28 * constructor & destructor
29 */
30
31#if (!defined(_MSC_VER) && defined(NDEBUG))
32bool World::Lock::guard_ = false;
33#endif
34
36 : driver_(driver)
37 , state_(state) {
38 data_.univ = insert<Univ>(0, *this);
39 data_.lit_univ_0 = lit_univ(0);
40 data_.lit_univ_1 = lit_univ(1);
41 data_.type_0 = type(lit_univ_0());
42 data_.type_1 = type(lit_univ_1());
43 data_.type_bot = insert<Bot>(0, type());
44 data_.type_top = insert<Top>(0, type());
45 data_.sigma = insert<Sigma>(0, type(), Defs{})->as<Sigma>();
46 data_.tuple = insert<Tuple>(0, sigma(), Defs{})->as<Tuple>();
47 data_.type_nat = insert<mim::Nat>(0, *this);
48 data_.type_idx = insert<mim::Idx>(0, pi(type_nat(), type()));
49 data_.top_nat = insert<Top>(0, type_nat());
50 data_.lit_nat_0 = lit_nat(0);
51 data_.lit_nat_1 = lit_nat(1);
52 data_.lit_0_1 = lit_idx(1, 0);
53 data_.type_bool = type_idx(2);
54 data_.lit_bool[0] = lit_idx(2, 0_u64);
55 data_.lit_bool[1] = lit_idx(2, 1_u64);
56 data_.lit_nat_max = lit_nat(nat_t(-1));
57}
58
61
63 for (auto def : move_.defs) def->~Def();
64}
65
66/*
67 * Driver
68 */
69
70Log& World::log() { return driver().log(); }
71Flags& World::flags() { return driver().flags(); }
72
73Sym World::sym(const char* s) { return driver().sym(s); }
74Sym World::sym(std::string_view s) { return driver().sym(s); }
75Sym World::sym(const std::string& s) { return driver().sym(s); }
76
77const Def* World::register_annex(flags_t f, const Def* def) {
78 DLOG("register: 0x{x} -> {}", f, def);
79 auto plugin = Annex::demangle(driver(), f);
80 if (driver().is_loaded(plugin)) {
81 assert_emplace(move_.flags2annex, f, def);
82 return def;
83 }
84 return nullptr;
85}
86
88 assert(!def->is_external());
89 assert(def->is_closed());
90 def->external_ = true;
91 assert_emplace(move_.sym2external, def->sym(), def);
92}
93
95 assert(def->is_external());
96 def->external_ = false;
97 auto num = move_.sym2external.erase(def->sym());
98 assert_unused(num == 1);
99}
100
101/*
102 * factory methods
103 */
104
105const Type* World::type(const Def* level) {
106 if (!level->type()->isa<Univ>())
107 error(level->loc(), "argument `{}` to `Type` must be of type `Univ` but is of type `{}`", level, level->type());
108
109 return unify<Type>(1, level)->as<Type>();
110}
111
112const Def* World::uinc(const Def* op, level_t offset) {
113 if (!op->type()->isa<Univ>())
114 error(op->loc(), "operand '{}' of a universe increment must be of type `Univ` but is of type `{}`", op,
115 op->type());
116
117 if (auto l = Lit::isa(op)) return lit_univ(*l + 1);
118 return unify<UInc>(1, op, offset);
119}
120
121template<Sort sort> const Def* World::umax(Defs ops_) {
122 // consume nested umax
123 DefVec ops;
124 for (auto op : ops_)
125 if (auto um = op->isa<UMax>())
126 ops.insert(ops.end(), um->ops().begin(), um->ops().end());
127 else
128 ops.emplace_back(op);
129
130 level_t lvl = 0;
131 for (auto& op : ops) {
132 const Def* r = op;
133 if (sort == Sort::Term) r = r->unfold_type();
134 if (sort <= Sort::Type) r = r->unfold_type();
135 if (sort <= Sort::Kind) {
136 if (auto type = r->isa<Type>())
137 r = type->level();
138 else
139 error(r->loc(), "operand '{}' must be a Type of some level", r);
140 }
141
142 if (!r->type()->isa<Univ>())
143 error(r->loc(), "operand '{}' of a universe max must be of type 'Univ' but is of type '{}'", r, r->type());
144
145 op = r;
146
147 if (auto l = Lit::isa(op))
148 lvl = std::max(lvl, *l);
149 else
150 lvl = level_t(-1);
151 }
152
153 const Def* ldef;
154 if (lvl != level_t(-1))
155 ldef = lit_univ(lvl);
156 else {
157 std::ranges::sort(ops, [](auto op1, auto op2) { return op1->gid() < op2->gid(); });
158 ops.erase(std::unique(ops.begin(), ops.end()), ops.end());
159 ldef = unify<UMax>(ops.size(), *this, ops);
160 }
161
162 return sort == Sort::Univ ? ldef : type(ldef);
163}
164
165// TODO more thorough & consistent checks for singleton types
166
167const Def* World::var(const Def* type, Def* mut) {
168 if (auto s = Idx::isa(type)) {
169 if (auto l = Lit::isa(s); l && l == 1) return lit_0_1();
170 }
171
172 if (auto var = mut->var_) return var;
173 return mut->var_ = unify<Var>(1, type, mut);
174}
175
176template<bool Normalize> const Def* World::implicit_app(const Def* callee, const Def* arg) {
177 while (auto pi = Pi::isa_implicit(callee->type())) callee = app(callee, mut_hole(pi->dom()));
178 return app<Normalize>(callee, arg);
179}
180
181template<bool Normalize> const Def* World::app(const Def* callee, const Def* arg) {
182 callee = callee->zonk();
183 arg = arg->zonk();
184 if (auto pi = callee->type()->isa<Pi>()) {
185 if (auto new_arg = Checker::assignable(pi->dom(), arg)) {
186 arg = new_arg->zonk();
187 if (auto imm = callee->isa_imm<Lam>()) return imm->body();
188 if (auto lam = callee->isa_mut<Lam>(); lam && lam->is_set() && lam->filter() != lit_ff()) {
189 auto rw = VarRewriter(lam->has_var(), arg);
190 if (rw.rewrite(lam->filter()) == lit_tt()) {
191 DLOG("partial evaluate: {} ({})", lam, arg);
192 return rw.rewrite(lam->body());
193 }
194 }
195
196 auto type = pi->reduce(arg)->zonk();
197 callee = callee->zonk();
198 auto [axiom, curry, trip] = Axiom::get(callee);
199 if (axiom) {
200 curry = curry == 0 ? trip : curry;
201 curry = curry == Axiom::Trip_End ? curry : curry - 1;
202
203 if (auto normalizer = axiom->normalizer(); Normalize && normalizer && curry == 0) {
204 if (auto norm = normalizer(type, callee, arg)) return norm;
205 }
206 }
207
208 return raw_app(axiom, curry, trip, type, callee, arg);
209 }
210
211 throw Error()
212 .error(arg->loc(), "cannot apply argument to callee")
213 .note(callee->loc(), "callee: '{}'", callee)
214 .note(arg->loc(), "argument: '{}'", arg)
215 .note(callee->loc(), "vvv domain type vvv\n'{}'\n'{}'", pi->dom(), arg->type())
216 .note(arg->loc(), "^^^ argument type ^^^");
217 }
218
219 throw Error()
220 .error(callee->loc(), "called expression not of function type")
221 .error(callee->loc(), "'{}' <--- callee type", callee->type());
222}
223
224const Def* World::raw_app(const Def* type, const Def* callee, const Def* arg) {
225 auto [axiom, curry, trip] = Axiom::get(callee);
226 if (axiom) {
227 curry = curry == 0 ? trip : curry;
228 curry = curry == Axiom::Trip_End ? curry : curry - 1;
229 }
230
231 return raw_app(axiom, curry, trip, type, callee, arg);
232}
233
234const Def* World::raw_app(const Axiom* axiom, u8 curry, u8 trip, const Def* type, const Def* callee, const Def* arg) {
235 return unify<App>(2, axiom, curry, trip, type, callee, arg);
236}
237
238const Def* World::sigma(Defs ops) {
239 auto n = ops.size();
240 if (n == 0) return sigma();
241 if (n == 1) return ops[0];
242 if (auto uni = Checker::is_uniform(ops)) return arr(n, uni);
243 return unify<Sigma>(ops.size(), Sigma::infer(*this, ops), ops);
244}
245
246const Def* World::tuple(Defs ops) {
247 auto n = ops.size();
248 if (n == 0) return tuple();
249 if (n == 1) return ops[0];
250
251 auto sigma = Tuple::infer(*this, ops);
252 auto t = tuple(sigma, ops);
253 auto new_t = Checker::assignable(sigma, t);
254 if (!new_t)
255 error(t->loc(), "cannot assign tuple '{}' of type '{}' to incompatible tuple type '{}'", t, t->type(), sigma);
256
257 return new_t;
258}
259
260const Def* World::tuple(const Def* type, Defs ops) {
261 // TODO type-check type vs inferred type
262
263 auto n = ops.size();
264 if (!type->isa_mut<Sigma>()) {
265 if (n == 0) return tuple();
266 if (n == 1) return ops[0];
267 if (auto uni = Checker::is_uniform(ops)) return pack(n, uni);
268 }
269
270 if (n != 0) {
271 // eta rule for tuples:
272 // (extract(tup, 0), extract(tup, 1), extract(tup, 2)) -> tup
273 if (auto extract = ops[0]->isa<Extract>()) {
274 auto tup = extract->tuple();
275 bool eta = tup->type() == type;
276 for (size_t i = 0; i != n && eta; ++i) {
277 if (auto extract = ops[i]->isa<Extract>()) {
278 if (auto index = Lit::isa(extract->index())) {
279 if (eta &= u64(i) == *index) {
280 eta &= extract->tuple() == tup;
281 continue;
282 }
283 }
284 }
285 eta = false;
286 }
287
288 if (eta) return tup;
289 }
290 }
291
292 return unify<Tuple>(ops.size(), type, ops);
293}
294
295const Def* World::tuple(Sym sym) {
296 DefVec defs;
297 std::ranges::transform(sym, std::back_inserter(defs), [this](auto c) { return lit_i8(c); });
298 return tuple(defs);
299}
300
301const Def* World::extract(const Def* d, const Def* index) {
302 if (index->isa<Tuple>()) {
303 auto n = index->num_ops();
304 auto idx = DefVec(n, [&](size_t i) { return index->op(i); });
305 auto ops = DefVec(n, [&](size_t i) { return d->proj(n, Lit::as(idx[i])); });
306 return tuple(ops);
307 } else if (index->isa<Pack>()) {
308 auto ops = DefVec(index->as_lit_arity(), [&](size_t) { return extract(d, index->ops().back()); });
309 return tuple(ops);
310 }
311
312 const Def* size = Idx::isa(index->type());
313 const Def* type = d->unfold_type()->zonk();
314
315 if (auto l = Lit::isa(size); l && *l == 1) {
316 if (auto l = Lit::isa(index); !l || *l != 0) WLOG("unknown Idx of size 1: {}", index);
317 if (auto sigma = type->isa_mut<Sigma>(); sigma && sigma->num_ops() == 1) {
318 // mut sigmas can be 1-tuples; TODO mutables Arr?
319 } else {
320 return d;
321 }
322 }
323
324 if (auto pack = d->isa_imm<Pack>()) return pack->body();
325
326 if (!Checker::alpha<Checker::Check>(type->arity(), size))
327 error(index->loc(), "index '{}' does not fit within arity '{}'", index, type->arity());
328
329 // extract(insert(x, index, val), index) -> val
330 if (auto insert = d->isa<Insert>()) {
331 if (index == insert->index()) return insert->value();
332 }
333
334 if (auto i = Lit::isa(index)) {
335 if (auto hole = d->isa_mut<Hole>()) d = hole->tuplefy();
336 if (auto tuple = d->isa<Tuple>()) return tuple->op(*i);
337
338 // extract(insert(x, j, val), i) -> extract(x, i) where i != j (guaranteed by rule above)
339 if (auto insert = d->isa<Insert>()) {
340 if (insert->index()->isa<Lit>()) return extract(insert->tuple(), index);
341 }
342
343 if (auto sigma = type->isa<Sigma>()) {
344 if (auto mut_sigma = sigma->isa_mut<Sigma>()) {
345 auto t = VarRewriter(mut_sigma->has_var(), d).rewrite(sigma->op(*i));
346 return unify<Extract>(2, t, d, index);
347 }
348
349 return unify<Extract>(2, sigma->op(*i), d, index);
350 }
351 }
352
353 const Def* elem_t;
354 if (auto arr = type->isa<Arr>())
355 elem_t = arr->reduce(index);
356 else
357 elem_t = extract(tuple(type->as<Sigma>()->ops()), index);
358
359 assert(d);
360 return unify<Extract>(2, elem_t, d, index);
361}
362
363const Def* World::insert(const Def* d, const Def* index, const Def* val) {
364 auto type = d->unfold_type();
365 auto size = Idx::isa(index->type());
366 auto lidx = Lit::isa(index);
367
368 if (!Checker::alpha<Checker::Check>(type->arity(), size))
369 error(index->loc(), "index '{}' does not fit within arity '{}'", index, type->arity());
370
371 if (lidx) {
372 auto elem_type = type->proj(*lidx);
373 auto new_val = Checker::assignable(elem_type, val);
374 if (!new_val) {
375 throw Error()
376 .error(val->loc(), "value to be inserted not assignable to element")
377 .note(val->loc(), "vvv value type vvv \n'{}'\n'{}'", val->type(), elem_type)
378 .note(val->loc(), "^^^ element type ^^^", elem_type);
379 }
380 val = new_val;
381 }
382
383 if (auto l = Lit::isa(size); l && *l == 1)
384 return tuple(d, {val}); // d could be mut - that's why the tuple ctor is needed
385
386 // insert((a, b, c, d), 2, x) -> (a, b, x, d)
387 if (auto t = d->isa<Tuple>(); t && lidx) return t->refine(*lidx, val);
388
389 // insert(‹4; x›, 2, y) -> (x, x, y, x)
390 if (auto pack = d->isa<Pack>(); pack && lidx) {
391 if (auto a = pack->isa_lit_arity(); a && *a < flags().scalarize_threshold) {
392 auto new_ops = DefVec(*a, pack->body());
393 new_ops[*lidx] = val;
394 return tuple(type, new_ops);
395 }
396 }
397
398 // insert(insert(x, index, y), index, val) -> insert(x, index, val)
399 if (auto insert = d->isa<Insert>()) {
400 if (insert->index() == index) d = insert->tuple();
401 }
402
403 return unify<Insert>(3, d, index, val);
404}
405
406// TODO merge this code with pack
407const Def* World::arr(const Def* shape, const Def* body) {
408 if (!is_shape(shape->type())) error(shape->loc(), "expected shape but got '{}' of type '{}'", shape, shape->type());
409
410 if (auto a = Lit::isa(shape)) {
411 if (*a == 0) return sigma();
412 if (*a == 1) return body;
413 }
414
415 // «(a, b)#i; T» -> («a, T», <b, T»)#i
416 if (auto ex = shape->isa<Extract>()) {
417 if (auto tup = ex->tuple()->isa<Tuple>()) {
418 auto arrs = DefVec(tup->num_ops(), [&](size_t i) { return arr(tup->op(i), body); });
419 return extract(tuple(arrs), ex->index());
420 }
421 }
422
423 // «(a, b, c); body» -> «a; «(b, c); body»»
424 if (auto tuple = shape->isa<Tuple>()) return arr(tuple->ops().front(), arr(tuple->ops().subspan(1), body));
425
426 // «<n; x>; body» -> «x; «<n-1, x>; body»»
427 if (auto p = shape->isa<Pack>()) {
428 if (auto s = Lit::isa(p->shape())) return arr(*s, arr(pack(*s - 1, p->body()), body));
429 }
430
431 return unify<Arr>(2, body->unfold_type(), shape, body);
432}
433
434const Def* World::pack(const Def* shape, const Def* body) {
435 if (!is_shape(shape->type())) error(shape->loc(), "expected shape but got '{}' of type '{}'", shape, shape->type());
436
437 if (auto a = Lit::isa(shape)) {
438 if (*a == 0) return tuple();
439 if (*a == 1) return body;
440 }
441
442 // <(a, b, c); body> -> <a; «(b, c); body>>
443 if (auto tuple = shape->isa<Tuple>()) return pack(tuple->ops().front(), pack(tuple->ops().subspan(1), body));
444
445 // <<n; x>; body> -> <x; <<n-1, x>; body>>
446 if (auto p = shape->isa<Pack>()) {
447 if (auto s = Lit::isa(p->shape())) return pack(*s, pack(pack(*s - 1, p->body()), body));
448 }
449
450 auto type = arr(shape, body->type());
451 return unify<Pack>(1, type, body);
452}
453
454const Def* World::arr(Defs shape, const Def* body) {
455 if (shape.empty()) return body;
456 return arr(shape.rsubspan(1), arr(shape.back(), body));
457}
458
459const Def* World::pack(Defs shape, const Def* body) {
460 if (shape.empty()) return body;
461 return pack(shape.rsubspan(1), pack(shape.back(), body));
462}
463
464const Lit* World::lit(const Def* type, u64 val) {
465 if (auto size = Idx::isa(type)) {
466 if (auto s = Lit::isa(size)) {
467 if (*s != 0 && val >= *s) error(type->loc(), "index '{}' does not fit within arity '{}'", size, val);
468 } else if (val != 0) { // 0 of any size is allowed
469 error(type->loc(), "cannot create literal '{}' of 'Idx {}' as size is unknown", val, size);
470 }
471 }
472
473 return unify<Lit>(0, type, val);
474}
475
476/*
477 * set
478 */
479
480template<bool Up> const Def* World::ext(const Def* type) {
481 if (auto arr = type->isa<Arr>()) return pack(arr->shape(), ext<Up>(arr->body()));
482 if (auto sigma = type->isa<Sigma>())
483 return tuple(sigma, DefVec(sigma->num_ops(), [&](size_t i) { return ext<Up>(sigma->op(i)); }));
484 return unify<TExt<Up>>(0, type);
485}
486
487template<bool Up> const Def* World::bound(Defs ops) {
488 auto kind = umax<Sort::Type>(ops);
489
490 // has ext<Up> value?
491 if (std::ranges::any_of(ops, [&](const Def* op) { return Up ? bool(op->isa<Top>()) : bool(op->isa<Bot>()); }))
492 return ext<Up>(kind);
493
494 // ignore: ext<!Up>
495 DefVec cpy(ops.begin(), ops.end());
496 auto [_, end] = std::ranges::copy_if(ops, cpy.begin(), [&](const Def* op) { return !op->isa<Ext>(); });
497
498 // sort and remove duplicates
499 std::sort(cpy.begin(), end, GIDLt<const Def*>());
500 end = std::unique(cpy.begin(), end);
501 cpy.resize(std::distance(cpy.begin(), end));
502
503 if (cpy.size() == 0) return ext<!Up>(kind);
504 if (cpy.size() == 1) return cpy[0];
505
506 // TODO simplify mixed terms with joins and meets
507
508 return unify<TBound<Up>>(cpy.size(), kind, cpy);
509}
510
511const Def* World::ac(const Def* type, Defs ops) {
512 if (type->isa<Meet>()) {
513 auto types = DefVec(ops.size(), [&](size_t i) { return ops[i]->type(); });
514 return unify<Ac>(ops.size(), meet(types), ops);
515 }
516
517 assert(ops.size() == 1);
518 return ops[0];
519}
520
521const Def* World::ac(Defs ops) { return ac(umax<Sort::Term>(ops), ops); }
522
523const Def* World::vel(const Def* type, const Def* value) {
524 if (type->isa<Join>()) return unify<Vel>(1, type, value);
525 return value;
526}
527
528const Def* World::pick(const Def* type, const Def* value) { return unify<Pick>(1, type, value); }
529
530const Def* World::test(const Def* value, const Def* probe, const Def* match, const Def* clash) {
531 auto m_pi = match->type()->isa<Pi>();
532 auto c_pi = clash->type()->isa<Pi>();
533
534 // TODO proper error msg
535 assert(m_pi && c_pi);
536 auto a = m_pi->dom()->isa_lit_arity();
537 assert_unused(a && *a == 2);
538 assert(Checker::alpha<Checker::Check>(m_pi->dom(2, 0_s), c_pi->dom()));
539
540 auto codom = join({m_pi->codom(), c_pi->codom()});
541 return unify<Test>(4, pi(c_pi->dom(), codom), value, probe, match, clash);
542}
543
544const Def* World::uniq(const Def* inhabitant) { return unify<Uniq>(1, inhabitant->type()->unfold_type(), inhabitant); }
545
546Sym World::append_suffix(Sym symbol, std::string suffix) {
547 auto name = symbol.str();
548
549 auto pos = name.find(suffix);
550 if (pos != std::string::npos) {
551 auto num = name.substr(pos + suffix.size());
552 if (num.empty()) {
553 name += "_1";
554 } else {
555 num = num.substr(1);
556 num = std::to_string(std::stoi(num) + 1);
557 name = name.substr(0, pos + suffix.size()) + "_" + num;
558 }
559 } else {
560 name += suffix;
561 }
562
563 return sym(std::move(name));
564}
565
566/*
567 * debugging
568 */
569
570#ifdef MIM_ENABLE_CHECKS
571
572void World::breakpoint(u32 gid) { state_.breakpoints.emplace(gid); }
573
574const Def* World::gid2def(u32 gid) {
575 auto i = std::ranges::find_if(move_.defs, [=](auto def) { return def->gid() == gid; });
576 if (i == move_.defs.end()) return nullptr;
577 return *i;
578}
579
581 for (auto mut : externals()) assert(mut->is_closed() && mut->is_set());
582 for (auto anx : annexes()) assert(anx->is_closed());
583 return *this;
584}
585
586#endif
587
588#ifndef DOXYGEN
589template const Def* World::umax<Sort::Term>(Defs);
590template const Def* World::umax<Sort::Type>(Defs);
591template const Def* World::umax<Sort::Kind>(Defs);
592template const Def* World::umax<Sort::Univ>(Defs);
593template const Def* World::ext<true>(const Def*);
594template const Def* World::ext<false>(const Def*);
595template const Def* World::bound<true>(Defs);
596template const Def* World::bound<false>(Defs);
597template const Def* World::app<true>(const Def*, const Def*);
598template const Def* World::app<false>(const Def*, const Def*);
599template const Def* World::implicit_app<true>(const Def*, const Def*);
600template const Def* World::implicit_app<false>(const Def*, const Def*);
601#endif
602
603} // namespace mim
A (possibly paramterized) Array.
Definition tuple.h:68
static std::tuple< const Axiom *, u8, u8 > get(const Def *def)
Yields currying counter of def.
Definition axiom.cpp:38
static constexpr u8 Trip_End
Definition axiom.h:45
static const Def * is_uniform(Defs defs)
Yields defs.front(), if all defs are Check::alpha-equivalent (Mode::Test) and nullptr otherwise.
Definition check.cpp:240
static bool alpha(const Def *d1, const Def *d2)
Definition check.h:71
static const Def * assignable(const Def *type, const Def *value)
Can value be assigned to sth of type?
Definition check.h:77
Base class for all Defs.
Definition def.h:198
const Def * zonk() const
Definition check.cpp:35
nat_t as_lit_arity() const
Definition def.h:252
constexpr auto ops() const noexcept
Definition def.h:261
T * isa_mut() const
If this is *mut*able, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:430
const Def * op(size_t i) const noexcept
Definition def.h:264
bool is_external() const
Definition def.h:414
const Def * unfold_type() const
Yields the type of this Def and builds a new Type (UInc n) if necessary.
Definition def.cpp:420
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:242
Loc loc() const
Definition def.h:450
Sym sym() const
Definition def.h:451
const T * isa_imm() const
Definition def.h:424
bool is_closed() const
Has no free_vars()?
Definition def.cpp:392
constexpr size_t num_ops() const noexcept
Definition def.h:265
Some "global" variables needed all over the place.
Definition driver.h:17
Log & log()
Definition driver.h:24
Flags & flags()
Definition driver.h:23
Error & error(Loc loc, const char *s, Args &&... args)
Definition dbg.h:71
Error & note(Loc loc, const char *s, Args &&... args)
Definition dbg.h:73
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:155
This node is a hole in the IR that is inferred by its context later on.
Definition check.h:10
static const Def * isa(const Def *def)
Checks if def is a Idx s and returns s or nullptr otherwise.
Definition def.cpp:555
Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
Definition tuple.h:181
A function.
Definition lam.h:105
static std::optional< T > isa(const Def *def)
Definition def.h:730
static T as(const Def *def)
Definition def.h:735
Facility to log what you are doing.
Definition log.h:17
A (possibly paramterized) Tuple.
Definition tuple.h:115
A dependent function type.
Definition lam.h:11
const Def * dom() const
Definition lam.h:32
const Def * codom() const
Definition lam.h:33
static Pi * isa_implicit(const Def *d)
Is d an Pi::is_implicit (mutable) Pi?
Definition lam.h:51
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:11
A dependent tuple type.
Definition tuple.h:9
static const Def * infer(World &, Defs)
Definition check.cpp:267
Data constructor for a Sigma.
Definition tuple.h:50
static const Def * infer(World &, Defs)
Definition check.cpp:261
const Lit * lit_idx(nat_t size, u64 val)
Constructs a Lit of type Idx of size size.
Definition world.h:397
const Def * insert(const Def *d, const Def *i, const Def *val)
Definition world.cpp:363
const Def * meet(Defs ops)
Definition world.h:445
const Def * uinc(const Def *op, level_t offset=1)
Definition world.cpp:112
const Def * raw_app(const Axiom *axiom, u8 curry, u8 trip, const Def *type, const Def *callee, const Def *arg)
Definition world.cpp:234
const Lit * lit(const Def *type, u64 val)
Definition world.cpp:464
Log & log()
Definition world.cpp:70
const Lit * lit_i8()
Definition world.h:391
const Def * ac(const Def *type, Defs ops)
Definition world.cpp:511
const Type * type(const Def *level)
Definition world.cpp:105
void make_external(Def *)
Definition world.cpp:87
const Driver & driver() const
Definition world.h:80
const Lit * lit_tt()
Definition world.h:423
World(Driver *)
Definition world.cpp:59
const Def * sigma(Defs ops)
Definition world.cpp:238
const Def * pack(const Def *arity, const Def *body)
Definition world.cpp:434
const Def * app(const Def *callee, const Def *arg)
Definition world.cpp:181
const Def * arr(const Def *shape, const Def *body)
Definition world.cpp:407
const Pi * pi(const Def *dom, const Def *codom, bool implicit=false)
Definition world.h:251
const Axiom * axiom(NormalizeFn n, u8 curry, u8 trip, const Def *type, plugin_t p, tag_t t, sub_t s)
Definition world.h:233
const Lit * lit_0_1()
Definition world.h:388
World & verify()
Verifies that all externals() and annexes() are Def::is_closed(), if MIM_ENABLE_CHECKS.
Definition world.cpp:580
const Idx * type_idx()
Definition world.h:465
const Lit * lit_univ_0()
Definition world.h:382
Sym name() const
Definition world.h:83
const Lit * lit_univ_1()
Definition world.h:383
const Nat * type_nat()
Definition world.h:464
const Def * pick(const Def *type, const Def *value)
Definition world.cpp:528
Hole * mut_hole(const Def *type)
Definition world.h:218
const Lam * lam(const Pi *pi, Lam::Filter f, const Def *body)
Definition world.h:279
const Def * tuple(Defs ops)
Definition world.cpp:246
const Def * gid2def(u32 gid)
Lookup Def by gid.
Definition world.cpp:574
Flags & flags()
Retrieve compile Flags.
Definition world.cpp:71
const Def * implicit_app(const Def *callee, const Def *arg)
Places Holes as demanded by Pi::is_implicit() and then apps arg.
Definition world.cpp:176
const Type * type()
Definition world.h:205
const Def * var(const Def *type, Def *mut)
Definition world.cpp:167
const Def * extract(const Def *d, const Def *i)
Definition world.cpp:301
auto externals() const
Definition world.h:192
Sym sym(std::string_view)
Definition world.cpp:74
const Lit * lit_ff()
Definition world.h:422
const Def * bound(Defs ops)
Definition world.cpp:487
const Def * join(Defs ops)
Definition world.h:444
const Def * ext(const Def *type)
Definition world.cpp:480
Sym append_suffix(Sym name, std::string suffix)
Appends a suffix or an increasing number if the suffix already exists.
Definition world.cpp:546
void make_internal(Def *)
Definition world.cpp:94
const Lit * lit_univ(u64 level)
Definition world.h:381
const Tuple * tuple()
the unit value of type []
Definition world.h:343
const Def * vel(const Def *type, const Def *value)
Definition world.cpp:523
const Def * uniq(const Def *inhabitant)
Definition world.cpp:544
const Def * umax(Defs)
Definition world.cpp:121
const Sigma * sigma()
The unit type within Type 0.
Definition world.h:322
const Lit * lit_nat(nat_t a)
Definition world.h:384
const State & state() const
Definition world.h:78
const Def * register_annex(flags_t f, const Def *)
Definition world.cpp:77
void breakpoint(u32 gid)
Trigger breakpoint in your debugger when creating Def with Def::gid gid.
Definition world.cpp:572
Sigma * mut_sigma(const Def *type, size_t size)
Definition world.h:318
auto annexes() const
Definition world.h:168
const Def * test(const Def *value, const Def *probe, const Def *match, const Def *clash)
Definition world.cpp:530
#define WLOG(...)
Definition log.h:88
#define DLOG(...)
Vaporizes to nothingness in Debug build.
Definition log.h:93
Definition ast.h:14
View< const Def * > Defs
Definition def.h:49
u64 nat_t
Definition types.h:43
Vector< const Def * > DefVec
Definition def.h:50
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
Definition util.h:104
u64 flags_t
Definition types.h:45
TBound< true > Join
Definition lattice.h:180
void error(Loc loc, const char *f, Args &&... args)
Definition dbg.h:122
u64 level_t
Definition types.h:42
TExt< true > Top
Definition lattice.h:178
auto match(const Def *def)
Definition axiom.h:112
uint32_t u32
Definition types.h:34
TExt< false > Bot
Definition lattice.h:177
uint64_t u64
Definition types.h:34
uint8_t u8
Definition types.h:34
@ Univ
Definition def.h:94
@ Type
Definition def.h:94
@ Term
Definition def.h:94
@ Kind
Definition def.h:94
TBound< false > Meet
Definition lattice.h:179
Compiler switches that must be saved and looked up in later phases of compilation.
Definition flags.h:11
static Sym demangle(Driver &, plugin_t plugin)
Reverts an Axiom::mangled string to a Sym.
Definition plugin.cpp:37