Пример #1
0
        /// <summary>
        /// We will use several helper functions to make the main add-production procedure simpler.
        /// The first one, build-or-share-beta-memory-node, looks for an existing beta memory node that is
        /// a child of the given parent node. If there is one, it returns it so it can be shared by the new
        /// production; otherwise the function builds a new one and returns it. This pseudocode assumes
        /// that beta memories are not indexed; if indexing is used, the procedure would take an extra
        /// argument specifying which field(s) the memory must be indexed on.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <returns></returns>
        private ReteNode build_or_share_beta_memory_node(ReteNode parent)
        {
            if (parent is DummyTopNode)
            {
                return parent;
            }

            foreach (ReteNode child in parent.Children)
            {
                if (child.Type == ReteNodeType.BetaMemory)
                {
                    return child;
                }
            }

            BetaMemory new_rete = new BetaMemory();
            new_rete.Type = ReteNodeType.BetaMemory;
            new_rete.Parent = parent;
            new_rete.Label = "B" + (++_next_beta_node);
            parent.Children.AddToFront(new_rete);

            update_new_node_with_matches_from_above(new_rete);
            return new_rete;
        }
Пример #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;
        }
Пример #3
0
        /// <summary>
        /// Whenever a beta memory is informed of a new match (consisting of an existing token and some
        /// WME), we build a token, add it to the list in the beta memory, and inform each of the beta
        /// memory's children:
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="t">The token.</param>
        /// <param name="w">The wme.</param>
        private void beta_memory_left_activation(BetaMemory node, Token t, WME w)
        {
            Token new_token = make_token(node, t, w);
            node.Items.Add(new_token);

            //The unlinking process changes the underlying collection so we need a new collection...
            BigList<ReteNode> children = node.Children.Clone();
            foreach (ReteNode child in children)
            {
                left_activation(child, new_token, null);
            }
        }