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); } }
/// <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); }
private void NccNodeLeftActivation(NCC_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); // insert new-token at the head of node.Items node.Items.Insert(0, new_token); // get initial ncc results new_token.NCC_Results.Clear(); NCC_Partner_Node partner = node.Partner as NCC_Partner_Node; //foreach (Token result in partner.New_Result_Buffer) //{ // partner.New_Result_Buffer.Remove(result); // new_token.NCC_Results.Insert(0, result); // result.Owner = new_token; //} // foamliu, 2008/12/10, fix following error: // System.InvalidOperationException : Collection was modified; // enumeration operation may not execute. while (partner.New_Result_Buffer.Count != 0) { Token result = partner.New_Result_Buffer[0]; partner.New_Result_Buffer.Remove(result); new_token.NCC_Results.Insert(0, result); result.Owner = new_token; } // if no ncc results, then inform children if (0 == new_token.NCC_Results.Count) { foreach (ReteNode child in node.Children) { LeftActivation(child, new_token, null); } } }
private void NccPartnerNodeLeftActivation(NCC_Partner_Node partner, Token t, WME w) { NCC_Node ncc_node = partner.NCC_Node as NCC_Node; // build a result token <t,w> Token new_result = Make_Token(partner, t, w); // To find the appropriate owner token (into whose local memory we should put this // result), first figure out what pair <owners-t,owners-w> would represent the owner. To // do this, we start with the <t,w> pair we just received, and walk up the right number // of links to find the pair that emerged from the join node for the preceding condition. Token owners_t = t; WME owners_w = w; for (int i = 0; i < partner.Number_Of_Conjuncts; i++) { owners_w = owners_t.WME; owners_t = owners_t.Parent; } // Look for this owner in the NCC node's memory. If we find it, add new-result to its // local memory, and propagate (deletions) to the NCC node's children. Token owner = ncc_node.FindOwner(owners_t, owners_w); if (null != owner) { owner.NCC_Results.Add(new_result); new_result.Owner = owner; DeleteDescendentsOfToken(owner); } else { // We didn't find an appropriate owner token already in the NCC node's memory. // This means the subnetwork has been activated for a new match for the preceding // conditions, and this new result emerged from the bottom of the subnetwork, but // the NCC node hasn't been activated for the new match yet. So, we just stuff the // result in our temporary buffer. partner.New_Result_Buffer.Insert(0, new_result); } }
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; }