public void Apply_Many_Implication_With_Value_Override(
            [Values("Algebraic", "Drastic", "Einstein", "Hamacher", "Lukasiewicz", "MinMax")] string evalStrategyName,
            [Values("Average", "Max", "Min", "Sum")] string mergeStrategy)
        {
            var evaluationStrategy = createEvaluationStrategy(evalStrategyName);
            var merger = createFuzzyValueMerger(mergeStrategy);

            var termA1 = new FuzzyTerm("TermA1", new MembershipFunction());
            var termA2 = new FuzzyTerm("TermA1", new MembershipFunction());
            var varA = new FuzzyVariable("Variable A", null, termA1, termA2);

            var value = new FuzzyValue(varA, new Dictionary<FuzzyTerm, double> { { termA1, 0.2 }, { termA2, 0.6 } });

            var sut = new RuleEvaluation(evaluationStrategy, merger) { InputScope = new Scope(value) };

            var impl1 = new FuzzyImplication(new AndExpression(new ValueExpression(varA, termA1), new ValueExpression(varA, termA2)), new ValueExpression(varA, termA1));

            var result = sut.Apply(new Scope(value), new[] { impl1 });

            var val = evaluationStrategy.And(0.2, 0.6);

            Assert.AreEqual(1, result.Count);
            Assert.AreEqual(varA, result[0].AssociatedVariable);
            Assert.AreEqual(2, result[0].Values.Count);
            // A = A1 got overridden:
            Assert.AreEqual(val, result[0].Values[termA1]);
            // A = A2 stays the same:
            Assert.AreEqual(0.6, result[0].Values[termA2]);
        }
        public void Apply_Many_Implication(
            [Values("Algebraic", "Drastic", "Einstein", "Hamacher", "Lukasiewicz", "MinMax")] string evalStrategyName,
            [Values("Average", "Max", "Min", "Sum")] string mergeStrategy)
        {
            var evaluationStrategy = createEvaluationStrategy(evalStrategyName);
            var merger = createFuzzyValueMerger(mergeStrategy);

            var termA1 = new FuzzyTerm("TermA1", new MembershipFunction());
            var termA2 = new FuzzyTerm("TermA1", new MembershipFunction());
            var termB1 = new FuzzyTerm("TermB1", new MembershipFunction());
            var termB2 = new FuzzyTerm("TermB2", new MembershipFunction());
            var varA = new FuzzyVariable("Variable A", null, termA1, termA2);
            var varB = new FuzzyVariable("Variable B", null, termB1, termB2);

            var value = new FuzzyValue(varA, new Dictionary<FuzzyTerm, double> { { termA1, 0.4 }, { termA2, 0.6 } });

            var sut = new RuleEvaluation(evaluationStrategy, merger);

            var impl1 = new FuzzyImplication(new ValueExpression(varA, termA1), new ValueExpression(varB, termB1));
            var impl2 = new FuzzyImplication(new ValueExpression(varA, termA2), new ValueExpression(varB, termB2));

            var result = sut.Apply(new Scope(value), new[] {impl1, impl2}).ToList();

            Assert.AreEqual(2, result.Count);
            var valA = result.Find(val => val.AssociatedVariable.Equals(varA));
            Assert.IsNotNull(valA);
            Assert.AreEqual(2, valA.Values.Count);
            Assert.AreEqual(0.4, valA.Values[termA1]);
            Assert.AreEqual(0.6, valA.Values[termA2]);

            var valB = result.Find(val => val.AssociatedVariable.Equals(varB));
            Assert.IsNotNull(valB);
            Assert.AreEqual(2, valB.Values.Count);
            Assert.AreEqual(0.4, valB.Values[termB1]);
            Assert.AreEqual(0.6, valB.Values[termB2]);
        }
        public void Apply_Many_Implication_With_Value_Merging(
            [Values("Algebraic", "Drastic", "Einstein", "Hamacher", "Lukasiewicz", "MinMax")] string evalStrategyName,
            [Values("Average", "Max", "Min", "Sum")] string mergeStrategy)
        {
            var evaluationStrategy = createEvaluationStrategy(evalStrategyName);
            var merger = createFuzzyValueMerger(mergeStrategy);

            var termA1 = new FuzzyTerm("TermA1", new MembershipFunction());
            var termA2 = new FuzzyTerm("TermA1", new MembershipFunction());
            var termB1 = new FuzzyTerm("TermB1", new MembershipFunction());
            var varA = new FuzzyVariable("Variable A", null, termA1, termA2);
            var varB = new FuzzyVariable("Variable B", null, termB1);

            var value = new FuzzyValue(varA, new Dictionary<FuzzyTerm, double> { { termA1, 0.5 }, { termA2, 0.6 } });

            var sut = new RuleEvaluation(evaluationStrategy, merger) { InputScope = new Scope(value) };

            var impl1 = new FuzzyImplication(new ValueExpression(varA, termA1), new ValueExpression(varB, termB1));
            var impl2 = new FuzzyImplication(new ValueExpression(varA, termA2), new ValueExpression(varB, termB1));

            var result = sut.Apply(new Scope(value), new[] { impl1, impl2 });

            var mergedValue = merger.Apply(new FuzzyValue[]
            {
                new FuzzyValue(varB, new Dictionary<FuzzyTerm, double> { { termB1, 0.5 } }),
                new FuzzyValue(varB, new Dictionary<FuzzyTerm, double> { { termB1, 0.6 } })
            });

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(varA, result[0].AssociatedVariable);
            Assert.AreEqual(2, result[0].Values.Count);
            Assert.AreEqual(0.5, result[0].Values[termA1]);
            Assert.AreEqual(0.6, result[0].Values[termA2]);


            Assert.AreEqual(varB, result[1].AssociatedVariable);
            Assert.AreEqual(1, result[1].Values.Count);
            Assert.AreEqual(mergedValue[0].Values[termB1], result[1].Values[termB1]);
        }
        public void Apply_One_Implication(
            [Values("Algebraic", "Drastic", "Einstein", "Hamacher", "Lukasiewicz", "MinMax")] string evalStrategyName,
            [Values("Average", "Max", "Min", "Sum")] string mergeStrategy)
        {
            var evaluationStrategy = createEvaluationStrategy(evalStrategyName);
            var merger = createFuzzyValueMerger(mergeStrategy);

            var termA = new FuzzyTerm("TermA", new MembershipFunction());
            var termB = new FuzzyTerm("TermB", new MembershipFunction());
            var varA = new FuzzyVariable("Variable A", null, termA);
            var varB = new FuzzyVariable("Variable B", null, termB);

            var value = new FuzzyValue(varA, new Dictionary<FuzzyTerm, double> { { termA, 0.4 } });

            var sut = new RuleEvaluation(evaluationStrategy, merger);

            var result = sut.Apply(new Scope(value), new[] {new FuzzyImplication(new ValueExpression(varA, termA), new ValueExpression(varB, termB))});

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(varA, result[0].AssociatedVariable);
            Assert.AreEqual(1, result[0].Values.Count);
            Assert.AreEqual(0.4, result[0].Values[termA]);
            Assert.AreEqual(varB, result[1].AssociatedVariable);
            Assert.AreEqual(1, result[1].Values.Count);
            Assert.AreEqual(0.4, result[1].Values[termB]);
        }