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 ReteNode BuildOrShareJoinNode(ReteNode parent, Alpha_Memory am, List <Test_At_Join_Node> tests) { // look for an existing node to share foreach (ReteNode child in parent.Children) { Join_Node j_node = child as Join_Node; if (null != j_node) { if (j_node.Amem.Equals(am) && Test_At_Join_Node.IsListEquals(j_node.Tests, tests)) { return(child); } } } Join_Node new_j_node = new Join_Node(); new_j_node.Parent = parent; // insert new at the head of the list parent.children parent.Children.Insert(0, new_j_node); // foamliu, 2008/11/29, new object, no need. //new_j_node.Children.Clear(); new_j_node.Tests = tests; new_j_node.Amem = am; am.Successors.Insert(0, new_j_node); return(new_j_node); }
private ReteNode BuildOrShareBetaMemoryNode(ReteNode parent) { // foamliu, 2008/12/10, the first is positive, the beta is not necessary if (parent is Dummy_Top_Node) { return(parent); } // look for an existing node to share foreach (ReteNode child in parent.Children) { if (child.Type == ReteNodeType.Beta_Memory) { return(child); } } Beta_Memory new_beta = new Beta_Memory(); //new_beta.Type = ReteNodeType.Beta_Memory; new_beta.Parent = parent; // insert new at the head of the list parent.children parent.Children.Insert(0, new_beta); //new_beta.Children.Clear(); //new_beta.Items.Clear(); UpdateNewNodeWithMatchesFromAbove(new_beta); return(new_beta); }
private void LeftActivation(ReteNode node, Token t, WME w) { Beta_Memory b_node; P_Node p_node; Negative_Node n_node; NCC_Node ncc_node; NCC_Partner_Node nccp_node; if ((b_node = node as Beta_Memory) != null) { BetaMemoryLeftActivation(b_node, t, w); } else if ((p_node = node as P_Node) != null) { P_NodeLeftActivation(p_node, t, w); } else if ((n_node = node as Negative_Node) != null) { NegativeNodeLeftActivation(n_node, t, w); } else if ((ncc_node = node as NCC_Node) != null) { NccNodeLeftActivation(ncc_node, t, w); } else if ((nccp_node = node as NCC_Partner_Node) != null) { NccPartnerNodeLeftActivation(nccp_node, t, w); } else { System.Console.WriteLine("Left_Activation lose type: {0}", node.GetType()); } }
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 UpdateNewNodeWithMatchesFromAbove(ReteNode new_node) { ReteNode parent = new_node.Parent; switch (parent.Type) { case ReteNodeType.Beta_Memory: foreach (Token tok in ((Beta_Memory)parent).Items) { // do left-activation (new-node, tok) LeftActivation(new_node, tok); } break; case ReteNodeType.Join_Node: List <ReteNode> saved_list_of_children = new List <ReteNode>(); //saved_list_of_children.AddRange(parent.Children); foreach (ReteNode node in parent.Children) { saved_list_of_children.Add(node); } parent.Children.Clear(); //parent.Children.Add(new_node); parent.Children.Add(new_node); foreach (WME w in ((Join_Node)parent).Amem.Items) { RightActivation(parent, w); } parent.Children = saved_list_of_children; break; case ReteNodeType.Negative_Node: foreach (Token tok in ((Negative_Node)parent).Items) { if (tok.Join_Results.Count == 0) { LeftActivation(new_node, tok, null); } } break; case ReteNodeType.NCC_Node: foreach (Token tok in ((NCC_Node)parent).Items) { if (tok.NCC_Results.Count == 0) { LeftActivation(new_node, tok, null); } } break; default: break; } }
/// <summary> /// /// </summary> /// <param name="current_node"></param> /// <param name="condition">The NCC condition.</param> /// <param name="conds_higher_up"></param> /// <returns>Returns the NCC node</returns> private ReteNode BuildOrShareNccNodes(ReteNode parent, NCCCondition condition, List <Condition> earlier_conds) { ReteNode bottom_of_subnetwork = BuildOrShareNetworkForConditions(parent, condition.SubConditions, earlier_conds); // look for an existing node to share foreach (ReteNode child in parent.Children) { NCC_Node ncc_child = child as NCC_Node; if (null != ncc_child) { if (ncc_child.Partner.Parent == bottom_of_subnetwork) { return(child); } } } NCC_Node new_ncc_partner = new NCC_Node(); NCC_Partner_Node new_partner = new NCC_Partner_Node(); new_ncc_partner.Parent = parent; // foamliu, 2008/11/21, more comments // insert new at the tail of the list bottom_of_subnetwork.children, so the subnetwork comes first. // parent.Children.Add(new_ncc_partner); new_partner.Parent = bottom_of_subnetwork; bottom_of_subnetwork.Children.Insert(0, new_partner); //new_ncc_partner.Children.Clear(); //new_partner.Children.Clear(); new_ncc_partner.Partner = new_partner; new_partner.NCC_Node = new_ncc_partner; //new_ncc_partner.Items.Clear(); //new_partner.New_Result_Buffer.Clear(); new_partner.Number_Of_Conjuncts = condition.SubConditions.Count; // foamliu, 2008/11/21, more comments // Note: we have to inform NCC node of existing matches before informing the partner, otherwise // lots of matches would all get mixed together in the new-result-buffer. // UpdateNewNodeWithMatchesFromAbove(new_ncc_partner); UpdateNewNodeWithMatchesFromAbove(new_partner); return(new_ncc_partner); }
//public void Add_Production(List<Condition> lhs) //{ // if (lhs == null || lhs.Count==0) // return; // //// dummy-top-node // RETE_Node current_node = this.m_dummy_top_node; // List<Condition> earlier_conditions = new List<Condition>(); // //Condition c0 = lhs[0]; // //List<Test_At_Join_Node> tests = Get_Join_Tests_From_Condition(c0, earlier_conditions); // //Alpha_Memory am = Build_Or_Share_Alpha_Memory(c0); // //current_node = Build_Or_Share_Join_Node(current_node, am, tests); // //for (int i = 1; i < lhs.Count; i++) // //{ // // Condition ci = lhs[i]; // // current_node = Build_Or_Share_Beta_Memory_Node(current_node); // // earlier_conditions.Add(lhs[i - 1]); // c(i-1) // // tests = Get_Join_Tests_From_Condition(ci, earlier_conditions); // // am = Build_Or_Share_Alpha_Memory(ci); // // current_node = Build_Or_Share_Join_Node(current_node, am, tests); // //} // current_node = Build_Or_Share_Network_For_Conditions(current_node, lhs, earlier_conditions); // P_Node p_node = new P_Node(); // current_node.Children.Add(p_node); // p_node.Parent = current_node; // this.P_Nodes.Add(p_node); // Update_New_Node_With_Matches_From_Above(p_node); //} public void AddProduction(Production prod) { ReteNode current_node = BuildOrShareNetworkForConditions(this.m_dummy_top_node, prod.LHS, new List <Condition>()); // foamliu, 2008/11/21, more comments. // build a new production node P_Node p_node = new P_Node(prod); prod.P_Node = p_node; // make it a child of current node current_node.Children.Add(p_node); p_node.Parent = current_node; // foamliu, 2008/11/21, remove "P_Nodes", access p-nodes from productions. //this.P_Nodes.Add(p_node); UpdateNewNodeWithMatchesFromAbove(p_node); }
private void RightActivation(ReteNode node, WME w) { Join_Node j_node; Negative_Node n_node; if ((j_node = node as Join_Node) != null) { JoinNodeRightActivation(j_node, w); } else if ((n_node = node as Negative_Node) != null) { NegativeNodeRightActivation(n_node, w); } else { System.Console.WriteLine("Right_Activation lose type: {0}", node.GetType()); } }
private Token Make_Token(ReteNode node, Token parent, WME w) { Token tok = new Token(); tok.Parent = parent; tok.WME = w; // for tree-based removal tok.Node = node; if (parent != null) { parent.Children.Insert(0, tok); } // foamliu, 2008/08/25, we need this check for negative conditions if (w != null) { w.Tokens.Insert(0, tok); } return(tok); }
private ReteNode BuildOrShareNetworkForConditions(ReteNode parent, List <Condition> conds, List <Condition> earlier_conds) { // foamliu, 2008/11/20. ReteNode current_node = parent; List <Condition> conds_higher_up = earlier_conds; List <Test_At_Join_Node> tests; Alpha_Memory am; int k = conds.Count; for (int i = 0; i < k; i++) { Condition ci = conds[i]; if (ci.Type == ConditionType.Positive) { current_node = BuildOrShareBetaMemoryNode(current_node); tests = GetJoinTestsFromCondition(ci, conds_higher_up); am = BuildOrShareAlphaMemory(ci); current_node = BuildOrShareJoinNode(current_node, am, tests); } else if (ci.Type == ConditionType.Negative) { tests = GetJoinTestsFromCondition(ci, conds_higher_up); am = BuildOrShareAlphaMemory(ci); current_node = BuildOrShareNegativeNode(current_node, am, tests); } else if (ci.Type == ConditionType.NCC) { current_node = BuildOrShareNccNodes(current_node, (NCCCondition)ci, conds_higher_up); } conds_higher_up.Add(ci); } return(current_node); }
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; }
private void LeftActivation(ReteNode node, Token t) { LeftActivation(node, t, null); }