Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ghost opened this issue Dec 5, 2018 · 10 comments
Open

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

ghost opened this issue Dec 5, 2018 · 10 comments

Comments

@ghost
Copy link

ghost commented Dec 5, 2018

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"

@FoggyFinder
Copy link
Contributor

I think it's just trying to calculate:

"29^(11^7)"

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

@Happypig375
Copy link

Happypig375 commented Dec 5, 2018

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
Copy link

Happypig375 commented Dec 5, 2018

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

@ghost
Copy link
Author

ghost commented Dec 5, 2018

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?

@Happypig375
Copy link

Happypig375 commented Dec 5, 2018

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

@ghost
Copy link
Author

ghost commented Dec 5, 2018

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.

@Happypig375
Copy link

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

@ghost
Copy link
Author

ghost commented Dec 5, 2018

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.

@cdrnet
Copy link
Member

cdrnet commented Dec 5, 2018

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?

@MovGP0
Copy link

MovGP0 commented Sep 14, 2020

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 => // ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants