1 //---------------------------------------------------------------------
2 // <copyright file="NegationPusher.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System.Collections.Generic;
13 using System.Diagnostics;
16 namespace System.Data.Common.Utils.Boolean
18 // Top-down push-down of negation in Boolean expressions.
19 // - !(A or B) iff. !A and !B
20 // - !(A and B) iff. !A or !B
22 // Uses two visitor classes: one to handle negated subtrees (essentially creates
23 // an inverted tree) and one to handle non-negated subtrees (replicates until it
24 // encounters NotExpr)
25 internal static class NegationPusher
27 internal static BoolExpr<DomainConstraint<T_Variable, T_Element>> EliminateNot<T_Variable, T_Element>(BoolExpr<DomainConstraint<T_Variable, T_Element>> expression)
29 return expression.Accept(NonNegatedDomainConstraintTreeVisitor<T_Variable, T_Element>.Instance);
32 private class NonNegatedTreeVisitor<T_Identifier> : BasicVisitor<T_Identifier>
34 internal static readonly NonNegatedTreeVisitor<T_Identifier> Instance = new NonNegatedTreeVisitor<T_Identifier>();
36 protected NonNegatedTreeVisitor()
40 internal override BoolExpr<T_Identifier> VisitNot(NotExpr<T_Identifier> expression)
42 return expression.Child.Accept(NegatedTreeVisitor<T_Identifier>.Instance);
46 private class NegatedTreeVisitor<T_Identifier> : Visitor<T_Identifier, BoolExpr<T_Identifier>>
48 internal static readonly NegatedTreeVisitor<T_Identifier> Instance = new NegatedTreeVisitor<T_Identifier>();
50 protected NegatedTreeVisitor()
54 internal override BoolExpr<T_Identifier> VisitTrue(TrueExpr<T_Identifier> expression)
56 return FalseExpr<T_Identifier>.Value;
59 internal override BoolExpr<T_Identifier> VisitFalse(FalseExpr<T_Identifier> expression)
61 return TrueExpr<T_Identifier>.Value;
64 internal override BoolExpr<T_Identifier> VisitTerm(TermExpr<T_Identifier> expression)
66 return new NotExpr<T_Identifier>(expression);
69 internal override BoolExpr<T_Identifier> VisitNot(NotExpr<T_Identifier> expression)
71 return expression.Child.Accept(NonNegatedTreeVisitor<T_Identifier>.Instance);
74 internal override BoolExpr<T_Identifier> VisitAnd(AndExpr<T_Identifier> expression)
76 return new OrExpr<T_Identifier>(expression.Children.Select(child => child.Accept(this)));
79 internal override BoolExpr<T_Identifier> VisitOr(OrExpr<T_Identifier> expression)
81 return new AndExpr<T_Identifier>(expression.Children.Select(child => child.Accept(this)));
85 private class NonNegatedDomainConstraintTreeVisitor<T_Variable, T_Element> : NonNegatedTreeVisitor<DomainConstraint<T_Variable, T_Element>>
87 internal new static readonly NonNegatedDomainConstraintTreeVisitor<T_Variable, T_Element> Instance = new NonNegatedDomainConstraintTreeVisitor<T_Variable, T_Element>();
89 private NonNegatedDomainConstraintTreeVisitor()
93 internal override BoolExpr<DomainConstraint<T_Variable, T_Element>> VisitNot(NotExpr<DomainConstraint<T_Variable, T_Element>> expression)
95 return expression.Child.Accept(NegatedDomainConstraintTreeVisitor<T_Variable, T_Element>.Instance);
99 private class NegatedDomainConstraintTreeVisitor<T_Variable, T_Element> : NegatedTreeVisitor<DomainConstraint<T_Variable, T_Element>>
101 internal new static readonly NegatedDomainConstraintTreeVisitor<T_Variable, T_Element> Instance = new NegatedDomainConstraintTreeVisitor<T_Variable, T_Element>();
103 private NegatedDomainConstraintTreeVisitor()
107 internal override BoolExpr<DomainConstraint<T_Variable, T_Element>> VisitNot(NotExpr<DomainConstraint<T_Variable, T_Element>> expression)
109 return expression.Child.Accept(NonNegatedDomainConstraintTreeVisitor<T_Variable, T_Element>.Instance);
112 internal override BoolExpr<DomainConstraint<T_Variable, T_Element>> VisitTerm(TermExpr<DomainConstraint<T_Variable, T_Element>> expression)
114 return new TermExpr<DomainConstraint<T_Variable, T_Element>>(expression.Identifier.InvertDomainConstraint());