cortex-js / compute-engine

An engine for symbolic manipulation and numeric evaluation of math formulas expressed with MathJSON
https://cortexjs.io
MIT License
356 stars 42 forks source link

LaTeX parser does not support the quantifiers on the MathLive keyboard #139

Closed nathancarter closed 6 months ago

nathancarter commented 8 months ago

Description

If one creates an expression using MathLive, and uses either the universal or existential quantifiers (∀ as \forall, ∃ as \exists), the resulting LaTeX cannot be parsed into MathJSON. These quantifiers appear on the MathLive keyboard, and thus appear as if they are supported.

Steps to Reproduce

Here I show how to reproduce the behavior from the browser console, since that does not require clicking, etc., but the LaTeX used here could be created using the live widget if one wanted. to.

> MathfieldElement.computeEngine.parse('\\forall x, P').json
// => ["Error",["ErrorCode","'unexpected-command'","'\\forall'"],["LatexString","'\\forall'"]]
> MathfieldElement.computeEngine.parse('\\exists x, P').json
// => ["Error",["ErrorCode","'unexpected-command'","'\\exists'"],["LatexString","'\\exists'"]]

Actual Behavior

See above.

Expected Behavior

Well, I'm not sure exactly what the MathJSON convention for bound variables is. By parsing an integral, I find that it does not seem there is any special indicator that a variable is bound, other than the fact that the operator in question is one that binds variables, like so:

> MathfieldElement.computeEngine.parse('\\int x dx').json
// => ["Integrate","x","x"]
// (as opposed to something like ["Bound","x",["Integrate","x"]])

That's not a criticism, just an observation about the format. So I suppose what I'd expect is an analogous thing for the predicate logic quantifiers:

> MathfieldElement.computeEngine.parse('\\forall x, P').json
// => ["forall","x","P"]
> MathfieldElement.computeEngine.parse('\\exists x, P').json
// => ["exists","x","P"]

Although some folks use a nonstandard separator between the bound variable and the body (as in \forall x.P) or some other notation (as in (\forall x)P) those are atypical, and the most common thing I would expect to see in a math textbook is the syntax shown above.

Environment

I do not expect that this is a regression; it has probably always been this way.

MathLive version 0.98.5

Operating System macOS 12.4

Browser

Brave v1.61.109, but I don't expect this is browser-dependent.

nathancarter commented 6 months ago

Awesome, thanks!

One small suggestion: Your diff shows that you also support exists-unique and forall-unique, but I do not think that forall-unique is a real thing. https://math.stackexchange.com/questions/502101/for-all-unique-notation

arnog commented 6 months ago

Yes, good point. I've removed it.

arnog commented 6 months ago

Regarding "bound" variables... You can indicate that a variable should not be evaluated by wrapping it in a Hold expression, i.e. ["Hold", "x"]. This can be used to "declare" a variable, as in the first argument of a universal quantifier or integral, or to indicate that an expression should not be evaluated, as in the body of a universal quantifier or integral.

However, functions also have "attributes" that can indicate if the arguments of a function (or some arguments of a function) should be evaluated or not.

The universal quantifiers (and integral function) have their arguments automatically "held" (i.e. not evaluated), so they don't need to be wrapped with a ["Hold"] function, although that won't cause any problem if they are.

If you encounter additional syntactic variants for universal quantifiers that you feel it would be useful to support, let me know.