mathlive
mathlive copied to clipboard
MathLive.latexToAST misbehaves on expressions involving symbols f,g
Prerequisites
- [X] New issue
Description
MathLive.latexToAST interprets single letters f,g as functions in all contexts, even when that is mathematically inappropriate;
Fore example, f \cdot h being interpreted as f(\cdot h) instead of as a product.
Actual behavior
MathLive.latexToAST("f \cdot h")
returns
{"fn":"f","arg":[
{"fn":"multiply","arg":[
{"sym":"*"},
{"sym":"h"}
]}
]}
Expected Behavior
MathLive.latexToAST("f \cdot h")
returns
{"fn":"multiply","arg":[
{"sym":"f"},
{"sym":"h"}
]}
Steps to Reproduce
Invoke MathLive.latexToAST("f \cdot h") or equivalent
Environment
Operating System Windows 10 Home Version 10.0.18362 Browser Firefox 73.0 Chrome 80.0
Additionally, expressions such as h(x) are not intepreted as functions.
I am not sure whether to consider this a bug per se in its own issue, as it can be ambiguous in cases such as x(x+1), but for my use cases would prefer h(x) interpreted as a function h and h \cdot (x) as unambiguously a product.
This is a known limitation.
I intend to resolve it by allowing the input of "rules" for the generation of the MathJSON, so you could specify which symbols should be interpreted as functions (or which operators you want to support, etc...).
I do need to do some underlying work in the implementation of the LatexToJSON converter before I can do this (ETA April). I'm not sure if providing another (temporary) mechanism in the short term is worthwhile, though.
That ability would allow for me to achieve what I want via parsing $text() for function names before passing it on.
As far as workarounds go, is there a way to specify for latexToAST in the LaTeX that a string is a function name? That would allow for a preprocessing workaround as well.
@arnog what's your priorities in terms of fully specing out the MathJSON? Do you have a list of operation/rules you want to full be able to implement? I've been interested in your MathJSON since I stumbled across it a year ago... I'd love to help out if you have a proposal or plan
It's high on the list. Something I want to make some progress on in the next few weeks. I do have a pretty good idea of what I want to do, but nothing written down yet. One non-backward compatible change I want to make is to change how function nodes work:
- before:
{fn:"add", arg: [{num:2},{num:3}]} - after:
{fn: ["add", {num:2}, {num:3}]}
The first argument to the fn key could also be not only a function name (as a string), but also an expression to support lambda-expressions.
I also plan to introduce new primitive representing concatenation of symbols (to represent "xy" without assuming it's a multiplication).
And as I mention above, use a dictionary of (customizable) transformation rules to transform a basic expression depending on the specific domain of interest (i.e. to transform a sequence "xy" into a multiplication of "x" by "y").
Oh, and before that I'll introduce a (customizable) dictionary of symbols to be interpreted as functions, which will solve the issue in this particular report.
I think the behavior of the fn should be similar to the behavior I see in the sympy package... where expr == expr.func(*expr.args)... such that the fn is an abstract tree where each node comprises of a fn (which can be an atom like num) and args. That way we can recurse through the fn tree.
I think you're considering that with the ability to pass in lambda expressions into the first argument of fn.
And as I mention above, use a dictionary of (customizable) transformation rules to transform a basic expression depending on the specific domain of interest (i.e. to transform a sequence "xy" into a multiplication of "x" by "y").
That would be HUGE.
This is now behaving as expected