//--------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Text; using System.Globalization; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; namespace System.Data.Common.Utils.Boolean { /// /// Abstract base class for nodes in normal form expressions, e.g. Conjunctive Normal Form /// sentences. /// /// Type of expression leaf term identifiers. internal abstract class NormalFormNode { private readonly BoolExpr _expr; /// /// Initialize a new normal form node representing the given expression. Caller must /// ensure the expression is logically equivalent to the node. /// /// Expression logically equivalent to this node. protected NormalFormNode(BoolExpr expr) { _expr = expr.Simplify(); } /// /// Gets an expression that is logically equivalent to this node. /// internal BoolExpr Expr { get { return _expr; } } /// /// Utility method for delegation that return the expression corresponding to a given /// normal form node. /// /// Type of node /// Node to examine. /// Equivalent Boolean expression for the given node. protected static BoolExpr ExprSelector(T_NormalFormNode node) where T_NormalFormNode : NormalFormNode { return node._expr; } } /// /// Abstract base class for normal form sentences (CNF and DNF) /// /// Type of expression leaf term identifiers. /// Type of clauses in the sentence. internal abstract class Sentence : NormalFormNode where T_Clause : Clause, IEquatable { private readonly Set _clauses; /// /// Initialize a sentence given the appropriate sentence clauses. Produces /// an equivalent expression by composing the clause expressions using /// the given tree type. /// /// Sentence clauses /// Tree type for sentence (and generated expression) protected Sentence(Set clauses, ExprType treeType) : base(ConvertClausesToExpr(clauses, treeType)) { _clauses = clauses.AsReadOnly(); } // Produces an expression equivalent to the given clauses by composing the clause // expressions using the given tree type. private static BoolExpr ConvertClausesToExpr(Set clauses, ExprType treeType) { bool isAnd = ExprType.And == treeType; Debug.Assert(isAnd || ExprType.Or == treeType); IEnumerable> clauseExpressions = clauses.Select(new Func>(ExprSelector)); if (isAnd) { return new AndExpr(clauseExpressions); } else { return new OrExpr(clauseExpressions); } } public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append("Sentence{"); builder.Append(_clauses); return builder.Append("}").ToString(); } } /// /// Represents a sentence in disjunctive normal form, e.g.: /// /// Clause1 + Clause2 . ... /// /// Where each DNF clause is of the form: /// /// Literal1 . Literal2 . ... /// /// Each literal is of the form: /// /// Term /// /// or /// /// !Term /// /// Type of expression leaf term identifiers. internal sealed class DnfSentence : Sentence> { // Initializes a new DNF sentence given its clauses. internal DnfSentence(Set> clauses) : base(clauses, ExprType.Or) { } } /// /// Represents a sentence in conjunctive normal form, e.g.: /// /// Clause1 . Clause2 . ... /// /// Where each DNF clause is of the form: /// /// Literal1 + Literal2 + ... /// /// Each literal is of the form: /// /// Term /// /// or /// /// !Term /// /// Type of expression leaf term identifiers. internal sealed class CnfSentence : Sentence> { // Initializes a new CNF sentence given its clauses. internal CnfSentence(Set> clauses) : base(clauses, ExprType.And) { } } }