示例#1
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);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Builtin_node_left_activations the specified memory.
        /// </summary>
        /// <param name="memory">The memory.</param>
        /// <param name="tok">The tok.</param>
        /// <param name="w">The w.</param>
        private void builtin_node_left_activation(BuiltinMemory memory, Token tok, WME w)
        {
            Token new_token = make_token(memory, tok, w);
            memory.Items.AddToFront(new_token);

            if (memory.PerformEvaluation(new_token))
            {
                foreach (ReteNode child in memory.Children)
                {
                    left_activation(child, new_token, w);
                }
            }
        }
示例#3
0
 /// <summary>
 /// Adds the fact.
 /// </summary>
 /// <param name="fact">The fact to the initial facts list.</param>
 public void AddFact(WME fact)
 {
     _initialFacts.Add(fact);
 }
示例#4
0
        /// <summary>
        /// Now, to remove a WME, we just remove it from each alpha memory containing it (these
        /// alpha memories are now conveniently on a list) and call the helper routine delete-token-and-
        /// descendents to delete all the tokens involving it (all the necessary "root" tokens involving it are
        /// also conveniently on a list):
        /// </summary>
        /// <param name="wme">The wme.</param>
        public void RemoveWME(WME wme)
        {
            int pos = _working_memory.IndexOf(wme);
            if (pos < 0)
                return;

            WME w = _working_memory[pos];

            foreach (ItemInAlphaMemory item in w.AlphaMemoryItems)
            {
                item.AlphaMemory.Items.Remove(item);

                // *** Left Unlinking ***
                if (item.AlphaMemory.Items.Count == 0)
                {
                    foreach (ReteNode node in item.AlphaMemory.Successors)
                    {
                        if (node.Type == ReteNodeType.Join)
                        {
                            node.Parent.Children.Remove(node);
                            ((JoinNode) node).IsLeftUnlinked = true;
                        }
                    }
                }
                // *** End Left Unlinking ***
            }
            while (w.Tokens.Count > 0)
            {
                delete_token_and_descendents(w.Tokens[0]);
            }

            foreach (NegativeJoinResult jr in w.NegativeJoinResults)
            {
                jr.Owner.JoinResults.Remove(jr);
                if (jr.Owner.JoinResults.Count == 0)
                {
                    foreach (ReteNode child in jr.Owner.Node.Children)
                    {
                        left_activation(child, jr.Owner, null);
                    }
                }
            }

            _working_memory.Remove(w);
        }
示例#5
0
        /// <summary>
        /// Whenever a new WME is filtered through the alpha network and reaches an alpha memory, we
        /// simply add it to the list of other WMEs in that memory, and inform each of the attached join
        /// nodes:
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="w">The w.</param>
        private void alpha_memory_activation(AlphaMemory node, WME w)
        {
            ItemInAlphaMemory new_item = new ItemInAlphaMemory();
            new_item.WME = w;
            new_item.AlphaMemory = node;
            node.Items.Add(new_item);
            w.AlphaMemoryItems.AddToFront(new_item);

            // *** Neo Integration ***

            if (w.Value.TermType == TermType.EntityObject)
            {
                IFactProvider eo = (IFactProvider) w.Value.Value;
                if (eo.MyFactsHaveBeenAsserted == false)
                {
                    foreach (WME wme in eo.GenerateFactsForRelatedObject(w.Attribute.Value.ToString(), w.Identifier.Value as IFactProvider))
                    {
                        AddWME(wme);
                    }
                }
            }

            if (w.Value.TermType == TermType.ObjectRelation)
            {
                ObjectRelationBase orb = (ObjectRelationBase) w.Value.Value;
                foreach (RulesEnabledEntityObject eo in orb)
                {
                    if (eo.MyFactsHaveBeenAsserted == false)
                    {
                        foreach (WME wme in eo.GenerateFactsForObjectInCollection(w.Attribute.Value.ToString(), orb))
                        {
                            AddWME(wme);
                        }
                    }
                }
            }

            // *** End Neo Integration ***

            //The unlinking process changes the underlying collection so we need a new collection...
            BigList<ReteNode> successors = node.Successors.Clone();

            foreach (ReteNode successor in successors)
            {
                right_activation(successor, w);
            }
        }
示例#6
0
        /// <summary>
        /// P_node_activations the specified node.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="tok">The tok.</param>
        /// <param name="w">The w.</param>
        private void p_node_activation(ProductionNode node, Token tok, WME w)
        {
            Token new_token = make_token(node, tok, w);
            node.Items.AddToFront(new_token);

            int lhsCnt = node.Production.Lhs.Count - 1;

            foreach (RightHandSideCondition rhsCondition in node.Production.Rhs)
            {
                WME newfact = new WME();
                for (int f = 0; f < 3; f++)
                {
                    Term term = rhsCondition.Fields[f];
                    if (term.TermType == TermType.Variable)
                    {
                        for (int i = lhsCnt; i >= 0; i--)
                        {
                            Condition lhsCondition = node.Production.Lhs[i];
                            if (lhsCondition.ConditionType == ConditionType.Positive)
                            {
                                int pos = lhsCondition.Contains(term);
                                if (pos >= 0)
                                {
                                    Token tok2 = new_token.GetTokenUp(lhsCnt - i);
                                    newfact.Fields[f] = tok2.WME[pos];
                                    i = -1;
                                }
                            }
                        }
                    }
                    else
                    {
                        newfact.Fields[f] = term;
                    }
                }
                Activation newact = new Activation(newfact, rhsCondition.ConditionType);
                if (node.Production.InferredFacts.Contains(newact) == false)
                {
                    node.Production.InferredFacts.Add(newact);
                }
            }
        }
示例#7
0
 /// <summary>
 /// Controls the activation flow based on node type
 /// </summary>
 /// <param name="child">The child.</param>
 /// <param name="w">The w.</param>
 private void right_activation(ReteNode child, WME w)
 {
     switch (child.Type)
     {
         case ReteNodeType.Join:
             join_node_right_activation(child as JoinNode, w);
             break;
         case ReteNodeType.Negative:
             negative_node_right_activation(child as NegativeNode, w);
             break;
         default:
             throw new ApplicationException("???");
     }
 }
示例#8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DummyTopToken"/> class.
 /// </summary>
 public DummyTopToken()
 {
     _wme = new WME("null");
 }
示例#9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DummyTopToken"/> class.
 /// </summary>
 public DummyTopToken()
 {
     _wme = new WME("null");
 }
示例#10
0
 /// <summary>
 /// Binds the RHS.
 /// </summary>
 private void BindRHS(List<Activation> items)
 {
     int lhsCnt = _lhs.Count - 1;
     foreach (Activation act in items)
     {
         foreach (RightHandSideCondition condition in _rhs)
         {
             WME newfact = new WME();
             for (int f = 0; f < 3; f++)
             {
                 Term term = condition.Fields[f];
                 if (term.TermType == TermType.Variable)
                 {
                     for (int i = lhsCnt; i >= 0; i--)
                     {
                         Condition rh = _lhs[i];
                         if (rh.ConditionType == ConditionType.Positive)
                         {
                             int pos = rh.Contains(term);
                             if (pos >= 0)
                             {
                                 newfact.Fields[f] = act.InferredFact[pos];
                                 i = -1;
                             }
                         }
                     }
                 }
                 else
                 {
                     newfact.Fields[f] = term;
                 }
             }
             Activation newact = new Activation(newfact, condition.ConditionType);
             if (_inferredFacts.Contains(newact) == false)
             {
                 _inferredFacts.Add(newact);
             }
         }
     }
 }
示例#11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Activation"/> class.
 /// </summary>
 /// <param name="prod">The prod.</param>
 /// <param name="tok">The tok.</param>
 public Activation(WME prod, ConditionType tok)
 {
     _fact          = prod;
     _conditionType = tok;
 }
示例#12
0
 /// <summary>
 /// Sets the specified fact.
 /// </summary>
 /// <param name="fact">The fact.</param>
 private void Set(WME fact)
 {
     IFactProvider eo = fact.Identifier.Value as IFactProvider;
     if (eo == null)
     {
         return;
     }
     try
     {
         eo.SetProperty(fact.Attribute.Value.ToString(), fact.Value.Value);
         _actionsTaken.Add(fact);
     }
     catch
     {
         _actionsSkipped.Add(fact);
     }
 }
示例#13
0
 /// <summary>
 /// Retracts the specified fact.
 /// </summary>
 /// <param name="fact">The fact.</param>
 private void Retract(WME fact)
 {
     _inferredFacts.Remove(fact);
     _rete.RemoveWME(fact);
 }
示例#14
0
 /// <summary>
 /// Asserts the specified fact.
 /// </summary>
 /// <param name="fact">The fact.</param>
 private void Assert(WME fact)
 {
     _inferredFacts.Add(fact);
     _rete.AddWME(fact);
 }
示例#15
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);
         }
     }
 }
示例#16
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);
                    }
                }
            }
        }
示例#17
0
 /// <summary>
 /// Performs the specified tests.
 /// </summary>
 /// <param name="tests">The tests.</param>
 /// <param name="t">The t.</param>
 /// <param name="w">The w.</param>
 /// <returns></returns>
 private bool perform_join_tests(IEnumerable<TestAtJoinNode> tests, Token t, WME w)
 {
     foreach (TestAtJoinNode this_test in tests)
     {
         Term arg1 = w[this_test.FieldOfArg1];
         WME wme2 = t[this_test.NumberOfLevelsUp];
         Term arg2 = wme2[this_test.FieldOfArg2];
         if (this_test.Evaluator.Evaluate(arg1, arg2) == false)
             return false;
     }
     return true;
 }
示例#18
0
 /// <summary>
 /// Left_activations the specified new_node.
 /// </summary>
 /// <param name="new_node">The new_node.</param>
 /// <param name="tok">The tok.</param>
 /// <param name="w">The w.</param>
 private void left_activation(ReteNode new_node, Token tok, WME w)
 {
     switch (new_node.Type)
     {
         case ReteNodeType.BetaMemory:
             beta_memory_left_activation(new_node as BetaMemory, tok, w);
             break;
         case ReteNodeType.Negative:
             negative_node_left_activation(new_node as NegativeNode, tok, w);
             break;
         case ReteNodeType.Builtin:
             builtin_node_left_activation(new_node as BuiltinMemory, tok, w);
             break;
         case ReteNodeType.NCCPartner:
             ncc_partner_node_left_activation(new_node as NCCPartnerNode, tok, w);
             break;
         case ReteNodeType.NCC:
             ncc_node_left_activation(new_node as NCCNode, tok, w);
             break;
         case ReteNodeType.Join:
             join_node_left_activation(new_node as JoinNode, tok);
             break;
         case ReteNodeType.Production:
             p_node_activation(new_node as ProductionNode, tok, w);
             break;
         case ReteNodeType.Mutex:
             mutex_node_activation(new_node as MutexNode, tok, w);
             break;
         case ReteNodeType.Aggregator:
             aggregator_node_activation(new_node as AggregatorNode, tok, w);
             break;
         default:
             throw new ApplicationException("Unknown left_activation type: " + new_node.GetType().Name);
     }
 }
示例#19
0
        /// <summary>
        /// Adds the WME.
        /// </summary>
        /// <param name="w">The WME.</param>
        public void AddWME(WME w)
        {
            int v1 = w.Fields[0].GetHashCode();
            int v2 = w.Fields[1].GetHashCode();
            int v3 = w.Fields[2].GetHashCode();

            _working_memory.Add(w);

            AlphaMemory alpha_mem;

            alpha_mem = lookup_in_hash_table(0, 0, 0);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
            alpha_mem = lookup_in_hash_table(0, 0, v3);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
            alpha_mem = lookup_in_hash_table(0, v2, 0);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
            alpha_mem = lookup_in_hash_table(0, v2, v3);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
            alpha_mem = lookup_in_hash_table(v1, 0, 0);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
            alpha_mem = lookup_in_hash_table(v1, 0, v3);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
            alpha_mem = lookup_in_hash_table(v1, v2, 0);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
            alpha_mem = lookup_in_hash_table(v1, v2, v3);
            if (alpha_mem != null)
                alpha_memory_activation(alpha_mem, w);
        }
示例#20
0
 /// <summary>
 /// Similarly, whenever a new token tok = ht;wi is added to a beta memory, we add tok to
 /// t.children and to w.tokens. We also fill in the new node field on the token. To simplify our
 /// pseudocode, it is convenient to define a "helper" function make-token which builds a new token
 /// and initializes its various fields as necessary for tree-based removal. Although we write this as
 /// a separate function, it would normally be coded "inline" for efficiency.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="parent">The parent.</param>
 /// <param name="w">The w.</param>
 /// <returns></returns>
 private Token make_token(ReteNode node, Token parent, WME w)
 {
     Token tok = new Token();
     tok.Parent = parent;
     tok.WME = w;
     tok.Node = node;
     parent.Children.AddToFront(tok);
     if (w != null)
     {
         w.Tokens.AddToFront(tok);
     }
     return tok;
 }
示例#21
0
 /// <summary>
 /// Modifies an existing WME.
 /// </summary>
 /// <param name="oldWME">The old WME.</param>
 /// <param name="newWME">The new WME.</param>
 public virtual void ModifyWME(WME oldWME, WME newWME)
 {
     RemoveWME(oldWME);
     AddWME(newWME);
 }
示例#22
0
 /// <summary>
 /// Mutex_node_activations the specified node.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="tok">The tok.</param>
 /// <param name="w">The w.</param>
 private void mutex_node_activation(MutexNode node, Token tok, WME w)
 {
     Token new_token = make_token(node, tok, w);
     node.Items.Add(new_token);
 }
示例#23
0
 private void aggregator_node_activation(AggregatorNode node, Token tok, WME w)
 {
     Token new_token = make_token(node, tok, w);
     node.Items.AddToFront(new_token);
 }
示例#24
0
 /// <summary>
 /// Ncc_node_left_activations the specified node.
 /// </summary>
 /// <remarks>
 /// Our ncc-node-left-activation procedure is similar to the negative-node-left-activation procedure
 /// (page 42). In both cases, we need to find the join results for a new token. For negative
 /// nodes, we compute these join results by scanning the WMEs in an alpha memory and performing
 /// the join tests on them. For NCC nodes, the join results have already been computed by the
 /// subnetwork, so we simply look at the new-result-buffer in the NCC partner node to find them.
 /// </remarks>
 /// <param name="node">The node.</param>
 /// <param name="t">The t.</param>
 /// <param name="w">The w.</param>
 private void ncc_node_left_activation(NCCNode node, Token t, WME w)
 {
     Token new_token = make_token(node, t, w);
     node.Items.AddToFront(new_token);
     foreach (Token result in node.Partner.NewResultBuffer)
     {
         node.Partner.NewResultBuffer.Remove(result);
         new_token.NCCResults.AddToFront(result);
         result.Owner = new_token;
     }
     if (new_token.NCCResults.Count == 0)
     {
         foreach (ReteNode child in node.Children)
         {
             left_activation(child, new_token, null);
         }
     }
 }
示例#25
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);
            }
        }
示例#26
0
        /// <summary>
        /// Ncc_partner_node_left_activations the specified partner.
        /// </summary>
        /// <remarks>
        /// To handle an NCC partner node (left) activation, we take the new match from the subnetwork
        /// and build a "result" token to store it. (The pseudocode for this is shown in Figure 2.8.) Next we
        /// try to find the appropriate owner token in the NCC node's memory. (There might be one there,
        /// if this is a new subconditions match for an old preceding-conditions match, or there might not
        /// be one there, if this is an initial subconditions match for a new preceding-conditions match.)
        /// If we find an appropriate owner token, then we add the new result token to its local memory;
        /// if the number of results in the local memory changes from zero to one | indicating that the
        /// NCC 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 owner token. (This is
        /// similar to the negative-node-right-activation procedure on page 43.) On the other hand, if there
        /// isn't an appropriate owner token already in the NCC node's memory, then this new result token
        /// is placed in the new-result-buffer. (The NCC node will soon be activated and collect any new
        /// results from the buffer.)
        /// </remarks>
        /// <param name="partner">The partner.</param>
        /// <param name="t">The t.</param>
        /// <param name="w">The w.</param>
        private void ncc_partner_node_left_activation(NCCPartnerNode partner, Token t, WME w)
        {
            NCCNode nccNode = partner.NCCNode;
            Token new_result = make_token(partner, t, w);
            Token owners_t = t;
            WME owners_w = w;
            for (int i = 0; i < partner.NumberOfConjuncts; i++)
            {
                owners_w = owners_t.WME;
                owners_t = owners_t.Parent;
            }

            foreach (Token owner in nccNode.Items)
            {
                if (owner.Parent == owners_t && owner.WME == owners_w)
                {
                    owner.NCCResults.Add(new_result);
                    new_result.Owner = owner;
                    delete_descendents_of_token(owner);
                }
                else
                {
                    partner.NewResultBuffer.AddToFront(new_result);
                }
            }
        }
示例#27
0
 /// <summary>
 /// Check_constant_testses the specified w.
 /// </summary>
 /// <param name="w">The w.</param>
 /// <param name="c">The c.</param>
 /// <returns></returns>
 private bool check_constant_tests(WME w, Condition c)
 {
     foreach (Term o in c.Fields)
     {
         if ((o is Variable) == false)
         {
             if (w.Contains(o) == false)
                 return false;
         }
     }
     return true;
 }
示例#28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Activation"/> class.
 /// </summary>
 /// <param name="prod">The prod.</param>
 /// <param name="tok">The tok.</param>
 public Activation(WME prod, ConditionType tok)
 {
     _fact = prod;
     _conditionType = tok;
 }