occam-verify-cli 0.0.478 → 0.0.480

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.
package/src/equality.js CHANGED
@@ -2,10 +2,11 @@
2
2
 
3
3
  import { nodeQuery } from "./utilities/query";
4
4
  import { TERM_RULE_NAME } from "./ruleNames";
5
+ import { EQUALS_CHARACTER } from "./constants";
5
6
 
6
- const equalityNodeQuery = nodeQuery("/statement/equality!"),
7
- leftTermNodeQuery = nodeQuery("/equality/term[0]"),
8
- rightTermNodeQuery = nodeQuery("/equality/term[1]");
7
+ const specialNodeQuery = nodeQuery("/statement/@special!"),
8
+ leftTermNodeQuery = nodeQuery("/statement/term[0]"),
9
+ rightTermNodeQuery = nodeQuery("/statement/term[1]");
9
10
 
10
11
  export default class Equality {
11
12
  constructor(leftTermNode, rightTermNode) {
@@ -85,23 +86,20 @@ export default class Equality {
85
86
  const statementNode = proofStep.getStatementNode();
86
87
 
87
88
  if (statementNode !== null) {
88
- const equalityNode = equalityNodeQuery(statementNode);
89
+ const specialNode = specialNodeQuery(statementNode);
89
90
 
90
- if (equalityNode !== null) {
91
- const leftTermNode = leftTermNodeQuery(equalityNode),
92
- rightTermNode = rightTermNodeQuery(equalityNode);
91
+ if (specialNode !== null) {
92
+ const terminalNode = specialNode, ///
93
+ terminalNodeContent = terminalNode.getContent();
93
94
 
94
- equality = new Equality(leftTermNode, rightTermNode);
95
- }
96
- }
95
+ if (terminalNodeContent === EQUALS_CHARACTER) {
96
+ const leftTermNode = leftTermNodeQuery(statementNode),
97
+ rightTermNode = rightTermNodeQuery(statementNode);
97
98
 
98
- return equality;
99
- }
100
-
101
- static fromEqualityNode(equalityNode) {
102
- const leftTermNode = leftTermNodeQuery(equalityNode),
103
- rightTermNode = rightTermNodeQuery(equalityNode),
104
99
  equality = new Equality(leftTermNode, rightTermNode);
100
+ }
101
+ }
102
+ }
105
103
 
106
104
  return equality;
107
105
  }
@@ -1,58 +1,62 @@
1
1
  "use strict";
2
2
 
3
- import { matchNodes, bracketedChildNodeFromChildNodes } from "./utilities/node";
3
+ import { METASTATEMENT_RULE_NAME } from "./ruleNames";
4
+ import { matchNode, bracketedNonTerminalChildNodeFromChildNodes } from "./utilities/node";
4
5
 
5
6
  export default class MetaSubstitution {
6
- constructor(metavariableName, nodes) {
7
+ constructor(metavariableName, metastatementNode) {
7
8
  this.metavariableName = metavariableName;
8
- this.nodes = nodes;
9
+ this.metastatementNode = metastatementNode;
9
10
  }
10
11
 
11
12
  getMetavariableName() {
12
13
  return this.metavariableName;
13
14
  }
14
15
 
15
- getNodes() {
16
- return this.nodes;
16
+ getMetastatementNode() {
17
+ return this.metastatementNode;
17
18
  }
18
19
 
19
- matchNodes(nodes) {
20
- let matches;
20
+ matchMetastatementNode(metastatementNode) {
21
+ let matchesMetastatementNode;
21
22
 
22
- const nodesA = this.nodes, ///
23
- nodesB = nodes,
24
- metaSubstitutionNodesMatch = matchNodes(nodesA, nodesB);
23
+ const nodeA = this.metastatementNode, ///
24
+ nodeB = metastatementNode,
25
+ nodeMatches = matchNode(nodeA, nodeB);
25
26
 
26
- matches = metaSubstitutionNodesMatch; ///
27
+ matchesMetastatementNode = nodeMatches; ///
27
28
 
28
- if (!matches) {
29
- const childNodes = nodes, ///
30
- bracketedChildNode = bracketedChildNodeFromChildNodes(childNodes);
29
+ if (!matchesMetastatementNode) {
30
+ const nonTerminalNode = metastatementNode, ///
31
+ childNodes = nonTerminalNode.getChildNodes(), ///
32
+ ruleName = METASTATEMENT_RULE_NAME;
31
33
 
32
- if (bracketedChildNode !== null) {
33
- const nonTerminalNode = bracketedChildNode, ///
34
- childNodes = nonTerminalNode.getChildNodes(),
35
- nodesB = childNodes, ///
36
- nodesMatch = matchNodes(nodesA, nodesB);
34
+ metastatementNode = bracketedNonTerminalChildNodeFromChildNodes(childNodes, ruleName); ///
37
35
 
38
- matches = nodesMatch; ///
36
+ if (metastatementNode !== null) {
37
+ const nodeA = this.metastatementNode, ///
38
+ nodeB = metastatementNode,
39
+ nodeMatches = matchNode(nodeA, nodeB);
40
+
41
+ matchesMetastatementNode = nodeMatches; ///
39
42
  }
40
43
  }
41
44
 
42
- return matches;
45
+ return matchesMetastatementNode;
43
46
  }
44
47
 
45
- static fromMetavariableNameAndNodes(metavariableName, nodes) {
46
- const bracketedChildNode = bracketedChildNodeFromChildNodes(nodes);
48
+ static fromMetavariableNameAndMetastatementNode(metavariableName, metastatementNode) {
49
+ let metaSubstitution = new MetaSubstitution(metavariableName, metastatementNode);
47
50
 
48
- if (bracketedChildNode !== null) {
49
- const nonTerminalNode = bracketedChildNode, ///
50
- childNodes = nonTerminalNode.getChildNodes();
51
+ const nonTerminalNode = metastatementNode, ///
52
+ childNodes = nonTerminalNode.getChildNodes(),
53
+ ruleName = METASTATEMENT_RULE_NAME;
51
54
 
52
- nodes = childNodes; ///
53
- }
55
+ metastatementNode = bracketedNonTerminalChildNodeFromChildNodes(childNodes, ruleName); ///
54
56
 
55
- const metaSubstitution = new MetaSubstitution(metavariableName, nodes);
57
+ if (metastatementNode !== null) {
58
+ metaSubstitution = new MetaSubstitution(metavariableName, metastatementNode);
59
+ }
56
60
 
57
61
  return metaSubstitution;
58
62
  }
package/src/premise.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ import Substitution from "./substitution";
3
4
  import MetaSubstitution from "./metaSubstitution";
4
5
 
5
6
  import { first } from "./utilities/array";
@@ -7,11 +8,13 @@ import { nodeAsString } from "./utilities/string";
7
8
  import { nodeQuery, nodesQuery } from "./utilities/query";
8
9
  import { metavariableNameFromMetavariableNode } from "./utilities/query";
9
10
  import { metastatementNodeFromMetastatementString } from "./utilities/string";
10
- import { METAVARIABLE_RULE_NAME, METASTATEMENT_RULE_NAME } from "./ruleNames";
11
+ import { STATEMENT_RULE_NAME, METASTATEMENT_RULE_NAME, METAVARIABLE_RULE_NAME } from "./ruleNames";
11
12
 
12
13
  const metastatementNodesQuery = nodesQuery("/metaSubproofAssertion/metastatement"),
13
14
  metaSubproofAssertionNodeQuery = nodeQuery("/metastatement/metaSubproofAssertion!"),
15
+ unqualifiedStatementStatementNodesQuery = nodesQuery("/subproof/unqualifiedStatement/statement!"),
14
16
  unqualifiedMetastatementMetastatementNodesQuery = nodesQuery("/metaSubproof/unqualifiedMetastatement/metastatement!"),
17
+ qualifiedOrUnqualifiedStatementStatementNodeQuery = nodeQuery("/subproof/derivation|abridgedDerivation/qualifiedStatement|unqualifiedStatement[-1]/statement!"),
15
18
  qualifiedOrUnqualifiedMetastatementMetastatementNodeQuery = nodeQuery("/metaSubproof/metaDerivation|abridgedMetaDerivation/qualifiedMetastatement|unqualifiedMetastatement[-1]/metastatement!");
16
19
 
17
20
  export default class Premise {
@@ -23,6 +26,48 @@ export default class Premise {
23
26
  return this.metastatementNode;
24
27
  }
25
28
 
29
+ matchSubproofNode(subproofNode, substitutions) {
30
+ let subproofNodeMatches = false;
31
+
32
+ const subproofAssertionNode = metaSubproofAssertionNodeQuery(this.metastatementNode);
33
+
34
+ if (subproofAssertionNode !== null) {
35
+ const metaSubproofAssertionMetastatementNodes = metastatementNodesQuery(subproofAssertionNode),
36
+ unqualifiedStatementStatementNodes = unqualifiedStatementStatementNodesQuery(subproofNode),
37
+ qualifiedOrUnqualifiedStatementStatementNode = qualifiedOrUnqualifiedStatementStatementNodeQuery(subproofNode),
38
+ statementNodes = [
39
+ ...unqualifiedStatementStatementNodes,
40
+ qualifiedOrUnqualifiedStatementStatementNode
41
+ ],
42
+ statementNodesLength = statementNodes.length,
43
+ metaSubproofAssertionMetastatementNodesLength = metaSubproofAssertionMetastatementNodes.length;
44
+
45
+ if (statementNodesLength === metaSubproofAssertionMetastatementNodesLength) {
46
+ subproofNodeMatches = metaSubproofAssertionMetastatementNodes.every((metaSubproofAssertionMetastatementNode, index) => {
47
+ const statementNode = statementNodes[index],
48
+ nonTerminalNode = statementNode, ///
49
+ premiseNonTerminalNode = metaSubproofAssertionMetastatementNode, ///
50
+ premiseNonTerminalNodeMatches = matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, substitutions);
51
+
52
+ if (premiseNonTerminalNodeMatches) {
53
+ return true;
54
+ }
55
+ });
56
+ }
57
+ }
58
+
59
+ return subproofNodeMatches;
60
+ }
61
+
62
+ matchStatementNode(statementNode, substitutions) {
63
+ const nonTerminalNode = statementNode, ///
64
+ premiseNonTerminalNode = this.metastatementNode, ///
65
+ premiseNonTerminalNodeMatches = matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, substitutions),
66
+ statementNodeMatches = premiseNonTerminalNodeMatches; ///
67
+
68
+ return statementNodeMatches;
69
+ }
70
+
26
71
  matchMetaSubproofNode(metaSubproofNode, metaSubstitutions) {
27
72
  let metaSubproofNodeMatches = false;
28
73
 
@@ -44,7 +89,7 @@ export default class Premise {
44
89
  const metastatementNode = metastatementNodes[index],
45
90
  nonTerminalNode = metastatementNode, ///
46
91
  premiseNonTerminalNode = metaSubproofAssertionMetastatementNode, ///
47
- premiseNonTerminalNodeMatches = matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions);
92
+ premiseNonTerminalNodeMatches = metaMatchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions);
48
93
 
49
94
  if (premiseNonTerminalNodeMatches) {
50
95
  return true;
@@ -59,7 +104,7 @@ export default class Premise {
59
104
  matchMetastatementNode(metastatementNode, metaSubstitutions) {
60
105
  const nonTerminalNode = metastatementNode, ///
61
106
  premiseNonTerminalNode = this.metastatementNode, ///
62
- premiseNonTerminalNodeMatches = matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions),
107
+ premiseNonTerminalNodeMatches = metaMatchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions),
63
108
  metastatementNodeMatches = premiseNonTerminalNodeMatches; ///
64
109
 
65
110
  return metastatementNodeMatches;
@@ -91,23 +136,23 @@ export default class Premise {
91
136
  }
92
137
  }
93
138
 
94
- function matchPremiseNode(premiseNode, node, metaSubstitutions) {
139
+ function matchPremiseNode(premiseNode, node, substitutions) {
95
140
  let premiseNodeMatches = false;
96
141
 
97
142
  const nodeTerminalNode = node.isTerminalNode(),
98
- ruleNodeTerminalNode = premiseNode.isTerminalNode();
143
+ ruleNodeTerminalNode = premiseNode.isTerminalNode();
99
144
 
100
145
  if (nodeTerminalNode === ruleNodeTerminalNode) {
101
146
  if (nodeTerminalNode) {
102
147
  const terminalNode = node, ///
103
148
  premiseTerminalNode = premiseNode, ///
104
- premiseTerminalNodeMatches = matchPremiseTerminalNode(premiseTerminalNode, terminalNode, metaSubstitutions);
149
+ premiseTerminalNodeMatches = matchPremiseTerminalNode(premiseTerminalNode, terminalNode, substitutions);
105
150
 
106
151
  premiseNodeMatches = premiseTerminalNodeMatches; ///
107
152
  } else {
108
153
  const nonTerminalNode = node, ///
109
154
  premiseNonTerminalNode = premiseNode, ///
110
- premiseNonTerminalNodeMatches = matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions);
155
+ premiseNonTerminalNodeMatches = matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, substitutions);
111
156
 
112
157
  premiseNodeMatches = premiseNonTerminalNodeMatches; ///
113
158
  }
@@ -116,7 +161,7 @@ function matchPremiseNode(premiseNode, node, metaSubstitutions) {
116
161
  return premiseNodeMatches;
117
162
  }
118
163
 
119
- function matchPremiseNodes(premiseNodes, nodes, metaSubstitutions) {
164
+ function matchPremiseNodes(premiseNodes, nodes, substitutions) {
120
165
  let premiseNodesMatches = false;
121
166
 
122
167
  const nodesLength = nodes.length,
@@ -125,7 +170,7 @@ function matchPremiseNodes(premiseNodes, nodes, metaSubstitutions) {
125
170
  if (nodesLength === premiseNodesLength) {
126
171
  premiseNodesMatches = nodes.every((node, index) => {
127
172
  const premiseNode = premiseNodes[index],
128
- premiseNodeMatches = matchPremiseNode(premiseNode, node, metaSubstitutions);
173
+ premiseNodeMatches = matchPremiseNode(premiseNode, node, substitutions);
129
174
 
130
175
  if (premiseNodeMatches) {
131
176
  return true;
@@ -136,81 +181,225 @@ function matchPremiseNodes(premiseNodes, nodes, metaSubstitutions) {
136
181
  return premiseNodesMatches;
137
182
  }
138
183
 
139
- function matchPremiseMetavariable(premiseMetavariableNode, nodes, metaSubstitutions) {
140
- let premiseMetavariableMatches;
184
+ function matchPremiseTerminalNode(premiseTerminalNode, terminalNode, substitutions) {
185
+ const matches = premiseTerminalNode.match(terminalNode),
186
+ premiseTerminalNodeMatches = matches;
187
+
188
+ return premiseTerminalNodeMatches;
189
+ }
190
+
191
+ function matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, substitutions) {
192
+ let premiseNonTerminalNodeMatches = false;
193
+
194
+ const ruleName = nonTerminalNode.getRuleName(),
195
+ childNodes = nonTerminalNode.getChildNodes(),
196
+ premiseNonTerminalNodeRuleName = premiseNonTerminalNode.getRuleName(),
197
+ premiseNonTerminalNodeChildNodes = premiseNonTerminalNode.getChildNodes(),
198
+ nodes = childNodes, ///
199
+ premiseNodes = premiseNonTerminalNodeChildNodes, ///
200
+ ruleNameStatementRuleName = (ruleName === STATEMENT_RULE_NAME),
201
+ premiseNonTerminalNodeRuleNameMetastatementRuleName = (premiseNonTerminalNodeRuleName === METASTATEMENT_RULE_NAME);
202
+
203
+ if (ruleNameStatementRuleName && premiseNonTerminalNodeRuleNameMetastatementRuleName) {
204
+ const statementNode = nonTerminalNode, ///
205
+ premiseMetastatementNode = premiseNonTerminalNode, ///
206
+ premiseMetastatementNodeMatches = matchPremiseMetastatementNode(premiseMetastatementNode, statementNode, substitutions);
207
+
208
+ if (premiseMetastatementNodeMatches) {
209
+ premiseNonTerminalNodeMatches = true;
210
+ } else {
211
+ const premiseNonTerminalNodeChildNodesMatches = matchPremiseNodes(premiseNodes, nodes, substitutions);
212
+
213
+ premiseNonTerminalNodeMatches = premiseNonTerminalNodeChildNodesMatches; ///
214
+ }
215
+ } else if (ruleName === premiseNonTerminalNodeRuleName) {
216
+ const premiseNonTerminalNodeChildNodesMatches = matchPremiseNodes(premiseNodes, nodes, substitutions);
217
+
218
+ premiseNonTerminalNodeMatches = premiseNonTerminalNodeChildNodesMatches; ///
219
+ }
220
+
221
+ return premiseNonTerminalNodeMatches;
222
+ }
223
+
224
+ function matchPremiseMetavariableNode(premiseMetavariableNode, statementNode, substitutions) {
225
+ let premiseMetavariableNodeMatches;
141
226
 
142
227
  const premiseMetavariableName = metavariableNameFromMetavariableNode(premiseMetavariableNode),
143
- metaSubstitution = metaSubstitutions.find((metaSubstitution) => {
144
- const metavariableName = metaSubstitution.getMetavariableName();
228
+ substitution = substitutions.find((substitution) => {
229
+ const metavariableName = substitution.getMetavariableName();
145
230
 
146
231
  if (metavariableName === premiseMetavariableName) {
147
232
  return true;
148
233
  }
149
234
  }) || null;
150
235
 
151
- if (metaSubstitution !== null) {
152
- const metaSubstitutionNodesMatch = metaSubstitution.matchNodes(nodes);
236
+ if (substitution !== null) {
237
+ const substitutionNodesMatch = substitution.matchStatementNode(statementNode);
153
238
 
154
- premiseMetavariableMatches = metaSubstitutionNodesMatch; ///
239
+ premiseMetavariableNodeMatches = substitutionNodesMatch; ///
155
240
  } else {
156
241
  const metavariableName = premiseMetavariableName, ///
157
- metaSubstitution = MetaSubstitution.fromMetavariableNameAndNodes(metavariableName, nodes);
242
+ substitution = Substitution.fromMetavariableNameAndStatementNode(metavariableName, statementNode);
158
243
 
159
- metaSubstitutions.push(metaSubstitution);
244
+ substitutions.push(substitution);
245
+
246
+ premiseMetavariableNodeMatches = true;
247
+ }
248
+
249
+ return premiseMetavariableNodeMatches;
250
+ }
251
+
252
+ function matchPremiseMetastatementNode(premiseMetastatementNode, statementNode, substitutions) {
253
+ let premiseMetastatementNodeMatches = false;
254
+
255
+ const premiseNonTerminalNode = premiseMetastatementNode, ///
256
+ premiseNonTerminalNodeChildNodes = premiseNonTerminalNode.getChildNodes(),
257
+ premiseNonTerminalNodeChildNodesLength = premiseNonTerminalNodeChildNodes.length;
258
+
259
+ if (premiseNonTerminalNodeChildNodesLength === 1) {
260
+ const firstPremiseChildNode = first(premiseNonTerminalNodeChildNodes),
261
+ premiseChildNode = firstPremiseChildNode, ///
262
+ premiseChildNodeNonTerminalNode = premiseChildNode.isNonTerminalNode();
263
+
264
+ if (premiseChildNodeNonTerminalNode) {
265
+ const premiseNonTerminalChildNode = premiseChildNode, ///
266
+ premiseNonTerminalChildNodeRuleName = premiseNonTerminalChildNode.getRuleName(),
267
+ premiseNonTerminalChildNodeRuleNameMetavariableRuleName = (premiseNonTerminalChildNodeRuleName === METAVARIABLE_RULE_NAME);
268
+
269
+ if (premiseNonTerminalChildNodeRuleNameMetavariableRuleName) {
270
+ const premiseMetavariableNode = premiseNonTerminalChildNode, ///
271
+ premiseMetaVariableNodeMatches = matchPremiseMetavariableNode(premiseMetavariableNode, statementNode, substitutions);
272
+
273
+ premiseMetastatementNodeMatches = premiseMetaVariableNodeMatches; ///
274
+ }
275
+ }
276
+ }
160
277
 
161
- premiseMetavariableMatches = true;
278
+ return premiseMetastatementNodeMatches;
279
+ }
280
+
281
+ function metaMatchPremiseNode(premiseNode, node, metaSubstitutions) {
282
+ let premiseNodeMatches = false;
283
+
284
+ const nodeTerminalNode = node.isTerminalNode(),
285
+ ruleNodeTerminalNode = premiseNode.isTerminalNode();
286
+
287
+ if (nodeTerminalNode === ruleNodeTerminalNode) {
288
+ if (nodeTerminalNode) {
289
+ const terminalNode = node, ///
290
+ premiseTerminalNode = premiseNode, ///
291
+ premiseTerminalNodeMatches = metaMatchPremiseTerminalNode(premiseTerminalNode, terminalNode, metaSubstitutions);
292
+
293
+ premiseNodeMatches = premiseTerminalNodeMatches; ///
294
+ } else {
295
+ const nonTerminalNode = node, ///
296
+ premiseNonTerminalNode = premiseNode, ///
297
+ premiseNonTerminalNodeMatches = metaMatchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions);
298
+
299
+ premiseNodeMatches = premiseNonTerminalNodeMatches; ///
300
+ }
162
301
  }
163
302
 
164
- return premiseMetavariableMatches;
303
+ return premiseNodeMatches;
165
304
  }
166
305
 
167
- function matchPremiseTerminalNode(premiseTerminalNode, terminalNode, metaSubstitutions) {
306
+ function metaMatchPremiseNodes(premiseNodes, nodes, metaSubstitutions) {
307
+ let premiseNodesMatches = false;
308
+
309
+ const nodesLength = nodes.length,
310
+ premiseNodesLength = premiseNodes.length;
311
+
312
+ if (nodesLength === premiseNodesLength) {
313
+ premiseNodesMatches = nodes.every((node, index) => {
314
+ const premiseNode = premiseNodes[index],
315
+ premiseNodeMatches = metaMatchPremiseNode(premiseNode, node, metaSubstitutions);
316
+
317
+ if (premiseNodeMatches) {
318
+ return true;
319
+ }
320
+ });
321
+ }
322
+
323
+ return premiseNodesMatches;
324
+ }
325
+
326
+ function metaMatchPremiseTerminalNode(premiseTerminalNode, terminalNode, metaSubstitutions) {
168
327
  const matches = premiseTerminalNode.match(terminalNode),
169
328
  premiseTerminalNodeMatches = matches;
170
329
 
171
330
  return premiseTerminalNodeMatches;
172
331
  }
173
332
 
174
- function matchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions) {
333
+ function metaMatchPremiseNonTerminalNode(premiseNonTerminalNode, nonTerminalNode, metaSubstitutions) {
175
334
  let premiseNonTerminalNodeMatches = false;
176
335
 
177
336
  const ruleName = nonTerminalNode.getRuleName(),
178
- premiseRuleName = premiseNonTerminalNode.getRuleName(); ///
337
+ childNodes = nonTerminalNode.getChildNodes(),
338
+ premiseNonTerminalNodeRuleName = premiseNonTerminalNode.getRuleName(),
339
+ premiseNonTerminalNodeChildNodes = premiseNonTerminalNode.getChildNodes(),
340
+ nodes = childNodes, ///
341
+ premiseNodes = premiseNonTerminalNodeChildNodes, ///
342
+ ruleNameMetastatementRuleName = (ruleName === METASTATEMENT_RULE_NAME),
343
+ premiseNonTerminalNodeRuleNameMetastatementRuleName = (premiseNonTerminalNodeRuleName === METASTATEMENT_RULE_NAME);
344
+
345
+ if (ruleNameMetastatementRuleName && premiseNonTerminalNodeRuleNameMetastatementRuleName) {
346
+ const metastatementNode = nonTerminalNode, ///
347
+ premiseMetastatementNode = premiseNonTerminalNode, ///
348
+ premiseMetastatementNodeMatches = metaMatchPremiseMetastatementNode(premiseMetastatementNode, metastatementNode, metaSubstitutions);
349
+
350
+ if (premiseMetastatementNodeMatches) {
351
+ premiseNonTerminalNodeMatches = true;
352
+ } else {
353
+ const premiseNonTerminalNodeChildNodesMatches = metaMatchPremiseNodes(premiseNodes, nodes, metaSubstitutions);
179
354
 
180
- if (ruleName === premiseRuleName) {
181
- const childNodes = nonTerminalNode.getChildNodes(),
182
- premiseChildNodes = premiseNonTerminalNode.getChildNodes(),
183
- nodes = childNodes, ///
184
- premiseNodes = premiseChildNodes, ///
185
- premiseChildNodesMatches = matchPremiseNodes(premiseNodes, nodes, metaSubstitutions);
355
+ premiseNonTerminalNodeMatches = premiseNonTerminalNodeChildNodesMatches; ///
356
+ }
357
+ } else if (ruleName === premiseNonTerminalNodeRuleName) {
358
+ const premiseNonTerminalNodeChildNodesMatches = metaMatchPremiseNodes(premiseNodes, nodes, metaSubstitutions);
186
359
 
187
- premiseNonTerminalNodeMatches = premiseChildNodesMatches; ///
360
+ premiseNonTerminalNodeMatches = premiseNonTerminalNodeChildNodesMatches; ///
361
+ }
188
362
 
189
- if (!premiseNonTerminalNodeMatches) {
190
- const ruleNameMetastatementRuleName = (ruleName === METASTATEMENT_RULE_NAME);
363
+ return premiseNonTerminalNodeMatches;
364
+ }
191
365
 
192
- if (ruleNameMetastatementRuleName) {
193
- const metastatementNode = nonTerminalNode, ///
194
- premiseMetastatementNode = premiseNonTerminalNode, ///
195
- premiseMetastatementNodeMatches = matchPremiseMetastatementNode(premiseMetastatementNode, metastatementNode, metaSubstitutions);
366
+ function metaMatchPremiseMetavariableNode(premiseMetavariableNode, metastatementNode, metaSubstitutions) {
367
+ let premiseMetavariableNodeMatches;
196
368
 
197
- premiseNonTerminalNodeMatches = premiseMetastatementNodeMatches; ///
198
- }
199
- }
369
+ const premiseMetavariableName = metavariableNameFromMetavariableNode(premiseMetavariableNode),
370
+ metaSubstitution = metaSubstitutions.find((metaSubstitution) => {
371
+ const metavariableName = metaSubstitution.getMetavariableName();
372
+
373
+ if (metavariableName === premiseMetavariableName) {
374
+ return true;
375
+ }
376
+ }) || null;
377
+
378
+ if (metaSubstitution !== null) {
379
+ const metaSubstitutionNodesMatch = metaSubstitution.matchMetastatementNode(metastatementNode);
380
+
381
+ premiseMetavariableNodeMatches = metaSubstitutionNodesMatch; ///
382
+ } else {
383
+ const metavariableName = premiseMetavariableName, ///
384
+ metaSubstitution = MetaSubstitution.fromMetavariableNameAndMetastatementNode(metavariableName, metastatementNode);
385
+
386
+ metaSubstitutions.push(metaSubstitution);
387
+
388
+ premiseMetavariableNodeMatches = true;
200
389
  }
201
390
 
202
- return premiseNonTerminalNodeMatches;
391
+ return premiseMetavariableNodeMatches;
203
392
  }
204
393
 
205
- function matchPremiseMetastatementNode(premiseMetastatementNode, metastatementNode, metaSubstitutions) {
394
+ function metaMatchPremiseMetastatementNode(premiseMetastatementNode, metastatementNode, metaSubstitutions) {
206
395
  let premiseMetastatementNodeMatches = false;
207
396
 
208
397
  const premiseNonTerminalNode = premiseMetastatementNode, ///
209
- premiseChildNodes = premiseNonTerminalNode.getChildNodes(),
210
- premiseChildNodesLength = premiseChildNodes.length;
398
+ premiseNonTerminalNodeChildNodes = premiseNonTerminalNode.getChildNodes(),
399
+ premiseNonTerminalNodeChildNodesLength = premiseNonTerminalNodeChildNodes.length;
211
400
 
212
- if (premiseChildNodesLength === 1) {
213
- const firstPremiseChildNode = first(premiseChildNodes),
401
+ if (premiseNonTerminalNodeChildNodesLength === 1) {
402
+ const firstPremiseChildNode = first(premiseNonTerminalNodeChildNodes),
214
403
  premiseChildNode = firstPremiseChildNode, ///
215
404
  premiseChildNodeNonTerminalNode = premiseChildNode.isNonTerminalNode();
216
405
 
@@ -221,12 +410,9 @@ function matchPremiseMetastatementNode(premiseMetastatementNode, metastatementNo
221
410
 
222
411
  if (premiseNonTerminalChildNodeRuleNameMetavariableRuleName) {
223
412
  const premiseMetavariableNode = premiseNonTerminalChildNode, ///
224
- nonTerminalNode = metastatementNode, ///
225
- childNodes = nonTerminalNode.getChildNodes(),
226
- nodes = childNodes, ///
227
- premiseMetaVariableMatches = matchPremiseMetavariable(premiseMetavariableNode, nodes, metaSubstitutions);
413
+ premiseMetaVariableNodeMatches = metaMatchPremiseMetavariableNode(premiseMetavariableNode, metastatementNode, metaSubstitutions);
228
414
 
229
- premiseMetastatementNodeMatches = premiseMetaVariableMatches; ///
415
+ premiseMetastatementNodeMatches = premiseMetaVariableNodeMatches; ///
230
416
  }
231
417
  }
232
418
  }