@Test
  public void testSingleSharedEmptyLhs() throws Exception {
    KnowledgeBase kbase = buildKnowledgeBase(" ", " ");

    ReteooWorkingMemoryInterface wm =
        ((StatefulKnowledgeSessionImpl) kbase.newStatefulKnowledgeSession()).session;

    ObjectTypeNode aotn = getObjectTypeNode(kbase, InitialFactImpl.class);

    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) aotn.getSinkPropagator().getSinks()[0];
    RuleTerminalNode rtn1 = (RuleTerminalNode) liaNode.getSinkPropagator().getSinks()[0];
    RuleTerminalNode rtn2 = (RuleTerminalNode) liaNode.getSinkPropagator().getSinks()[1];

    wm.insert(new A());

    // LiaNode  is in it's own segment
    LiaNodeMemory liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode);
    SegmentMemory smem = liaMem.getSegmentMemory();
    assertEquals(liaNode, smem.getRootNode());
    assertEquals(liaNode, smem.getTipNode());

    // each RTN is in it's own segment
    SegmentMemory rtnSmem1 = smem.getFirst();
    assertEquals(rtn1, rtnSmem1.getRootNode());
    assertEquals(rtn1, rtnSmem1.getTipNode());

    SegmentMemory rtnSmem2 = rtnSmem1.getNext();
    assertEquals(rtn2, rtnSmem2.getRootNode());
    assertEquals(rtn2, rtnSmem2.getTipNode());
  }
  public <T> T execute(Context context, Command<T> command) {

    ExecutionResultImpl results = null;
    if (context != null) {
      results = (ExecutionResultImpl) ((KnowledgeCommandContext) context).getExecutionResults();
    }

    if (results == null) {
      results = new ExecutionResultImpl();
    }

    if (!(command instanceof BatchExecutionCommandImpl)) {
      return (T)
          ((GenericCommand) command)
              .execute(new FixedKnowledgeCommandContext(context, null, this.kbase, this, results));
    }

    try {
      session.startBatchExecution(results);
      ((GenericCommand) command)
          .execute(new FixedKnowledgeCommandContext(context, null, this.kbase, this, results));
      ExecutionResults result = session.getExecutionResult();
      return (T) result;
    } finally {
      session.endBatchExecution();
    }
  }
  @Test
  public void tesShareInSubnetwork() throws Exception {
    KnowledgeBase kbase =
        buildKnowledgeBase("   A() \n", "   A() B() C() \n", "   A()  not ( B() and C() ) \n");

    ReteooWorkingMemoryInterface wm =
        ((StatefulKnowledgeSessionImpl) kbase.newStatefulKnowledgeSession()).session;

    ObjectTypeNode aotn = getObjectTypeNode(kbase, A.class);

    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) aotn.getSinkPropagator().getSinks()[0];
    RuleTerminalNode rtn1 = (RuleTerminalNode) liaNode.getSinkPropagator().getSinks()[0];

    JoinNode bNode = (JoinNode) liaNode.getSinkPropagator().getSinks()[1];
    JoinNode cNode = (JoinNode) bNode.getSinkPropagator().getSinks()[0];
    RuleTerminalNode rtn2 = (RuleTerminalNode) cNode.getSinkPropagator().getSinks()[0];
    RightInputAdapterNode riaNode = (RightInputAdapterNode) cNode.getSinkPropagator().getSinks()[1];

    NotNode notNode = (NotNode) liaNode.getSinkPropagator().getSinks()[2];
    RuleTerminalNode rtn3 = (RuleTerminalNode) notNode.getSinkPropagator().getSinks()[0];

    wm.insert(new A());
    wm.insert(new B());
    wm.insert(new C());

    // LiaNode  is in it's own segment
    LiaNodeMemory liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode);
    SegmentMemory smem = liaMem.getSegmentMemory();
    assertEquals(liaNode, smem.getRootNode());
    assertEquals(liaNode, smem.getTipNode());

    SegmentMemory rtnSmem1 = smem.getFirst();
    assertEquals(rtn1, rtnSmem1.getRootNode());
    assertEquals(rtn1, rtnSmem1.getTipNode());

    SegmentMemory bSmem = rtnSmem1.getNext();
    assertEquals(bNode, bSmem.getRootNode());
    assertEquals(cNode, bSmem.getTipNode());

    assertNull(bSmem.getFirst()); // segment is not initialized yet

    wm.fireAllRules();

    SegmentMemory rtn2Smem = bSmem.getFirst();
    assertEquals(rtn2, rtn2Smem.getRootNode());
    assertEquals(rtn2, rtn2Smem.getTipNode());

    SegmentMemory riaSmem = rtn2Smem.getNext();
    assertEquals(riaNode, riaSmem.getRootNode());
    assertEquals(riaNode, riaSmem.getTipNode());

    SegmentMemory notSmem = bSmem.getNext();
    assertEquals(notNode, notSmem.getRootNode());
    assertEquals(rtn3, notSmem.getTipNode());
  }
  @Test
  public void testMultiSharedPattern() throws Exception {
    KnowledgeBase kbase = buildKnowledgeBase("   A() \n", "   A() B() \n", "   A() B() C() \n");

    ReteooWorkingMemoryInterface wm =
        ((StatefulKnowledgeSessionImpl) kbase.newStatefulKnowledgeSession()).session;

    ObjectTypeNode aotn = getObjectTypeNode(kbase, A.class);

    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) aotn.getSinkPropagator().getSinks()[0];
    RuleTerminalNode rtn1 = (RuleTerminalNode) liaNode.getSinkPropagator().getSinks()[0];
    JoinNode bNode = (JoinNode) liaNode.getSinkPropagator().getSinks()[1];
    RuleTerminalNode rtn2 = (RuleTerminalNode) bNode.getSinkPropagator().getSinks()[0];

    JoinNode cNode = (JoinNode) bNode.getSinkPropagator().getSinks()[1];
    RuleTerminalNode rtn3 = (RuleTerminalNode) cNode.getSinkPropagator().getSinks()[0];

    wm.insert(new A());
    wm.insert(new B());
    wm.insert(new C());

    // LiaNode  is in it's own segment
    LiaNodeMemory liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode);
    SegmentMemory smem = liaMem.getSegmentMemory();
    assertEquals(liaNode, smem.getRootNode());
    assertEquals(liaNode, smem.getTipNode());

    SegmentMemory rtnSmem1 = smem.getFirst();
    assertEquals(rtn1, rtnSmem1.getRootNode());
    assertEquals(rtn1, rtnSmem1.getTipNode());

    SegmentMemory bSmem = rtnSmem1.getNext();
    assertEquals(bNode, bSmem.getRootNode());
    assertEquals(bNode, bSmem.getTipNode());

    // child segment is not yet initialised, so null
    assertNull(bSmem.getFirst());

    // there is no next
    assertNull(bSmem.getNext());

    wm.fireAllRules(); // child segments should now be initialised

    SegmentMemory rtnSmem2 = bSmem.getFirst();
    assertEquals(rtn2, rtnSmem2.getRootNode());
    assertEquals(rtn2, rtnSmem2.getTipNode());

    SegmentMemory cSmem = rtnSmem2.getNext();
    assertEquals(cNode, cSmem.getRootNode());
    assertEquals(rtn3, cSmem.getTipNode()); // note rtn3 is in the same segment as C
  }
  @Test
  public void testSinglePattern() throws Exception {
    KnowledgeBase kbase = buildKnowledgeBase("   A() \n");

    ReteooWorkingMemoryInterface wm =
        ((StatefulKnowledgeSessionImpl) kbase.newStatefulKnowledgeSession()).session;

    ObjectTypeNode aotn = getObjectTypeNode(kbase, A.class);

    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) aotn.getSinkPropagator().getSinks()[0];
    RuleTerminalNode rtn = (RuleTerminalNode) liaNode.getSinkPropagator().getSinks()[0];

    wm.insert(new A());

    // LiaNode and Rule are in same segment
    LiaNodeMemory liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode);
    SegmentMemory smem = liaMem.getSegmentMemory();
    assertEquals(liaNode, smem.getRootNode());
    assertEquals(rtn, smem.getTipNode());
    assertNull(smem.getNext());
    assertNull(smem.getFirst());
  }
  @Test
  public void testSubnetworkNoSharing() throws Exception {
    KnowledgeBase kbase = buildKnowledgeBase(" A()  not ( B() and C() ) \n");

    ReteooWorkingMemoryInterface wm =
        ((StatefulKnowledgeSessionImpl) kbase.newStatefulKnowledgeSession()).session;

    ObjectTypeNode aotn = getObjectTypeNode(kbase, A.class);

    LeftInputAdapterNode liaNode = (LeftInputAdapterNode) aotn.getSinkPropagator().getSinks()[0];

    JoinNode bNode = (JoinNode) liaNode.getSinkPropagator().getSinks()[0];
    JoinNode cNode = (JoinNode) bNode.getSinkPropagator().getSinks()[0];
    RightInputAdapterNode riaNode = (RightInputAdapterNode) cNode.getSinkPropagator().getSinks()[0];

    NotNode notNode = (NotNode) liaNode.getSinkPropagator().getSinks()[1];
    RuleTerminalNode rtn1 = (RuleTerminalNode) notNode.getSinkPropagator().getSinks()[0];

    wm.insert(new A());
    wm.insert(new B());
    wm.insert(new C());

    // LiaNode and Rule are in same segment
    LiaNodeMemory liaMem = (LiaNodeMemory) wm.getNodeMemory(liaNode);
    SegmentMemory smem = liaMem.getSegmentMemory();
    assertEquals(liaNode, smem.getRootNode());
    assertEquals(rtn1, smem.getTipNode());
    assertNull(smem.getNext());
    assertNull(smem.getFirst());

    SegmentMemory bSmem =
        wm.getNodeMemory(bNode).getSegmentMemory(); // it's nested inside of smem, so lookup from wm
    assertEquals(bNode, bSmem.getRootNode());
    assertEquals(riaNode, bSmem.getTipNode());

    BetaMemory bm = (BetaMemory) wm.getNodeMemory(notNode);
    assertEquals(bSmem, bm.getSubnetworkSegmentMemory()); // check subnetwork ref was made
  }
 public org.drools.FactHandle getFactHandleByIdentity(Object object) {
   return session.getFactHandleByIdentity(object);
 }
 public Collection<Object> getObjects(org.kie.runtime.ObjectFilter filter) {
   return new ObjectStoreWrapper(session.getObjectStore(), filter, ObjectStoreWrapper.OBJECT);
 }
 public EntryPoint getEntryPoint() {
   return session.getEntryPoint();
 }
 public Collection<Object> getObjects() {
   return new ObjectStoreWrapper(session.getObjectStore(), null, ObjectStoreWrapper.OBJECT);
 }
 public <T extends org.kie.runtime.rule.FactHandle> Collection<T> getFactHandles(
     org.kie.runtime.ObjectFilter filter) {
   return new ObjectStoreWrapper(session.getObjectStore(), filter, ObjectStoreWrapper.FACT_HANDLE);
 }
 public KnowledgeBase getKieBase() {
   if (this.kbase == null) {
     this.kbase = new KnowledgeBaseImpl(session.getRuleBase());
   }
   return this.kbase;
 }
 public Collection<? extends org.kie.runtime.rule.SessionEntryPoint> getEntryPoints() {
   return session.getWorkingMemoryEntryPoints();
 }
 public SessionEntryPoint getEntryPoint(String name) {
   return session.getWorkingMemoryEntryPoint(name);
 }