occam-verify-cli 0.0.464 → 0.0.466

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/lib/antecedent.js +214 -0
  2. package/lib/axiom.js +93 -78
  3. package/lib/axiomLemmaTheorem.js +190 -0
  4. package/lib/consequent.js +157 -0
  5. package/lib/constants.js +9 -1
  6. package/lib/lemma.js +93 -78
  7. package/lib/ruleNames.js +4 -4
  8. package/lib/substitution.js +123 -0
  9. package/lib/theorem.js +93 -78
  10. package/lib/utilities/statement.js +45 -0
  11. package/lib/utilities/string.js +6 -6
  12. package/lib/verify/antecedentOrAntecedents.js +38 -0
  13. package/lib/verify/axiom.js +15 -14
  14. package/lib/verify/conditinalIndicative.js +32 -0
  15. package/lib/verify/{indicativeConditional.js → conditionalIndicative.js} +10 -10
  16. package/lib/verify/consequent.js +36 -0
  17. package/lib/verify/derivation.js +1 -1
  18. package/lib/verify/lemma.js +25 -19
  19. package/lib/verify/proof.js +26 -11
  20. package/lib/verify/statement/qualified.js +16 -4
  21. package/lib/verify/theorem.js +22 -17
  22. package/lib/verify/unconditionalIndicative.js +28 -0
  23. package/package.json +3 -3
  24. package/src/antecedent.js +235 -0
  25. package/src/axiom.js +5 -95
  26. package/src/axiomLemmaTheorem.js +190 -0
  27. package/src/consequent.js +187 -0
  28. package/src/constants.js +2 -0
  29. package/src/lemma.js +5 -95
  30. package/src/ruleNames.js +1 -1
  31. package/src/substitution.js +130 -0
  32. package/src/theorem.js +5 -95
  33. package/src/utilities/statement.js +50 -0
  34. package/src/utilities/string.js +6 -6
  35. package/src/verify/antecedentOrAntecedents.js +40 -0
  36. package/src/verify/axiom.js +21 -16
  37. package/src/verify/conditinalIndicative.js +31 -0
  38. package/src/verify/conditionalIndicative.js +29 -0
  39. package/src/verify/consequent.js +36 -0
  40. package/src/verify/derivation.js +1 -1
  41. package/src/verify/lemma.js +38 -21
  42. package/src/verify/proof.js +32 -14
  43. package/src/verify/statement/qualified.js +15 -6
  44. package/src/verify/theorem.js +32 -20
  45. package/src/verify/unconditionalIndicative.js +24 -0
  46. package/src/verify/indicativeConditional.js +0 -29
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+
3
+ import Label from "./label";
4
+ import Antecedent from "./antecedent";
5
+ import Consequent from "./consequent";
6
+
7
+ import { prune } from "./utilities/array";
8
+ import { someSubArray } from "./utilities/array";
9
+
10
+ export default class AxiomLemmaTheorem {
11
+ constructor(labels, antecedents, consequent) {
12
+ this.labels = labels;
13
+ this.antecedents = antecedents;
14
+ this.consequent = consequent;
15
+ }
16
+
17
+ getLabels() {
18
+ return this.labels;
19
+ }
20
+
21
+ getAntecedents() {
22
+ return this.antecedents;
23
+ }
24
+
25
+ getConsequent() {
26
+ return this.consequent;
27
+ }
28
+
29
+ matchLabelName(labelName) {
30
+ const matchesLabelName = this.labels.some((label) => {
31
+ const name = labelName, ///
32
+ labelMatchesName = label.matchName(name);
33
+
34
+ if (labelMatchesName) {
35
+ return true;
36
+ }
37
+ });
38
+
39
+ return matchesLabelName;
40
+ }
41
+
42
+ matchStatement(statementNode, proofContext) {
43
+ let statementNatches;
44
+
45
+ const antecedentsLength = this.antecedents.length;
46
+
47
+ if (antecedentsLength === 0) {
48
+ const substitutions = [],
49
+ consequentMatches = matchConsequent(this.consequent, statementNode, substitutions);
50
+
51
+ statementNatches = consequentMatches; ///
52
+ } else {
53
+ const assertions = proofContext.getAssertions();
54
+
55
+ statementNatches = someSubArray(assertions, antecedentsLength, (assertions) => {
56
+ const antecedentsMatchConsequent = matchAntecedentsAndConsequent(this.antecedents, this.consequent, assertions, statementNode);
57
+
58
+ if (antecedentsMatchConsequent) {
59
+ return true;
60
+ }
61
+ });
62
+ }
63
+
64
+ return statementNatches;
65
+ }
66
+
67
+ toJSON() {
68
+ const { kind } = this.constructor,
69
+ labelsJSON = this.labels.map((label) => {
70
+ const labelJSON = label.toJSON();
71
+
72
+ return labelJSON;
73
+ }),
74
+ antecedentsJSON = this.antecedents.map((antecedent) => {
75
+ const antecedentJSON = antecedent.toJSON();
76
+
77
+ return antecedentJSON;
78
+ }),
79
+ consequentJSON = this.consequent.toJSON(),
80
+ labels = labelsJSON, ///
81
+ antecedents = antecedentsJSON, ///
82
+ consequent = consequentJSON, ///
83
+ json = {
84
+ kind,
85
+ labels,
86
+ antecedents,
87
+ consequent
88
+ };
89
+
90
+ return json;
91
+ }
92
+
93
+ static fromJSON(Class, json, releaseContext) {
94
+ let { labels } = json;
95
+
96
+ const labelsJSON = labels; ///
97
+
98
+ labels = labelsJSON.map((labelJSON) => {
99
+ const json = labelJSON, ///
100
+ label = Label.fromJSON(json, releaseContext);
101
+
102
+ return label;
103
+ });
104
+
105
+ let { antecedents } = json;
106
+
107
+ const antecedentsJSON = antecedents; ///
108
+
109
+ antecedents = antecedentsJSON.map((antecedentJSON) => {
110
+ const json = antecedentJSON, ///
111
+ antecedent = Antecedent.fromJSON(json, releaseContext);
112
+
113
+ return antecedent;
114
+ });
115
+
116
+ let { consequent } = json;
117
+
118
+ const consequentJSON = consequent; ///
119
+
120
+ json = consequentJSON; ///
121
+
122
+ consequent = Consequent.fromJSON(json, releaseContext);
123
+
124
+ return new Class(labels, antecedents, consequent); ///
125
+ }
126
+
127
+ static fromLabelsAntecedentsAndConsequent(Class, labels, antecedents, consequent) { return new Class(labels, antecedents, consequent); }
128
+ }
129
+
130
+ function matchAntecedent(antecedent, assertions, substitutions) {
131
+ const assertion = prune(assertions, (assertion) => {
132
+ const subproofNode = assertion.getSubproofNode(),
133
+ statementNode = assertion.getStatementNode();
134
+
135
+ if (subproofNode !== null) {
136
+ const subProofMatches = antecedent.matchSubproofNode(subproofNode, substitutions);
137
+
138
+ if (!subProofMatches) { ///
139
+ return true;
140
+ }
141
+ }
142
+
143
+ if (statementNode !== null) {
144
+ const statementMatches = antecedent.matchStatementNode(statementNode, substitutions);
145
+
146
+ if (!statementMatches) { ///
147
+ return true;
148
+ }
149
+ }
150
+
151
+ }) || null;
152
+
153
+ const antecedentMatches = (assertion !== null);
154
+
155
+ return antecedentMatches;
156
+ }
157
+
158
+ function matchAntecedents(antecedent, assertions, substitutions) {
159
+ const antecedentsMatches = antecedent.every((antecedent) => {
160
+ const antecedentMatches = matchAntecedent(antecedent, assertions, substitutions);
161
+
162
+ if (antecedentMatches) {
163
+ return true;
164
+ }
165
+ });
166
+
167
+ return antecedentsMatches;
168
+ }
169
+
170
+ function matchConsequent(consequent, statementNode, substitutions) {
171
+ const nonTerminalNodeMatches = consequent.matchStatementNode(statementNode, substitutions),
172
+ consequentMatches = nonTerminalNodeMatches; ///
173
+
174
+ return consequentMatches;
175
+ }
176
+
177
+ function matchAntecedentsAndConsequent(antecedents, consequent, assertions, statementNode) {
178
+ let antecedentsMatchConsequent = false;
179
+
180
+ const substitutions = [],
181
+ antecedentsMatches = matchAntecedents(antecedents, assertions, substitutions);
182
+
183
+ if (antecedentsMatches) {
184
+ const consequentMatches = matchConsequent(consequent, statementNode, substitutions);
185
+
186
+ antecedentsMatchConsequent = consequentMatches; ///
187
+ }
188
+
189
+ return antecedentsMatchConsequent;
190
+ }
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+
3
+ import { first } from "./utilities/array";
4
+ import { nodeAsString } from "./utilities/string";
5
+ import { variableNameFromVariableNode } from "./utilities/query";
6
+ import { statementNodeFromStatementString } from "./utilities/string";
7
+ import { VARIABLE_RULE_NAME, STATEMENT_RULE_NAME } from "./ruleNames";
8
+
9
+ export default class Consequent {
10
+ constructor(statementNode) {
11
+ this.statementNode = statementNode;
12
+ }
13
+
14
+ getStatementNode() {
15
+ return this.statementNode;
16
+ }
17
+
18
+ matchStatementNode(statementNode, metaSubstitutions) {
19
+ const nonTerminalNode = statementNode, ///
20
+ consequentNonTerminalNode = this.statementNode, ///
21
+ consequentNonTerminalNodeMatches = matchConsequentNonTerminalNode(consequentNonTerminalNode, nonTerminalNode, metaSubstitutions),
22
+ statementNodeMatches = consequentNonTerminalNodeMatches; ///
23
+
24
+ return statementNodeMatches;
25
+ }
26
+
27
+ toJSON() {
28
+ const statementString = nodeAsString(this.statementNode),
29
+ statement = statementString, ///
30
+ json = {
31
+ statement
32
+ };
33
+
34
+ return json;
35
+ }
36
+
37
+ static fromJSON(json, releaseContext) {
38
+ const { statement } = json,
39
+ statementString = statement, ///
40
+ statementNode = statementNodeFromStatementString(statementString, releaseContext),
41
+ consequent = new Consequent(statementNode);
42
+
43
+ return consequent;
44
+ }
45
+
46
+ static fromStatementNode(statementNode) {
47
+ const consequent = new Consequent(statementNode);
48
+
49
+ return consequent;
50
+ }
51
+ }
52
+
53
+ function matchConsequentNode(consequentNode, node, metaSubstitutions) {
54
+ let consequentNodeMatches = false;
55
+
56
+ const nodeTerminalNode = node.isTerminalNode(),
57
+ ruleNodeTerminalNode = consequentNode.isTerminalNode();
58
+
59
+ if (nodeTerminalNode === ruleNodeTerminalNode) {
60
+ if (nodeTerminalNode) {
61
+ const terminalNode = node, ///
62
+ consequentTerminalNode = consequentNode, ///
63
+ consequentTerminalNodeMatches = matchConsequentTerminalNode(consequentTerminalNode, terminalNode, metaSubstitutions);
64
+
65
+ consequentNodeMatches = consequentTerminalNodeMatches; ///
66
+ } else {
67
+ const nonTerminalNode = node, ///
68
+ consequentNonTerminalNode = consequentNode, ///
69
+ consequentNonTerminalNodeMatches = matchConsequentNonTerminalNode(consequentNonTerminalNode, nonTerminalNode, metaSubstitutions);
70
+
71
+ consequentNodeMatches = consequentNonTerminalNodeMatches; ///
72
+ }
73
+ }
74
+
75
+ return consequentNodeMatches;
76
+ }
77
+
78
+ function matchConsequentNodes(consequentNodes, nodes, metaSubstitutions) {
79
+ let consequentNodesMatches = false;
80
+
81
+ const nodesLength = nodes.length,
82
+ consequentNodesLength = consequentNodes.length;
83
+
84
+ if (nodesLength === consequentNodesLength) {
85
+ consequentNodesMatches = nodes.every((node, index) => {
86
+ const consequentNode = consequentNodes[index],
87
+ consequentNodeMatches = matchConsequentNode(consequentNode, node, metaSubstitutions);
88
+
89
+ if (consequentNodeMatches) {
90
+ return true;
91
+ }
92
+ });
93
+ }
94
+
95
+ return consequentNodesMatches;
96
+ }
97
+
98
+ function matchConsequentVariable(consequentVariableNode, nodes, metaSubstitutions) {
99
+ let consequentVariableMatches = true;
100
+
101
+ const consequentVariableName = variableNameFromVariableNode(consequentVariableNode),
102
+ metaSubstitution = metaSubstitutions.find((metaSubstitution) => {
103
+ const variableName = metaSubstitution.getVariableName();
104
+
105
+ if (variableName === consequentVariableName) {
106
+ return true;
107
+ }
108
+ }) || null;
109
+
110
+ if (metaSubstitution !== null) {
111
+ const metaSubstitutionNodesMatch = metaSubstitution.matchNodes(nodes);
112
+
113
+ consequentVariableMatches = metaSubstitutionNodesMatch; ///
114
+ }
115
+
116
+ return consequentVariableMatches;
117
+ }
118
+
119
+ function matchConsequentTerminalNode(consequentTerminalNode, terminalNode, metaSubstitutions) {
120
+ const matches = consequentTerminalNode.match(terminalNode),
121
+ consequentTerminalNodeMatches = matches; ///
122
+
123
+ return consequentTerminalNodeMatches;
124
+ }
125
+
126
+ function matchConsequentNonTerminalNode(consequentNonTerminalNode, nonTerminalNode, metaSubstitutions) {
127
+ let consequentNonTerminalNodeMatches = false;
128
+
129
+ const ruleName = nonTerminalNode.getRuleName(),
130
+ consequentRuleName = consequentNonTerminalNode.getRuleName(); ///
131
+
132
+ if (ruleName === consequentRuleName) {
133
+ const childNodes = nonTerminalNode.getChildNodes(),
134
+ consequentChildNodes = consequentNonTerminalNode.getChildNodes(),
135
+ nodes = childNodes, ///
136
+ consequentNodes = consequentChildNodes, ///
137
+ consequentChildNodesMatches = matchConsequentNodes(consequentNodes, nodes, metaSubstitutions);
138
+
139
+ consequentNonTerminalNodeMatches = consequentChildNodesMatches; ///
140
+
141
+ if (!consequentNonTerminalNodeMatches) {
142
+ const ruleNameStatementRuleName = (ruleName === STATEMENT_RULE_NAME);
143
+
144
+ if (ruleNameStatementRuleName) {
145
+ const statementNode = nonTerminalNode, ///
146
+ consequentStatementNode = consequentNonTerminalNode, ///
147
+ consequentStatementNodeMatches = matchConsequentStatementNode(consequentStatementNode, statementNode, metaSubstitutions);
148
+
149
+ consequentNonTerminalNodeMatches = consequentStatementNodeMatches; ///
150
+ }
151
+ }
152
+ }
153
+
154
+ return consequentNonTerminalNodeMatches;
155
+ }
156
+
157
+ function matchConsequentStatementNode(consequentStatementNode, statementNode, metaSubstitutions) {
158
+ let consequentStatementNodeMatches = false;
159
+
160
+ const consequentNonTerminalNode = consequentStatementNode, ///
161
+ consequentChildNodes = consequentNonTerminalNode.getChildNodes(),
162
+ consequentChildNodesLength = consequentChildNodes.length;
163
+
164
+ if (consequentChildNodesLength === 1) {
165
+ const firstConsequentChildNode = first(consequentChildNodes),
166
+ consequentChildNode = firstConsequentChildNode, ///
167
+ consequentChildNodeNonTerminalNode = consequentChildNode.isNonTerminalNode();
168
+
169
+ if (consequentChildNodeNonTerminalNode) {
170
+ const consequentNonTerminalChildNode = consequentChildNode, ///
171
+ consequentNonTerminalChildNodeRuleName = consequentNonTerminalChildNode.getRuleName(),
172
+ consequentNonTerminalChildNodeRuleNameVariableRuleName = (consequentNonTerminalChildNodeRuleName === VARIABLE_RULE_NAME);
173
+
174
+ if (consequentNonTerminalChildNodeRuleNameVariableRuleName) {
175
+ const consequentVariableNode = consequentNonTerminalChildNode, ///
176
+ nonTerminalNode = statementNode, ///
177
+ childNodes = nonTerminalNode.getChildNodes(),
178
+ nodes = childNodes, ///
179
+ consequentMetaVariableMatches = matchConsequentVariable(consequentVariableNode, nodes, metaSubstitutions);
180
+
181
+ consequentStatementNodeMatches = consequentMetaVariableMatches; ///
182
+ }
183
+ }
184
+ }
185
+
186
+ return consequentStatementNodeMatches;
187
+ }
package/src/constants.js CHANGED
@@ -4,8 +4,10 @@ export const COMMA = ',';
4
4
  export const STRING = "string";
5
5
  export const NUMBER = "number";
6
6
  export const BOOLEAN = "boolean";
7
+ export const EMPTY_STRING = "";
7
8
  export const LEFT_BRACKET = "(";
8
9
  export const RIGHT_BRACKET = ")";
9
10
  export const MAXIMUM_INDEXES_LENGTH = 10;
10
11
  export const MAXIMUM_PERMUTATION_LENGTH = 5;
12
+ export const BRACKETED_STATEMENT_CHILD_NODES_LENGTH = 3;
11
13
  export const BRACKETED_METASTATEMENT_CHILD_NODES_LENGTH = 3;
package/src/lemma.js CHANGED
@@ -1,103 +1,13 @@
1
1
  "use strict";
2
2
 
3
- import Label from "./label";
3
+ import AxiomLemmaTheorem from "./axiomLemmaTheorem";
4
4
 
5
5
  import { LEMMA_KIND } from "./kinds";
6
- import { nodeAsString } from "./utilities/string";
7
6
 
8
- import { unqualifiedStatementNodeFromUnqualifiedStatementString, indicativeConditionalNodeFromIndicativeConditionalString } from "./utilities/string";
7
+ export default class Lemma extends AxiomLemmaTheorem {
8
+ static kind = LEMMA_KIND;
9
9
 
10
- export default class Lemma {
11
- constructor(labels, unqualifiedStatementNode, indicativeConditionalNode) {
12
- this.labels = labels;
13
- this.unqualifiedStatementNode = unqualifiedStatementNode;
14
- this.indicativeConditionalNode = indicativeConditionalNode;
15
- }
10
+ static fromJSON(json, releaseContext) { return AxiomLemmaTheorem.fromJSON(Lemma, json); }
16
11
 
17
- getLabels() {
18
- return this.labels;
19
- }
20
-
21
- getUnqualifiedStatementNode() {
22
- return this.unqualifiedStatementNode;
23
- }
24
-
25
- getIndicativeConditionalNode() {
26
- return this.indicativeConditionalNode;
27
- }
28
-
29
- matchLabelName(labelName) {
30
- const matchesLabelName = this.labels.some((label) => {
31
- const name = labelName, ///
32
- labelMatchesName = label.matchName(name);
33
-
34
- if (labelMatchesName) {
35
- return true;
36
- }
37
- });
38
-
39
- return matchesLabelName;
40
- }
41
-
42
- toJSON() {
43
- const labelsJSON = this.labels.map((label) => {
44
- const labelJSON = label.toJSON();
45
-
46
- return labelJSON;
47
- }),
48
- unqualifiedStatementString = nodeAsString(this.unqalifiedStatementNode),
49
- indicativeConditionalString = nodeAsString(this.indicativeConditionalNode),
50
- kind = LEMMA_KIND,
51
- labels = labelsJSON, ///
52
- unqualifiedStatement = unqualifiedStatementString, ///
53
- indicativeConditional = indicativeConditionalString, ///
54
- json = {
55
- kind,
56
- labels,
57
- unqualifiedStatement,
58
- indicativeConditional
59
- };
60
-
61
- return json;
62
- }
63
-
64
- static fromJSON(json, releaseContext) {
65
- let { labels } = json;
66
-
67
- const labelsJSON = labels; ///
68
-
69
- labels = labelsJSON.map((labelJSON) => {
70
- const json = labelJSON, ///
71
- label = Label.fromJSON(json, releaseContext);
72
-
73
- return label;
74
- });
75
-
76
- let { unqualifiedStatement, indicativeConditional } = json;
77
-
78
- let unqualifiedStatementNode = null,
79
- indicativeConditionalNode = null;
80
-
81
- if (unqualifiedStatement !== null) {
82
- const unqualifiedStatementString = unqualifiedStatement; ///
83
-
84
- unqualifiedStatementNode = unqualifiedStatementNodeFromUnqualifiedStatementString(unqualifiedStatementString, releaseContext);
85
- }
86
-
87
- if (indicativeConditional !== null) {
88
- const indicativeConditionalString = indicativeConditional; ///
89
-
90
- indicativeConditionalNode = indicativeConditionalNodeFromIndicativeConditionalString(indicativeConditionalString, releaseContext);
91
- }
92
-
93
- const lemma = new Lemma(labels, unqualifiedStatementNode, indicativeConditionalNode);
94
-
95
- return lemma;
96
- }
97
-
98
- static fromLabelsUnqualifiedStatementNodeAndIndicativeConditionalNode(labels, unqualifiedStatementNode, indicativeConditionalNode) {
99
- const lemma = new Lemma(labels, unqualifiedStatementNode, indicativeConditionalNode);
100
-
101
- return lemma;
102
- }
12
+ static fromLabelsAntecedentsAndConsequent(labels, antecedents, consequent) { return AxiomLemmaTheorem.fromLabelsAntecedentsAndConsequent(Lemma, labels, antecedents, consequent); }
103
13
  }
package/src/ruleNames.js CHANGED
@@ -8,7 +8,7 @@ export const METAVARIABLE_RULE_NAME = "metavariable";
8
8
  export const METASTATEMENT_RULE_NAME = "metastatement";
9
9
  export const META_SUBPROOF_RULE_NAME = "metaSubproof";
10
10
  export const UNQUALIFIED_STATEMENT_RULE_NAME = "unqualifiedStatement";
11
- export const INDICATIVE_CONDITIONAL_RULE_NAME = "indicativeConditional";
11
+ export const CONDITIONAL_INDICATIVE_RULE_NAME = "conditionalIndicative";
12
12
  export const COMBINATOR_DECLARATION_RULE_NAME = "combinatorDeclaration";
13
13
  export const CONSTRUCTOR_DECLARATION_RULE_NAME = "constructorDeclaration";
14
14
  export const QUALIFIED_METASTATEMENT_RULE_NAME = "qualifiedMetastatement";
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+
3
+ import { matchBracketedStatementChildNode, bracketedStatementChildNodeFromChildNodes } from "./utilities/statement";
4
+
5
+ export default class Substitution {
6
+ constructor(variableName, nodes) {
7
+ this.variableName = variableName;
8
+ this.nodes = nodes;
9
+ }
10
+
11
+ getVariableName() {
12
+ return this.variableName;
13
+ }
14
+
15
+ getNodes() {
16
+ return this.nodes;
17
+ }
18
+
19
+ matchNodes(nodes) {
20
+ let matches;
21
+
22
+ const substitutionNodes = this.nodes, ///
23
+ substitutionNonTerminalNodeMatches = matchSubstitutionNodes(substitutionNodes, nodes);
24
+
25
+ matches = substitutionNonTerminalNodeMatches; ///
26
+
27
+ if (!matches) {
28
+ const childNodes = nodes, ///
29
+ bracketedStatementChildNodeMatches = matchBracketedStatementChildNode(childNodes, (bracketedStatementChildNode) => {
30
+ const nonTerminalNode = bracketedStatementChildNode, ///
31
+ childNodes = nonTerminalNode.getChildNodes(),
32
+ nodes = childNodes, ///
33
+ assertionNonTerminalNodeMatches = matchSubstitutionNodes(substitutionNodes, nodes),
34
+ bracketedStatementChildNodeMatches = assertionNonTerminalNodeMatches; ///
35
+
36
+ return bracketedStatementChildNodeMatches;
37
+ });
38
+
39
+ matches = bracketedStatementChildNodeMatches; ///
40
+ }
41
+
42
+ return matches;
43
+ }
44
+
45
+ static fromVariableNameAndNodes(variableName, nodes) {
46
+ const bracketedStatementChildNode = bracketedStatementChildNodeFromChildNodes(nodes);
47
+
48
+ if (bracketedStatementChildNode !== null) {
49
+ const nonTerminalNode = bracketedStatementChildNode, ///
50
+ childNodes = nonTerminalNode.getChildNodes();
51
+
52
+ nodes = childNodes; ///
53
+ }
54
+
55
+ const substitution = new Substitution(variableName, nodes);
56
+
57
+ return substitution;
58
+ }
59
+ }
60
+
61
+ function matchSubstitutionNode(substitutionNode, node) {
62
+ let substitutionNodeMatches = false;
63
+
64
+ const nodeTerminalNode = node.isTerminalNode(),
65
+ ruleNodeTerminalNode = substitutionNode.isTerminalNode();
66
+
67
+ if (nodeTerminalNode === ruleNodeTerminalNode) {
68
+ if (nodeTerminalNode) {
69
+ const terminalNode = node, ///
70
+ substitutionTerminalNode = substitutionNode, ///
71
+ substitutionTerminalNodeMatches = matchSubstitutionTerminalNode(substitutionTerminalNode, terminalNode);
72
+
73
+ substitutionNodeMatches = substitutionTerminalNodeMatches; ///
74
+ } else {
75
+ const nonTerminalNode = node, ///
76
+ substitutionNonTerminalNode = substitutionNode, ///
77
+ substitutionNonTerminalNodeMatches = matchSubstitutionNonTerminalNode(substitutionNonTerminalNode, nonTerminalNode);
78
+
79
+ substitutionNodeMatches = substitutionNonTerminalNodeMatches; ///
80
+ }
81
+ }
82
+
83
+ return substitutionNodeMatches;
84
+ }
85
+
86
+ function matchSubstitutionNodes(substitutionNodes, nodes) {
87
+ let substitutionNodesMatches = false;
88
+
89
+ const nodesLength = nodes.length,
90
+ substitutionNodesLength = substitutionNodes.length;
91
+
92
+ if (nodesLength === substitutionNodesLength) {
93
+ substitutionNodesMatches = nodes.every((node, index) => {
94
+ const substitutionNode = substitutionNodes[index],
95
+ substitutionNodeMatches = matchSubstitutionNode(substitutionNode, node);
96
+
97
+ if (substitutionNodeMatches) {
98
+ return true;
99
+ }
100
+ })
101
+ }
102
+
103
+ return substitutionNodesMatches;
104
+ }
105
+
106
+ function matchSubstitutionTerminalNode(substitutionTerminalNode, terminalNode) {
107
+ const matches = substitutionTerminalNode.match(terminalNode),
108
+ substitutionTerminalNodeMatches = matches; ///
109
+
110
+ return substitutionTerminalNodeMatches;
111
+ }
112
+
113
+ function matchSubstitutionNonTerminalNode(substitutionNonTerminalNode, nonTerminalNode) {
114
+ let substitutionNonTerminalNodeMatches = false;
115
+
116
+ const ruleName = nonTerminalNode.getRuleName(),
117
+ substitutionRuleName = substitutionNonTerminalNode.getRuleName(); ///
118
+
119
+ if (ruleName === substitutionRuleName) {
120
+ const childNodes = nonTerminalNode.getChildNodes(),
121
+ substitutionChildNodes = substitutionNonTerminalNode.getChildNodes(),
122
+ nodes = childNodes, ///
123
+ substitutionNodes = substitutionChildNodes, ///
124
+ substitutionNodesMatches = matchSubstitutionNodes(substitutionNodes, nodes);
125
+
126
+ substitutionNonTerminalNodeMatches = substitutionNodesMatches; ///
127
+ }
128
+
129
+ return substitutionNonTerminalNodeMatches;
130
+ }