[rules-users] Tree iteration with accumulate: is it possible ?
Davide Sottara
dsotty at gmail.com
Thu Feb 28 18:18:47 EST 2013
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 at 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-possible-tp4022639.html
>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
More information about the rules-users
mailing list