-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubstitution.cpp
60 lines (40 loc) · 1.29 KB
/
substitution.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "substitution.hpp"
namespace type {
substitution::value_type substitution::find(key_type key) const {
auto it = map.find(key);
if(it != map.end()) return it->second;
if(parent) return parent->find(key);
return key;
}
void substitution::link(key_type key, value_type value) {
auto it = map.emplace(key, value);
assert(it.second); (void) it;
}
void substitution::merge() {
assert(parent);
for(auto& it : map) {
parent->link(it.first, it.second);
}
}
ref<substitution> scope(const ref<substitution>& self) {
return make_ref<substitution>(self);
}
substitution::substitution(const ref<substitution>& parent)
: parent(parent) { }
struct substitute_visitor {
mono operator()(const ref<variable>& self, const substitution& sub) const {
const mono t = sub.find(self);
if(t == self) return t;
return sub.substitute(t);
}
mono operator()(const ref<application>& self, const substitution& sub) const {
return sub.substitute(self->ctor)(sub.substitute(self->arg));
}
mono operator()(const ref<constant>& self, const substitution&) const {
return self;
}
};
mono substitution::substitute(const mono& t) const {
return t.visit(substitute_visitor(), *this);
}
}