Thorin 1.9.0
The Higher ORder INtermediate representation
Loading...
Searching...
No Matches
lam.cpp
Go to the documentation of this file.
1#include "thorin/lam.h"
2
3#include "thorin/world.h"
4
5using namespace std::string_literals;
6
7namespace thorin {
8
9/*
10 * Pi
11 */
12
13const Pi* Pi::ret_pi() const {
14 if (num_doms() > 0) {
15 auto ret = dom(num_doms() - 1);
16 if (auto pi = Pi::isa_basicblock(ret)) return pi;
17 }
18
19 return nullptr;
20}
21
22Pi* Pi::set_dom(Defs doms) { return Def::set(0, world().sigma(doms))->as<Pi>(); }
23
24/*
25 * Lam
26 */
27
28Lam* Lam::set_filter(Filter filter) { return Def::set(0, world().filter(filter))->as<Lam>(); }
29Lam* Lam::app(Filter f, const Def* callee, const Def* arg) { return set_filter(f)->set_body(world().app(callee, arg)); }
30Lam* Lam::app(Filter filter, const Def* callee, Defs args) { return app(filter, callee, world().tuple(args)); }
31
32Lam* Lam::branch(Filter filter, const Def* cond, const Def* t, const Def* f, const Def* mem) {
33 return app(filter, world().select(cond, t, f), mem ? mem : world().tuple());
34}
35
36Lam* Lam::test(Filter filter, const Def* value, const Def* index, const Def* match, const Def* clash, const Def* mem) {
37 return app(filter, world().test(value, index, match, clash), mem);
38}
39
40/*
41 * Helpers
42 */
43
44std::deque<const App*> decurry(const Def* def) {
45 std::deque<const App*> apps;
46 while (auto app = def->isa<App>()) {
47 apps.emplace_front(app);
48 def = app->callee();
49 }
50 return apps;
51}
52
53const Def* compose_cn(const Def* f, const Def* g) {
54 auto& world = f->world();
55 world.DLOG("compose f (B->C): {} : {}", f, f->type());
56 world.DLOG("compose g (A->B): {} : {}", g, g->type());
57
58 auto F = f->type()->as<Pi>();
59 auto G = g->type()->as<Pi>();
60
61 assert(Pi::isa_returning(F));
62 assert(Pi::isa_returning(G));
63
64 auto A = G->dom(2, 0);
65 auto B = G->ret_dom();
66 auto C = F->ret_dom();
67 // The type check of codom G = dom F is better handled by the application type checking
68
69 world.DLOG("compose f (B->C): {} : {}", f, F);
70 world.DLOG("compose g (A->B): {} : {}", g, G);
71 world.DLOG(" A: {}", A);
72 world.DLOG(" B: {}", B);
73 world.DLOG(" C: {}", C);
74
75 auto h = world.mut_fun(A, C)->set("comp_"s + f->sym().str() + "_"s + g->sym().str());
76 auto hcont = world.mut_con(B)->set("comp_"s + f->sym().str() + "_"s + g->sym().str() + "_cont"s);
77
78 h->app(true, g, {h->var((nat_t)0), hcont});
79
80 auto hcont_var = hcont->var(); // Warning: not var(0) => only one var => normalization flattens tuples down here.
81 hcont->app(true, f, {hcont_var, h->var(1) /* ret_var */});
82
83 return h;
84}
85
86std::pair<const Def*, std::vector<const Def*>> collect_args(const Def* def) {
87 std::vector<const Def*> args;
88 if (auto app = def->isa<App>()) {
89 auto callee = app->callee();
90 auto arg = app->arg();
91 auto [inner_callee, args] = collect_args(callee);
92 args.push_back(arg);
93 return {inner_callee, args};
94 } else {
95 return {def, args};
96 }
97}
98
99} // namespace thorin
Base class for all Defs.
Definition def.h:222
Def * set(size_t i, const Def *def)
Successively set from left to right.
Definition def.cpp:254
World & world() const
Definition def.cpp:421
A function.
Definition lam.h:97
std::variant< bool, const Def * > Filter
Definition lam.h:158
Lam * app(Filter filter, const Def *callee, const Def *arg)
Set body to an App of callee and arg.
Definition lam.cpp:29
Lam * test(Filter filter, const Def *val, const Def *idx, const Def *match, const Def *clash, const Def *mem)
Definition lam.cpp:36
Ref filter() const
Definition lam.h:107
Lam * set_filter(Filter)
Set filter first.
Definition lam.cpp:28
Lam * set_body(const Def *body)
Set body second.
Definition lam.h:161
Lam * branch(Filter filter, const Def *cond, const Def *t, const Def *f, const Def *mem=nullptr)
Set body to an App of (f, t)#cond mem or (f, t)#cond () if mem is nullptr.
Definition lam.cpp:32
A dependent function type.
Definition lam.h:11
static const Pi * isa_returning(Ref d)
Is this a continuation (Pi::isa_cn) which has a Pi::ret_pi?
Definition lam.h:52
static const Pi * isa_basicblock(Ref d)
Is this a continuation (Pi::isa_cn) that is not Pi::isa_returning?
Definition lam.h:54
Pi * set_dom(Ref dom)
Definition lam.h:74
Ref ret_dom() const
Pi::domain of Pi::ret_pi.
Definition lam.h:67
Ref dom() const
Definition lam.h:32
const Pi * ret_pi() const
Yields the last Pi::dom, if it Pi::isa_basicblock.
Definition lam.cpp:13
This is a thin wrapper for std::span<T, N> with the following additional features:
Definition span.h:28
Ref tuple(Defs ops)
Definition world.cpp:226
The mem Plugin
Definition mem.h:11
Definition cfg.h:11
const Def * compose_cn(const Def *f, const Def *g)
The high level view is:
Definition lam.cpp:53
auto match(Ref def)
Definition axiom.h:105
u64 nat_t
Definition types.h:44
std::pair< const Def *, std::vector< const Def * > > collect_args(const Def *def)
Helper function to cope with the fact that normalizers take all arguments and not only its axiom argu...
Definition lam.cpp:86
std::deque< const App * > decurry(const Def *)
Yields curried Apps in a flat std::deque<const App*>.
Definition lam.cpp:44