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> /// Initializes a new instance of the <see cref="BasicActivation"/> class. /// </summary> /// <param name="rule">The rule.</param> /// <param name="inx">The inx.</param> public BasicActivation(IRule rule, Index inx) { theRule = rule; index = inx; timetag = (DateTime.Now.Ticks - 621355968000000000)/10000; calculateTime(inx.Facts); }
/// <summary> Set the Current node in the sequence of 1-input nodes. /// The Current node can be an AlphaNode or a LIANode. /// </summary> /// <param name="">node /// /// </param> public override void addSuccessorNode(BaseNode node, Rete engine, IWorkingMemory mem) { if (addNode(node)) { // if there are matches, we propogate the facts to // the new successor only IAlphaMemory alpha = (IAlphaMemory) mem.getAlphaMemory(this); if (alpha.size() > 0) { IEnumerator itr = alpha.GetEnumerator(); while (itr.MoveNext()) { if (node is BaseAlpha) { BaseAlpha next = (BaseAlpha) node; next.assertFact((IFact) itr.Current, engine, mem); } else if (node is BaseJoin) { BaseJoin next = (BaseJoin) node; Index inx = new Index(new IFact[] {(IFact) itr.Current}); next.assertLeft(inx, engine, mem); } } } } }
/// <param name="">facts /// </param> /// <param name="">engine /// /// </param> public override void assertFacts(Index inx, Rete engine, IWorkingMemory mem) { long time = (DateTime.Now.Ticks - 621355968000000000)/10000; if (theRule.ExpirationDate > 0 && time > theRule.EffectiveDate && time < theRule.ExpirationDate) { LinkedActivation act = new LinkedActivation(theRule, inx); act.TerminalNode = this; // fire the activation immediately engine.fireActivation(act); } }
/// <summary> The implementation checks to see if the rule is active before it tries to /// assert the fact. It checks in the following order. /// 1. is the expiration date greater than zero /// 2. is the current time > the effective date /// 3. is the current time the expiration date /// </summary> /// <param name="">facts /// </param> /// <param name="">engine /// /// </param> public override void assertFacts(Index inx, Rete engine, IWorkingMemory mem) { long time = (DateTime.Now.Ticks - 621355968000000000)/10000; if (theRule.ExpirationDate > 0 && time > theRule.EffectiveDate && time < theRule.ExpirationDate) { LinkedActivation act = new LinkedActivation(theRule, inx); act.TerminalNode = this; IGenericMap<Object, Object> tmem = (IGenericMap<Object, Object>) mem.getTerminalMemory(this); tmem.Put(act.Index, act); // Add the activation to the current module's activation list. engine.Agenda.addActivation(act); } }
/// <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); // 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> Method will call checkFacts() first to make sure none of the facts have /// expired. An activation is only created if the facts are valid. /// </summary> /// <param name="">facts /// </param> /// <param name="">engine /// /// </param> public override void assertFacts(Index inx, Rete engine, IWorkingMemory mem) { // first check the facts and make sure they didn't expire if (checkFacts(inx, engine, mem)) { LinkedActivation act = new LinkedActivation(theRule, inx); act.TerminalNode = this; if (temporal) { engine.fireActivation(act); } else { IGenericMap<Object, Object> tmem = (IGenericMap<Object, Object>) mem.getTerminalMemory(this); tmem.Put(inx, act); // Add the activation to the current module's activation list. engine.Agenda.addActivation(act); } } }
/// <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> if all the facts have not expired, the method returns true. If a fact has /// expired, the method will retract the fact. /// </summary> /// <param name="">inx /// </param> /// <param name="">engine /// </param> /// <param name="">mem /// </param> /// <returns> /// /// </returns> protected internal virtual bool checkFacts(Index inx, Rete engine, IWorkingMemory mem) { IFact[] facts = inx.Facts; bool fresh = true; long current = (DateTime.Now.Ticks - 621355968000000000)/10000; for (int idx = 0; idx < facts.Length; idx++) { if (facts[idx] is ITemporalFact) { TemporalDeffact tf = (TemporalDeffact) facts[idx]; if (tf.ExpirationTime < current) { // the fact has expired fresh = false; try { engine.retractFact(tf); } catch (RetractException e) { // we do nothing } } } } return fresh; }
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); } } }
/// <summary> Retracting from the left requires that we propogate the /// /// </summary> /// <param name="">factInstance /// </param> /// <param name="">engine /// /// </param> public abstract override void retractLeft(Index linx, Rete engine, IWorkingMemory mem);
/// <summary> Propogate the fact using the normal way of iterating over the /// successors and calling assert on AlphaNodes and assertRight on /// BetaNodes. /// </summary> /// <param name="">fact /// </param> /// <param name="">engine /// </param> /// <param name="">mem /// @throws AssertException /// /// </param> public virtual void assertAllSuccessors(IFact fact, Rete engine, IWorkingMemory mem) { for (int idx = 0; idx < successorNodes.Length; idx++) { Object node = successorNodes[idx]; if (node is BaseAlpha) { ((BaseAlpha) node).assertFact(fact, engine, mem); } else if (node is BaseJoin) { ((BaseJoin) node).assertRight(fact, engine, mem); } else if (node is TerminalNode) { Index inx = new Index(new IFact[] {fact}); ((TerminalNode) node).assertFacts(inx, engine, mem); } } assertSecondSuccessors(fact, engine, mem); }
/// <summary> method for propogating the retract /// </summary> /// <param name="">fact /// </param> /// <param name="">engine /// /// </param> protected internal virtual void propogateRetract(IFact fact, Rete engine, IWorkingMemory mem) { for (int idx = 0; idx < successorNodes.Length; idx++) { Object nNode = successorNodes[idx]; if (nNode is BaseAlpha) { BaseAlpha next = (BaseAlpha) nNode; next.retractFact(fact, engine, mem); } else if (nNode is BaseJoin) { BaseJoin next = (BaseJoin) nNode; // AlphaNodes always call retractRight in the // BetaNode next.retractRight(fact, engine, mem); } else if (nNode is TerminalNode) { Index inx = new Index(new IFact[] {fact}); ((TerminalNode) nNode).retractFacts(inx, engine, mem); } } }
/// <summary> Method is used to pass a fact to the successor nodes /// </summary> /// <param name="">fact /// </param> /// <param name="">engine /// /// </param> protected internal virtual void propogateAssert(IFact fact, Rete engine, IWorkingMemory mem) { for (int idx = 0; idx < successorNodes.Length; idx++) { Object nNode = successorNodes[idx]; if (nNode is BaseAlpha) { BaseAlpha next = (BaseAlpha) nNode; next.assertFact(fact, engine, mem); } else if (nNode is BaseJoin) { BaseJoin next = (BaseJoin) nNode; next.assertRight(fact, engine, mem); } else if (nNode is TerminalNode) { TerminalNode next = (TerminalNode) nNode; Index inx = new Index(new IFact[] {fact}); next.assertFacts(inx, engine, mem); } } }
///// <summary> ///// Adds the specified fact. ///// </summary> ///// <param name="fact">The fact.</param> ///// <returns></returns> //public Index add(IFact fact) //{ // int factsLength = this._facts.Length; // Array.Resize<IFact>(ref this._facts, factsLength + 1); // this._facts[factsLength] = fact; // this._hash = _hash + fact.GetHashCode(); // return this; //} /// <summary> /// Adds all. /// </summary> /// <param name="index">The index.</param> /// <returns></returns> public Index addAll(Index index) { IFact[] facts1 = new IFact[this._facts.Length + index._facts.Length]; Array.Copy(this._facts, 0, facts1, 0, this._facts.Length); Array.Copy(index._facts, 0, facts1, this._facts.Length, index._facts.Length); return new Index(facts1, _hash + index._hash); }
/// <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); propogateRetract(linx, engine, mem); }
/// <summary> /// </summary> public override void retractLeft(Index linx, Rete engine, WorkingMemory mem) { Map leftmem = (Map) mem.getBetaLeftMemory(this); int prev = leftmem.size(); if (leftmem.containsKey(linx)) { // the memory contains the key, so we retract and propogate leftmem.remove(linx); } if (prev != 0 && leftmem.size() == 0) { propogateRetract(linx, engine, mem); } }
/// <summary> Retract the fact to the succeeding nodes. ObjectTypeNode does not call /// assertEvent, since it's not that important and doesn't really /// help debugging. /// </summary> /// <param name="">fact /// </param> /// <param name="">engine /// /// </param> public override void retractFact(IFact fact, Rete engine, IWorkingMemory mem) { if (fact.Deftemplate == deftemplate) { ((IAlphaMemory) mem.getAlphaMemory(this)).removePartialMatch(fact); for (int idx = 0; idx < successorNodes.Length; idx++) { Object node = successorNodes[idx]; if (node is BaseAlpha) { ((BaseAlpha) node).retractFact(fact, engine, mem); } else if (node is BaseJoin) { ((BaseJoin) node).retractRight(fact, engine, mem); } } IEnumerator itr2 = successor2.GetEnumerator(); while (itr2.MoveNext()) { BaseNode node = (BaseNode) itr2.Current; if (node is BaseAlpha) { ((BaseAlpha) node).retractFact(fact, engine, mem); } else if (node is BaseJoin) { ((BaseJoin) node).retractRight(fact, engine, mem); } else if (node is TerminalNode) { Index inx = new Index(new IFact[] {fact}); ((TerminalNode) node).retractFacts(inx, engine, mem); } } } }
/// <summary> /// Once the facts propogate to this point, it means all the conditions of /// the rule have been met. The method creates a new Activation and adds it /// to the activationList of the correct module. Note: we may want to change /// the design so that we don't create a new Activation object. /// </summary> /// <param name="facts">The facts.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public abstract void assertFacts(Index facts, Rete engine, IWorkingMemory mem);
/// <summary> Assert will first pass the facts to the parameters. Once the /// parameters are set, it should call execute to Get the result. /// </summary> public override void assertLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); if (!leftmem.ContainsKey(linx)) { Parameters = linx.Facts; IReturnVector rv = func.executeFunction(engine, params_Renamed); if (!rv.firstReturnValue().BooleanValue) { IBetaMemory bmem = new BetaMemoryImpl(linx); leftmem.Put(bmem.Index, bmem); } // only propogate if left memories count is zero if (leftmem.Count == 0) { propogateAssert(linx, engine, mem); } } }
/// <summary> assert using HashMap approach /// /// </summary> /// <param name="">fact /// </param> /// <param name="">engine /// </param> /// <param name="">mem /// /// </param> public virtual void assertFactWithMap(IFact fact, Rete engine, IWorkingMemory mem) { Slot[] slots = fact.Deftemplate.AllSlots; // iterate over the slots for (int idx = 0; idx < slots.Length; idx++) { // only if the slot's node count is greater than zero // do we go ahead and lookup in the HashMap if (slots[idx].NodeCount > 0) { // iterate over the operators for (int ops = 0; ops < operators.Length; ops++) { CompositeIndex comIndex = new CompositeIndex(slots[idx].Name, operators[ops], fact.getSlotValue(idx)); Object node = entries.Get(comIndex); if (node != null) { if (node is BaseAlpha) { ((BaseAlpha) node).assertFact(fact, engine, mem); } else if (node is BaseJoin) { ((BaseJoin) node).assertRight(fact, engine, mem); } else if (node is TerminalNode) { Index inx = new Index(new IFact[] {fact}); ((TerminalNode) node).assertFacts(inx, engine, mem); } } } } } assertSecondSuccessors(fact, engine, mem); }
/// <summary> The implementation checks to see if the rule is active before it tries to /// retract the fact. It checks in the following order. /// 1. is the expiration date greater than zero /// 2. is the current time > the effective date /// 3. is the current time the expiration date /// </summary> /// <param name="">facts /// </param> /// <param name="">engine /// /// </param> public override void retractFacts(Index inx, Rete engine, IWorkingMemory mem) { long time = (DateTime.Now.Ticks - 621355968000000000)/10000; if (theRule.ExpirationDate > 0 && time > theRule.EffectiveDate && time < theRule.ExpirationDate) { IGenericMap<Object, Object> tmem = (IGenericMap<Object, Object>) mem.getTerminalMemory(this); LinkedActivation act = (LinkedActivation) tmem.RemoveWithReturn(inx); if (act != null) { engine.Agenda.removeActivation(act); } } }
public virtual void assertSecondSuccessors(IFact fact, Rete engine, IWorkingMemory mem) { IEnumerator itr = successor2.GetEnumerator(); while (itr.MoveNext()) { BaseNode node = (BaseNode) itr.Current; if (node is BaseAlpha) { ((BaseAlpha) node).assertFact(fact, engine, mem); } else if (node is BaseJoin) { ((BaseJoin) node).assertRight(fact, engine, mem); } else if (node is TerminalNode) { Index inx = new Index(new IFact[] {fact}); ((TerminalNode) node).assertFacts(inx, engine, mem); } } }
/// <summary> Retracting from the left is different than retractRight for couple /// of reasons. /// <ul> /// <li> NotJoin will only propogate the facts from the left</li> /// <li> NotJoin never needs to merge the left and right</li> /// </ul> /// </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); // the left memory Contains the fact array, so we // retract it. IBetaMemory bmem = (IBetaMemory) leftmem.RemoveWithReturn(linx); if (bmem != null) { // if watch is turned on, we send an event propogateRetract(linx, engine, mem); } }
/// <summary> Add a successor node /// </summary> public override void addSuccessorNode(BaseNode node, Rete engine, IWorkingMemory mem) { if (!containsNode(successorNodes, node) && !successor2.Contains(node)) { if (node is BaseJoin || node is TerminalNode) { successor2.Add(node); } else { // we test to see if the operator is ==, nil, not nil // if the node isn't BaseJoin, it should be BaseAlpha BaseAlpha ba = (BaseAlpha) node; if (ba.Operator == Constants.LESS || ba.Operator == Constants.GREATER || ba.Operator == Constants.LESSEQUAL || ba.Operator == Constants.GREATEREQUAL || ba.Operator == Constants.NOTEQUAL || ba.Operator == Constants.NOTNILL) { successor2.Add(node); } else { addNode(node); } } if (gauranteeUnique && node is AlphaNode) { // now we use CompositeIndex instead of HashString AlphaNode anode = (AlphaNode) node; entries.Put(anode.HashIndex, node); // we increment the node count for the slot deftemplate.getSlot(anode.slot.Id).incrementNodeCount(); } // if there are matches, we propogate the facts to // the new successor only IAlphaMemory alpha = (IAlphaMemory) mem.getAlphaMemory(this); if (alpha.size() > 0) { IEnumerator itr = alpha.GetEnumerator(); while (itr.MoveNext()) { IFact f = (IFact) itr.Current; if (node is BaseAlpha) { BaseAlpha next = (BaseAlpha) node; next.assertFact(f, engine, mem); } else if (node is BaseJoin) { BaseJoin next = (BaseJoin) node; next.assertRight(f, engine, mem); } else if (node is TerminalNode) { TerminalNode t = (TerminalNode) node; Index inx = new Index(new IFact[] {f}); t.assertFacts(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="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> /// </summary> public override void retractLeft(Index linx, Rete engine, IWorkingMemory mem) { IGenericMap<Object, Object> leftmem = (IGenericMap<Object, Object>) mem.getBetaLeftMemory(this); int prev = leftmem.Count; if (leftmem.ContainsKey(linx)) { // the memory Contains the key, so we retract and propogate leftmem.Remove(linx); } if (prev != 0 && leftmem.Count == 0) { propogateRetract(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); } }