3#include <absl/container/flat_hash_set.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;
94 if (d1 == d2)
return true;
101 if (type == value->
type())
return value;
102 return Checker(type->world()).assignable_(type, value);
109#ifdef MIM_ENABLE_CHECKS
118 const Def* fail() {
return {}; }
121 [[nodiscard]]
const Def* assignable_(
const Def* type,
const Def* value);
123 [[nodiscard]]
bool alpha_(
const Def* d1,
const Def* d2);
125 [[nodiscard]]
bool alpha_impl_(
const Def* d1,
const Def* d2);
130 [[nodiscard]] std::optional<bool> try_alpha_(
const Def* d1,
const Def* d2);
133 [[nodiscard]]
bool check(
const Prod*,
const Def*);
135 [[nodiscard]]
bool check(
const Seq*,
const Def*);
136 [[nodiscard]]
bool check(Hole*,
const Def*);
137 [[nodiscard]]
bool check_rank(
const Seq*, Hole* rank,
const Def*);
138 [[nodiscard]]
bool check1(
const Seq*,
const Def*);
139 [[nodiscard]]
bool check(Seq*,
const Seq*);
140 [[nodiscard]]
bool check(
const UMax*,
const Def*);
144 static constexpr u64 memo_key(
const Def* d1,
const Def* d2)
noexcept {
145 auto g1 =
u64(d1->gid()), g2 =
u64(d2->gid());
146 return g1 < g2 ? g1 << 32 | g2 : g2 << 32 | g1;
149 using Binders = MutMap<const Def*>;
150 std::pair<Binders::iterator, bool> bind(Def* mut,
const Def* d);
155 std::array<absl::flat_hash_set<u64>, 2> memo_;
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?
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