3#include <ankerl/unordered_dense.h>
16class Hole :
public Def,
public Setters<Hole> {
30 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;
92 template<Mode mode = C>
94 if (d1 == d2)
return true;
96 if (!checker.alpha_<mode>(d1, d2))
return false;
106 if (type == value->
type())
return value;
107 auto checker =
Check(type->world());
108 auto res = checker.coerce_(type, value);
109 if (res) checker.commit();
117#ifdef MIM_ENABLE_CHECKS
126 const Def* fail() {
return {}; }
129 [[nodiscard]]
const Def* coerce_(
const Def* type,
const Def* value);
131 [[nodiscard]]
bool alpha_(
const Def* d1,
const Def* d2);
133 [[nodiscard]]
bool alpha_impl_(
const Def* d1,
const Def* d2);
138 [[nodiscard]] std::optional<bool> try_alpha_(
const Def* d1,
const Def* d2);
141 [[nodiscard]]
bool check(
const Prod*,
const Def*);
143 [[nodiscard]]
bool check(
const Seq*,
const Seq*);
144 [[nodiscard]]
bool check(Hole*,
const Def*);
145 [[nodiscard]]
bool check_rank(
const Seq*, Hole* rank,
const Def*);
146 [[nodiscard]]
bool check1(
const Seq*,
const Def*);
147 [[nodiscard]]
bool check(Seq*,
const Seq*);
148 [[nodiscard]]
bool check(
const LMax*,
const Def*);
149 [[nodiscard]]
bool check(
const LSucc*,
const Def*);
154 static constexpr u64 memo_key(
const Def* d1,
const Def* d2)
noexcept {
155 auto g1 =
u64(d1->gid()), g2 =
u64(d2->gid());
156 return g1 < g2 ? g1 << 32 | g2 : g2 << 32 | g1;
159 using Binders = MutMap<const Def*>;
160 std::pair<Binders::iterator, bool> bind(Def* mut,
const Def* d);
165 std::array<ankerl::unordered_dense::set<u64>, 2> memo_;
166 fe::Vector<std::pair<const LMax*, const Def*>> deferred_;
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)
@ C
In Mode::Check, type inference is happening and Holes will be resolved, if possible.
@ T
In Mode::Test, no type inference is happening and Holes will not be touched.
static bool alpha(const Def *d1, const Def *d2)
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 only partially set.
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
static Hole * isa_unset(const Def *def)
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).
fe::View< const Def * > Defs
fe::Patricia< const Var, DefKey >::Set Vars