/// <summary> /// Determines whether the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>. /// </summary> /// <param name="obj">The <see cref="T:System.Object"></see> to compare with the current <see cref="T:System.Object"></see>.</param> /// <returns> /// true if the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>; otherwise, false. /// </returns> public override bool Equals(object obj) { TestAtJoinNode test = obj as TestAtJoinNode; if (test == null) { return(base.Equals(obj)); } return(test.ConditionNumberOfArg2.Equals(ConditionNumberOfArg2) && test.Evaluator.ToString().Equals(Evaluator.ToString()) && test.FieldOfArg1.Equals(FieldOfArg1) && test.FieldOfArg2.Equals(FieldOfArg2) && test.NumberOfLevelsUp.Equals(NumberOfLevelsUp)); }
/// <summary> /// <para> /// Our next helper function, get-join-tests-from-condition, takes a condition and builds a list of /// all the variable binding consistency tests that need to be performed by its join node. To do this, /// it needs to know what all the earlier conditions are, so it can determine whether a given variable /// appeared in them - in which case its occurrence in the current condition means a consistency /// test is needed - or whether it is simply a new (not previously seen) variable - in which case /// no test is needed. If a variable v has more than one previous occurrence, we still only need /// one consistency test for it - join nodes for earlier conditions will ensure that all the previous /// occurrences are equal, so the current join node just has to make sure the current WME has the /// same value for it as any one of the previous occurrences. The pseudocode below always chooses /// the nearest (i.e., most recent) occurrence for the test, because with list-form tokens, the nearest /// occurrence is the cheapest to access. With array-form tokens, this choice does not matter. /// </para> /// <para> /// We make one minor change to get-join-tests-from-condition. We must now allow earlier- /// conds to contain negative conditions. Occurrences of variables inside negative conditions do not /// represent bindings of those variables -- a negative condition tests for the absence of something /// in working memory, so there will be no binding. Thus, we modify the function so that it ignores /// negative conditions in earlier-conds. /// </para> /// </summary> /// <param name="c">The c.</param> /// <param name="earlier_conds">The earlier_conds.</param> /// <returns></returns> private List<TestAtJoinNode> get_join_tests_from_condition(Condition c, IList<LeftHandSideCondition> earlier_conds) { List<TestAtJoinNode> result = new List<TestAtJoinNode>(); int cntOfEarlierConditions = earlier_conds.Count - 1; for (int f = 0; f < 3; f++) { Variable v = c.Fields[f] as Variable; if (v != null) { for (int i = cntOfEarlierConditions; i >= 0; i--) { Condition earlier_cond = earlier_conds[i]; if (earlier_cond.ConditionType == ConditionType.Positive) { for (int f2 = 0; f2 < 3; f2++) { Variable o = earlier_cond.Fields[f2] as Variable; if (o != null && o.Equals(v)) { TestAtJoinNode this_test = new TestAtJoinNode(); this_test.FieldOfArg1 = f; this_test.ConditionNumberOfArg2 = i; this_test.FieldOfArg2 = f2; this_test.NumberOfLevelsUp = (cntOfEarlierConditions - i); this_test.Evaluator = c.Evaluator; result.Add(this_test); i = -1; } } } } } } return result; }