/// <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> 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> addPartialMatch stores the fact with the factId as the /// key. /// </summary> public virtual int addPartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap <Object, Object> matches = (IGenericMap <Object, Object>)memory.Get(index); int count = 0; if (matches == null) { count = addNewPartialMatch(index, fact); } else { IGenericMap <object, object> submatch = (IGenericMap <object, object>)matches.Get(index.SubIndex); if (submatch == null) { submatch = CollectionFactory.newHashMap(); submatch.Put(fact, fact); matches.Put(index.SubIndex, submatch); count = matches.Count; } else { submatch.Put(fact, fact); count = submatch.Count; } } counter++; return(count); }
/// <summary> /// if there are zero matches for the NotEqHashIndex2, the method /// return true. If there are matches, the method returns false. /// False means there's 1 or more matches /// </summary> /// <param name="index">The index.</param> /// <returns></returns> public virtual bool zeroMatch(NotEqHashIndex index) { IGenericMap <Object, Object> matches = (IGenericMap <Object, Object>)memory.Get(index); int idz = 0; if (matches != null) { IEnumerator itr = matches.Keys.GetEnumerator(); while (itr.MoveNext()) { Object key = itr.Current; // if the key doesn't match the subindex, Add it to the // counter. if (!index.SubIndex.Equals(key)) { IGenericMap <Object, Object> submatch = (IGenericMap <Object, Object>)matches.Get(key); idz += submatch.Count; } if (idz > 0) { break; } } return(false); } else { return(true); } }
/// <summary> addPartialMatch stores the fact with the factId as the /// key. /// </summary> public virtual int addPartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap<Object, Object> matches = (IGenericMap<Object, Object>) memory.Get(index); int count = 0; if (matches == null) { count = addNewPartialMatch(index, fact); } else { IGenericMap<object, object> submatch = (IGenericMap<object, object>)matches.Get(index.SubIndex); if (submatch == null) { submatch = CollectionFactory.newHashMap(); submatch.Put(fact, fact); matches.Put(index.SubIndex, submatch); count = matches.Count; } else { submatch.Put(fact, fact); count = submatch.Count; } } counter++; return count; }
/// <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); } } }
public virtual int addNewPartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap<object, object> matches = CollectionFactory.newHashMap(); IGenericMap<object, object> submatch = CollectionFactory.newHashMap(); submatch.Put(fact, fact); matches.Put(index.SubIndex, submatch); memory.Put(index, matches); return 1; }
public virtual int addNewPartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap <object, object> matches = CollectionFactory.newHashMap(); IGenericMap <object, object> submatch = CollectionFactory.newHashMap(); submatch.Put(fact, fact); matches.Put(index.SubIndex, submatch); memory.Put(index, matches); return(1); }
/// <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); 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); // 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> Remove a partial match from the memory /// </summary> public virtual int removePartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap <Object, Object> match = (IGenericMap <Object, Object>)memory.Get(index); if (match != null) { IGenericMap <Object, Object> submatch = (IGenericMap <Object, Object>)match.Get(index.SubIndex); submatch.Remove(fact); if (submatch.Count == 0) { match.Remove(index.SubIndex); } counter--; return(submatch.Count); } return(-1); }
/// <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); } } }
public virtual bool isPartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap <Object, Object> match = (IGenericMap <Object, Object>)memory.Get(index); if (match != null) { IGenericMap <Object, Object> submatch = (IGenericMap <Object, Object>)match.Get(index.SubIndex); if (submatch != null) { return(submatch.ContainsKey(fact)); } else { return(false); } } else { return(false); } }
/// <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) { 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); } } } }
/// <summary> Return an GetEnumerator of the values /// </summary> public virtual Object[] iterator(NotEqHashIndex index) { IGenericMap <Object, Object> matches = (IGenericMap <Object, Object>)memory.Get(index); Object[] list = new Object[counter]; Object[] trim = null; int idz = 0; if (matches != null) { IEnumerator itr = matches.Keys.GetEnumerator(); while (itr.MoveNext()) { Object key = itr.Current; // if the key doesn't match the subindex, we // Add it to the list. If it matches, we exclude // it. if (!index.SubIndex.Equals(key)) { IGenericMap <Object, Object> submatch = (IGenericMap <Object, Object>)matches.Get(key); IEnumerator itr2 = submatch.Keys.GetEnumerator(); while (itr2.MoveNext()) { list[idz] = itr2.Current; idz++; } } trim = new Object[idz]; Array.Copy(list, 0, trim, 0, idz); } list = null; return(trim); } else { return(null); } }
/// <summary> The implementation is similar to the index class. /// </summary> public override bool Equals(Object val) { if (this == val) { return(true); } if (val == null || !(val is NotEqHashIndex)) { return(false); } NotEqHashIndex eval = (NotEqHashIndex)val; bool eq = true; for (int idx = 0; idx < values.Length; idx++) { if (!values[idx].negated() && !eval.values[idx].Value.Equals(values[idx].Value)) { eq = false; break; } } return(eq); }
/// <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> /// if there are zero matches for the NotEqHashIndex2, the method /// return true. If there are matches, the method returns false. /// False means there's 1 or more matches /// </summary> /// <param name="index">The index.</param> /// <returns></returns> public virtual bool zeroMatch(NotEqHashIndex index) { IGenericMap<Object, Object> matches = (IGenericMap<Object, Object>) memory.Get(index); int idz = 0; if (matches != null) { IEnumerator itr = matches.Keys.GetEnumerator(); while (itr.MoveNext()) { Object key = itr.Current; // if the key doesn't match the subindex, Add it to the // counter. if (!index.SubIndex.Equals(key)) { IGenericMap<Object, Object> submatch = (IGenericMap<Object, Object>) matches.Get(key); idz += submatch.Count; } if (idz > 0) { break; } } return false; } else { return true; } }
/// <summary> Remove a partial match from the memory /// </summary> public virtual int removePartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap<Object, Object> match = (IGenericMap<Object, Object>) memory.Get(index); if (match != null) { IGenericMap<Object, Object> submatch = (IGenericMap<Object, Object>) match.Get(index.SubIndex); submatch.Remove(fact); if (submatch.Count == 0) { match.Remove(index.SubIndex); } counter--; return submatch.Count; } return - 1; }
/// <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); } } } } }
public virtual bool isPartialMatch(NotEqHashIndex index, IFact fact) { IGenericMap<Object, Object> match = (IGenericMap<Object, Object>) memory.Get(index); if (match != null) { IGenericMap<Object, Object> submatch = (IGenericMap<Object, Object>) match.Get(index.SubIndex); if (submatch != null) { return submatch.ContainsKey(fact); } else { return false; } } else { return false; } }
/// <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> Return an GetEnumerator of the values /// </summary> public virtual Object[] iterator(NotEqHashIndex index) { IGenericMap<Object, Object> matches = (IGenericMap<Object, Object>) memory.Get(index); Object[] list = new Object[counter]; Object[] trim = null; int idz = 0; if (matches != null) { IEnumerator itr = matches.Keys.GetEnumerator(); while (itr.MoveNext()) { Object key = itr.Current; // if the key doesn't match the subindex, we // Add it to the list. If it matches, we exclude // it. if (!index.SubIndex.Equals(key)) { IGenericMap<Object, Object> submatch = (IGenericMap<Object, Object>) matches.Get(key); IEnumerator itr2 = submatch.Keys.GetEnumerator(); while (itr2.MoveNext()) { list[idz] = itr2.Current; idz++; } } trim = new Object[idz]; Array.Copy(list, 0, trim, 0, idz); } list = null; return trim; } else { return null; } }
/// <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); } } } } }