private IEnumerable <BoolExpr <T_To> > VisitChildren(TreeExpr <T_From> expression) { foreach (BoolExpr <T_From> child in expression.Children) { yield return(child.Accept(this)); } }
private bool VisitTree(TreeExpr <T_Identifier> expression) { foreach (BoolExpr <T_Identifier> child in expression.Children) { child.Accept(this); } return(true); }
private int VisitTree(TreeExpr <T_Identifier> expression) { int sum = 0; foreach (var child in expression.Children) { sum += child.Accept(this); } return(sum); }
private BoolExpr <T_Identifier> SimplifyTree(TreeExpr <T_Identifier> tree) { bool isAnd = ExprType.And == tree.ExprType; Debug.Assert(isAnd || ExprType.Or == tree.ExprType); // Get list of simplified children, flattening nested And/Or expressions List <BoolExpr <T_Identifier> > simplifiedChildren = new List <BoolExpr <T_Identifier> >(tree.Children.Count); foreach (BoolExpr <T_Identifier> child in tree.Children) { BoolExpr <T_Identifier> simplifiedChild = child.Accept(this); // And(And(A, B), C) iff. And(A, B, C) // Or(Or(A, B), C) iff. Or(A, B, C) if (simplifiedChild.ExprType == tree.ExprType) { simplifiedChildren.AddRange(((TreeExpr <T_Identifier>)simplifiedChild).Children); } else { simplifiedChildren.Add(simplifiedChild); } } // Track negated children separately to identify tautologies and contradictions Dictionary <BoolExpr <T_Identifier>, bool> negatedChildren = new Dictionary <BoolExpr <T_Identifier>, bool>(tree.Children.Count); List <BoolExpr <T_Identifier> > otherChildren = new List <BoolExpr <T_Identifier> >(tree.Children.Count); foreach (BoolExpr <T_Identifier> simplifiedChild in simplifiedChildren) { switch (simplifiedChild.ExprType) { case ExprType.Not: negatedChildren[((NotExpr <T_Identifier>)simplifiedChild).Child] = true; break; case ExprType.False: // False And A --> False if (isAnd) { return(FalseExpr <T_Identifier> .Value); } // False || A --> A (omit False from child collections) break; case ExprType.True: // True Or A --> True if (!isAnd) { return(TrueExpr <T_Identifier> .Value); } // True And A --> A (omit True from child collections) break; default: otherChildren.Add(simplifiedChild); break; } } List <BoolExpr <T_Identifier> > children = new List <BoolExpr <T_Identifier> >(); foreach (BoolExpr <T_Identifier> child in otherChildren) { if (negatedChildren.ContainsKey(child)) { // A && !A --> False, A || !A --> True if (isAnd) { return(FalseExpr <T_Identifier> .Value); } else { return(TrueExpr <T_Identifier> .Value); } } children.Add(child); } foreach (BoolExpr <T_Identifier> child in negatedChildren.Keys) { children.Add(child.MakeNegated()); } if (0 == children.Count) { // And() iff. True if (isAnd) { return(TrueExpr <T_Identifier> .Value); } // Or() iff. False else { return(FalseExpr <T_Identifier> .Value); } } else if (1 == children.Count) { // Or(A) iff. A, And(A) iff. A return(children[0]); } else { // Construct simplified And/Or expression TreeExpr <T_Identifier> result; if (isAnd) { result = new AndExpr <T_Identifier>(children); } else { result = new OrExpr <T_Identifier>(children); } return(result); } }