This repository was archived by the owner on Aug 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 282
Expand file tree
/
Copy pathTreeSearch.js
More file actions
77 lines (67 loc) · 2.3 KB
/
TreeSearch.js
File metadata and controls
77 lines (67 loc) · 2.3 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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
const Node = require('./node');
const TreeSearch = {};
// Returns a function that performs a preorder search on the tree for the given
// simplification function
TreeSearch.preOrder = function(simplificationFunction) {
return function (node, options={}) {
return search(simplificationFunction, node, true, options);
};
};
// Returns a function that performs a postorder search on the tree for the given
// simplification function
TreeSearch.postOrder = function(simplificationFunction) {
return function (node, options={}) {
return search(simplificationFunction, node, false, options);
};
};
// A helper function for performing a tree search with a function
function search(simplificationFunction, node, preOrder, options={}) {
let status;
if (preOrder) {
status = simplificationFunction(node, options);
if (status.hasChanged()) {
return status;
}
}
if (Node.Type.isConstant(node)) {
return Node.Status.noChange(node);
}
// Check isUnaryMinus before Symbol because symbols nested inside unaryMinus
// (e.g., 2x - symbol) need to be subtracted from the expression. Checking
// symbol first causes the symbol to be added.
else if (Node.Type.isUnaryMinus(node)) {
status = search(simplificationFunction, node.args[0], preOrder, options);
if (status.hasChanged()) {
return Node.Status.childChanged(node, status);
}
}
// symbols can be simplified through variable substitution
else if (Node.Type.isSymbol(node)) {
return simplificationFunction(node, options);
}
else if (Node.Type.isOperator(node) || Node.Type.isFunction(node)) {
for (let i = 0; i < node.args.length; i++) {
const child = node.args[i];
const childNodeStatus = search(simplificationFunction, child, preOrder, options);
if (childNodeStatus.hasChanged()) {
return Node.Status.childChanged(node, childNodeStatus, i);
}
}
}
else if (Node.Type.isParenthesis(node)) {
status = search(simplificationFunction, node.content, preOrder, options);
if (status.hasChanged()) {
return Node.Status.childChanged(node, status);
}
}
else {
throw Error('Unsupported node type: ' + node);
}
if (!preOrder) {
return simplificationFunction(node, options);
}
else {
return Node.Status.noChange(node);
}
}
module.exports = TreeSearch;