MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
check.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/def.h"
4
5namespace mim {
6
7/// This node is a hole in the IR that is inferred by its context later on.
8/// It is modelled as a *mutable* Def.
9/// If inference was successful, it's Hole::op will be set to the inferred Def.
10class Hole : public Def, public Setters<Hole> {
11private:
12 Hole(const Def* type)
13 : Def(Node, type, 1, 0) {}
14
15public:
16 using Setters<Hole>::set;
17
18 /// @name op
19 ///@{
20 const Def* op() const { return Def::op(0); }
21
22 /// Transitively walks up Hole%s until the last one while path-compressing everything.
23 /// @returns the final Hole in the chain and final op() (if any).
24 std::pair<Hole*, const Def*> find();
25 Hole* set(const Def* op) {
26 assert(op != this);
27 return Def::set(0, op)->as<Hole>();
28 }
29 ///@}
30
31 Hole* unset() { return Def::unset()->as<Hole>(); }
32 Hole* stub(const Def* type) { return stub_(world(), type)->set(dbg()); }
33
34 /// If unset, explode to Tuple.
35 /// @returns the new Tuple, or `this` if unsuccessful.
36 const Def* tuplefy(nat_t);
37
38 static const Def* isa(const Def*);
39
40 static constexpr auto Node = mim::Node::Hole;
41
42private:
43 const Def* rebuild_(World&, const Def*, Defs) const final;
44 Hole* stub_(World&, const Def*) final;
45
46 friend class World;
47 friend class Checker;
48};
49
50class Checker {
51public:
53 : world_(world) {}
54
55 World& world() { return world_; }
56
57 enum Mode {
58 /// In Mode::Check, type inference is happening and Hole%s will be resolved, if possible.
59 /// Also, two *free* but *different* Var%s **are** considered α-equivalent.
61 /// In Mode::Test, no type inference is happening and Hole%s will not be touched.
62 /// Also, Two *free* but *different* Var%s are **not** considered α-equivalent.
64 };
65
66 template<Mode mode> static bool alpha(const Def* d1, const Def* d2) {
67 return Checker(d1->world()).alpha_<mode>(d1, d2);
68 }
69
70 /// Can @p value be assigned to sth of @p type?
71 /// @note This is different from `equiv(type, value->type())` since @p type may be dependent.
72 [[nodiscard]] static const Def* assignable(const Def* type, const Def* value) {
73 return Checker(type->world()).assignable_(type, value);
74 }
75
76 /// Yields `defs.front()`, if all @p defs are Check::alpha-equivalent (`Mode::Test`) and `nullptr` otherwise.
77 static const Def* is_uniform(Defs defs);
78
79private:
80#ifdef MIM_ENABLE_CHECKS
81 template<Mode> bool fail();
82 const Def* fail();
83#else
84 template<Mode> bool fail() { return false; }
85 const Def* fail() { return {}; }
86#endif
87
88 template<Mode> bool alpha_(const Def* d1, const Def* d2);
89 template<Mode> bool alpha_internal(const Def*, const Def*);
90 [[nodiscard]] const Def* assignable_(const Def* type, const Def* value);
91
92 World& world_;
93 MutMap<const Def*> binders_;
94 fe::Arena arena_;
95};
96
97} // namespace mim
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:305
static bool alpha(const Def *d1, const Def *d2)
Definition check.h:66
Checker(World &world)
Definition check.h:52
World & world()
Definition check.h:55
@ Test
In Mode::Test, no type inference is happening and Holes will not be touched.
Definition check.h:63
@ Check
In Mode::Check, type inference is happening and Holes will be resolved, if possible.
Definition check.h:60
static const Def * assignable(const Def *type, const Def *value)
Can value be assigned to sth of type?
Definition check.h:72
Base class for all Defs.
Definition def.h:203
Def * set(size_t i, const Def *)
Successively set from left to right.
Definition def.cpp:241
World & world() const noexcept
Definition def.cpp:377
const Def * op(size_t i) const noexcept
Definition def.h:269
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:247
Def * unset()
Unsets all Def::ops; works even, if not set at all or partially.
Definition def.cpp:259
Dbg dbg() const
Definition def.h:453
std::pair< Hole *, const Def * > find()
Transitively walks up Holes until the last one while path-compressing everything.
Definition check.cpp:70
const Def * op() const
Definition check.h:20
Hole * set(const Def *op)
Definition check.h:25
friend class Checker
Definition check.h:47
const Def * tuplefy(nat_t)
If unset, explode to Tuple.
Definition check.cpp:95
static const Def * isa(const Def *)
static constexpr auto Node
Definition check.h:40
const Def * rebuild_(World &, const Def *, Defs) const final
Definition def.cpp:110
friend class World
Definition check.h:46
Hole * stub(const Def *type)
Definition check.h:32
Hole * unset()
Definition check.h:31
Hole * stub_(World &, const Def *) final
Definition def.cpp:151
CRTP-based Mixin to declare setters for Def::loc & Def::name using a covariant return type.
Definition def.h:148
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
Definition ast.h:14
View< const Def * > Defs
Definition def.h:49
u64 nat_t
Definition types.h:43
@ Hole
Definition def.h:85
GIDMap< Def *, To > MutMap
Definition def.h:56