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

Optimizer does not account for INF and NAN #16

Open
Muqsit opened this issue Oct 28, 2022 · 0 comments
Open

Optimizer does not account for INF and NAN #16

Muqsit opened this issue Oct 28, 2022 · 0 comments
Labels
bug Something isn't working

Comments

@Muqsit
Copy link
Owner

Muqsit commented Oct 28, 2022

Description

Operator Strength Reduction optimizer directly substitutes a sub-expression x - x with 0, not accounting for INF or NAN values being supplied to x (inf - inf and nan - nan must produce nan). Other affected cases include 0 * inf returning 0 instead of NAN, and sqrt(-1) / sqrt(-1) getting substituted for 1 despite sqrt(-1) === NAN (NAN / NAN === NAN).

As variable resolution occurs during evaluation, x - x cannot be resolved during parsing although 1 - 1 and inf - inf can. One way to address this would be to resolve operations between numeric literal operands during parsing and implement a mechanism to toggle optimizations that disregard INF and NAN (like GCC's FloatingPointMath flags).

Workarounds

  1. Filter out operator strength reduction optimization from ExpressionOptimizerRegistry
    $parser = Parser::createDefault();
    
    $optimizations = new ExpressionOptimizerRegistry();
    foreach($parser->getExpressionOptimizerRegistry()->getRegistered() as $identifier => $value){
    	if(!($value instanceof OperatorStrengthReductionExpressionOptimizer)){
    		$optimizations->register($identifier, $value);
    	}
    }
    
    $parser = new Parser(
    	$parser->getBinaryOperatorRegistry(),
    	$parser->getUnaryOperatorRegistry(),
    	$parser->getConstantRegistry(),
    	$parser->getFunctionRegistry(),
    	$optimizations,
    	$parser->getScanner()
    );
  2. Disable optimizations altogether — $parser = Parser::createUnoptimized();
@Muqsit Muqsit added the bug Something isn't working label Oct 28, 2022
Muqsit added a commit that referenced this issue Nov 1, 2022
…ls (address #16)

Constant folding will resolve this on its next visit by executing the operation instead of direct substitution
Muqsit added a commit that referenced this issue Nov 3, 2022
Muqsit added a commit that referenced this issue Nov 3, 2022
Muqsit added a commit that referenced this issue Nov 3, 2022
NhanAZ added a commit to nhanaz-pm-pl/Calculator that referenced this issue Nov 4, 2022
Introduced `Parser::getOperatorManager()` ([`4ff725f`](Muqsit/arithmexp@4ff725f))
	Replaced `Parser::getBinaryOperatorRegistry()` with `Parser::getOperatorManager()->getBinaryRegistry()`
	Replaced `Parser::getUnaryOperatorRegistry()` with `Parser::getOperatorManager()->getUnaryRegistry()`
Fixed a few cases where optimizers did not account for INF and NAN ([#16](Muqsit/arithmexp#16)) ([`1ef49eb`](Muqsit/arithmexp@1ef49eb), [`db1df91`](Muqsit/arithmexp@db1df91), [`03440ab`](Muqsit/arithmexp@03440ab), [`b9dd31e`](Muqsit/arithmexp@b9dd31e), [`3c9b8a0`](Muqsit/arithmexp@3c9b8a0), [`14442ca`](Muqsit/arithmexp@14442ca), [`082ccf3`](Muqsit/arithmexp@082ccf3))
Fixed operator precedence of unary operators being greater than exponentiation ([#17](Muqsit/arithmexp#17)) ([`4ff725f`](Muqsit/arithmexp@4ff725f))
Fixed division by zero with zero `0 / 0` returning `int(0)` with optimizations ([`1672970`](Muqsit/arithmexp@1672970))
Function properties (commutativity and determinism) are governed by function flags instead of boolean properties (3e34845)
	See newer examples on the [wiki](https://github.com/Muqsit/arithmexp/wiki) about how to register custom binary operators, unary operators, and functions
Implemented idempotent functions ([`bd08609`](Muqsit/arithmexp@bd08609))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant