private void ValidateRootIsDisjunction(LogicalTreeNode root) { if (root.Type != NodeType.Disjunction) { throw new ArgumentException("При применении трансформации удаления лишних скобок для дизъюнкции, корень должен быть дизъюнкцией", "root"); } }
private void ValidateRootIsConjunction(LogicalTreeNode root) { if (root.Type != NodeType.Conjunction) { throw new ArgumentException("При применении трансформации раскрытия дистрибутивности, корень должен быть конъюнкцией", "root"); } }
private void UpdateHeightUsingChild(LogicalTreeNode node) { if (Height < node.Height + 1) { Height = node.Height + 1; } }
public void Transform(LogicalTreeNode root) { ValidateRootIsConjunction(root); // Необходимо выполнить предварительную энумерацию (.ToArray()), // т.к. далее модифицируется коллекция, по которой происходит выборка var disjunctions = root.Children.Where(x => x.Type == NodeType.Disjunction).ToArray(); var conjunctions = root.Children.Where(x => x.Type == NodeType.Conjunction).ToArray(); var leafs = root.Children.Where(x => x.Type == NodeType.Leaf).ToArray(); var conjunctionsDescendants = conjunctions.SelectMany(x => x.Children).ToArray(); var disjunctionDescendants = disjunctions.Select(x => x.Children).ToArray(); var disjunctionsCombinations = SequencesCombinator <LogicalTreeNode> .Combinate(disjunctionDescendants); // Результат состоит из дизъюнкции элементарных конъюнкций // Каждая конъюнкция состоит из всех листовых переменных, непосредственных детей корня // Всех детей конъюнкций, где конъюнкция - непосредственный ребенок корня // Одного из вариантов комбинации детей дизъюнкций, где дизъюнкция - непосредственный ребенок корня root.Type = NodeType.Disjunction; root.ClearChildren(); foreach (var disjunctionsCombination in disjunctionsCombinations) { // Сплащиваем конъюнкции, которые могли содержаться в комбинации детей дизъюнкций. var disjunctionLeafs = FlatInnerConjunctions(disjunctionsCombination); var conjunction = new LogicalTreeNode(NodeType.Conjunction); conjunction.AddNodes(disjunctionLeafs); conjunction.AddNodes(conjunctionsDescendants); conjunction.AddNodes(leafs); root.AddNode(conjunction); } }
public void RemoveNode(LogicalTreeNode node) { _children.Remove(node); node.Parent = null; UpdateHeight(); }
public void AddNode(LogicalTreeNode node) { _children.Add(node); node.SetParent(this); UpdateHeightUsingChild(node); }
public void Transform(LogicalTreeNode root) { // Вначале избавляемся от всех отрицаний в нелистьях // Потом редуцируем дерево по высоте к КНФ форме PullNegationsDown(root); ReductHeight(root); }
/// <summary> /// Возвращает все вершины дерева, включая корень /// </summary> /// <param name="root">Корень дерева, для которого вычисляется список его вершин</param> /// <returns>Список вершин дерева</returns> private IEnumerable <LogicalTreeNode> GetNodes(LogicalTreeNode root) { var result = new List <LogicalTreeNode>(); result.Add(root); foreach (var node in root.Children) { result.AddRange(GetNodes(node)); } return(result); }
private void ReductHeight(LogicalTreeNode root) { // Т.к. высота какого-либо элемента дерева не может увеличиться, // и высота вершины после редукции никогда не превышает 3 (высота КНФ) // то проходя от самого "низкого" элемента к самому "высокому", // гарантированно в конце получим правильный результат. var heightOrderedNodes = GetNodesOrderedByHeight(root).ToArray(); foreach (var node in heightOrderedNodes) { _treeHeightReductionTransformation.Transform(node); } }
public void Transform(LogicalTreeNode root) { ValidateRootIsConjunction(root); // Необходимо выполнить предварительную энумерацию (.ToArray()), // т.к. далее модифицируется коллекция, по которой происходит выборка var conjunctions = root.Children.Where(x => x.Type == NodeType.Conjunction).ToArray(); var leafs = root.Children.Where(x => x.Type == NodeType.Leaf).ToArray(); root.ClearChildren(); root.AddNodes(conjunctions.SelectMany(x => x.Children).ToList()); root.AddNodes(leafs); }
private LogicalTreeNode Clone() { var clone = new LogicalTreeNode(Type); clone.Name = Name; clone.Negated = Negated; foreach (var node in _children) { clone.AddNode(node.Clone()); } return(clone); }
private void SetParent(LogicalTreeNode newParent) { DelinkFromParent(); Parent = newParent; }
/// <summary> /// Возвращает список вершин дерева, упорядоченные по высоте /// </summary> /// <param name="root">Корень дерева, для которого вычисляется упорядоченный список его вершин</param> /// <returns>Список вершин дерева, упорядоченные по высоте</returns> private IEnumerable <LogicalTreeNode> GetNodesOrderedByHeight(LogicalTreeNode root) { var nodes = GetNodes(root); return(nodes.OrderBy(x => x.Height)); }
private void PullNegationsDown(LogicalTreeNode root) { _deMorganNegationPuller.Transform(root); }