/// <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); } } } } }
/// <summary> /// </summary> /// <param name="source">- the source should be either the workingMemory or Rete /// </param> /// <param name="typeCode">- event type /// </param> /// <param name="sourceNode">- the node which initiated the event /// /// </param> public EngineEvent(Object source, int typeCode, BaseNode sourceNode, IFact[] facts) { InitBlock(); this.typeCode = typeCode; this.sourceNode = sourceNode; this.facts = facts; }
/// <summary> /// Adds the successor node. /// </summary> /// <param name="node">The node.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public override void addSuccessorNode(BaseNode node, Rete engine, IWorkingMemory mem) { if (node is BaseJoin) { addSuccessorNode((BaseJoin) node, engine, mem); } else { addSuccessorNode((TerminalNode) node, engine, mem); } }
/// <summary> The current implementation checks to make sure the node is a /// TestNode. If it is, it will set the node. If not, it will ignore /// it. /// </summary> public virtual void addNode(BaseNode node) { if (node is TestNode) { this.node = (TestNode) node; } }
/// <summary> Remove a successor node /// </summary> /// <param name="">node /// </param> /// <param name="">engine /// </param> /// <param name="">mem /// @throws AssertException /// /// </param> public virtual void removeSuccessorNode(BaseNode node, Rete engine, IWorkingMemory mem) { if (removeNode(node)) { // we retract the memories first, before removing the node 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.retractFact((IFact) itr.Current, engine, mem); } else if (node is BaseJoin) { BaseJoin next = (BaseJoin) node; next.retractRight((IFact) itr.Current, engine, mem); } } } } }
/// <summary> Remove an object from an object array /// </summary> /// <param name="">list /// </param> /// <param name="">nobj /// </param> /// <returns> /// /// </returns> public static BaseNode[] remove(BaseNode[] list, Object nobj) { BaseNode[] newlist = new BaseNode[list.Length - 1]; int pos = 0; for (int idx = 0; idx < list.Length; idx++) { if (list[idx] != nobj) { newlist[pos] = list[idx]; pos++; } } return newlist; }
/// <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> /// Retracts the event. /// </summary> /// <param name="node">The node.</param> /// <param name="facts">The facts.</param> public virtual void retractEvent(BaseNode node, IFact[] facts) { IEnumerator itr = listeners.GetEnumerator(); while (itr.MoveNext()) { EngineEventListener eel = (EngineEventListener) itr.Current; eel.eventOccurred(new EngineEvent(this, EngineEvent.ASSERT_EVENT, node, facts)); } }
/// <summary> /// Method will process the retractEvent, preferably with an event queue /// </summary> /// <param name="node">The node.</param> /// <param name="fact">The fact.</param> public virtual void assertEvent(BaseNode node, IFact fact) { if (debug) { Trace.WriteLine("\"assert at nodeid=" + node.nodeID + " - " + node.ToString().Replace("\"", "'") + ":: with fact -" + fact.toFactString().Replace("\"", "'") + "::\""); } IEnumerator itr = listeners.GetEnumerator(); while (itr.MoveNext()) { EngineEventListener eel = (EngineEventListener) itr.Current; eel.eventOccurred(new EngineEvent(this, EngineEvent.ASSERT_EVENT, node, new IFact[] {fact})); } }
/// <summary> the method doesn't apply and isn't implemented currently /// </summary> public virtual void addNode(BaseNode node) { }
/// <summary> Here is a description of the compilation algorithm. /// 1. iterate over the conditional elements /// i. generate the alpha nodes /// a. literal constraints generate alpha node /// b. predicate constaints that compare against a literal generate alpha node /// ii. calculate the bindings /// a. each binding has a rowId /// b. NOT and EXIST CE do not increment the rowId /// 2. iterate over the conditional elements /// i. generate the beta nodes /// ii. attach the Left Input adapater nodes /// iii. attach the join nodes to the alpha nodes /// 3. create the terminal node and attach to the last /// join node. /// /// This means the rule compiler takes a 2 pass approach to /// compiling rules. At the start of the method, it sets 3 /// attributes to null: prevCE, prevJoinNode, joinNode. /// Those attributes are used by the compile join methods, /// so it's important to set it to null at the start. If /// we don't the Current rule won't compile correctly. /// </summary> public virtual bool addRule(Rule.IRule rule) { rule.resolveTemplates(engine); if (!validate || (validate && tval.analyze(rule) == Analysis_Fields.VALIDATION_PASSED)) { // we have to set the attributes to null, before we start compiling a rule. // we've set the attributes to null, so we can compile now!! if (rule.Conditions != null && rule.Conditions.Length > 0) { // we check the name of the rule to see if it is for a specific // module. if it is, we have to Add it to that module Module = rule; try { ICondition[] conds = rule.Conditions; // first we create the constraints, before creating the Conditional // elements which include joins // we use a counter and only increment it to make sure the // row index of the bindings are accurate. this makes it simpler // for the rule compiler and compileJoins is cleaner and does // less work. int counter = 0; for (int idx = 0; idx < conds.Length; idx++) { ICondition con = conds[idx]; // compile object conditions //implement in the ObjectConditionCompiler.compile or ExistConditionCompiler.compile con.getCompiler(this).compile(con, counter, rule, rule.RememberMatch); if ((con is ObjectCondition) && (!((ObjectCondition)con).Negated)) { counter++; } } // now we compile the joins compileJoins(rule); BaseNode last = rule.LastNode; TerminalNode tnode = createTerminalNode(rule); attachTerminalNode(last, tnode); // compile the actions compileActions(rule, rule.Actions); // now we pass the bindings to the rule, so that actiosn can // resolve the bindings // now we Add the rule to the module currentMod.addRule(rule); CompileMessageEventArgs ce = new CompileMessageEventArgs(rule, EventType.ADD_RULE_EVENT); ce.Rule = rule; notifyListener(ce); return(true); } catch (AssertException e) { CompileMessageEventArgs ce = new CompileMessageEventArgs(rule, EventType.INVALID_RULE); ce.Message = Messages.getString("RuleCompiler.assert.error"); //$NON-NLS-1$ notifyListener(ce); TraceLogger.Instance.Debug(e); return(false); } } else if (rule.Conditions.Length == 0) { Module = rule; // the rule has no LHS, this means it only has actions BaseNode last = (BaseNode)inputnodes.Get(engine.initFact); TerminalNode tnode = createTerminalNode(rule); compileActions(rule, rule.Actions); attachTerminalNode(last, tnode); // now we Add the rule to the module currentMod.addRule(rule); CompileMessageEventArgs ce = new CompileMessageEventArgs(rule, EventType.ADD_RULE_EVENT); ce.Rule = rule; notifyListener(ce); return(true); } return(false); } else { // we need to print out a message saying the rule was not valid ISummary error = tval.Errors; engine.writeMessage("Rule " + rule.Name + " was not added. ", Constants.DEFAULT_OUTPUT); //$NON-NLS-1$ //$NON-NLS-2$ engine.writeMessage(error.Message, Constants.DEFAULT_OUTPUT); ISummary warn = tval.Warnings; engine.writeMessage(warn.Message, Constants.DEFAULT_OUTPUT); return(false); } }
/// <summary> /// Add the node to the list of successors /// </summary> /// <param name="n">The n.</param> /// <returns></returns> protected internal virtual bool addNode(BaseNode n) { bool add = false; if (!containsNode(successorNodes, n)) { successorNodes = ConversionUtils.add(successorNodes, n); add = true; } return add; }
/// <summary> /// Remove the node from the succesors /// </summary> /// <param name="n">The n.</param> /// <returns></returns> public virtual bool removeNode(BaseNode n) { bool rem = false; if (containsNode(successorNodes, n)) { successorNodes = ConversionUtils.remove(successorNodes, n); rem = true; } return rem; }
/// <summary> /// Adds the successor node. /// </summary> /// <param name="node">The node.</param> /// <param name="engine">The engine.</param> /// <param name="mem">The mem.</param> public abstract void addSuccessorNode(BaseNode node, Rete engine, IWorkingMemory mem);
/// <summary> Add a new object to an object array /// </summary> /// <param name="">list /// </param> /// <param name="">nobj /// </param> /// <returns> /// /// </returns> public static BaseNode[] add(BaseNode[] list, BaseNode nobj) { BaseNode[] newlist = new BaseNode[list.Length + 1]; Array.Copy(list, 0, newlist, 0, list.Length); newlist[list.Length] = nobj; return newlist; }
/// <summary> not implemented currently /// </summary> public virtual void addNewAlphaNodes(BaseNode node) { }
public virtual IList getNodeEvents(BaseNode node) { return (IList) nodeFilter.Get(node); }
/// <summary> /// The method will print out the node. It is up to the method to check if /// pretty printer is true and call the appropriate node method to Get the /// string. /// TODO - need to implement this /// </summary> /// <param name="node">The node.</param> public virtual void writeMessage(BaseNode node) { }
/// <summary> To listen to a specific node, Add the node to the filter /// </summary> /// <param name="">node /// /// </param> public virtual void addNodeFilter(BaseNode node) { nodeFilter.Put(node, new List<Object>()); }
/// <summary> /// Asserts the event. /// </summary> /// <param name="node">The node.</param> /// <param name="facts">The facts.</param> public virtual void assertEvent(BaseNode node, IFact[] facts) { if (debug) { if (node is TerminalNode) { Trace.WriteLine(((TerminalNode) node).Rule.Name + " fired"); } else { } } IEnumerator itr = listeners.GetEnumerator(); while (itr.MoveNext()) { EngineEventListener eel = (EngineEventListener) itr.Current; eel.eventOccurred(new EngineEvent(this, EngineEvent.ASSERT_EVENT, node, facts)); } }
/// <summary> /// Method will attach a new JoinNode to an ancestor node. An ancestor /// could be LIANode, AlphaNode or BetaNode. /// </summary> /// <param name="last">The last.</param> /// <param name="join">The join.</param> public virtual void attachJoinNode(BaseNode last, BaseJoin join) { if (last is BaseAlpha) { ((BaseAlpha) last).addSuccessorNode(join, engine, memory); } else if (last is BaseJoin) { ((BaseJoin) last).addSuccessorNode(join, engine, memory); } }
/// <summary> method to Clear the successors. method doesn't iterate over /// the succesors and Clear them individually. /// </summary> public virtual void clearSuccessors() { IEnumerator itr = successor2.GetEnumerator(); while (itr.MoveNext()) { BaseNode n = (BaseNode) itr.Current; n.removeAllSuccessors(); } itr = entries.Values.GetEnumerator(); while (itr.MoveNext()) { BaseNode n = (BaseNode) itr.Current; n.removeAllSuccessors(); } for (int idx = 0; idx < successorNodes.Length; idx++) { successorNodes[idx].removeAllSuccessors(); } successor2.Clear(); successorNodes = new BaseNode[0]; entries.Clear(); }
protected internal virtual void attachTerminalNode(BaseNode last, TerminalNode terminal) { if (last != null && terminal != null) { try { if (last is BaseJoin) { ((BaseJoin) last).addSuccessorNode(terminal, engine, memory); } else if (last is BaseAlpha) { ((BaseAlpha) last).addSuccessorNode(terminal, engine, memory); } } catch (AssertException e) { } } }
public override bool removeNode(BaseNode n) { bool rem = base.removeNode(n); successor2.Remove(n); if (n is AlphaNode) { entries.Remove(((AlphaNode)n).HashIndex); } return rem; }
/// <summary> Method is used to decompose the network and make sure /// the nodes are detached from each other. /// </summary> public override void removeAllSuccessors() { for (int idx = 0; idx < successorNodes.Length; idx++) { BaseNode bn = (BaseNode) successorNodes[idx]; bn.removeAllSuccessors(); } successorNodes = new BaseNode[0]; useCount = 0; }