Adding this rule attribute will fire the rule only once. Still, you won't be able to tell from the two titles which one is the odd-man-out. Also, if there are two or more violations, it won't show either.

rule "check-same"
    activation-group "one-shot"
when
    ...

Otherwise, duplicate firings for a pair can be eliminated by adding a constraint that reduces activations to a specific order of a pair; for this you'll need an attribute in your Fact that can be compared with '<', to wit:

   $p1 : Fact( $n1 : num, $t1 : title, $g1 : groupNames, $p1 : propNames )
   $p2 : Fact( num > $n1, $t2 : title,  ( groupNames != $g1 || propNames != $p1 ) )

As for your question ("comparing sets"), I suggest that you write a simple wrapper class, say, class PropNameSet, with a single attribute Set<String> names. Then you might write rules such as

rule "make set"
    when
        $f1 : Fact( $p1 : propNames )
        not PropNameSet()                           // not Set()
    then
        insert( new PropNameSet( $p1 ) );  // insert( $p1 );
    end

rule "check-names"
    when
        PropNameSet( $names : names )                           // $names : Set()
        $f1 : Fact( $t1 : title, propNames != $names )
    then
        System.out.println( "mismatch " + $t1  );
    end

You could also use the indicated alternative with the raw Set as a fact, but there is a fairly obvious disadvantage: not Set() is a very general condition.

Note that the PropNameSet will be derived from an arbitrary Fact; thus the mismatch might occur repeatedly, and for the good ones.

-W



2009/5/15 Ian Spence <ianspence@gmail.com>
Wolfgang and all,

Your suggestion did work.  Thank you for that.  I am learning more as I go along.

I am thinking of another approach now.  To populate working memory with a Set of all names "allNames"; call fireAllRules; then in the DRL, for each Title compare Proprietor names (set) with "allNames".

How can I compare 2 sets like this in a DRL ?

Ian Spence

2009/5/14 Wolfgang Laun <wolfgang.laun@gmail.com>
Assuming that your facts are structured as the indentation suggests, I would solve this using a technique you could call "virtual field". So, if a fact object has fields
   String title
   List<PropGroup> pgList

and a PropGroup has fields
  String name
  List<String> pList

I would not try to get at the embedded data from the objects contained within List<PropGroup>. Rather, I'd add a couple of getters to your Fact class, each of which would return a Set<String> computed from the contained List<PropGroup>. Then the rule simply becomes

rule "check-same"
    when
        $p1 : Fact( $t1 : title, $g1 : groupNames, $p1 : propNames )
        $p2 : Fact( this != $p1, $t2 : title,  ( groupNames != $g1 || propNames != $p1 ) )
    then
        System.out.println( "mismatch " + $t1 + " and " + $t2 );
    end

Notice that this won't find the odd-man-out; it will fire twice for each unequal pair.

-W



2009/5/14 Ian Spence <ianspence@gmail.com>
Hello all,

I am new to Drools…

 

I have a scenario

 

Each fact object will have the structure:

 

Title

   Proprietor Group

      Proprietor Name

 

E.g.

            2100-100

                        J2 ˝ share

                                    SMITH, JOHN

                                    JONES, FRED

                        T ˝ share

                                    BROWN, CHARLIE

            2100-101

                        J2 ˝ share

                                    BROWN, CHARLIE

                                    JONES, FRED

                        T ˝ share

                                    SMITH, JOHN

            2100-102

                        T ˝ share

                                    BROWN, CHARLIE

                        J2 ˝ share

                                    JONES, FRED

                                    SMITH, JOHN

 

The group names and the proprietor names must be the same across each Title.  The scenario above is a valid case. A failed case would result for Title 2100-100 if we add an extra Proprietor name e.g. WHITE, MARY.

 

I anticipate having one rule to cater for this.  I am hedging towards the ‘collect’ operator but cannot get a clear picture on how to implement it.


--
Regards,
Ian Spence



_______________________________________________
rules-users mailing listhttps://lists.jboss.org/mailman/listinfo/rules-users



_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users




--
Regards,
Ian Spence



_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users