示例#1
0
 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);
     }
 }
示例#2
0
        /// <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);
        }
示例#3
0
        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);
                }
            }
        }
示例#4
0
        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);
            }
        }
示例#5
0
        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;
        }