The not-so-immediate solution would be to use queries,
for example something along the following lines:
declare Node
id : String
children : Node[]
value : Integer
end
rule "Init"
when
then
Node n1 = new Node( "l1", new Node[] {}, 10 );
Node n2 = new Node( "l2", new Node[] {}, 7 );
Node n3 = new Node( "l3", new Node[] {}, 9 );
Node x1 = new Node( "x1", new Node[] { n1, n2 }, -1 );
Node x2 = new Node( "x2", new Node[] { n3 }, -2 );
Node rt = new Node( "00", new Node[] { x1, x2 }, -3 );
insert( n1 );
insert( n2 );
insert( n3 );
insert( x1 );
insert( x2 );
insert( rt );
end
query score( Node $node, Integer $score )
// either the node is a leaf, so just return its value
$node := Node( children.length == 0, $score := value )
or
( // or it is not, so let's pick the children
$node := Node( $children : children, $sz : children.length > 0, $val
: value )
and
accumulate (
// for each child...
$child : Node( this memberOf $children )
and
// ... calculate the partial child's score recursively
score( $child, $x ; ),
// sum all the partial scores
$tot : sum( $x )
)
and
// add the local parent value and return
$score := Integer() from $tot.intValue() + $val
)
end
rule "Check"
when
$n : Node()
score( $n, $x ; )
then
System.out.println( "Query-ed value from node " + $n + " >>>
" + $x );
end
In the last rule, you can replace $x with a literal (also remove it from
the printout) :
score( $n, 20 ; )
and the rule will fire only for those nodes whose "deep sum" is 20
On 02/28/2013 01:20 PM, Wolfgang Laun wrote:
I think that the simplest solution would be to either store the sum
of
the children's values into each Node, or to create and insert
additional facts containing these sums, in parallel to non-leaf Node
facts.
-W
On 28/02/2013, mcyrb <cyrille.martins(a)thalesgroup.com> wrote:
> Hello.
>
> I have a tree, with each leaf containing a random value.
> The value of each node is the sum of its children value.
>
> I would like to write a rule which looks like this:
> when
> nodeValue == 18 (e.g.)
> then
> // do something with this node
> end
>
> The accumulate conditional element looked adequate for this, so I wrote
> something like this
> when
> n: Node()
> accumulate( Leaf( parentNode == n, v : value ); nodeValue : sum( v );
> nodeValue == 18 )
> then
> // do something with n
> end
>
> So... the problem is that this works only for nodes where its direct childs
> are leafs, and not for upper nodes.
> Have you got an idea to solve this ?
>
> Thank you
>
>
>
> --
> View this message in context:
>
http://drools.46999.n3.nabble.com/Tree-iteration-with-accumulate-is-it-po...
> Sent from the Drools: User forum mailing list archive at
Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
>
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users