-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreduce.hpp
More file actions
61 lines (40 loc) · 1.42 KB
/
reduce.hpp
File metadata and controls
61 lines (40 loc) · 1.42 KB
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
61
#pragma once
#include "nodes.hpp"
#include "apply.hpp"
namespace lambda {
inline bool reduceOnce(std::unique_ptr<LambdaBase>& node);
namespace _reduce {
inline bool reduceVariable(std::unique_ptr<LambdaBase>& node) { return false; }
inline bool reduceFunction(std::unique_ptr<LambdaBase>& node) {
return reduceOnce(((std::unique_ptr<Function>&)node)->body);
}
inline bool reduceApplication(std::unique_ptr<LambdaBase>& node) {
std::unique_ptr<Application>& app = (std::unique_ptr<Application>&)node;
if (app->left->getType() == LambdaType::FUNCTION) {
std::unique_ptr<LambdaBase> value = std::move(app->right);
const Variable target = ((std::unique_ptr<Function>&)(app->left))->bound;
node = std::move(((std::unique_ptr<Function>&)(app->left))->body);
apply(node, target, std::move(value));
return true;
}
if (reduceOnce(app->left)) return true;
if (reduceOnce(app->right)) return true;
return false;
}
} // namespace _beta
inline bool reduceOnce(std::unique_ptr<LambdaBase>& node) {
if (!node) return false;
switch (node->getType()) {
case LambdaType::VARIABLE:
return _reduce::reduceVariable(node);
case LambdaType::FUNCTION:
return _reduce::reduceFunction(node);
case LambdaType::APPLICATION:
return _reduce::reduceApplication(node);
}
return false;
}
inline void reduce(std::unique_ptr<LambdaBase>& node) {
while (reduceOnce(node));
}
} // namespace lambda