Esempio n. 1
0
        /// <summary>
        /// The function for creating new negative nodes is similar to the ones for creating beta memories
        /// and join nodes. However, one additional consideration is important with negative conditions,
        /// and also with conjunctive negations. Any time there is a variable &lt;v&gt; which is tested in a negative
        /// condition and bound in one or more other (positive) conditions, at least one of these positive
        /// conditions must come before the negative condition. Recall that when we add a production to
        /// the network, the network-construction routines are given a list of its conditions in some order. If
        /// all conditions are positive, any order will work. Negative conditions require the aforementioned
        /// constraint on the order, though, because negative nodes need to be able to access the appropriate
        /// variable bindings in tokens, and the tokens "seen" by negative nodes indicate only variable
        /// bindings from earlier conditions, i.e., conditions higher up in the network.
        /// </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_negative_node(ReteNode parent, AlphaMemory am, ICollection<TestAtJoinNode> tests)
        {
            foreach (ReteNode child in parent.Children)
            {
                if (child.Type == ReteNodeType.Negative)
                {
                    NegativeNode negativenodeChild = (NegativeNode) child;
                    if (negativenodeChild.AlphaMemory == am)
                    {
                        if (negativenodeChild.Tests.Count == 0 && tests.Count == 0)
                        {
                            return child;
                        }
                        else
                        {
                            //Need to compare tests...
                            throw new ApplicationException("Unhandled...");
                        }
                    }
                }
            }

            NegativeNode new_node = new NegativeNode();
            new_node.Type = ReteNodeType.Negative; // "negative";
            new_node.Parent = parent;

            parent.Children.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);
            update_new_node_with_matches_from_above(new_node);

            // *** Right Unlinking ***
            if (new_node.Items.Count == 0)
            {
                am.Successors.Remove(new_node);
                new_node.IsRightUnlinked = true;
            }
            // *** End Right Unlinking ***

            return new_node;
        }
Esempio n. 2
0
 /// <summary>
 /// On a right activation of a negative node (when a WME is added to its alpha memory),
 /// we look for any tokens in its memory consistent with the WME; for each such token, we add
 /// this WME to its local result memory. Also, if the number of results changes from zero to
 /// one - indicating that the negated condition was previously true but is now false - then we
 /// call the delete-descendents-of-token helper function to delete any tokens lower in the network
 /// that depend on this token.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="w">The w.</param>
 private void negative_node_right_activation(NegativeNode node, WME w)
 {
     foreach (Token t in node.Items)
     {
         if (perform_join_tests(node.Tests, t, w))
         {
             if (t.JoinResults.Count == 0)
             {
                 delete_descendents_of_token(t);
             }
             NegativeJoinResult jr = new NegativeJoinResult();
             jr.Owner = t;
             jr.WME = w;
             t.JoinResults.AddToFront(jr);
             w.NegativeJoinResults.AddToFront(jr);
         }
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Relink_to_alpha_memories the specified node.
 /// </summary>
 /// <param name="node">The node.</param>
 private void relink_to_alpha_memory(NegativeNode node)
 {
     NegativeNode ancestor = (NegativeNode) node.NearestAncestorWithSameAmem;
     while (ancestor != null && ancestor.IsRightUnlinked)
     {
         ancestor = (NegativeNode) 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. 4
0
        /// <summary>
        /// On a left activation
        /// (when there is a new match for all the earlier conditions), we build and store a new token, perform
        /// a join for the token, store the join results in the token structure, and pass the token onto any
        /// successor nodes if there were no join results.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="t">The t.</param>
        /// <param name="w">The w.</param>
        private void negative_node_left_activation(NegativeNode node, Token t, WME w)
        {
            // *** Right Unlinking ***
            if (node.Items.Count == 0)
                relink_to_alpha_memory(node);
            // *** End Right Unlinking ***

            Token new_token = make_token(node, t, w);
            node.Items.AddToFront(new_token);
            foreach (ItemInAlphaMemory item in node.AlphaMemory.Items)
            {
                if (perform_join_tests(node.Tests, new_token, item.WME))
                {
                    NegativeJoinResult jr = new NegativeJoinResult();
                    jr.Owner = new_token;
                    jr.WME = w;
                    new_token.JoinResults.AddToFront(jr);
                    w.NegativeJoinResults.AddToFront(jr);
                }
            }
            if (new_token.JoinResults.Count == 0)
            {
                foreach (ReteNode child in node.Children)
                {
                    left_activation(child, new_token, null);
                }
            }
        }