On 14/02/2011 09:30, Wolfgang Laun wrote:
Compare these three quotes from the current
Expert documentation:
(1) Return Value restriction (...) must return results that do
not depend on time.
(2) An inline
eval constraint (...) expression (...) expression must be
constant over time.
(3) [CE] Evals (...)
are (...) ideal (...) when functions return values that change
over time.
There are two aspects here. One was indexing. Field constraint are
potentially indexed, evals were not. For indexing to work the
evaluations must be time constant or the update and retract fails.
Eval nodes have no joins and no indexing so they are safe from time
sensitive changes.
Drools 4.0 implemented shadow facts in the same way that Jess did.
Further more Drools allows nested access access. When a modify or
retract was done if something had changed and the engine was not
aware of it, or a nested field changed, it effectively broke the
engine - modifies and retracts would not work. Eval was/is slightly
less immune from that.
Drools 5.0 uses tree graph approach and now retracts will always
work and aren't sensitive to any data. Modifies can still
potentially be a problem as it can screw up indexing if you changed
a nested field without notifying the engine. Eval has no indexing,
so is not impacted by this.
Mark
Note that this appears to mean that the behaviour of (1) == (2)
!= (3).
Many things can or must "change over time:" fact data, global
data, results of constructors such as new Date() or methods such
as System.currentTimeMillis().
So what can I use in an Eval CE that cannot be used in a Return
Value or Inline Eval?
Perhaps this is trying to convey some notion of caching for
constraints and the evaluation strategy for LHS, but then the
wording is insufficient. Let's make an experiment.
Example 1: Given
these rules and one pair of facts A, B, which of the three rules
ab1, ab2, ab3 will fire after the last rule (a) fires? There are
8 possible answers. (You may notice that there is some
redundancy in each rule.)
rule ab1
when
A( $va:va, $b: b ) eval( $va + $b.getVb() > 100 )
B( this == $b, $vb: vb ) eval( $va + $vb > 100 )
then
System.out.println( "ab1: a+b > 100" );
end
rule ab2
when
A( $va:va, $b: b , eval( $va + $b.getVb() > 100 ) )
B( this == $b, $vb: vb, eval( $va + $vb > 100 ) )
then
System.out.println( "ab2: a+b > 100" );
end
rule ab3
when
$a: A( $b: b , $va: va > ( 100 - $b.getVb() ) )
B( this == $b, $vb: vb > ( 100 - $a.getVa() ) )
then
System.out.println( "ab3: a+b > 100" );
end
rule a
salience -10
no-loop true
when
$a: A( $va: va )
$b: B( $vb: vb )
then
modify( $b ){ setVb( 200 ) }
end
Example 2: Now change the first line in the when parts according
to:
ab1:
A( $va:va, $b: b )
ab2:
A( $va:va, $b: b
)
ab3:
$a: A( $b: b )
Which of the three
rules ab1, ab2, ab3 will fire now after the last rule (a) fires?
Wolfgang
PS: Scroll down for the answers.
v
v
v
v
v
v
v
Example 1: None of the rules fires.
Example 2: All three rules fire.
_______________________________________________
rules-dev mailing list
rules-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-dev