Varis
Varis

Reputation: 254

Drools rule implementation

I have a rule that I do not know if it is possible to implement in drools.

The description: A, L, P are all facts/POJOs which are connected. I need to find out if each A can be assigned to a free P through L. And if not, how many A elements are left unassigned.

Fact model diagram

In the case above one A will be left unassigned.

I thought up an algorithm that is simple to describe:

  1. Find A with least edges

    • If A has no edges, increase result counter by 1, remove A
  2. Choose random L->P from that A and remove the A, L, P elements

  3. Repeat until there are no A left

I'm having a hard time describing that in drools. I'm no expert in drools rules. In JAVA, you'd have to do a lot of manipulations with collections, including sorting, which drools does not seem to support. Is it possible to do this somehow in drools?

Upvotes: 3

Views: 377

Answers (1)

laune
laune

Reputation: 31290

Here is a set of rules that implements the algorithm. It will not be very efficient on large numbers of As and Ps. A pure Java solution shouldn't be all that difficult either. Note that a complete sort isn't necessary after removing one A from the set and clearing away all dangling L and P objects.

rule findMin
when
    $mina: A( $edges: edges )
    not A( edges.size() < $edges.size() )
then
    System.out.println( "retract " + $mina );
    retract( $mina );
end

rule countFail extends findMin
when
    eval( $edges.size() == 0 )
then
    Main.counter++;
    System.out.println( "fail to match " + $mina );
end

rule matchLP extends findMin
when
    $l: L( this memberOf $edges, $p: p )
then
    retract( $p );
    retract( $l );
    System.out.println( "retract " + $p + " and " + $l );
end

rule cleanup
salience 10
when
    $l: L( $p: p )
    not P( this == $p )
    $a: A( edges contains $l )
then
    retract( $l );
    modify( $a ){
        remove( $l );
    }
    System.out.println( "cleanup " + $l + ", " + $a );
end

Upvotes: 1

Related Questions