예제 #1
0
 public LogicFact(CustomSocketDomain.SocketDomain domain, object value) : base(domain, value)
 {
     Negation       = false;
     RightOperation = LogicOperation.Operation.None;
     Level          = new LogicFactLevel {
         Depth = 0, Negation = false
     };
 }
예제 #2
0
 public LogicFact(CustomSocketDomain.SocketDomain domain, object value, LogicOperation.Operation operation,
                  bool negation = false)
     : base(domain, value)
 {
     Negation       = negation;
     RightOperation = operation;
     Level          = new LogicFactLevel {
         Depth = 0, Negation = false
     };
 }
예제 #3
0
        /// <summary>Возвращает конъюктивную нормальную форму</summary>
        public static LogicRule ConjunctionNormalFrom(LogicRule rule, int priority = 100)
        {
            // Если список пуст или содержит один факт - вернуть его
            if (rule.Count <= 1)
            {
                return(rule);
            }

            // Получить максимальный приоритет операции
            var maxPriority = Math.Min(
                rule.Select(fact => LogicOperation.Priority[fact.RightOperation]).Max(), priority
                );

            // Получить первый элемент списка
            var node = rule.First;

            // Итерируемся по элементам списка
            while (node != null)
            {
                if (LogicOperation.Priority[node.Value.RightOperation] == maxPriority)
                {
                    switch (node.Value.RightOperation)
                    {
                    case LogicOperation.Operation.Implication:
                        // Заменяем импликацию дизъюнцией
                        node.Value.RightOperation = LogicOperation.Operation.Disjunction;

                        // Создаем уровень ниже
                        var level = new LogicFactLevel {
                            Depth = node.Value.Level.Depth + 1, Negation = true
                        };
                        // Помещаем всю левую часть на уровень ниже
                        var currentNode = node;
                        while (currentNode != null)
                        {
                            currentNode.Value.Level = level;
                            currentNode             = currentNode.Previous;
                        }

                        break;

                    case LogicOperation.Operation.Conjunction:
                        if (node.Value.Level.Depth != 0 && node.Value.Level.Negation)
                        {
                            node.Value.Negation       = !node.Value.Negation;
                            node.Value.RightOperation = LogicOperation.Operation.Disjunction;
                            node.Value.Level          =
                                new LogicFactLevel {
                                Depth = node.Value.Level.Depth - 1, Negation = false
                            };
                        }

                        break;

                    case LogicOperation.Operation.Disjunction:
                        if (node.Value.Level.Depth != 0 && node.Value.Level.Negation)
                        {
                            node.Value.Negation = !node.Value.Negation;
                            node.Value.Level    =
                                new LogicFactLevel {
                                Depth = node.Value.Level.Depth - 1, Negation = false
                            };
                        }

                        break;

                    case LogicOperation.Operation.None:
                        return(rule);
                    }
                }

                node = node.Next;
            }

            return(ConjunctionNormalFrom(rule, maxPriority - 1));
        }