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); } }
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); }