public bool Processing(FactSet inputFacts, string socketName)
        {
            var statements = new LogicFactSet();

            // Добавляем входные параметры, объединенные союзом "и"
            var inputDomains = new List <SocketDomain>();

            foreach (var inputFact in inputFacts.Facts.Where(p => !p.IsDefaultValue()))
            {
                inputDomains.Add(inputFact.Domain);
                var logicInputFacts = new LogicRule();
                logicInputFacts.AddLast(
                    new LogicFact(inputFact.Domain, inputFact.Value, LogicOperation.Operation.None));
                statements.Add(logicInputFacts);
            }

            // Добавляем имеющиеся правила (отфильтрованные по входным св-м домена)
            foreach (var factStatement in _rules)
            {
                var statementFiltered = new LogicRule(factStatement.Where(p => inputDomains.Contains(p.Domain)));
                if (statementFiltered.Count == 0)
                {
                    continue;
                }

                statementFiltered.Last.Value.RightOperation = LogicOperation.Operation.Implication;
                statementFiltered.AddLast(factStatement.Last.Value);
                statements.Add(statementFiltered);
            }

            // Добавляем отрицание утверждения
            var socketNegation = new LogicRule();

            socketNegation.AddLast(
                new LogicFact(SocketDomain.SocketName, socketName, LogicOperation.Operation.None, true)
                );
            statements.Add(socketNegation);

            // Выводим отладочную информацию первого шага
            DebugWrite("".PadLeft(40, '-'));
            DebugWrite("Начальная диспозиция: " + statements);

            // Получаем конъюнктивную нормальную форму
            var cnfStatements = new LogicFactSet();

            foreach (var statement in statements)
            {
                cnfStatements.Add(LogicRule.ConjunctionNormalFrom(statement));
            }

            // Выводим отладочную информацию КНФ
            DebugWrite("".PadLeft(40, '-'));
            DebugWrite("Конъюнктивная нормальная форма: " + cnfStatements);
            return(Resolve(
                       cnfStatements, new LogicFact(SocketDomain.SocketName, socketName, LogicOperation.Operation.None)
                       ));
        }
        public static LogicRule ParseRule(string ruleString)
        {
            var rule = new LogicRule();

            rule.Functor   = ruleString.Substring(0, ruleString.IndexOf('('));
            rule.Arguments = ParseArguments(ruleString);
            rule.Body      = ParseBody(ruleString);
            return(rule);
        }
        public void ConjunctionNormalForm_IsCorrectWithSingleFact()
        {
            // Arrange
            var singleFact  = new LogicFact(SocketDomain.Color, "value", LogicOperation.Operation.None, true);
            var singleRules = new LogicRule();

            singleRules.AddLast(singleFact);

            // Act
            var cnfStatement = LogicRule.ConjunctionNormalFrom(singleRules);

            // Assert
            Assert.True(singleFact.Equals(cnfStatement.First.Value), "Исходный факт не соответствует полученному");
        }
        public void ConjunctionNormalForm_IsCorrectWithDisjunction()
        {
            // Arrange
            var disjunctionFactA = new LogicFact(SocketDomain.Color, "valueA", LogicOperation.Operation.Disjunction);
            var disjunctionFactB = new LogicFact(SocketDomain.HousingColor, "valueB", LogicOperation.Operation.None);
            var disjunctionRules = new LogicRule();

            disjunctionRules.AddLast(disjunctionFactA);
            disjunctionRules.AddLast(disjunctionFactB);

            // Act
            disjunctionRules = LogicRule.ConjunctionNormalFrom(disjunctionRules);

            Assert.True(disjunctionFactA.Equals(disjunctionRules.First.Value));
            Assert.True(disjunctionFactB.Equals(disjunctionRules.Last.Value));
        }
        public void ConjunctionNormalForm_IsCorrectWithImplication()
        {
            var implicationFactA = new LogicFact(SocketDomain.Material, "valueA", LogicOperation.Operation.Conjunction);
            var implicationFactB =
                new LogicFact(SocketDomain.HousingMaterial, "valueB", LogicOperation.Operation.Implication);
            var implicationResult = new LogicFact(SocketDomain.SocketName, "valueC", LogicOperation.Operation.None);
            var implicationRules  = new LogicRule();

            implicationRules.AddLast(implicationFactA);
            implicationRules.AddLast(implicationFactB);
            implicationRules.AddLast(implicationResult);
            implicationRules = LogicRule.ConjunctionNormalFrom(implicationRules);

            var cnfImplicationFactA =
                new LogicFact(SocketDomain.Material, "valueA", LogicOperation.Operation.Disjunction, true);
            var cnfImplicationFactB = new LogicFact(SocketDomain.HousingMaterial, "valueB",
                                                    LogicOperation.Operation.Disjunction, true);

            Assert.True(cnfImplicationFactA.Equals(implicationRules.First.Value));
            Assert.True(cnfImplicationFactB.Equals(implicationRules.First?.Next?.Value));
            Assert.True(implicationResult.Equals(implicationRules.Last.Value));
        }