7#include <fe/container.h>
9#include <fe/worklist.h>
25std::optional<nat_t> pack_unrolls(
const Def* d,
const Def* index,
u64 threshold) {
28 if (
auto a =
Lit::isa(pack->arity()); a && *a < threshold)
return a;
35bool has_unset_curry(
const Lam* lam) {
37 for (
auto body = lam->body();
auto inner = body->isa_mut<
Lam>(); body = inner->
body()) {
38 if (!inner->is_set())
return true;
39 if (!seen.emplace(inner).second)
break;
45bool insert_rebuilds(
const Def* d,
const Def* index,
u64 threshold) {
47 return bool(pack_unrolls(d, index, threshold));
51std::optional<nat_t> own_rank(
const Def* type) {
52 if (
auto arr =
type->isa<
Arr>())
return arr->shape().rank();
59 auto arr =
t->unfold_type()->isa<
Arr>();
63 auto rt = arr->shape().rank();
64 if (!ri || !rj || !rt || *ri + *rj > *rt)
return {};
69const Def* assign_or_bail(
const Def* elem_type,
const Def* val) {
72 val->blame(
"value is not assignable to element type")
73 .n(
"expected `{}`, got `{}`", elem_type,
type_of(val))
79const Def* nary_elem_type(
const Def* d,
Shape index) {
80 auto type =
d->unfold_type();
82 if (!arr) index->
blame(
"multi-dimensional index expects an array but got `{}`", type).bail();
84 auto shape = arr->shape();
85 auto ri = index.rank();
90 index->blame(
"index of rank `{}` does not fit shape `{}` of rank `{}`", index->arity(), *shape,
shape->arity())
96 for (
nat_t i = 0; i != *ri; ++i)
98 index[i]->blame(
"index does not fit within arity `{}`", shape[i]).bail();
100 return d->world().peel(arr, *index);
104const Def* mut_shaped(
const Seq* seq,
Shape shape,
const Def* elem,
auto rest) {
105 auto&
w = seq->world();
106 auto is_pack = seq->is_intro();
107 auto res =
w.mut_seq(is_pack, is_pack ?
w.arr(shape, elem) : seq->type());
108 res->Def::set(0, *shape);
109 return res->Def::set(1, rest(res))->zonk_mut();
113const Def*
const Filling = (
const Def*)1;
116void sort_unique(
DefVec& defs) {
118 defs.erase(std::unique(defs.begin(), defs.end()), defs.end());
126 def->external_ =
true;
127 fe::assert_emplace(sym2mut_, def->
sym(), def);
132 def->external_ =
false;
133 auto num = sym2mut_.erase(def->
sym());
134 assert_unused(num == 1);
141 fe::assert_emplace(sym2flags_,
sym,
flags);
142 def2flags_.emplace(def,
flags);
153 if (
auto [i, ins] = sym2flags_.try_emplace(
sym,
flags); !ins) assert(i->second ==
flags);
162 if (
auto lib =
driver().library())
168 if (
auto lib =
driver().library(); lib && lib !=
this)
169 if (
auto e = fe::lookup(lib->annexes().flags2entry(),
flags)) {
170 log().d(
"import annex `{}`", e->sym);
194 data_.sigma = unify<Sigma>(
type(),
Defs{});
195 data_.tuple = unify<Tuple>(
sigma(),
Defs{});
201 data_.lit_idx_1_0 =
lit_idx(1, 0);
203 data_.lit_bool[0] =
lit_idx(2, 0_u64);
204 data_.lit_bool[1] =
lit_idx(2, 1_u64);
214static_assert(std::is_trivially_destructible_v<Dbg> && std::is_trivially_destructible_v<Vars>
215 && std::is_trivially_destructible_v<Muts> && std::is_trivially_destructible_v<NormalizeFn>,
216 "a Def member gained a non-trivial destructor: World::~World must destroy Defs again");
236 if (!
level)
return nullptr;
244 return unify<Type>(
level);
250 if (!op->isa_type<
Level>())
251 op->blame(
"operand of a level successor must be of type `Level` but is of type `{}`",
type_of(op)).bail();
253 if (offset == 0)
return op;
255 if (
auto inc = op->isa<
LSucc>())
return lsucc(inc->op(), inc->offset() + offset);
256 if (
auto max = op->isa<
LMax>())
return lmax(
DefVec(max->ops(), [&](
const Def* op) { return lsucc(op, offset); }));
257 return unify<LSucc>(op, offset);
263 auto push = [&](
const Def* op) {
265 lvl = std::max(lvl, *l);
267 ops.emplace_back(op);
270 for (
auto level : levels) {
273 level->
blame(
"operand of a level max must be of type `Level` but is of type `{}`",
type_of(
level)).bail();
277 for (
auto op : max->ops())
283 if (lvl > 0 || ops.empty()) ops.emplace_back(
lit_level(lvl));
285 return ops.size() == 1 ? ops.front() : unify<LMax>(*
this, ops);
290 hole->set(hole->world().lit_level(0));
291 else if (
auto inc = level->isa<
LSucc>())
293 else if (
auto max = level->isa<
LMax>())
294 for (
auto op : max->ops())
300 level = level->
zonk();
301 if (
auto l =
Lit::isa(level))
return *l;
302 if (
auto succ = level->isa<
LSucc>())
return eval0(succ->op()) + succ->offset();
303 if (
auto max = level->isa<
LMax>()) {
305 for (
auto op : max->ops())
306 res = std::max(res,
eval0(op));
315 for (
auto eq : std::exchange(move_.levels, {})) {
316 auto _ =
push(eq.loc);
318 error().e(eq.loc,
"universe level `{}` does not match `{}`", eq.lmax->zonk(), eq.level->zonk()).bail();
321 auto eqs = std::exchange(move_.levels, {});
325 .e(eq.loc,
"ambiguous universe levels: `{}` = `{}` has no unique solution", eq.lmax->zonk(),
329 for (
auto eq : eqs) {
337 if (
auto kind = type->zonk()->unfold_type()) {
339 if (
auto t = kind->isa<
Type>())
return t->level();
341 auto& w = type->world();
342 auto level = w.mut_hole_level();
346 type->blame(
"`{}` is not a type", type).bail();
352 for (
auto type : types) {
355 lvl = std::max(lvl, *l);
357 levels.emplace_back(
level);
360 if (levels.empty())
return lit_level(lvl);
365const Def* World::inhabitant_(
const Def* type) {
381 if (
auto arr =
type->isa_imm<Arr>())
388 default:
return nullptr;
393 if (
auto var = mut->var_)
return var;
395 if (
auto var_type = mut->
var_type())
398 return mut->var_ = unify<Var>(mut);
410template<
bool Normalize>
415template<
bool Normalize>
417 callee = callee->
zonk();
421 auto declared_here = [callee](fe::Error& err) -> fe::Error& {
422 if (callee->
isa_mut() || callee->isa<
Var>() || callee->isa<
Lam>() || callee->isa<
Axm>())
423 err.n(callee->
loc(),
"callee `{}` declared here", callee);
430 callee->
blame(
"callee is not of function type").n(
"callee `{}` has type `{}`", callee,
type_of(callee)))
436 declared_here(arg->
blame(
"argument is not assignable to callee's domain")
441 arg = new_arg->
zonk();
442 callee = callee->
zonk();
446 if (
auto imm = callee->
isa_imm<
Lam>())
return imm->body();
453 if (
var && arg ==
var)
return lam->body();
456 if (
lam->filter() !=
lit_ff() && !has_unset_curry(
lam)) {
460 if (cached_reduct(
var, arg, 0) ==
lit_tt())
461 if (
auto body = cached_reduct(
var, arg, 1))
return body;
464 auto i = move_.substs.find({
var, arg});
465 auto body = i != move_.substs.end() ? i->second->ops()[1] :
nullptr;
466 if (body != Filling) {
468 if (data_.pe_depth ==
flags().pe_fuel)
469 callee->
blame(
"partial evaluation of `{}` ran out of fuel",
lam)
470 .n(
"nested more than {} partial evaluations; raise the limit with `--pe-fuel`",
473 log().d(
"partially evaluate `{} ({})`",
lam, arg);
474 auto _ = fe::Restore(data_.pe_depth, data_.pe_depth + 1);
482 callee = callee->
zonk();
486 if (
auto normalizer =
axm->
normalizer(); Normalize && normalizer && curry == 0)
487 if (
auto norm = normalizer(
type, callee, arg))
return norm;
494 callee = callee->
zonk();
503 return unify<App>(
axm, curry, trip,
type, callee, arg);
508 if (n == 0)
return sigma();
509 if (n == 1)
return ops[0]->zonk();
518 if (n == 0)
return tuple();
519 if (n == 1)
return ops[0]->zonk();
523 if (!op->type()) op->blame(
"`Level` has no type and cannot be a tuple element").bail();
528 if (!new_t) t->blame(
"tuple of type `{}` is not assignable to inferred type `{}`",
type_of(t),
sigma).bail();
535 if (
auto tup = t->isa<
Tuple>()) check_tuple(tup);
546 if (n == 0)
return tuple();
547 if (n == 1)
return ops[0];
553 if (
auto ex0 = n != 0 ? ops[0]->isa<Extract>() :
nullptr) {
554 auto tup = ex0->tuple();
555 bool eta = tup->type() ==
type;
556 for (
size_t i = 0; i != n && eta; ++i) {
557 auto ex = ops[i]->isa<Extract>();
558 auto id = ex ?
Lit::isa(ex->index()) : std::nullopt;
559 eta = ex &&
id && *
id == u64(i) && ex->tuple() == tup;
565 return unify<Tuple>(
type, ops);
568void World::check_tuple(
const Tuple* t) {
569 auto type =
t->type();
570 auto n =
t->num_ops();
571 if (!
type->isa<Sigma>() && !
type->isa<Arr>())
return;
573 t->blame(
"tuple has {} elements but its type `{}` has arity `{}`", n,
type,
type->arity()).bail();
575 for (
size_t i = 0; i != n; ++i) {
579 op->blame(
"tuple element is not assignable to its type")
580 .n(
"expected `{}`, got `{}` in `{}`", expected,
type_of(op),
type)
587 auto args =
DefVec(n, [&](
size_t k) {
return k < parts.size() ? parts[k] :
var->
proj(n, k); });
591 return type->proj(n, i);
599 if (!d || !index_)
return nullptr;
602 auto index = check_index(index_->
zonk());
603 if (index.is_dim())
return extract1(d, *index);
605 auto r = index.rank();
606 if (!r)
return extract_fused(d, index);
607 if (*r == 0)
return d;
610 for (
nat_t i = 0; i != *r; ++i) {
612 auto next = extract1(d, c);
613 if (
auto ex = next->isa<
Extract>(); ex && ex->
tuple() == d && ex->index() == c)
614 return extract_fused(d, index.drop(i));
624Shape World::check_index(
const Def* index) {
628 auto& err = index->
blame(
"index must be of `Idx` type but is of type `{}`",
type_of(index));
630 err.n(
"a bare literal is a `Nat`; an index literal carries its arity, e.g. `{}_{}` for an `Idx {}`", *l,
634 return Shape(index).fold();
638 auto shape = s->shape();
639 auto r = shape.rank();
640 if (!r || k > *r || s->has_var())
return nullptr;
641 if (k == *r)
return s->body();
643 return seq(s->is_intro(), shape.drop(k), s->body());
647 if (!index)
return nullptr;
649 auto rank = shape.rank();
650 auto k =
Shape(index).rank();
651 if (!rank || !k || *k >= *rank)
return seq->
reduce(index);
657 [&](
Seq* res) { return seq->reduce(*(Shape(index) + res->var())); });
667 auto ro = outer.rank();
668 auto shape = outer + inner->shape();
672 return mut_shaped(
seq, shape, inner->body()->unfold_type(), [&](
Seq* res) {
673 auto v = Shape(res->var());
674 return seq->reduce(*v.take(*ro))->as<Seq>()->reduce(*v.drop(*ro));
679 if (shape.is_dim())
return type_idx(*shape);
680 if (
auto r = shape.rank())
return sigma(shape->projs(*r, [
this](
const Def* e) { return type_idx(e); }));
688const Def* World::extract_fused(
const Def* d,
Shape index) {
689 if (index.
is_dim())
return extract1(d, *index);
693 auto ri = index.
rank();
694 auto rt = own_rank(d->unfold_type());
699 return unify_elim<Extract>(nary_elem_type(d, index), d, *index);
705bool World::is_folded_axis(
const Def* type,
const Def* index,
const Def* size) {
712 if (!
Check::alpha(
type->arity(), size)) index->blame(
"index does not fit within arity `{}`",
type->arity()).bail();
716const Def* World::extract1(
const Def* d,
const Def* index) {
720 auto type =
d->unfold_type();
721 if (!
type)
d->blame(
"`Level` has no type and hence no elements to extract").bail();
724 if (is_folded_axis(
type, index, size))
return d;
726 if (
auto pack =
d->isa<Pack>()) {
732 if (
auto insert =
d->isa<Insert>()) {
737 if (
auto ex =
is_frozen() ?
nullptr :
d->isa<Extract>())
738 if (
auto is = fused_index(ex->tuple(), ex->index(), index))
return extract_fused(ex->tuple(), is);
742 if (
auto hole =
d->isa_mut<Hole>())
747 if (
auto insert =
d->isa<Insert>()) {
753 if (d ==
var)
return unify_elim<Extract>(
sigma->
op(*lidx), d, index);
756 auto t = cached_reduct(
var, d, *lidx);
757 return t ? unify_elim<Extract>(t, d, index) : nullptr;
759 return unify_elim<Extract>(
reduce(
var, d, *lidx), d, index);
762 return unify_elim<Extract>(
sigma->
op(*lidx), d, index);
767 if (
auto arr =
type->isa<Arr>()) {
774 const Def* body =
nullptr;
777 auto op_arr =
op->zonk()->isa<
Arr>();
778 if (!op_arr || (body && op_arr->body()->zonk() != body)) {
782 body = op_arr->body()->zonk();
783 extents.emplace_back(*op_arr->shape());
785 if (!extents.empty()) elem_t = this->
arr(
extract(
tuple(extents), index), body);
790 if (index->isa<
Top>()) {
793 hole->set(
pack(size, elem_hole));
799 return unify_elim<Extract>(elem_t, d, index);
806 auto type = d->unfold_type();
807 auto index = check_index(index_->
zonk());
810 if (!index.is_dim()) {
811 auto r = index.rank();
813 if (r && *r == 0)
return assign_or_bail(
type, val);
817 auto rt = own_rank(
type);
818 auto cut = r && rt && *r > *rt ? rt
819 : r && insert_rebuilds(d, index[0],
flags().scalarize_threshold) ? std::optional<nat_t>(1)
822 auto head = *index.take(*cut);
826 auto new_val = assign_or_bail(nary_elem_type(d, index), val);
831 if (
auto ex = inner->tuple()->isa<
Extract>(); ex && ex->
tuple() == d && ex->index() == *index)
832 if (
auto is = fused_index(d, *index, inner->index()))
return insert(d, *is, inner->value());
835 if (
auto ex = new_val->isa<
Extract>(); ex && ex->
tuple() == d && ex->index() == *index)
return d;
838 return unify<Insert>(d, *index, new_val);
841 auto size =
Idx::isa(index->unfold_type());
844 if (is_folded_axis(
type, *index, size))
return assign_or_bail(
type, val);
847 if (
auto elem =
peel(
arr, *index)) val = assign_or_bail(elem, val);
849 val = assign_or_bail(
type->proj(
Lit::as(size), *lidx), val);
855 if (
auto t = d->isa<
Tuple>(); t && lidx) {
856 auto new_ops =
DefVec(t->ops().begin(), t->ops().end());
857 new_ops[*lidx] = val;
862 if (
auto a = pack_unrolls(d, *index,
flags().scalarize_threshold)) {
864 new_ops[*lidx] = val;
871 if (
auto ex = inner->tuple()->isa<
Extract>(); ex && ex->
tuple() == d && ex->index() == *index)
872 if (
auto is = fused_index(d, *index, inner->index()))
return insert(d, *is, inner->value());
875 if (
auto ex = val->isa<
Extract>())
876 if (ex->tuple() == d && ex->index() == *index)
return d;
884 return unify<Insert>(d, *index, val);
888 shape = shape.zonk();
891 auto shape_ty = shape->unfold_type();
893 shape->blame(
"expected a shape but got a value of type `{}`",
type_of(*shape)).bail();
896 shape = shape.fold();
897 auto r = shape.rank();
899 if (*r == 0)
return body;
901 for (
nat_t i = 0; i != *r; ++i)
908 if (
auto fused = shape + inner->shape())
return seq(is_pack, fused, inner->body());
910 if (is_pack)
return unify<Pack>(
arr(shape, body->
unfold_type()), *shape, body);
911 return unify<Arr>(body->
unfold_type(), *shape, body);
915 if (shape.empty())
return body;
916 return seq(is_pack,
tuple(shape), body);
920 if (!
type)
return nullptr;
925 if (*s != 0 && val >= *s)
type->blame(
"index `{}` does not fit within arity `{}`", val, size).bail();
926 }
else if (val != 0) {
927 type->blame(
"cannot create literal `{}` of `Idx {}` as size is unknown", val, size).bail();
931 return unify<Lit>(
type, val);
945 return unify<TExt<Up>>(
type);
950 ops.reserve(ops_.size());
951 auto push = [&ops](
const Def* op) {
952 if (!op->isa<
Bot>()) ops.emplace_back(op);
955 for (
auto op_ : ops_) {
956 auto op = op_->zonk();
958 if (
auto join = op->isa_imm<
Join>())
966 if (std::ranges::any_of(ops, [](
const Def* op) {
return op->isa<
Top>(); }))
return top(kind);
970 if (ops.empty())
return bot(kind);
971 if (ops.size() == 1)
return ops[0];
972 return unify<Join>(kind, ops);
977 value = value->
zonk();
980 value->
blame(
"injecting into variant type `{}` requires the index of a case",
type).bail();
985 auto is_case = [value, value_t](
bool infer) {
988 return [=](
const Def* c) {
993 return alpha(value_t, c);
996 if (!std::ranges::any_of(
join->
ops(), is_case(
false)) && !std::ranges::any_of(
join->
ops(), is_case(
true)))
997 value->
blame(
"value of type `{}` is not a case of union type `{}`",
type_of(value),
type).bail();
1001 value->
blame(
"value is not assignable to `{}`",
type)
1002 .n(
"`{}` is neither a union nor a nominal type, so `inj` into it is the identity",
type)
1003 .n(
"expected `{}`, got `{}`",
type,
type_of(value))
1009 value = value->
zonk();
1013 if (!
variant) value->
blame(
"cannot inject into case {} of non-variant type `{}`", index,
type).bail();
1018 value->
blame(
"value is not assignable to case {} of variant type `{}`", index,
type)
1026 if (zops.empty())
return bot(kind);
1027 return unify<Variant>(kind, zops);
1032 if (ops.size() == 1)
return ops.front();
1034 auto scrutinee = ops.front();
1035 auto arms = ops.span().subspan(1);
1037 for (
auto arm : arms)
1038 if (!arm->isa_type<
Pi>())
1039 arm->blame(
"arm of a match expression does not have a function type but has type `{}`",
type_of(arm))
1042 auto scrut_t = scrutinee->unfold_type();
1043 if (!scrut_t) scrutinee->blame(
"scrutinee of a match expression has no type").bail();
1048 ->blame(
"match expression has {} arms but variant type has {} cases", arms.size(),
variant->
num_ops())
1052 for (
size_t i = 0, e = arms.size(); i != e; ++i) {
1056 ->
blame(
"domain type `{}` of match-expression arm does not match variant case `{}`",
pi->
dom(),
1062 if (
auto inj = scrutinee->isa<
Inj>())
return app(arms[
inj->index()],
inj->value());
1063 return unify_elim<Match>(
type, ops);
1073 auto sel =
DefVec(cases.size());
1074 for (
size_t i = 0, e = cases.size(); i != e; ++i) {
1076 auto j = std::ranges::find_if(arms, [c](
const Def* arm) {
return Match::accepts(arm, c); });
1078 if (j == arms.end())
1079 j = std::ranges::find_if(arms, [c](
const Def* arm) {
return Match::accepts(arm, c,
true); });
1080 if (j == arms.end()) scrutinee->
blame(
"match expression has no arm for union case `{}`", c).bail();
1087 res.emplace_back(scrutinee);
1088 for (
auto arm : arms) {
1089 if (!std::ranges::contains(sel, arm))
continue;
1090 auto codom = arm->isa_type<
Pi>()->codom();
1092 res.emplace_back(arm);
1099 if (!
join)
return dispatch(sel[0], scrutinee);
1104 if (
auto inj = scrutinee->isa<
Inj>()) {
1105 auto value =
inj->value();
1106 for (
size_t i = 0, e = cases.size(); i != e; ++i)
1107 if (
Check::alpha(value->unfold_type(), cases[i]))
return dispatch(sel[i], value);
1108 scrutinee->blame(
"injected value type `{}` is not a case of union type `{}`",
type_of(value),
join).bail();
1111 return unify_elim<Match>(
type, res);
1116 if (
auto t = op->unfold_type())
1117 if (
auto tt = t->unfold_type())
return unify<Single>(tt, op);
1118 op->blame(
"operand is too high in the universe hierarchy to inhabit a singleton type")
1119 .n(
"a singleton type sits one level above its inhabitant, and nothing sits above `Level`")
1125 return unify<Wrap>(
single(op), op);
1131 op->blame(
"operand of a singleton elimination is of type `{}` but must be of singleton type",
type_of(op)).bail();
1136 if (
auto t =
type->unfold_type())
return unify<Nom>(t,
type, key);
1137 type->blame(
"`Level` cannot be wrapped in a nominal newtype").bail();
1142 value = value->
zonk();
1143 if (!
nom) value->
blame(
"cannot inject into non-nominal type `{}`", n).bail();
1145 value->
blame(
"value is not assignable to nominal type `{}`",
nom)
1146 .n(
"expected `{}`, got `{}`",
nom->
op(),
type_of(value))
1151 value = value->
zonk();
1154 value->
blame(
"operand of a nominal elimination is of type `{}` but must be of nominal type",
type_of(value)).bail();
1158 auto name = symbol.str();
1159 if (
auto pos =
name.rfind(suffix); pos != std::string::npos) {
1160 auto end = pos + suffix.size();
1161 auto num = std::string_view(
name).substr(end);
1162 if (num.empty())
return sym(
name +
"_1");
1163 if (num.size() > 1 && num[0] ==
'_'
1164 && std::ranges::all_of(num.substr(1), [](
char c) { return std::isdigit((unsigned char)c); }))
1165 return sym(
name.substr(0, end) +
"_" + std::to_string(std::stoull(std::string(num.substr(1))) + 1));
1173 auto n = mut->num_ops() - off;
1174 auto ops =
Defs(mut->ops().begin() + off, n);
1176 if (
var == arg || std::ranges::none_of(ops, [
var](
const Def* op) {
return op->has_free_var(
var); }))
return ops;
1178 auto reduct = this->reduct(
var, arg);
1180 for (
size_t i = 0; i != n; ++i) {
1181 auto& slot = reduct->ops()[i];
1182 assert(slot != Filling &&
"op requires its own reduction");
1185 slot = rw.rewrite(ops[i]);
1188 return reduct->ops();
1191const Def* World::cached_reduct(
const Var* var,
const Def* arg,
size_t i) {
1192 auto mut =
var->binder();
1193 auto op = mut->op(i + mut->reduction_offset());
1194 if (
var == arg || (op && !op->has_free_var(
var)))
return op;
1196 if (
auto it = move_.substs.find(std::pair{var, arg}); it != move_.substs.end())
1197 if (
auto slot = it->second->ops()[i]; slot != Filling)
return slot;
1204 auto op = mut->op(i + off);
1205 if (
var == arg)
return op;
1206 if (!op) fe::throwf(
"cannot reduce `{}`: operand {} is not set", mut, i + off);
1207 if (!op->has_free_var(
var))
return op;
1209 auto& slot = reduct(
var, arg)->ops()[i];
1210 assert(slot != Filling &&
"op requires its own reduction");
1221 auto keep = [elide_empty](
Def* mut) {
return mut->is_closed() && (!elide_empty || mut->is_set()); };
1222 auto muts = fe::Vector<Def*>();
1229 auto queue = fe::BFSWorklist<MutSet>();
1233 while (!queue.empty()) {
1234 auto mut = queue.pop();
1235 if (keep(mut))
muts.emplace_back(mut);
1237 for (
auto op : mut->deps())
1238 for (
auto local_mut : op->local_muts())
1239 queue.push(local_mut);
1243 for (
auto mut :
muts)
1251#ifdef MIM_ENABLE_CHECKS
1257 auto i = std::ranges::find_if(move_.sea, [=](
auto def) { return def->gid() == gid; });
1258 if (i == move_.sea.end())
return nullptr;
1264 assert(mut->is_closed() && mut->is_set());
1265 for (
auto anx :
annexes().defs())
1266 assert(anx->is_closed());
1267 assert(move_.levels.empty() &&
"postponed universe constraints must be solved via solve_levels");
1286 auto& curr = state_.pod.curr_loc;
1287 if (loc == curr.loc)
return ScopedLoc(curr);
1288 return ScopedLoc(curr, {loc, loc ?
driver().dbg(Dbg(loc)) : DbgKey()});
A (possibly paramterized) Array.
Arr * set_body(const Def *body)
Arr * set_shape(const Def *shape)
static std::tuple< const Axm *, u8, u8 > next(const Def *callee)
Like Axm::get, but advances the counter as one more App is about to be built on top of callee.
NormalizeFn normalizer() const
static const Def * is_uniform(Defs defs)
Yields defs.front(), if all defs are Check::alpha-equivalent (Mode::Test) and nullptr otherwise.
static const Def * coerce(const Def *type, const Def *value)
Can value be assigned to sth of type?
static bool test_alpha(const Def *d1, const Def *d2)
static bool alpha(const Def *d1, const Def *d2)
const Def * zonk_mut() const
If mutable, zonk()s all ops and tries to immutabilize it; otherwise just zonk.
const Def * proj(nat_t a, nat_t i) const
Similar to World::extract while assuming an arity of a, but also works on Sigmas and Arrays.
constexpr Node node() const noexcept
const Def * zonk() const
If Holes have been filled, reconstruct the program without them.
bool is_intro() const noexcept
constexpr auto ops() const noexcept
size_t reduction_offset() const noexcept
First Def::op that needs to be dealt with during reduction; e.g.
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 * unfold_type() const
Yields the type of this Def and builds a new Type (LSucc n) if necessary.
bool has_free_var(const Var *) const
Same as free_vars().contains(var).
fe::Error & blame(fe::cite_string< Args... > s, Args &&... args) const
Reports an error that blames this; chain Error::n for Notes and Error::bail to throw.
bool is_external() const noexcept
const Def * var_type()
If this is a binder, compute the type of its Variable.
constexpr auto reduce(const Def *arg) const
const T * isa_imm() const
bool is_closed() const
Same as !has_free_vars().
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
const T * isa_type() const
Is Def::unfold_type a T? Yields nullptr for Level, which has no type at all.
constexpr size_t num_ops() const noexcept
Some "global" variables needed all over the place.
static Hole * isa_unset(const Def *def)
static const Def * isa(const Def *def)
Checks if def is a Idx s and returns s or nullptr otherwise.
static std::optional< nat_t > isa_lit(const Def *def)
Constructs a Join or Variant value.
Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
A union type whose ops are sorted and deduplicated: T ∪ T is T.
static std::optional< T > isa(const Def *def)
static T as(const Def *def)
static bool accepts(const Def *arm, const Def *c, bool infer=false)
Does arm handle c?
static DefVec cases(const Def *scrutinee)
Nominal newtype term introduction.
Nominal newtype formation.
const Def * op() const
The wrapped type.
A (possibly paramterized) Tuple.
A dependent function type.
const Def * codom() const
static const Pi * isa_implicit(const Def *d)
Is d an Pi::is_implicit Pi?
const Def * reduce(const Def *arg) const
Base class for Arr and Pack.
const Def * reduce(const Def *arg) const
The extents of a Seq's axes: a plain Nat for a single axis, an aggregate of them for several.
std::optional< nat_t > rank() const
Number of axes; std::nullopt if not statically known.
bool is_fused() const
Does this span several axes? Also true for a dynamic rank.
static std::optional< nat_t > extent(const Def *axis)
The extent of axis: the axis itself for a shape, its Idx size for an index.
bool is_dim() const
Is this a single axis - a Nat/Idx rather than an aggregate of them?
static bool isa_extents(const Def *)
Is type Nat - or an aggregate of Nats, i.e. a shape?
Shape drop(nat_t n) const
All but the leading n axes.
Shape take(nat_t n) const
The leading n axes.
constexpr Shape() noexcept=default
static bool isa_indices(const Def *)
Is type Idx - or an aggregate of Idxs, i.e. a fused index?
static const Def * infer(World &, Defs)
Singleton type formation.
Data constructor for a Sigma.
static const Def * infer(World &, Defs)
VarRewriter(World &world)
A variable introduced by a binder (mutable).
Def * binder() const
The binder of this Var.
A sum type whose cases are positional: unlike a Join, they are neither sorted nor deduplicated.
static const Def * infer(World &, Defs)
static const Def * isa_lone(const Def *d)
The payload A of a single-case Variant | A, which is isomorphic to A.
const flags_t * flags(const Def *d) const
The flags of the annex def, if it is one.
void attach_alias(flags_t, Sym)
Registers a further Sym for an already attach()ed annex, sharing its flags_t;.
const Def * attach(flags_t, Sym, const Def *)
const Lit * lit_idx(nat_t size, u64 val)
Constructs a Lit of type Idx of size size.
const Def * insert(const Def *d, const Def *i, const Def *val)
const Def * variant(Defs ops)
const Lit * lit(const Def *type, u64 val)
const Def * inhabitant(const Def *type)
The sole inhabitant of type, if it has exactly one, nullptr otherwise.
const Def * struc(const Def *nom)
Get the structural part of a nominal.
const Def * pack(Shape shape, const Def *body)
const Def * level(Defs types)
The lmax of the levels of all types, each of which must be a Type level.
World(Driver *, Sym name)
void watchpoint(u32 gid)
Trigger breakpoint in your debugger when Def::setting a Def with this gid.
const Type * type(const Def *level)
const Def * component(const Def *type, Defs parts, size_t n, size_t i)
The type of component i of the n-ary type, given its leading components parts.
const Def * lsucc(const Def *op, level_t offset=1)
const Lit * lit_level_1()
const Def * sigma(Defs ops)
const Def * app(const Def *callee, const Def *arg)
const Def * arr(Shape shape, const Def *body)
const Def * seq(bool is_pack, Shape shape, const Def *body)
const Pi * pi(const Def *dom, const Def *codom, bool implicit=false)
const Def * implicit_holes(const Def *callee)
Only places the Holes.
World & verify()
Verifies that all externals() and annexes() are Def::is_closed(), if MIM_ENABLE_CHECKS.
const Def * bot(const Def *type)
const Def * single(const Def *)
Singleton type formation.
const fe::Log & log() const
Log via log().e("...", args) etc.; owned by the Driver.
const Def * fuse(Seq *seq)
«i: a; «j: b; T»» -> «v: (a, b); T» - the inverse of World::peel, for a nest that World::seq cannot f...
const Def * annex(Sym sym)
Lookup annex by Sym.
void for_each(bool elide_empty, std::function< void(Def *)>, bool schedule=false)
Hole * mut_hole(const Def *type)
const Lam * lam(const Pi *pi, Lam::Filter f, const Def *body)
const Def * tuple(Defs ops)
const Def * gid2def(u32 gid)
Lookup Def by gid.
const Def * lmax(Defs levels)
Flags & flags()
Retrieve compile Flags.
const Def * implicit_app(const Def *callee, const Def *arg)
const Def * unwrap(const Def *)
Singleton term elimination.
const Def * inj(const Def *type, const Def *value)
const Axm * axm(NormalizeFn n, u8 curry, u8 trip, const Def *type, plugin_t p, tag_t t, sub_t s)
const Lit * lit_level_0()
void solve_levels()
Defaults the level Holes of all postponed constraints that are still unknown to 0 and checks them.
const Def * extract(const Def *d, const Def *i)
Sym sym(std::string_view)
fe::Restore< CurrLoc > ScopedLoc
const Def * join(Defs ops)
const Def * ext(const Def *type)
Sym append_suffix(Sym name, std::string suffix)
Appends a suffix or an increasing number if the suffix already exists.
static constexpr nat_t Num_Lit_Nats
Def::arity of a Sigma is lit_nat(num_ops()) and Def::num_projs reads it straight back out,...
const Def * var(Def *mut)
const Tuple * tuple()
the unit value of type []
const Nom * nom(flags_t key, const Def *type)
Make type Nominal under key.
const Def * raw_app(const Axm *axm, u8 curry, u8 trip, const Def *type, const Def *callee, const Def *arg)
const Def * prod(bool term, Defs ops)
const Externals & externals() const
const Def * peel(const Seq *seq, const Def *index)
seq with the axes covered by index peeled off - the element itself once index covers all of them.
const Def * type_indices(Shape shape)
The type of an index into shape: Idx n, a Sigma of those, or «i: r; Idx (s#i)» for a dynamic rank.
const Sigma * sigma()
The unit type within Type 0.
const Lit * lit_nat(nat_t a)
const State & state() const
const Def * wrap(const Def *)
Singleton term introduction.
const Def * drop(const Seq *s, nat_t k)
s without its leading k axes - its body once k covers all of them; nullptr if that isn't a type.
const Def * top(const Def *type)
const Lit * lit_level(u64 level)
Defs reduce(const Var *var, const Def *arg)
Yields the new body of [mut->var() -> arg]mut.
void breakpoint(u32 gid)
Trigger breakpoint in your debugger when creating a Def with this gid.
const Def * annex()
Get Axm from a plugin.
const Level * type_level()
static const Def * level_of(const Def *type)
static level_t eval0(const Def *level)
fe::View< const Def * > Defs
void post_order(Def *mut, MutSet &done, fe::Vector< Def * > &res, MutPred auto descend, MutPred auto collect)
Appends the mutables reachable from mut via Def::deps / Def::local_muts to res in post-order: callees...
fe::Vector< const Def * > DefVec
auto type_of(const Def *def)
Def::unfold_type of def for a diagnostic - Level is the one Def that has no type at all.
static void default_level(const Def *level)
static std::string demangle(plugin_t plugin)
Reverts an Axm::mangled plugin back to its name; never longer than Annex::Max_Plugin_Size.
Compiler switches that must be saved and looked up in later phases of compilation.