14class Hole :
public Def,
public Setters<Hole> {
28 std::pair<Hole*, const Def*>
find();
48 static const Def*
isa_set(
const Def* def) {
49 if (
auto hole = def->isa<Hole>(); hole && hole->
is_set())
return hole->
op();
54 if (
auto hole = def->
isa_mut<Hole>(); hole && !hole->is_set())
return hole;
59 static const Def*
find(
const Def* def) {
60 if (
auto hole = def->
isa_mut<Hole>()) {
61 auto [last,
op] = hole->find();
62 return op ?
op : last;
97 if (d1 == d2)
return true;
104 if (type == value->
type())
return value;
105 return Checker(type->world()).assignable_(type, value);
112#ifdef MIM_ENABLE_CHECKS
121 const Def* fail() {
return {}; }
124 [[nodiscard]]
const Def* assignable_(
const Def* type,
const Def* value);
126 [[nodiscard]]
bool alpha_(
const Def* d1,
const Def* d2);
128 [[nodiscard]]
bool check(
const Prod*,
const Def*);
130 [[nodiscard]]
bool check(
const Seq*,
const Def*);
131 [[nodiscard]]
bool check1(
const Seq*,
const Def*);
132 [[nodiscard]]
bool check(Seq*,
const Seq*);
133 [[nodiscard]]
bool check(
const UMax*,
const Def*);
135 auto bind(Def* mut,
const Def* d) {
return mut ? binders_.emplace(mut, d) : std::pair(binders_.end(),
true); }
static const Def * is_uniform(Defs defs)
Yields defs.front(), if all defs are Check::alpha-equivalent (Mode::Test) and nullptr otherwise.
static bool alpha(const Def *d1, const Def *d2)
@ Test
In Mode::Test, no type inference is happening and Holes will not be touched.
@ Check
In Mode::Check, type inference is happening and Holes will be resolved, if possible.
static const Def * assignable(const Def *type, const Def *value)
Can value be assigned to sth of type?
bool is_set() const
Yields true if empty or the last op is set.
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.
const Def * op(size_t i) const noexcept
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Def * unset()
Unsets all Def::ops; works even, if not set at all or partially.
static constexpr size_t Num_Ops
std::pair< Hole *, const Def * > find()
Transitively walks up Holes until the last one while path-compressing everything.
Hole * set(const Def *op)
static const Def * find(const Def *def)
If def is a Hole, find last in chain, otherwise yields def again.
const Def * tuplefy(nat_t)
If unset, explode to Tuple.
static constexpr auto Node
const Def * rebuild_(World &, const Def *, Defs) const final
static Hole * isa_unset(const Def *def)
Hole * stub(const Def *type)
Hole * stub_(World &, const Def *) final
static const Def * isa_set(const Def *def)
Base class for Sigma and Tuple.
Base class for Arr and Pack.
CRTP-based Mixin to declare setters for Def::loc & Def::name using a covariant return type.
The World represents the whole program and manages creation of MimIR nodes (Defs).
GIDMap< Def *, To > MutMap