//--------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Linq; namespace System.Data.Common.Utils.Boolean { // Top-down push-down of negation in Boolean expressions. // - !(A or B) iff. !A and !B // - !(A and B) iff. !A or !B // - !!A iff. A // Uses two visitor classes: one to handle negated subtrees (essentially creates // an inverted tree) and one to handle non-negated subtrees (replicates until it // encounters NotExpr) internal static class NegationPusher { internal static BoolExpr> EliminateNot(BoolExpr> expression) { return expression.Accept(NonNegatedDomainConstraintTreeVisitor.Instance); } private class NonNegatedTreeVisitor : BasicVisitor { internal static readonly NonNegatedTreeVisitor Instance = new NonNegatedTreeVisitor(); protected NonNegatedTreeVisitor() { } internal override BoolExpr VisitNot(NotExpr expression) { return expression.Child.Accept(NegatedTreeVisitor.Instance); } } private class NegatedTreeVisitor : Visitor> { internal static readonly NegatedTreeVisitor Instance = new NegatedTreeVisitor(); protected NegatedTreeVisitor() { } internal override BoolExpr VisitTrue(TrueExpr expression) { return FalseExpr.Value; } internal override BoolExpr VisitFalse(FalseExpr expression) { return TrueExpr.Value; } internal override BoolExpr VisitTerm(TermExpr expression) { return new NotExpr(expression); } internal override BoolExpr VisitNot(NotExpr expression) { return expression.Child.Accept(NonNegatedTreeVisitor.Instance); } internal override BoolExpr VisitAnd(AndExpr expression) { return new OrExpr(expression.Children.Select(child => child.Accept(this))); } internal override BoolExpr VisitOr(OrExpr expression) { return new AndExpr(expression.Children.Select(child => child.Accept(this))); } } private class NonNegatedDomainConstraintTreeVisitor : NonNegatedTreeVisitor> { internal new static readonly NonNegatedDomainConstraintTreeVisitor Instance = new NonNegatedDomainConstraintTreeVisitor(); private NonNegatedDomainConstraintTreeVisitor() { } internal override BoolExpr> VisitNot(NotExpr> expression) { return expression.Child.Accept(NegatedDomainConstraintTreeVisitor.Instance); } } private class NegatedDomainConstraintTreeVisitor : NegatedTreeVisitor> { internal new static readonly NegatedDomainConstraintTreeVisitor Instance = new NegatedDomainConstraintTreeVisitor(); private NegatedDomainConstraintTreeVisitor() { } internal override BoolExpr> VisitNot(NotExpr> expression) { return expression.Child.Accept(NonNegatedDomainConstraintTreeVisitor.Instance); } internal override BoolExpr> VisitTerm(TermExpr> expression) { return new TermExpr>(expression.Identifier.InvertDomainConstraint()); } } } }