Search in sources :

Example 11 with ExistsNode

use of org.drools.core.reteoo.ExistsNode in project drools by kiegroup.

the class BackwardChainingTest method testSubNetworksAndQueries.

@Test(timeout = 10000)
public void testSubNetworksAndQueries() throws Exception {
    String str = "" + "package org.drools.compiler.test  \n" + "import java.util.List\n" + "import java.util.ArrayList\n" + "import java.util.Map\n" + "import java.util.HashMap\n" + "global List list\n" + "dialect \"mvel\"\n" + "\n" + "declare Location\n" + "    thing : String \n" + "    location : String \n" + "end" + "\n" + "declare Edible\n" + "   thing : String\n" + "end" + "\n" + "query whereFood( String x, String y ) \n" + "    Location(x, y;) Edible(x;) \n" + "end\n" + "\n" + "query look(String place, List food ) \n" + "    $s : String() // just here to give a OTN lookup point\n" + "    food := List() from accumulate( whereFood(thing, place;) ," + "                                    collectList( thing ) )\n" + "    exists( whereFood(thing, place;) )\n" + "    not( whereFood(thing, place;) and\n " + "         String( this == $s ) from thing )\n" + "end\n" + "\n" + "rule init when\n" + "then\n" + "        \n" + "        insert( new Location(\"apple\", \"kitchen\") );\n" + "        insert( new Location(\"crackers\", \"kitchen\") );\n" + "        insert( new Location(\"broccoli\", \"kitchen\") );\n" + "        insert( new Location(\"computer\", \"office\") );\n" + "        insert( new Edible(\"apple\") );\n" + "        insert( new Edible(\"crackers\") );\n" + "end\n" + "";
    logger.debug(str);
    KieBase kbase = SerializationHelper.serializeObject(loadKnowledgeBaseFromString(str));
    // Get the accumulate node, so we can test it's memory later
    // now check beta memory was correctly cleared
    List<ObjectTypeNode> nodes = ((KnowledgeBaseImpl) kbase).getRete().getObjectTypeNodes();
    ObjectTypeNode node = null;
    for (ObjectTypeNode n : nodes) {
        if (((ClassObjectType) n.getObjectType()).getClassType() == String.class) {
            node = n;
            break;
        }
    }
    BetaNode stringBetaNode = (BetaNode) node.getObjectSinkPropagator().getSinks()[0];
    QueryElementNode queryElementNode1 = (QueryElementNode) stringBetaNode.getSinkPropagator().getSinks()[0];
    RightInputAdapterNode riaNode1 = (RightInputAdapterNode) queryElementNode1.getSinkPropagator().getSinks()[0];
    AccumulateNode accNode = (AccumulateNode) riaNode1.getObjectSinkPropagator().getSinks()[0];
    QueryElementNode queryElementNode2 = (QueryElementNode) accNode.getSinkPropagator().getSinks()[0];
    RightInputAdapterNode riaNode2 = (RightInputAdapterNode) queryElementNode2.getSinkPropagator().getSinks()[0];
    ExistsNode existsNode = (ExistsNode) riaNode2.getObjectSinkPropagator().getSinks()[0];
    QueryElementNode queryElementNode3 = (QueryElementNode) existsNode.getSinkPropagator().getSinks()[0];
    FromNode fromNode = (FromNode) queryElementNode3.getSinkPropagator().getSinks()[0];
    RightInputAdapterNode riaNode3 = (RightInputAdapterNode) fromNode.getSinkPropagator().getSinks()[0];
    NotNode notNode = (NotNode) riaNode3.getObjectSinkPropagator().getSinks()[0];
    KieSession ksession = createKnowledgeSession(kbase);
    InternalWorkingMemory wm = ((StatefulKnowledgeSessionImpl) ksession);
    AccumulateMemory accMemory = (AccumulateMemory) wm.getNodeMemory(accNode);
    BetaMemory existsMemory = (BetaMemory) wm.getNodeMemory(existsNode);
    FromMemory fromMemory = (FromMemory) wm.getNodeMemory(fromNode);
    BetaMemory notMemory = (BetaMemory) wm.getNodeMemory(notNode);
    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    ksession.setGlobal("list", list);
    FactHandle fh = ksession.insert("bread");
    ksession.fireAllRules();
    final List food = new ArrayList();
    QueryResults results = null;
    // Execute normal query and check no subnetwork tuples are left behind
    results = ksession.getQueryResults("look", new Object[] { "kitchen", Variable.v });
    assertEquals(1, results.size());
    for (org.kie.api.runtime.rule.QueryResultsRow row : results) {
        food.addAll((Collection) row.get("food"));
        logger.debug(row.get("food").toString());
    }
    assertEquals(2, food.size());
    assertContains(new String[] { "crackers", "apple" }, food);
    assertEquals(0, accMemory.getBetaMemory().getRightTupleMemory().size());
    assertEquals(0, existsMemory.getRightTupleMemory().size());
    assertEquals(0, fromMemory.getBetaMemory().getLeftTupleMemory().size());
    assertEquals(0, notMemory.getRightTupleMemory().size());
    // Now execute an open query and ensure the memory is left populated
    food.clear();
    final List foodUpdated = new ArrayList();
    LiveQuery query = ksession.openLiveQuery("look", new Object[] { "kitchen", Variable.v }, new ViewChangedEventListener() {

        public void rowUpdated(Row row) {
            foodUpdated.addAll((Collection) row.get("food"));
        }

        public void rowDeleted(Row row) {
        }

        public void rowInserted(Row row) {
            food.addAll((Collection) row.get("food"));
        }
    });
    assertEquals(2, food.size());
    assertContains(new String[] { "crackers", "apple" }, food);
    assertEquals(2, accMemory.getBetaMemory().getRightTupleMemory().size());
    assertEquals(2, existsMemory.getRightTupleMemory().size());
    assertEquals(2, fromMemory.getBetaMemory().getLeftTupleMemory().size());
    assertEquals(0, notMemory.getRightTupleMemory().size());
    food.clear();
    // Now try again, make sure it only delete's it's own tuples
    results = ksession.getQueryResults("look", new Object[] { "kitchen", Variable.v });
    assertEquals(1, results.size());
    for (org.kie.api.runtime.rule.QueryResultsRow row : results) {
        food.addAll((Collection) row.get("food"));
        logger.debug(row.get("food").toString());
    }
    assertEquals(2, food.size());
    assertContains(new String[] { "crackers", "apple" }, food);
    assertEquals(2, accMemory.getBetaMemory().getRightTupleMemory().size());
    assertEquals(2, existsMemory.getRightTupleMemory().size());
    assertEquals(2, fromMemory.getBetaMemory().getLeftTupleMemory().size());
    assertEquals(0, notMemory.getRightTupleMemory().size());
    food.clear();
    // do an update and check it's  still memory size 2
    // however this time the food should be empty, as 'crackers' now blocks the not.
    ksession.update(fh, "crackers");
    ksession.fireAllRules();
    assertEquals(2, accMemory.getBetaMemory().getRightTupleMemory().size());
    assertEquals(2, existsMemory.getRightTupleMemory().size());
    assertEquals(2, fromMemory.getBetaMemory().getLeftTupleMemory().size());
    assertEquals(1, notMemory.getRightTupleMemory().size());
    assertEquals(0, foodUpdated.size());
    // do an update and check it's  still memory size 2
    // this time
    ksession.update(fh, "oranges");
    ksession.fireAllRules();
    assertEquals(2, accMemory.getBetaMemory().getRightTupleMemory().size());
    assertEquals(2, existsMemory.getRightTupleMemory().size());
    assertEquals(2, fromMemory.getBetaMemory().getLeftTupleMemory().size());
    assertEquals(0, notMemory.getRightTupleMemory().size());
    assertEquals(2, food.size());
    assertContains(new String[] { "crackers", "apple" }, food);
    // Close the open
    query.close();
    assertEquals(0, accMemory.getBetaMemory().getRightTupleMemory().size());
    assertEquals(0, existsMemory.getRightTupleMemory().size());
    assertEquals(0, fromMemory.getBetaMemory().getLeftTupleMemory().size());
    assertEquals(0, notMemory.getRightTupleMemory().size());
}
Also used : AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) NotNode(org.drools.core.reteoo.NotNode) QueryResultsRow(org.kie.api.runtime.rule.QueryResultsRow) InternalFactHandle(org.drools.core.common.InternalFactHandle) FactHandle(org.kie.api.runtime.rule.FactHandle) AccumulateNode(org.drools.core.reteoo.AccumulateNode) QueryElementNode(org.drools.core.reteoo.QueryElementNode) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) ArrayList(java.util.ArrayList) FromNode(org.drools.core.reteoo.FromNode) ExistsNode(org.drools.core.reteoo.ExistsNode) LiveQuery(org.kie.api.runtime.rule.LiveQuery) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) KieBase(org.kie.api.KieBase) KieSession(org.kie.api.runtime.KieSession) List(java.util.List) ArrayList(java.util.ArrayList) RightInputAdapterNode(org.drools.core.reteoo.RightInputAdapterNode) BetaNode(org.drools.core.reteoo.BetaNode) BetaMemory(org.drools.core.reteoo.BetaMemory) QueryResults(org.kie.api.runtime.rule.QueryResults) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) ViewChangedEventListener(org.kie.api.runtime.rule.ViewChangedEventListener) Collection(java.util.Collection) Row(org.kie.api.runtime.rule.Row) QueryResultsRow(org.kie.api.runtime.rule.QueryResultsRow) Map(java.util.Map) HashMap(java.util.HashMap) Test(org.junit.Test)

Example 12 with ExistsNode

use of org.drools.core.reteoo.ExistsNode in project drools by kiegroup.

the class LeftTupleIterator method getFirstLeftTuple.

public LeftTuple getFirstLeftTuple(LeftTupleSource source, LeftTupleSink sink, InternalWorkingMemory wm) {
    if (source instanceof AccumulateNode) {
        AccumulateMemory accmem = (AccumulateMemory) wm.getNodeMemory((MemoryFactory) source);
        BetaMemory memory = accmem.getBetaMemory();
        FastIterator localIt = memory.getLeftTupleMemory().fullFastIterator();
        Tuple leftTuple = BetaNode.getFirstTuple(memory.getLeftTupleMemory(), localIt);
        if (leftTuple != null) {
            AccumulateContext accctx = (AccumulateContext) leftTuple.getContextObject();
            return accctx.getResultLeftTuple();
        }
        return null;
    }
    if (source instanceof JoinNode || source instanceof NotNode || source instanceof FromNode || source instanceof AccumulateNode) {
        BetaMemory memory;
        FastIterator localIt;
        if (source instanceof FromNode) {
            memory = ((FromMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
        } else if (source instanceof AccumulateNode) {
            memory = ((AccumulateMemory) wm.getNodeMemory((MemoryFactory) source)).getBetaMemory();
        } else {
            memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
        }
        localIt = memory.getLeftTupleMemory().fullFastIterator();
        Tuple leftTuple = BetaNode.getFirstTuple(memory.getLeftTupleMemory(), localIt);
        while (leftTuple != null) {
            for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
                if (childleftTuple.getTupleSink() == sink) {
                    return childleftTuple;
                }
            }
            leftTuple = (LeftTuple) localIt.next(leftTuple);
        }
    }
    if (source instanceof ExistsNode) {
        BetaMemory memory = (BetaMemory) wm.getNodeMemory((MemoryFactory) source);
        FastIterator localIt = memory.getRightTupleMemory().fullFastIterator();
        RightTuple rightTuple = (RightTuple) BetaNode.getFirstTuple(memory.getRightTupleMemory(), localIt);
        while (rightTuple != null) {
            if (rightTuple.getBlocked() != null) {
                for (LeftTuple leftTuple = rightTuple.getBlocked(); leftTuple != null; leftTuple = leftTuple.getBlockedNext()) {
                    for (LeftTuple childleftTuple = leftTuple.getFirstChild(); childleftTuple != null; childleftTuple = childleftTuple.getHandleNext()) {
                        if (childleftTuple.getTupleSink() == sink) {
                            return childleftTuple;
                        }
                    }
                }
            }
            rightTuple = (RightTuple) localIt.next(rightTuple);
        }
    } else if (source instanceof LeftInputAdapterNode) {
        ObjectSource os = ((LeftInputAdapterNode) source).getParentObjectSource();
        while (!(os instanceof ObjectTypeNode)) {
            os = os.getParentObjectSource();
        }
        ObjectTypeNode otn = (ObjectTypeNode) os;
        otnIterator = wm.getNodeMemory(otn).iterator();
        while (otnIterator.hasNext()) {
            InternalFactHandle handle = otnIterator.next();
            LeftTuple leftTuple = handle.findFirstLeftTuple(lt -> lt.getTupleSink() == sink);
            if (leftTuple != null) {
                return leftTuple;
            }
        }
    } else if (source instanceof EvalConditionNode || source instanceof QueryElementNode) {
        LeftTuple parentLeftTuple = getFirstLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, wm);
        while (parentLeftTuple != null) {
            for (LeftTuple leftTuple = parentLeftTuple.getFirstChild(); leftTuple != null; leftTuple = leftTuple.getHandleNext()) {
                if (leftTuple.getTupleSink() == sink) {
                    return leftTuple;
                }
            }
            parentLeftTuple = getNextLeftTuple(source.getLeftTupleSource(), (LeftTupleSink) source, parentLeftTuple, wm);
        }
    }
    return null;
}
Also used : NotNode(org.drools.core.reteoo.NotNode) ExistsNode(org.drools.core.reteoo.ExistsNode) EvalConditionNode(org.drools.core.reteoo.EvalConditionNode) FastIterator(org.drools.core.util.FastIterator) AccumulateNode(org.drools.core.reteoo.AccumulateNode) AccumulateContext(org.drools.core.reteoo.AccumulateNode.AccumulateContext) BetaMemory(org.drools.core.reteoo.BetaMemory) JoinNode(org.drools.core.reteoo.JoinNode) FromNode(org.drools.core.reteoo.FromNode) LeftTuple(org.drools.core.reteoo.LeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode) QueryElementNode(org.drools.core.reteoo.QueryElementNode) Tuple(org.drools.core.spi.Tuple) BetaNode(org.drools.core.reteoo.BetaNode) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) FromMemory(org.drools.core.reteoo.FromNode.FromMemory) ObjectSource(org.drools.core.reteoo.ObjectSource) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) Iterator(org.drools.core.util.Iterator) LeftTupleSource(org.drools.core.reteoo.LeftTupleSource) AccumulateMemory(org.drools.core.reteoo.AccumulateNode.AccumulateMemory) NotNode(org.drools.core.reteoo.NotNode) EvalConditionNode(org.drools.core.reteoo.EvalConditionNode) AccumulateNode(org.drools.core.reteoo.AccumulateNode) JoinNode(org.drools.core.reteoo.JoinNode) QueryElementNode(org.drools.core.reteoo.QueryElementNode) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) LeftTupleSink(org.drools.core.reteoo.LeftTupleSink) BetaMemory(org.drools.core.reteoo.BetaMemory) FromNode(org.drools.core.reteoo.FromNode) LeftTuple(org.drools.core.reteoo.LeftTuple) ExistsNode(org.drools.core.reteoo.ExistsNode) RightTuple(org.drools.core.reteoo.RightTuple) ObjectSource(org.drools.core.reteoo.ObjectSource) FastIterator(org.drools.core.util.FastIterator) LeftTuple(org.drools.core.reteoo.LeftTuple) RightTuple(org.drools.core.reteoo.RightTuple) Tuple(org.drools.core.spi.Tuple) AccumulateContext(org.drools.core.reteoo.AccumulateNode.AccumulateContext) LeftInputAdapterNode(org.drools.core.reteoo.LeftInputAdapterNode)

Aggregations

ExistsNode (org.drools.core.reteoo.ExistsNode)12 ObjectTypeNode (org.drools.core.reteoo.ObjectTypeNode)12 LeftInputAdapterNode (org.drools.core.reteoo.LeftInputAdapterNode)11 JoinNode (org.drools.core.reteoo.JoinNode)10 Test (org.junit.Test)9 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)8 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)8 BetaMemory (org.drools.core.reteoo.BetaMemory)7 RuleTerminalNode (org.drools.core.reteoo.RuleTerminalNode)7 KnowledgeBuilder (org.kie.internal.builder.KnowledgeBuilder)7 PathMemory (org.drools.core.reteoo.PathMemory)6 RightInputAdapterNode (org.drools.core.reteoo.RightInputAdapterNode)6 FactHandle (org.kie.api.runtime.rule.FactHandle)5 BetaNode (org.drools.core.reteoo.BetaNode)4 EvalConditionNode (org.drools.core.reteoo.EvalConditionNode)4 NotNode (org.drools.core.reteoo.NotNode)4 AccumulateNode (org.drools.core.reteoo.AccumulateNode)3 AccumulateMemory (org.drools.core.reteoo.AccumulateNode.AccumulateMemory)3 FromNode (org.drools.core.reteoo.FromNode)3 FromMemory (org.drools.core.reteoo.FromNode.FromMemory)3