Esempio n. 1
0
 /// <summary>
 /// When adding a production that uses an NCC, we use the build-or-share-ncc-nodes function.
 /// Most of the work in this function is done by the helper function build-or-share-network-for-
 /// conditions, which builds or shares the whole subnetwork for the subconditions of the NCC. The
 /// rest of the build-or-share-ncc-nodes function then builds or shares the NCC and NCC partner
 /// nodes.
 /// </summary>
 /// <param name="parent">The parent.</param>
 /// <param name="c">The c.</param>
 /// <param name="earlier_conds">The earlier_conds.</param>
 /// <returns></returns>
 private ReteNode build_or_share_ncc_nodes(JoinNode parent, Condition c, List<LeftHandSideCondition> earlier_conds)
 {
     ReteNode bottom_of_subnetwork = build_or_share_network_for_conditions(parent, c.SubConditions, earlier_conds);
     foreach (ReteNode child in parent.Children)
     {
         if (child.Type == ReteNodeType.NCC && ((NCCNode) child).Partner.Parent == bottom_of_subnetwork)
         {
             return child;
         }
     }
     NCCNode new_node = new NCCNode();
     NCCPartnerNode new_partner = new NCCPartnerNode();
     new_node.Type = ReteNodeType.NCC; // "NCC";
     new_partner.Type = ReteNodeType.NCCPartner; // "NCC-partner";
     parent.IsHeadOfSubNetwork = true;
     new_node.Parent = parent;
     parent.Children.Add(new_node);
     new_partner.Parent = bottom_of_subnetwork;
     bottom_of_subnetwork.Children.AddToFront(new_partner);
     new_node.Partner = new_partner;
     new_partner.NCCNode = new_node;
     new_partner.NumberOfConjuncts = c.SubConditions.Count;
     update_new_node_with_matches_from_above(new_node);
     update_new_node_with_matches_from_above(new_partner);
     return new_node;
 }
Esempio n. 2
0
        /// <summary>
        /// The next helper function is similar, except it handles join nodes rather than beta memory
        /// nodes. The two additional arguments specify the alpha memory to which the join node must
        /// be attached and the variable binding consistency checks it must perform. Note that there is no
        /// need to call update-new-node-with-matches-from-above in this case, because a join node does not
        /// store any tokens, and a newly created join node has no children onto which join results should
        /// be passed.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="am">The am.</param>
        /// <param name="tests">The tests.</param>
        /// <returns></returns>
        private ReteNode build_or_share_join_node(BetaMemory parent, AlphaMemory am, ICollection<TestAtJoinNode> tests)
        {
            foreach (ReteNode child in parent.AllChildren)
            {
                if (child.Type == ReteNodeType.Join)
                {
                    JoinNode childJoinNode = (JoinNode) child;
                    if (childJoinNode.AlphaMemory == am)
                    {
                        if (childJoinNode.Tests.Count == 0 && tests.Count == 0)
                        {
                            return child;
                        }
                        else
                        {
                            if (childJoinNode.Tests.Count == tests.Count)
                            {
                                bool testsMatch = true;
                                foreach (TestAtJoinNode test in tests)
                                {
                                    if (childJoinNode.Tests.Contains(test) == false)
                                    {
                                        testsMatch = false;
                                        continue;
                                    }
                                }
                                if (testsMatch)
                                {
                                    return child;
                                }
            //Need to compare tests...
                                throw new ApplicationException("Unhandled...");
                            }
                        }
                    }
                }
            }

            JoinNode new_node = new JoinNode();
            new_node.Type = ReteNodeType.Join; // "join";
            new_node.Parent = parent;

            parent.Children.AddToFront(new_node);

            parent.AllChildren.AddToFront(new_node);

            foreach (TestAtJoinNode test in tests)
            {
                new_node.Tests.Add(test);
            }
            new_node.AlphaMemory = am;

            am.Successors.AddToFront(new_node);
            ++am.ReferenceCount;
            new_node.NearestAncestorWithSameAmem = find_nearest_ancestor_with_same_amem(parent, am);

            // *** Right Unlinking ***
            if (parent.Items.Count == 0)
            {
                am.Successors.Remove(new_node);
                new_node.IsRightUnlinked = true;
            }
            else if (am.Items.Count == 0)
            {
                if ((parent is DummyTopNode) == false)
                {
                    parent.Children.Remove(new_node);
                    new_node.IsRightUnlinked = true;
                }
            }
            // *** End Right Unlinking ***

            return new_node;
        }
Esempio n. 3
0
 /// <summary>
 /// Relink_to_beta_memories the specified node.
 /// </summary>
 /// <param name="node">The node.</param>
 private void relink_to_beta_memory(JoinNode node)
 {
     node.Parent.Children.AddToFront(node);
     node.IsLeftUnlinked = false;
 }
Esempio n. 4
0
 /// <summary>
 /// Relink_to_alpha_memories the specified node.
 /// </summary>
 /// <param name="node">The node.</param>
 private void relink_to_alpha_memory(JoinNode node)
 {
     JoinNode ancestor = (JoinNode) node.NearestAncestorWithSameAmem;
     while (ancestor != null && ancestor.IsRightUnlinked)
     {
         ancestor = (JoinNode) ancestor.NearestAncestorWithSameAmem;
     }
     if (ancestor != null)
     {
         int pos = node.AlphaMemory.Successors.IndexOf(ancestor);
         node.AlphaMemory.Successors.Insert(pos, node);
     }
     else
     {
         node.AlphaMemory.Successors.Add(node);
     }
     node.IsRightUnlinked = false;
 }
Esempio n. 5
0
        /// <summary>
        /// Upon a right activation (when a new WME w is added to the alpha memory), we look
        /// through the beta memory and find any token(s) t for which all these t-versus-w tests succeed.
        /// Any successful (t;w) combinations are passed on to the join node's children. 
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="w">The w.</param>
        private void join_node_right_activation(JoinNode node, WME w)
        {
            // *** Left Unlinking ***
            if (node.IsLeftUnlinked)
            {
                relink_to_beta_memory(node);
                if (((BetaMemory) node.Parent).Items.Count == 0)
                {
                    node.AlphaMemory.Successors.Remove(node);
                    node.IsRightUnlinked = true;
                }
            }
            // *** End Left Unlinking ***

            foreach (Token t in ((BetaMemory) node.Parent).Items)
            {
                if (perform_join_tests(node.Tests, t, w))
                {
                    foreach (ReteNode child in node.Children)
                    {
                        left_activation(child, t, w);
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Upon a left activation (when a new token t is added to the beta memory), we look through the
        /// alpha memory and find any WME(s) w for which all these t-versus-w tests succeed. Again, any
        /// successful (t;w) combinations are passed on to the node's children:
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="t">The t.</param>
        private void join_node_left_activation(JoinNode node, Token t)
        {
            // *** Right Unlinking ***
            if (node.IsRightUnlinked)
            {
                relink_to_alpha_memory(node);

                // *** Left Unlinking ***
                if (node.AlphaMemory.Items.Count == 0)
                {
                    node.Parent.Children.Remove(node);
                    node.IsLeftUnlinked = true;
                }
                // *** End Left Unlinking ***
            }
            // *** End Right Unlinking ***

            foreach (ItemInAlphaMemory item in node.AlphaMemory.Items)
            {
                if (perform_join_tests(node.Tests, t, item.WME))
                {
                    foreach (ReteNode child in node.Children)
                    {
                        left_activation(child, t, item.WME);
                    }
                }
            }
        }