private ReteNode BuildOrShareNegativeNode(ReteNode parent, Alpha_Memory am, List <Test_At_Join_Node> tests) { // look for an existing node to share foreach (ReteNode child in parent.Children) { if (child.Type == ReteNodeType.Negative_Node) { Negative_Node n_node = (Negative_Node)child; if (n_node.Amem.Equals(am) && Test_At_Join_Node.IsListEquals(n_node.Tests, tests)) { return(child); } } } Negative_Node new_n_node = new Negative_Node(); new_n_node.Type = ReteNodeType.Negative_Node; new_n_node.Parent = parent; // insert new at the head of the list parent.children parent.Children.Insert(0, new_n_node); //new_n_node.Children.Clear(); //new_n_node.Items.Clear(); new_n_node.Tests = tests; new_n_node.Amem = am; am.Successors.Insert(0, new_n_node); return(new_n_node); }
private void DeleteToken(ReteNode node, Token token) { if (node is Beta_Memory) { Beta_Memory b_node = (Beta_Memory)node; b_node.Items.Remove(token); } else if (node is P_Node) { P_Node p_node = (P_Node)node; //p_node.Items.Remove(tok); // foamliu, 2008/11/23, for publishing (de)activation events. p_node.RemoveToken(token); } else if (node is Negative_Node) { Negative_Node n_node = (Negative_Node)node; n_node.Items.Remove(token); } else if (node is NCC_Node) { NCC_Node ncc_node = (NCC_Node)node; ncc_node.Items.Remove(token); } }
private void NegativeNodeRightActivation(Negative_Node node, WME w) { foreach (Token t in node.Items) { if (PerformJoinTests(node.Tests, t, w)) { if (t.Join_Results.Count == 0) { DeleteDescendentsOfToken(t); } Negative_Join_Result jr = new Negative_Join_Result(); jr.Owner = t; jr.WME = w; t.Join_Results.Insert(0, jr); w.Negative_Join_Results.Insert(0, jr); } } }
// for supporting negated conditions private void NegativeNodeLeftActivation(Negative_Node node, Token t, WME w) { // build and store a new token, just like a beta memory would Token new_token = Make_Token(node, t, w); node.Items.Insert(0, new_token); // compute the join results new_token.Join_Results.Clear(); foreach (WME item in node.Amem.Items) { if (PerformJoinTests(node.Tests, new_token, item)) { Negative_Join_Result jr = new Negative_Join_Result(); jr.Owner = new_token; jr.WME = w; new_token.Join_Results.Insert(0, jr); if (w != null) { w.Negative_Join_Results.Insert(0, jr); } } } // if join results is empty, then inform children if (new_token.Join_Results.Count == 0) { foreach (ReteNode child in node.Children) { //Beta_Memory_Left_Activation((Beta_Memory)child, new_token, null); // foamliu, 2008/08/26, use a general method here // to support both join-node and negative-node. LeftActivation(child, new_token, null); } } }
private void DeleteNodeAndAnyUnusedAncestors(ReteNode node) { // foamliu, 2008/11/20, for NCC nodes, delete the partner node too NCC_Node ncc_node = node as NCC_Node; if (null != ncc_node) { DeleteNodeAndAnyUnusedAncestors(ncc_node.Partner); } // foamliu, 2008/11/20, clean up any tokens the node contains switch (node.Type) { case ReteNodeType.Beta_Memory: Beta_Memory b_node = (Beta_Memory)node; while (b_node.Items.Count != 0 && !(b_node.Items[0] is Dummy_Top_Token)) { DeleteTokenAndDescendents(b_node.Items[0]); } break; case ReteNodeType.Negative_Node: Negative_Node n_node = (Negative_Node)node; while (n_node.Items.Count != 0) { DeleteTokenAndDescendents(n_node.Items[0]); } break; case ReteNodeType.NCC_Node: while (ncc_node.Items.Count != 0) { DeleteTokenAndDescendents(ncc_node.Items[0]); } break; default: break; } NCC_Partner_Node par_node = node as NCC_Partner_Node; if (null != par_node) { while (par_node.New_Result_Buffer.Count != 0) { DeleteTokenAndDescendents(par_node.New_Result_Buffer[0]); } } // foamliu, 2008/11/20, for join and negative nodes, deal with the alpha memory // Join_Node j_node = node as Join_Node; if (null != j_node) { j_node.Amem.Successors.Remove(node); if (j_node.Amem.Successors.Count == 0) { DeleteAlphaMemory(j_node.Amem); } } else if (node.Type == ReteNodeType.Negative_Node) { Negative_Node n_node = (Negative_Node)node; n_node.Amem.Successors.Remove(node); if (n_node.Amem.Successors.Count == 0) { DeleteAlphaMemory(n_node.Amem); } } // foamliu, 2008/11/21, fix a null-ref bug. if (null != node.Parent) { node.Parent.Children.Remove(node); if (node.Parent.Children.Count == 0) { DeleteNodeAndAnyUnusedAncestors(node.Parent); } } node = null; }