/// <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; }
/// <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); } } }