Drools Flow (aka JBPM5) will look for all the Persons and Dogs you have in your session.
Since the conditions in an XOR gateway are evaluated in order, the first one being true is going to be selected.
In your case, after you insert the Persons, both rules are activated, but the gateway is always going to pick the first one.
I would suggest to use different process instances for different scenarios.

Best Regards,

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Esteban Aliverti
- Blog @ http://ilesteban.wordpress.com


On Tue, Aug 21, 2012 at 11:14 PM, BenjaminWolfe <benjamin.e.wolfe@gmail.com> wrote:
Thanks Wolfgang.

My original post was a conceptual analogy.  But this still isn't working
right for me, so I've written out a full-fledged example to see if you or
anyone else can help.  The full example is behaving exactly the way my real
(important) code is -- which is the wrong way for the business application.
:-/  I should add that in real life, the ruleflow groups each have multiple
rules within them.

So without further ado, here's my code -- two POJOs, a bpmn file, a rule
resource, and a test class -- along with the expected output and actual
output.

*User.java*

package com.examples.ruleflow;

public class User {

        private int id;

        public User() {}
        public User(int id) {
                this.id = id;
        }

        public int getId() {
                return id;
        }

        public void setId(int id) {
                this.id = id;
        }
}

*Dog.java*

package com.examples.ruleflow;

public class Dog {

        private int id;
        private int ownerId;
        private boolean hasDogTag;

        public Dog() {}
        public Dog(int id) {
                this.id = id;
        }

        public int getId() {
                return id;
        }
        public int getOwnerId() {
                return ownerId;
        }
        public boolean isHasDogTag() {
                return hasDogTag;
        }
        public void setId(int id) {
                this.id = id;
        }
        public void setOwnerId(int ownerId) {
                this.ownerId = ownerId;
        }
        public void setHasDogTag(boolean hasDogTag) {
                this.hasDogTag = hasDogTag;
        }

}

*dog_owner_flow.bpmn*

<?xml version="1.0" encoding="UTF-8"?>
<definitions id="Definition"
             targetNamespace="http://www.jboss.org/drools"
             typeLanguage="http://www.java.com/javaTypes"
             expressionLanguage="http://www.mvel.org/2.0"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
BPMN20.xsd"
             xmlns:g="http://www.jboss.org/drools/flow/gpd"
             xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
             xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
             xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
             xmlns:tns="http://www.jboss.org/drools">

  <process processType="Private" isExecutable="true"
id="com.examples.ruleflow.dogProcess" name="Dog Owner Process"
tns:packageName="com.examples.ruleflow" tns:version="1" >


    <startEvent id="_1" name="StartProcess" />
    <exclusiveGateway id="_2" name="Gateway" gatewayDirection="Diverging" />
    <businessRuleTask id="_3" name="Branch A" g:ruleFlowGroup="flowA"
></businessRuleTask>
    <businessRuleTask id="_4" name="Branch B" g:ruleFlowGroup="flowB"
></businessRuleTask>
    <exclusiveGateway id="_5" name="Gateway" gatewayDirection="Converging"
/>
    <endEvent id="_6" name="End" ><terminateEventDefinition/></endEvent>


    <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
    <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" name="dog tags
OK" tns:priority="1" >
      <conditionExpression xsi:type="tFormalExpression"
language="http://www.jboss.org/drools/rule" >
        /$u : User()
        not ( Dog( ownerId == $u.id, hasDogTag == false ) )/
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_2-_4" sourceRef="_2" targetRef="_4" name="dog tag
issue" tns:priority="1" >
      <conditionExpression xsi:type="tFormalExpression"
language="http://www.jboss.org/drools/rule" >
        /$u : User()
        exists ( Dog( ownerId == $u.id, hasDogTag == false ) )/
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_3-_5" sourceRef="_3" targetRef="_5" />
    <sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5" />
    <sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6" />
  </process>

  <bpmndi:BPMNDiagram>
    <bpmndi:BPMNPlane bpmnElement="com.examples.ruleflow.dogProcess" >
      <bpmndi:BPMNShape bpmnElement="_1" >
        <dc:Bounds x="16" y="16" width="48" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_2" >
        <dc:Bounds x="180" y="15" width="48" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" >
        <dc:Bounds x="42" y="162" width="80" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" >
        <dc:Bounds x="296" y="162" width="80" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" >
        <dc:Bounds x="180" y="306" width="48" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_6" >
        <dc:Bounds x="188" y="384" width="48" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_1-_2" >
        <di:waypoint x="40" y="40" />
        <di:waypoint x="204" y="39" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_2-_3" >
        <di:waypoint x="204" y="39" />
        <di:waypoint x="82" y="186" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_2-_4" >
        <di:waypoint x="204" y="39" />
        <di:waypoint x="336" y="186" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_3-_5" >
        <di:waypoint x="82" y="186" />
        <di:waypoint x="204" y="330" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_4-_5" >
        <di:waypoint x="336" y="186" />
        <di:waypoint x="204" y="330" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_5-_6" >
        <di:waypoint x="204" y="330" />
        <di:waypoint x="212" y="408" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

*dog_owners.drl*

package com.examples.ruleflow

rule "sample A"
        ruleflow-group "flowA"
        no-loop true
        dialect "mvel"
        when
                $u : User()
        then
                System.out.println("User " + $u.id + " took branch A.");
end

rule "sample B"
        ruleflow-group "flowB"
        no-loop true
        dialect "mvel"
        when
                $u : User()
        then
                System.out.println("User " + $u.id + " took branch B.");
end

*DogTest.java*

package com.examples.ruleflow;

import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;
/import java.util.List;
import java.util.ArrayList;/

public class DogTest {

    public static final void main(String[] args) {
        try {
            // load up the knowledge base
            KnowledgeBase kbase = readKnowledgeBase();
            StatefulKnowledgeSession ksession =
kbase.newStatefulKnowledgeSession();
            KnowledgeRuntimeLogger logger =
KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
            /// create and insert facts
            List<User> users = new ArrayList<User>();
            List<Dog> dogs = new ArrayList<Dog>();

            users.add(new User(0));
            dogs.add(new Dog(0));
            dogs.get(0).setOwnerId(1);
            dogs.get(0).setHasDogTag(true);
            dogs.add(new Dog(1));
            dogs.get(1).setOwnerId(0);
            dogs.get(1).setHasDogTag(true);

            users.add(new User(1));
            dogs.add(new Dog(2));
            dogs.get(2).setOwnerId(1);
            dogs.get(2).setHasDogTag(true);
            dogs.add(new Dog(3));
            dogs.get(3).setOwnerId(1);
            dogs.get(3).setHasDogTag(true);
            dogs.add(new Dog(4));
            dogs.get(4).setOwnerId(1);
            dogs.get(4).setHasDogTag(false);

            for (User u:users) {
                ksession.insert(u);
            }
            for (Dog d:dogs) {
                ksession.insert(d);
            }/

            // start a new process instance
            /ksession.startProcess("com.examples.ruleflow.dogProcess");
            ksession.fireAllRules();/
            logger.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    private static KnowledgeBase readKnowledgeBase() throws Exception {
        KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();

/kbuilder.add(ResourceFactory.newClassPathResource("dog_owners.drl"),
ResourceType.DRL);

kbuilder.add(ResourceFactory.newClassPathResource("dog_owner_flow.bpmn"),
ResourceType.BPMN2);/
        return kbuilder.newKnowledgeBase();
    }
}

*/Expected/ Console Output...*

User /0/ took branch /A/.
User /1/ took branch /B/.

*/Actual/ Console Output...*

User /1/ took branch /A/.
User /0/ took branch /A/.


laune wrote
>
> On 21/08/2012, BenjaminWolfe &lt;benjamin.e.wolfe@&gt; wrote:
>> I'm trying to wrap my mind around the nature of ruleflows -- and I think
>> this
>> question sums up a bit of my confusion.
>>
>> I have a stateful knowledge session.  The stateful knowledge session has
>> a
>> ruleflow associated with it.  That ruleflow diverges into two branches --
>> branch A and branch B -- based on a rule constraint.  It's an XOR, and
>> the
>> mvel rule constraints are something like this:
>>
>> to branch A
>> $u : User( $i : userId )
>> exists ( Dog( owner == $i, hasDogTag == false) )
>>
>> to branch B
>> $u : User( $i : userId )
>> not ( Dog( owner == $i, hasDogTag == false) )
>>
>> Then the two branches converge again.  I insert two facts: user 1, whose
>> dogs all have dog tags, and user 2 whose third dog is missing a tag.
>> Then,
>> after I insert both facts, I fire all rules.
>
> If you don't insert any Dogs, only the condition for branch B is true,
> since there no Dogs at all, tag or no tag.
>
> If you insert Dogs according to your statement, both conditions are
> true, A for user 2 and B for user 1 (which is not what you describe
> below, but I think this is an oversight).
>
> Anyway, a "flow" will not cycle automatically if there are several
> fact groups, with some of them requiring this or that processing. To
> notify Users with untagged dogs, a simple rule with the conditions
> you've posted and with a consequence notifying the user would be
> sufficient.
>
> For an overall decision between "there are tagless dogs" and "all dogs
> are tagged" you'd need conditions like these:
>
> exists( Dog( hasDogTag == false) )
>
> not( Dog( hasDogTag == false) )
>
> -W
>
>
>>
>> Should the flow be like this?
>>
>> user 1: start --> diverge --> branch A (tell him to buy dog tags) -->
>> converge --> end
>> user 2: start --> diverge --> branch B (leave him alone) --> converge -->
>> end
>>
>> Or does a ruleflow look at the whole session rather than each fact -- in
>> which case either both users would pass through branch A, or both would
>> pass
>> through branch B?
>>
>> If I want the first case to happen, is there something I'm missing in the
>> implementation?  And are there any more details I can add to make my post
>> more specific?  Thank you for your help.
>>
>>
>>
>> --
>> View this message in context:
>> http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292.html
>> Sent from the Drools: User forum mailing list archive at Nabble.com.
>> _______________________________________________
>> rules-users mailing list
>> rules-users@.jboss
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
> _______________________________________________
> rules-users mailing list
> rules-users@.jboss
> https://lists.jboss.org/mailman/listinfo/rules-users
>



--
View this message in context: http://drools.46999.n3.nabble.com/Question-about-the-Nature-of-Ruleflows-tp4019292p4019325.html
Sent from the Drools: User forum mailing list archive at Nabble.com.
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users