[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