mathnet-symbolics icon indicating copy to clipboard operation
mathnet-symbolics copied to clipboard

SymbolicExpression.Parse freeze for "29^11^7"

Open ghost opened this issue 6 years ago • 10 comments

Using C# nuget package MathNet.Symbolics, ver 0.20.0

Parsing this expression "29^11^7" leads to freeze. Tried with Infix.ParseOrUndefined("29^11^7"); and SymbolicExpression.Parse("29^11^7")

When tried to put parenthesis it works fine "(29^11)^7"

ghost avatar Dec 05 '18 15:12 ghost

I think it's just trying to calculate:

"29^(11^7)"

that's very big number. So, put a parentheses is a good idea.

FoggyFinder avatar Dec 05 '18 15:12 FoggyFinder

Yes. Exponentiation is right-associative, which means that it is evaluated right-to-left.

This is because (29^11)^7 can be written as 29^(11*7) while the other cannot be easily simplified.

Happypig375 avatar Dec 05 '18 16:12 Happypig375

I think large number detection can be done to avoid hangs. (Using power rules while calculating instead of expanding to a very big number)

Happypig375 avatar Dec 05 '18 16:12 Happypig375

Yes, it sounds reasonable. The problem in my case with this expression is that it is entered by user and I don't have control over what he can enter. Is there a way to handle this?

ghost avatar Dec 05 '18 16:12 ghost

Evaluate asynchronously, show an activity indicator and provide a cancel button?

Happypig375 avatar Dec 05 '18 16:12 Happypig375

Evaluate asynchronously, show an activity indicator and provide a cancel button?

This is not possible, because my code is in web service invoked by other applications.

ghost avatar Dec 05 '18 16:12 ghost

Setting a default timeout so that each request will not take too much time?

Happypig375 avatar Dec 05 '18 16:12 Happypig375

This is not an option too, because I have to return meaningful result in short time. I have to somehow handle expressions like this without affecting the whole functionality. For now my workaround is to run it in separate thread and wait for specified number of milliseconds, but I prefer to have better way to do it.

ghost avatar Dec 05 '18 17:12 ghost

I guess we could have a global Control instance like in Numerics to control how a few operations like power behave on very large input (or expected very large output or expensive operation). Ugly, but usually good enough.

Any proposals on what good rules would be for power? Should the limitation be opt-in or opt-out?

cdrnet avatar Dec 05 '18 20:12 cdrnet

Instead of a default timeout, there should be

  • no eager execution. the user needs to explicitly apply an Expression.simplify function
  • calculations should be done with CancellationToken support

Using a CancellationToken allows for scenarios with cancel buttons, web requests, as well as timeouts (via the CancellationTokenSource).

Example

let expression = 9Q ** (9Q ** 9Q);
expression ==> "9^(9^9)"
use cts = new CancellationTokenSource (TimeSpan.FromSeconds 5)
try
    Expression.simplifyAsync expression cts.Token
with
| :? TaskCanceledException as e => // ...

MovGP0 avatar Sep 14 '20 21:09 MovGP0