public IEnumerable <OutputParameterSolution> Solve(IDictionary <Parameter, double> inputValues) { if (InputParameters.Except(inputValues.Keys).Any()) { throw new ArgumentException("Input values do not represent all the task's input parameters."); } var inputMembershipValues = InputParameters .SelectMany(param => param.CalculateMembershipValuesFor(inputValues[param])) // obtains a sequence of KV-pairs instead of dictionaries .ToDictionary(pair => pair.Key, pair => pair.Value); // merges all the pairs in one dictionaty; throws exception on matching keys (which should never happen) var outputMembershipValues = Rules .GroupBy(rule => rule.Class) .ToDictionary(group => group.Key, group => group.Select(rule => rule.Expression.Evaluate(inputMembershipValues)).Max()); // joins the rules of the same target class via max (fuzzy disjunction) return(OutputParameters.Select(param => new OutputParameterSolution(param, outputMembershipValues))); }