/// <summary> Assert from the right side is always going to be from an Alpha node. /// /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void assertRight(IFact rfact, Rete engine, IWorkingMemory mem) { // Get the memory for the node HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getRightBindValues(binds, rfact)); rightmem.addPartialMatch(inx, rfact); bool zm = rightmem.zeroMatch(inx); IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { Index linx = (Index)itr.Current; if (evaluate(linx.Facts, rfact)) { if (!zm) { try { propogateRetract(linx, engine, mem); } catch (RetractException e) { throw new AssertException("NotJion - " + e.Message); } } } } }
/// <summary> Assert from the right side is always going to be from an Alpha node. /// /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void assertRight(IFact rfact, Rete engine, IWorkingMemory mem) { // Get the memory for the node HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getRightBindValues(binds, rfact)); rightmem.addPartialMatch(inx, rfact); // now that we've added the facts to the list, we // proceed with evaluating the fact // else we compare the fact to all facts in the left IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); // since there may be key collisions, we iterate over the // values of the HashMap. If we used keySet to iterate, // we could encounter a ClassCastException in the case of // key collision. IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { Index linx = (Index)itr.Current; if (evaluate(linx.Facts, rfact)) { // now we propogate propogateAssert(linx.add(rfact), engine, mem); } } }
/// <summary> Retract from the right works in the following order. /// 1. Remove the fact from the right memory /// 2. check which left memory matched /// 3. propogate the retract /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void retractRight(IFact rfact, Rete engine, IWorkingMemory mem) { NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getRightBindValues(binds, rfact)); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); // first we Remove the fact from the right rightmem.removePartialMatch(inx, rfact); bool zm = rightmem.zeroMatch(inx); // now we see the left memory matched and Remove it also IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { Index linx = (Index)itr.Current; if (evaluate(linx.Facts, rfact)) { if (zm) { try { propogateAssert(linx, engine, mem); } catch (AssertException e) { throw new RetractException("NotJion - " + e.Message); } } } } }
/// <summary> Retracting from the left requires that we propogate the /// /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void retractLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); leftmem.Remove(linx); NotEqHashIndex eqinx = new NotEqHashIndex(NodeUtils.getLeftBindValues(binds, linx.Facts)); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); Object[] objs = rightmem.iterator(eqinx); for (int idx = 0; idx < objs.Length; idx++) { propogateRetract(linx.add((IFact)objs[idx]), engine, mem); } }
/// <summary> assertLeft takes an array of facts. Since the Current join may be /// joining against one or more objects, we need to pass all /// previously matched facts. /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); leftmem.Put(linx, linx); // need to think the getLeftValues through better to // account for cases when a join has no bindings NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getLeftBindValues(binds, linx.Facts)); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); if (rightmem.zeroMatch(inx)) { propogateAssert(linx, engine, mem); } }
/// <summary> assertLeft takes an array of facts. Since the Current join may be /// joining against one or more objects, we need to pass all /// previously matched facts. /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); leftmem.Put(linx, linx); NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getLeftBindValues(binds, linx.Facts)); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); Object[] objs = rightmem.iterator(inx); // if the right side has 1 or more matches, we propogate the original // index down the network. We don't Add any facts to the index if (objs != null && objs.Length > 0) { propogateAssert(linx, engine, mem); } }
/// <summary> Clear will Clear the lists /// </summary> public override void clear(IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); IEnumerator itr = leftmem.Keys.GetEnumerator(); // first we iterate over the list for each fact // and Clear it. while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory)leftmem.Get(itr.Current); bmem.clear(); } // now that we've cleared the list for each fact, we // can Clear the Creshendo.rete.util.Map. leftmem.Clear(); rightmem.clear(); }
/// <summary> assertLeft takes an array of facts. Since the Current join may be /// joining against one or more objects, we need to pass all /// previously matched facts. /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); leftmem.Put(linx, linx); // need to think the getLeftValues through better to // account for cases when a join has no bindings NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getLeftBindValues(binds, linx.Facts)); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); Object[] objs = rightmem.iterator(inx); if (objs != null && objs.Length > 0) { for (int idx = 0; idx < objs.Length; idx++) { IFact rfcts = (IFact)objs[idx]; // now we propogate propogateAssert(linx.add(rfcts), engine, mem); } } }
/// <summary> the current implementation will try to find the memory for the node. /// If it doesn't find it, it checks the node type and creates the /// appropriate AlphaMemory for the node. Since right memories are /// hashed, it creates the appropriate type of Hashed memory. /// </summary> public virtual Object getBetaRightMemory(Object key) { Object val = betaRightMemories.Get(key); if (val != null) { return(val); } else { if (key is HashedEqBNode || key is HashedEqNJoin || key is ExistJoin) { String mname = "hnode" + ((BaseNode)key).nodeID; HashedAlphaMemoryImpl alpha = new HashedAlphaMemoryImpl(mname); betaRightMemories.Put(key, alpha); return(alpha); } else if (key is HashedNotEqBNode || key is HashedNotEqNJoin || key is ExistNeqJoin) { String mname = "hneq" + ((BaseNode)key).nodeID; HashedNeqAlphaMemory alpha = new HashedNeqAlphaMemory(mname); betaRightMemories.Put(key, alpha); return(alpha); } else if (key is TemporalEqNode) { String mname = "hnode" + ((BaseNode)key).nodeID; TemporalHashedAlphaMem alpha = new TemporalHashedAlphaMem(mname); betaRightMemories.Put(key, alpha); return(alpha); } else { String mname = "brmem" + ((BaseNode)key).nodeID; IGenericMap <IFact, IFact> right = CollectionFactory.newAlphaMemoryMap(mname); betaRightMemories.Put(key, right); return(right); } } }
/// <summary> Retract from the right works in the following order. /// 1. Remove the fact from the right memory /// 2. check which left memory matched /// 3. propogate the retract /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void retractRight(IFact rfact, Rete engine, IWorkingMemory mem) { NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getRightBindValues(binds, rfact)); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); // first we Remove the fact from the right rightmem.removePartialMatch(inx, rfact); // now we see the left memory matched and Remove it also IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { Index linx = (Index)itr.Current; if (evaluate(linx.Facts, rfact)) { // it matched, so we need to retract it from // succeeding nodes propogateRetract(linx.add(rfact), engine, mem); } } }
/// <summary> Assert from the right side is always going to be from an /// Alpha node. /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public override void assertRight(IFact rfact, Rete engine, IWorkingMemory mem) { HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)mem.getBetaRightMemory(this); NotEqHashIndex inx = new NotEqHashIndex(NodeUtils.getRightBindValues(binds, rfact)); rightmem.addPartialMatch(inx, rfact); IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); int after = rightmem.count(inx); while (itr.MoveNext()) { Index linx = (Index)itr.Current; if (evaluate(linx.Facts, rfact)) { if (after == 1) { propogateAssert(linx, engine, mem); } } } }
protected internal virtual void printBetaNodes(BaseJoin bjoin, bool detailed, int betaTotal) { if (bjoin is HashedEqBNode || bjoin is HashedEqNJoin) { IGenericMap <Object, Object> bm = (IGenericMap <Object, Object>)betaLeftMemories.Get(bjoin); // we iterate over the keys in the HashMap IEnumerator bitr = bm.Keys.GetEnumerator(); while (bitr.MoveNext()) { Index indx = (Index)bm.Get(bitr.Current); if (detailed) { engine.writeMessage(bjoin.toPPString(), Constants.DEFAULT_OUTPUT); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)getBetaRightMemory(bjoin); EqHashIndex eqinx = new EqHashIndex(NodeUtils.getLeftValues(bjoin.binds, indx.Facts)); // Add to the total count betaTotal += rightmem.count(eqinx); engine.writeMessage(" count=" + betaTotal + " - " + indx.toPPString() + ": ", Constants.DEFAULT_OUTPUT); IEnumerator ritr = rightmem.iterator(eqinx); if (ritr != null) { StringBuilder buf = new StringBuilder(); while (ritr.MoveNext()) { buf.Append(((IFact)ritr.Current).FactId + ","); } engine.writeMessage(buf.ToString(), Constants.DEFAULT_OUTPUT); } engine.writeMessage(Constants.LINEBREAK, Constants.DEFAULT_OUTPUT); } } } else if (bjoin is HashedNotEqNJoin || bjoin is HashedNotEqBNode) { IGenericMap <Object, Object> bm = (IGenericMap <Object, Object>)betaLeftMemories.Get(bjoin); // we iterate over the keys in the HashMap IEnumerator bitr = bm.Keys.GetEnumerator(); while (bitr.MoveNext()) { Index indx = (Index)bm.Get(bitr.Current); if (detailed) { engine.writeMessage(bjoin.toPPString(), Constants.DEFAULT_OUTPUT); HashedNeqAlphaMemory rightmem = (HashedNeqAlphaMemory)getBetaRightMemory(bjoin); EqHashIndex eqinx = new EqHashIndex(NodeUtils.getLeftValues(bjoin.binds, indx.Facts)); // Add to the total count betaTotal += rightmem.count(eqinx); engine.writeMessage(" count=" + betaTotal + " - " + indx.toPPString() + ": ", Constants.DEFAULT_OUTPUT); IEnumerator ritr = rightmem.iterator(eqinx); if (ritr != null) { StringBuilder buf = new StringBuilder(); while (ritr.MoveNext()) { buf.Append(((IFact)ritr.Current).FactId + ","); } engine.writeMessage(buf.ToString(), Constants.DEFAULT_OUTPUT); } engine.writeMessage(Constants.LINEBREAK, Constants.DEFAULT_OUTPUT); } } } else if (bjoin is ExistJoin) { ExistJoin henj = (ExistJoin)bjoin; IGenericMap <Object, Object> bm = (IGenericMap <Object, Object>)betaLeftMemories.Get(henj); // we iterate over the keys in the HashMap IEnumerator bitr = bm.Keys.GetEnumerator(); while (bitr.MoveNext()) { Index indx = (Index)bm.Get(bitr.Current); if (detailed) { engine.writeMessage(bjoin.toPPString(), Constants.DEFAULT_OUTPUT); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)getBetaRightMemory(henj); EqHashIndex eqinx = new EqHashIndex(NodeUtils.getLeftValues(henj.binds, indx.Facts)); // Add to the total count betaTotal += rightmem.count(eqinx); engine.writeMessage(" count=" + betaTotal + " - " + indx.toPPString() + ": ", Constants.DEFAULT_OUTPUT); IEnumerator ritr = rightmem.iterator(eqinx); if (ritr != null) { StringBuilder buf = new StringBuilder(); while (ritr.MoveNext()) { buf.Append(((IFact)ritr.Current).FactId + ","); } engine.writeMessage(buf.ToString(), Constants.DEFAULT_OUTPUT); } engine.writeMessage(Constants.LINEBREAK, Constants.DEFAULT_OUTPUT); } } } else if (bjoin is NotJoin) { NotJoin nj = (NotJoin)bjoin; IGenericMap <Object, Object> bm = (IGenericMap <Object, Object>)getBetaLeftMemory(bjoin); IEnumerator bitr = bm.Keys.GetEnumerator(); while (bitr.MoveNext()) { Index indx = (Index)bitr.Current; IBetaMemory bmem = (IBetaMemory)bm.Get(indx); engine.writeMessage(bmem.toPPString()); } } else if (bjoin is TemporalEqNode) { TemporalEqNode ten = (TemporalEqNode)bjoin; } else { IGenericMap <Object, Object> bm = (IGenericMap <Object, Object>)betaLeftMemories.Get(bjoin); // we iterate over the keys in the HashMap IEnumerator bitr = bm.Keys.GetEnumerator(); while (bitr.MoveNext()) { Index indx = (Index)bm.Get(bitr.Current); Object rightmem = betaRightMemories.Get(bjoin); if (detailed) { if (rightmem is HashedAlphaMemoryImpl) { HashedAlphaMemoryImpl hami = (HashedAlphaMemoryImpl)rightmem; engine.writeMessage(bjoin.toPPString() + " count=" + hami.size() + " - " + indx.toPPString() + Constants.LINEBREAK); } else { IGenericMap <Object, Object> rmap = (IGenericMap <Object, Object>)rightmem; engine.writeMessage(bjoin.toPPString() + " count=" + rmap.Count + " - " + indx.toPPString() + Constants.LINEBREAK); } } if (rightmem is HashedAlphaMemoryImpl) { betaTotal += ((HashedAlphaMemoryImpl)rightmem).size(); } else { betaTotal += ((IGenericMap <IFact, IFact>)rightmem).Count; } } } }
/// <summary> the current implementation will try to find the memory for the node. /// If it doesn't find it, it checks the node type and creates the /// appropriate AlphaMemory for the node. Since right memories are /// hashed, it creates the appropriate type of Hashed memory. /// </summary> public virtual Object getBetaRightMemory(Object key) { Object val = betaRightMemories.Get(key); if (val != null) { return val; } else { if (key is HashedEqBNode || key is HashedEqNJoin || key is ExistJoin) { String mname = "hnode" + ((BaseNode) key).nodeID; HashedAlphaMemoryImpl alpha = new HashedAlphaMemoryImpl(mname); betaRightMemories.Put(key, alpha); return alpha; } else if (key is HashedNotEqBNode || key is HashedNotEqNJoin || key is ExistNeqJoin) { String mname = "hneq" + ((BaseNode) key).nodeID; HashedNeqAlphaMemory alpha = new HashedNeqAlphaMemory(mname); betaRightMemories.Put(key, alpha); return alpha; } else if (key is TemporalEqNode) { String mname = "hnode" + ((BaseNode) key).nodeID; TemporalHashedAlphaMem alpha = new TemporalHashedAlphaMem(mname); betaRightMemories.Put(key, alpha); return alpha; } else { String mname = "brmem" + ((BaseNode) key).nodeID; IGenericMap<IFact, IFact> right = CollectionFactory.newAlphaMemoryMap(mname); betaRightMemories.Put(key, right); return right; } } }