public LogicFact(CustomSocketDomain.SocketDomain domain, object value) : base(domain, value) { Negation = false; RightOperation = LogicOperation.Operation.None; Level = new LogicFactLevel { Depth = 0, Negation = false }; }
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 }; }
/// <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)); }