I have an expression (an example)
(value1<15 AND value2>25) OR ((value3>0 and vaue4<5) OR (value5<6 and value7>8))
The issue is value1-7 are calls to external services, which are expensive. And we need to reduce cost, so we need to make a minimum number of calls to evaluate this expression. For example if we have
(value1<15 AND value2>25)
evaluated to true, we don't need to evaluate right part, so we don't need to make useless calls to external services. How to determine in java (or may be just in math) when we need to stop, and further evaluations will not make any effect?
UPDATE
I have 5 workers that works on 5 different servers.
first worker:
accept(expression)
value1=calculateValue1()
setValueToExpression(expression, 0, value1)
enough=expression.checkIsItEnough()
if(!enough){
determineNextWorker(expression)
sendToNExtWorker()
}
else return expression.evaluate()
The second worker
accept(expression)
value2=calculateValue2()
setValueToExpression(expression, 1, value2)
enough=expression.checkIsItEnough()
if(!enough){
determineNextWorker(expression)
sendToNextWorker()
}
else return expression.evaluate()
.....................
As I said in comments, I clearly understand that if we can write
evaluator.evaluate("(value1<5 and value2>6) or (value3>5 and value4>7)")
it evaluates it as all of us know, but I don't have this ability due to many reasons. I also can't make it function calls value1()<15... It's happening synchronously, one by one but even on different servers, kinda offline evaluation. Hope it's clear
Consider normal short-circuit intermediate code for:
(value1<15 AND value2>25) OR ((value3>0 and value4<5) OR (value5<6 and value7>8))
You could simplify things substantially by having a tree representation of your expression, and passing around subexpressions represented by trees rather than the whole expression.
For example, the first worker would have two subexpressions:
value2>25
and(value3>0 and value4<5) OR (value5<6 and value7>8)
. Select the first one if the test succeeds, the second one if it fails.The value2>25 worker would have two subexpressions: "success" and
(value3>0 and value4<5) OR (value5<6 and value7>8)
I am not aware of any library to do the conversions. If it exists, it would be in the domain of compiler construction.
I would try very hard to change this to something where one worker could organize the job, and simply call on other workers to evaluate one relational condition.
======================================================================== More detail, because this seems to be the sort of answer the OP is looking for:
Terminology:
value2>25
Consider only sum-of-products expressions, such as
(value1<15 AND value2>25) OR ((value3>0 and value4<5) OR (value5<6 and value7>8))
. This is not a very significant limitation. Many optimizations and simplifications used in digital logic design depend on converting arbitrary logical expressions to sum-of-products.At each step, the worker for the leading term of an expression is called. Depending on the expression and the outcome of its test, it can declare success, declare failure, or calculate a new expression that must be passed to the worker for its leading term.