/// <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> Clear will Clear the lists /// </summary> public override void clear(IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = mem.getBetaLeftMemory(this); IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); // first we iterate over the list for each fact // and Clear it. foreach (object item in leftmem.Keys) { ((IBetaMemory)leftmem.Get(item)).clear(); } /* * 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(); }
public override void assertRight(IFact rfact, Rete engine, IWorkingMemory mem) { long time = LeftTime; TemporalHashedAlphaMem rightmem = (TemporalHashedAlphaMem) mem.getBetaRightMemory(this); EqHashIndex inx = new EqHashIndex(NodeUtils.getRightValues(binds, rfact)); rightmem.addPartialMatch(inx, rfact); // now that we've added the facts to the list, we // proceed with evaluating the fact 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(); try { while (itr.MoveNext()) { Index linx = (Index) itr.Current; if (evaluate(linx.Facts, rfact, time)) { // now we propogate propogateAssert(linx.add(rfact), engine, mem); } else { propogateRetract(linx.add(rfact), engine, mem); } } } catch (RetractException e) { // we shouldn't Get a retract exception. if we do, it's a bug } }
/// <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="linx">The linx.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = mem.getBetaLeftMemory(this); leftmem.Put(linx, linx); //foreach(IFact rfcts in ((IGenericMap<IFact, IFact>)mem.getBetaRightMemory(this)).Values) //{ // propogateAssert(linx.add(rfcts), engine, mem); //} IGenericMap <IFact, IFact> rightmem = (IGenericMap <IFact, IFact>)mem.getBetaRightMemory(this); foreach (IFact rfcts in rightmem.Values) { propogateAssert(linx.add(rfcts), engine, mem); } //IEnumerator itr = rightmem.Values.GetEnumerator(); //while (itr.MoveNext()) //{ // IFact rfcts = (IFact)itr.Current; // // now we propogate // propogateAssert(linx.add(rfcts), engine, mem); //} }
public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { long time = RightTime; IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); leftmem.Put(linx, linx); EqHashIndex inx = new EqHashIndex(NodeUtils.getLeftValues(binds, linx.Facts)); TemporalHashedAlphaMem rightmem = (TemporalHashedAlphaMem) mem.getBetaRightMemory(this); IEnumerator itr = rightmem.iterator(inx); if (itr != null) { try { while (itr.MoveNext()) { IFact vl = (IFact) itr.Current; if (vl != null) { if (vl.timeStamp() > time) { propogateAssert(linx.add(vl), engine, mem); } else { rightmem.removePartialMatch(inx, vl); propogateRetract(linx.add(vl), engine, mem); } } } } catch (RetractException e) { // there shouldn't be any retract exceptions } } }
/// <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> 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); IBetaMemory bmem = new BetaMemoryImpl(linx); leftmem.Put(linx, bmem); IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); IEnumerator itr = rightmem.Keys.GetEnumerator(); if (itr != null) { while (itr.MoveNext()) { IFact vl = (IFact)itr.Current; // we have to evaluate the function if (vl != null && evaluate(linx.Facts, vl, engine)) { bmem.addMatch(vl); } } } if (bmem.matchCount() > 0) { propogateAssert(linx, engine, mem); } }
/// <summary> NotJoin has to have a special addSuccessorNode since it needs /// to just propogate the left facts if it has zero matches. /// </summary> public override void addSuccessorNode(TerminalNode node, Rete engine, IWorkingMemory mem) { if (addNode(node)) { // first, we Get the memory for this node IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); // now we iterate over the entry set IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { Object omem = itr.Current; if (omem is IBetaMemory) { IBetaMemory bmem = (IBetaMemory)omem; EqHashIndex inx = new EqHashIndex(NodeUtils.getLeftValues(binds, bmem.LeftFacts)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)mem.getBetaRightMemory(this); // we don't bother adding the right fact to the left, since // the right side is already Hashed if (rightmem.count(inx) == 0) { node.assertFacts(bmem.Index, engine, mem); } } } } }
/// <summary> NotJoin has to have a special addSuccessorNode since it needs /// to just propogate the left facts if it has zero matches. /// </summary> public override void addSuccessorNode(TerminalNode node, Rete engine, IWorkingMemory mem) { if (addNode(node)) { // first, we Get the memory for this node IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); // now we iterate over the entry set IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { Object omem = itr.Current; if (omem is IBetaMemory) { IBetaMemory bmem = (IBetaMemory) omem; EqHashIndex inx = new EqHashIndex(NodeUtils.getLeftValues(binds, bmem.LeftFacts)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl) mem.getBetaRightMemory(this); // we don't bother adding the right fact to the left, since // the right side is already Hashed if (rightmem.count(inx) == 0) { node.assertFacts(bmem.Index, 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> /// 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="linx">The linx.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); // we create a new list for storing the matches. // any fact that isn't in the list will be evaluated. IBetaMemory bmem = new BetaMemoryImpl(linx); leftmem.Put(bmem.Index, bmem); IGenericMap <IFact, IFact> rightmem = (IGenericMap <IFact, IFact>)mem.getBetaRightMemory(this); int prevCount = bmem.matchCount(); IEnumerator itr = rightmem.Values.GetEnumerator(); while (itr.MoveNext()) { IFact rfcts = (IFact)itr.Current; if (evaluate(linx.Facts, rfcts, engine)) { // it matched, so we Add it to the beta memory bmem.addMatch(rfcts); } } // since the Fact[] is entering the left for the first time, // if there are no matches, we merged the facts propogate. if (bmem.matchCount() == 0) { propogateAssert(linx, engine, mem); } }
/// <summary> /// Subclasses need to implement Clear and make sure all /// memories are cleared properly. /// </summary> /// <param name="mem">The mem.</param> public virtual void clear(IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); leftmem.Clear(); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)mem.getBetaRightMemory(this); 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); EqHashIndex inx = new EqHashIndex(NodeUtils.getLeftValues(binds, linx.Facts)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)mem.getBetaRightMemory(this); if (rightmem.count(inx) > 0) { propogateAssert(linx, engine, mem); } }
/// <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> 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); EqHashIndex inx = new EqHashIndex(NodeUtils.getLeftValues(binds, linx.Facts)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)mem.getBetaRightMemory(this); // we don't bother adding the right fact to the left, since // the right side is already Hashed if (rightmem.count(inx) == 0) { propogateAssert(linx, 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) { Index inx = new Index(new IFact[] { rfact }); IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); if (rightmem.ContainsKey(inx)) { int count = rightmem.Count; rightmem.Remove(inx); if (count == 1 && rightmem.Count == 0) { propogateRetract(inx, 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> 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); IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); IEnumerator itr = rightmem.Keys.GetEnumerator(); if (itr != null) { while (itr.MoveNext()) { propogateRetract(linx.add((IFact)itr.Current), 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) { IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); rightmem.Remove(rfact); IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory)itr.Current; if (evaluate(bmem.LeftFacts, rfact, engine)) { bmem.removeMatch(rfact); propogateRetract(bmem.Index, engine, mem); } } }
/// <summary> /// Retracting from the left requires that we propogate the /// </summary> /// <param name="linx">The linx.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public override void retractLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap <Object, Object> leftmem = mem.getBetaLeftMemory(this); leftmem.Remove(linx); IGenericMap <IFact, IFact> rightmem = (IGenericMap <IFact, IFact>)mem.getBetaRightMemory(this); foreach (IFact itr in rightmem.Values) { propogateRetract(linx.add(itr), engine, mem); } //IEnumerator itr = rightmem.Values.GetEnumerator(); //while (itr.MoveNext()) //{ // propogateRetract(linx.add((IFact) itr.Current), 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> 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) { IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); rightmem.Put(rfact, rfact); IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory)itr.Current; if (evaluate(bmem.LeftFacts, rfact, engine)) { // now we propogate bmem.addMatch(rfact); propogateAssert(bmem.Index.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) { // we only proceed if the fact hasn't already entered // the join node Index inx = new Index(new IFact[] { rfact }); IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); if (!rightmem.ContainsKey(inx)) { int count = rightmem.Count; rightmem.Put(inx, rfact); // now that we've added the facts to the list, we // proceed with evaluating the fact if (count == 0 && rightmem.Count == 1) { propogateAssert(inx, 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) { HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)mem.getBetaRightMemory(this); EqHashIndex inx = new EqHashIndex(NodeUtils.getRightValues(binds, rfact)); int after = rightmem.addPartialMatch(inx, rfact); 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 (after == 1) { 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); // 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> 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) { EqHashIndex inx = new EqHashIndex(NodeUtils.getRightValues(binds, rfact)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)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)) { propogateRetract(linx.add(rfact), 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); 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> /// 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="rfact"></param> /// <param name="engine"></param> /// <param name="mem"></param> public override void retractRight(IFact rfact, Rete engine, IWorkingMemory mem) { IGenericMap <IFact, IFact> rightmem = (IGenericMap <IFact, IFact>)mem.getBetaRightMemory(this); rightmem.Remove(rfact); IGenericMap <Object, Object> leftmem = mem.getBetaLeftMemory(this); foreach (Index bmem in leftmem.Values) { propogateRetract(bmem.add(rfact), engine, mem); } //IEnumerator itr = leftmem.Values.GetEnumerator(); //while (itr.MoveNext()) //{ // Index bmem = (Index) itr.Current; // // now we propogate // propogateRetract(bmem.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); } } } }
/// <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); EqHashIndex inx = new EqHashIndex(NodeUtils.getLeftValues(binds, linx.Facts)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)mem.getBetaRightMemory(this); IEnumerator itr = rightmem.iterator(inx); if (itr != null) { while (itr.MoveNext()) { IFact vl = (IFact)itr.Current; if (vl != null) { propogateAssert(linx.add(vl), 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); IBetaMemory bmem = new BetaMemoryImpl(linx); leftmem.Put(linx, bmem); IGenericMap<Object, Object> rightmem = (IGenericMap<Object, Object>) mem.getBetaRightMemory(this); IEnumerator itr = rightmem.Keys.GetEnumerator(); if (itr != null) { while (itr.MoveNext()) { IFact vl = (IFact) itr.Current; // we have to evaluate the function if (vl != null && evaluate(linx.Facts, vl, engine)) { bmem.addMatch(vl); propogateAssert(linx.add(vl), engine, mem); } } } }
/// <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); EqHashIndex eqinx = new EqHashIndex(NodeUtils.getLeftValues(binds, linx.Facts)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl)mem.getBetaRightMemory(this); // now we propogate the retract. To do that, we have // merge each item in the list with the Fact array // and call retract in the successor nodes IEnumerator itr = rightmem.iterator(eqinx); if (itr != null) { while (itr.MoveNext()) { propogateRetract(linx.add((IFact)itr.Current), 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) { // we only proceed if the fact hasn't already entered // the join node Index linx = new Index(new IFact[0]); IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); rightmem.Put(rfact, rfact); // now that we've added the facts to the list, we // proceed with evaluating the fact IGenericMap <Object, Object> leftmem = (IGenericMap <Object, Object>)mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory)itr.Current; int prevCount = bmem.matchCount(); if (evaluate(linx.Facts, rfact, engine)) { bmem.addMatch(rfact); } // When facts are asserted from the right, it can only // increase the match count, so basically it will never // need to propogate to successor nodes. if (prevCount == 0 && bmem.matchCount() != 0) { linx = new Index(new IFact[0]); // we have to retract try { propogateRetract(linx, engine, mem); } catch (RetractException e) { throw new AssertException("NotJion - " + e.Message); } } } }
/// <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) { Index linx = new Index(new IFact[0]); IGenericMap <Object, Object> rightmem = (IGenericMap <Object, Object>)mem.getBetaRightMemory(this); if (rightmem.RemoveWithReturn(rfact) != null) { // 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()) { IBetaMemory bmem = (IBetaMemory)itr.Current; int prevCount = bmem.matchCount(); if (bmem.matched(rfact)) { // we Remove the fact from the memory bmem.removeMatch(rfact); // since 1 or more matches prevents propogation // we don't need to propogate retract. if the // match count is now zero, we need to propogate // assert if (prevCount != 0 && bmem.matchCount() == 0) { try { propogateAssert(bmem.Index, engine, mem); } catch (AssertException e) { throw new RetractException("NotJion - " + e.Message); } } } } } }
public override void assertRight(IFact rfact, Rete engine, IWorkingMemory mem) { long time = LeftTime; TemporalHashedAlphaMem rightmem = (TemporalHashedAlphaMem)mem.getBetaRightMemory(this); EqHashIndex inx = new EqHashIndex(NodeUtils.getRightValues(binds, rfact)); rightmem.addPartialMatch(inx, rfact); // now that we've added the facts to the list, we // proceed with evaluating the fact 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(); try { while (itr.MoveNext()) { Index linx = (Index)itr.Current; if (evaluate(linx.Facts, rfact, time)) { // now we propogate propogateAssert(linx.add(rfact), engine, mem); } else { propogateRetract(linx.add(rfact), engine, mem); } } } catch (RetractException e) { // we shouldn't Get a retract exception. if we do, it's a bug } }
/// <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) { IGenericMap<Object, Object> rightmem = (IGenericMap<Object, Object>) mem.getBetaRightMemory(this); rightmem.Put(rfact, rfact); IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory) itr.Current; if (evaluate(bmem.LeftFacts, rfact, engine)) { // now we propogate bmem.addMatch(rfact); propogateAssert(bmem.Index.add(rfact), engine, mem); } } }
/// <summary> /// Subclasses need to implement Clear and make sure all /// memories are cleared properly. /// </summary> /// <param name="mem">The mem.</param> public virtual void clear(IWorkingMemory mem) { IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); leftmem.Clear(); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl) mem.getBetaRightMemory(this); rightmem.clear(); }
/// <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) { IGenericMap<Object, Object> rightmem = (IGenericMap<Object, Object>) mem.getBetaRightMemory(this); rightmem.Remove(rfact); IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory) itr.Current; if (evaluate(bmem.LeftFacts, rfact, engine)) { bmem.removeMatch(rfact); propogateRetract(bmem.Index, engine, mem); } } }
/// <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); IGenericMap<Object, Object> rightmem = (IGenericMap<Object, Object>) mem.getBetaRightMemory(this); IEnumerator itr = rightmem.Keys.GetEnumerator(); if (itr != null) { while (itr.MoveNext()) { propogateRetract(linx.add((IFact) itr.Current), 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); } } } } }
public override void retractLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); leftmem.Remove(linx); EqHashIndex eqinx = new EqHashIndex(NodeUtils.getLeftValues(binds, linx.Facts)); TemporalHashedAlphaMem rightmem = (TemporalHashedAlphaMem) mem.getBetaRightMemory(this); // now we propogate the retract. To do that, we have // merge each item in the list with the Fact array // and call retract in the successor nodes IEnumerator itr = rightmem.iterator(eqinx); if (itr != null) { while (itr.MoveNext()) { propogateRetract(linx.add((IFact) itr.Current), engine, mem); } } }
public override void retractRight(IFact rfact, Rete engine, IWorkingMemory mem) { long time = LeftTime; EqHashIndex inx = new EqHashIndex(NodeUtils.getRightValues(binds, rfact)); TemporalHashedAlphaMem rightmem = (TemporalHashedAlphaMem) 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, time)) { propogateRetract(linx.add(rfact), 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="linx">The linx.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); // we create a new list for storing the matches. // any fact that isn't in the list will be evaluated. IBetaMemory bmem = new BetaMemoryImpl(linx); leftmem.Put(bmem.Index, bmem); IGenericMap<IFact, IFact> rightmem = (IGenericMap<IFact, IFact>)mem.getBetaRightMemory(this); int prevCount = bmem.matchCount(); IEnumerator itr = rightmem.Values.GetEnumerator(); while (itr.MoveNext()) { IFact rfcts = (IFact) itr.Current; if (evaluate(linx.Facts, rfcts, engine)) { // it matched, so we Add it to the beta memory bmem.addMatch(rfcts); } } // since the Fact[] is entering the left for the first time, // if there are no matches, we merged the facts propogate. if (bmem.matchCount() == 0) { propogateAssert(linx, 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) { // we only proceed if the fact hasn't already entered // the join node IGenericMap<IFact, IFact> rightmem = (IGenericMap<IFact, IFact>)mem.getBetaRightMemory(this); rightmem.Put(rfact, rfact); // now that we've added the facts to the list, we // proceed with evaluating the fact IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory) itr.Current; Index linx = bmem.Index; int prevCount = bmem.matchCount(); if (evaluate(linx.Facts, rfact, engine)) { bmem.addMatch(rfact); } // When facts are asserted from the right, it can only // increase the match count, so basically it will never // need to propogate to successor nodes. if (prevCount == 0 && bmem.matchCount() != 0) { // we have to retract 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); // 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> 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> 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); EqHashIndex inx = new EqHashIndex(NodeUtils.getLeftValues(binds, linx.Facts)); HashedAlphaMemoryImpl rightmem = (HashedAlphaMemoryImpl) mem.getBetaRightMemory(this); // we don't bother adding the right fact to the left, since // the right side is already Hashed if (rightmem.count(inx) == 0) { propogateAssert(linx, engine, mem); } }
/// <summary> /// When new Successor nodes are added, we propogate the facts that matched to /// the new join node. /// </summary> /// <param name="node">The node.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public virtual void addSuccessorNode(BaseJoin node, Rete engine, IWorkingMemory mem) { if (addNode(node)) { // first, we Get the memory for this node IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); // now we iterate over the entry set IEnumerator itr = leftmem.GetEnumerator(); while (itr.MoveNext()) { IBetaMemory bmem = (IBetaMemory) itr.Current; Index left = bmem.Index; // iterate over the matches IGenericMap<Object, Object> rightmem = (IGenericMap<Object, Object>) mem.getBetaRightMemory(this); IEnumerator ritr = rightmem.Keys.GetEnumerator(); while (ritr.MoveNext()) { IFact rfcts = (IFact) ritr.Current; // now assert in the new join node node.assertLeft(left.add(rfcts), engine, mem); } } } }
/// <summary> /// it's unlikely 2 rules are identical, except for the name. The implementation /// gets the current memory and propogates, but I wonder how much sense this /// makes in a real production environment. An user really shouldn't be deploying /// identical rules with different rule name. /// </summary> /// <param name="node">The node.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public virtual void addSuccessorNode(TerminalNode node, Rete engine, IWorkingMemory mem) { if (addNode(node)) { // first, we Get the memory for this node IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); // now we iterate over the entry set IEnumerator itr = leftmem.Values.GetEnumerator(); while (itr.MoveNext()) { Object omem = itr.Current; if (omem is IBetaMemory) { IBetaMemory bmem = (IBetaMemory) omem; Index left = bmem.Index; // iterate over the matches IGenericMap<Object, Object> rightmem = (IGenericMap<Object, Object>) mem.getBetaRightMemory(this); IEnumerator ritr = rightmem.Keys.GetEnumerator(); while (ritr.MoveNext()) { IFact rfcts = (IFact) ritr.Current; // merge the left and right fact into a new Array node.assertFacts(left.add(rfcts), 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="rfact">The rfact.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public override void retractRight(IFact rfact, Rete engine, IWorkingMemory mem) { IGenericMap<IFact, IFact> rightmem = (IGenericMap<IFact, IFact>)mem.getBetaRightMemory(this); if (rightmem.RemoveWithReturn(rfact) != null) { // 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()) { IBetaMemory bmem = (IBetaMemory) itr.Current; int prevCount = bmem.matchCount(); if (bmem.matched(rfact)) { // we Remove the fact from the memory bmem.removeMatch(rfact); // since 1 or more matches prevents propogation // we don't need to propogate retract. if the // match count is now zero, we need to propogate // assert if (prevCount != 0 && bmem.matchCount() == 0) { try { propogateAssert(bmem.Index, engine, mem); } catch (AssertException e) { throw new RetractException("NotJion - " + e.Message); } } } } } }