Skip to content

Commit c2da6c0

Browse files
committed
forall and exists
1 parent dd6c3b2 commit c2da6c0

14 files changed

+93
-7
lines changed

build/math-expressions.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/math-expressions_umd.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/converters/ast-to-latex.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ const operators = {
101101
"ne": function (operands) {
102102
return operands.join(' \\ne ');
103103
},
104+
"forall": function (operands) {
105+
return "\\forall " + operands[0];
106+
},
107+
"exists": function (operands) {
108+
return "\\exists " + operands[0];
109+
},
104110
"in": function (operands) {
105111
return operands[0] + " \\in " + operands[1];
106112
},
@@ -284,6 +290,10 @@ class astToLatex {
284290
}.bind(this)));
285291
}
286292

293+
if (operator === "exists" || operator === "forall") {
294+
return operators[operator]([this.single_statement(operands[0])]);
295+
}
296+
287297
if ((operator === '=') || (operator === 'ne') ||
288298
(operator === '<') || (operator === '>') ||
289299
(operator === 'le') || (operator === 'ge') ||

lib/converters/ast-to-text.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ const unicode_operators = {
5050
"le": function (operands) { return operands.join(' ≤ '); },
5151
"ge": function (operands) { return operands.join(' ≥ '); },
5252
"ne": function (operands) { return operands.join(' ≠ '); },
53+
"forall": function (operands) { return "∀ " + operands[0]; },
54+
"exists": function (operands) { return "∃ " + operands[0]; },
5355
"in": function (operands) { return operands[0] + " ∈ " + operands[1]; },
5456
"notin": function (operands) { return operands[0] + " ∉ " + operands[1]; },
5557
"ni": function (operands) { return operands[0] + " ∋ " + operands[1]; },
@@ -111,6 +113,8 @@ const nonunicode_operators = {
111113
"le": function (operands) { return operands.join(' <= '); },
112114
"ge": function (operands) { return operands.join(' >= '); },
113115
"ne": function (operands) { return operands.join(' ne '); },
116+
"forall": function (operands) { return "forall " + operands[0]; },
117+
"exists": function (operands) { return "exists " + operands[0]; },
114118
"in": function (operands) { return operands[0] + " elementof " + operands[1]; },
115119
"notin": function (operands) { return operands[0] + " notelementof " + operands[1]; },
116120
"ni": function (operands) { return operands[0] + " containselement " + operands[1]; },
@@ -217,6 +221,10 @@ class astToText {
217221
}.bind(this)));
218222
}
219223

224+
if (operator === "exists" || operator === "forall") {
225+
return this.operators[operator]([this.single_statement(operands[0])]);
226+
}
227+
220228
if ((operator === '=') || (operator === 'ne')
221229
|| (operator === '<') || (operator === '>')
222230
|| (operator === 'le') || (operator === 'ge')

lib/converters/latex-to-ast.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ const base_latex_rules = [
296296
['>', '>'],
297297
['\\\\gt(?![a-zA-Z])', '>'],
298298

299+
['\\\\forall(?![a-zA-Z])', 'FORALL'],
300+
['\\\\exists(?![a-zA-Z])', 'EXISTS'],
301+
299302
['\\\\in(?![a-zA-Z])', 'IN'],
300303

301304
['\\\\notin(?![a-zA-Z])', 'NOTIN'],
@@ -594,6 +597,12 @@ class latexToAst {
594597
return ['not', this.relation(params)];
595598
}
596599

600+
if(this.token.token_type === "FORALL" || this.token.token_type === "EXISTS") {
601+
let operator = this.token.token_type.toLowerCase();
602+
this.advance();
603+
return [operator, this.relation(params)];
604+
}
605+
597606
var lhs = this.expression(params);
598607

599608
while ((this.token.token_type === '=') || (this.token.token_type === 'NE')

lib/converters/text-to-ast.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ const base_text_rules = [
295295
['<', '<'],
296296
['>', '>'],
297297

298+
['forall(?![a-zA-Z0-9])', 'FORALL'],
299+
['\u2200', 'FORALL'], // '∀'
300+
301+
['exists(?![a-zA-Z0-9])', 'EXISTS'],
302+
['\u2203', 'EXISTS'], // '∃'
303+
298304
['elementof(?![a-zA-Z0-9])', 'IN'],
299305
['\u2208', 'IN'], // '∈'
300306

@@ -592,6 +598,12 @@ class textToAst {
592598
return ['not', this.relation(params)];
593599
}
594600

601+
if(this.token.token_type === "FORALL" || this.token.token_type === "EXISTS") {
602+
let operator = this.token.token_type.toLowerCase();
603+
this.advance();
604+
return [operator, this.relation(params)];
605+
}
606+
595607
var lhs = this.expression(params);
596608

597609
while ((this.token.token_type === '=') || (this.token.token_type === 'NE') ||

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "math-expressions",
33
"description": "Perform basic equality testing and symbolic computations on mathematical expressions involving transcendental functions",
4-
"version": "2.0.0-alpha58",
4+
"version": "2.0.0-alpha59",
55
"author": {
66
"name": "Jim Fowler",
77
"email": "[email protected]",

spec/quick_ast-to-latex.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,22 @@ const objectsToTest = [
599599
'ast': ['notsuperseteq', 'A', 'B'],
600600
'latex': 'A \\not\\supseteq B'
601601
},
602+
{
603+
'ast': ['forall', 'x'],
604+
'latex': '\\forall x'
605+
},
606+
{
607+
'ast': ['forall', ['in', 'x', 'A']],
608+
'latex': '\\forall x \\in A'
609+
},
610+
{
611+
'ast': ['exists', 'x'],
612+
'latex': '\\exists x'
613+
},
614+
{
615+
'ast': ['exists', ['in', 'x', 'A']],
616+
'latex': '\\exists x \\in A'
617+
},
602618
{
603619
'ast': ['in', 'x', 'A'],
604620
'latex': 'x \\in A'

spec/quick_ast-to-text.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,22 @@ const objectsToTest = [
552552
'ast': ['notsuperseteq', 'A', 'B'],
553553
'text': 'A ⊉ B'
554554
},
555+
{
556+
'ast': ['forall', 'x'],
557+
'text': '∀ x'
558+
},
559+
{
560+
'ast': ['forall', ['in', 'x', 'A']],
561+
'text': '∀ x ∈ A'
562+
},
563+
{
564+
'ast': ['exists', 'x'],
565+
'text': '∃ x'
566+
},
567+
{
568+
'ast': ['exists', ['in', 'x', 'A']],
569+
'text': '∃ x ∈ A'
570+
},
555571
{
556572
'ast': ['in', 'x', 'A'],
557573
'text': 'x ∈ A'

0 commit comments

Comments
 (0)