1 //---------------------------------------------------------------------
2 // <copyright file="Clause.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 //---------------------------------------------------------------------
11 using System.Collections.Generic;
13 using System.Globalization;
14 using System.Collections.ObjectModel;
15 using System.Diagnostics;
18 namespace System.Data.Common.Utils.Boolean
21 /// Base class for clauses, which are (constrained) combinations of literals.
23 /// <typeparam name="T_Identifier">Type of normal form literal.</typeparam>
24 internal abstract class Clause<T_Identifier> : NormalFormNode<T_Identifier>
26 private readonly Set<Literal<T_Identifier>> _literals;
27 private readonly int _hashCode;
30 /// Initialize a new clause.
32 /// <param name="literals">Literals contained in the clause.</param>
33 /// <param name="treeType">Type of expression tree to produce from literals.</param>
34 protected Clause(Set<Literal<T_Identifier>> literals, ExprType treeType)
35 : base(ConvertLiteralsToExpr(literals, treeType))
37 _literals = literals.AsReadOnly();
38 _hashCode = _literals.GetElementsHashCode();
42 /// Gets the literals contained in this clause.
44 internal Set<Literal<T_Identifier>> Literals
46 get { return _literals; }
49 // Given a collection of literals and a tree type, returns an expression of the given type.
50 private static BoolExpr<T_Identifier> ConvertLiteralsToExpr(Set<Literal<T_Identifier>> literals, ExprType treeType)
52 bool isAnd = ExprType.And == treeType;
53 Debug.Assert(isAnd || ExprType.Or == treeType);
55 IEnumerable<BoolExpr<T_Identifier>> literalExpressions = literals.Select(
56 new Func<Literal<T_Identifier>, BoolExpr<T_Identifier>>(ConvertLiteralToExpression));
60 return new AndExpr<T_Identifier>(literalExpressions);
64 return new OrExpr<T_Identifier>(literalExpressions);
68 // Given a literal, returns its logical equivalent expression.
69 private static BoolExpr<T_Identifier> ConvertLiteralToExpression(Literal<T_Identifier> literal)
74 public override string ToString()
76 StringBuilder builder = new StringBuilder();
77 builder.Append("Clause{");
78 builder.Append(_literals);
79 return builder.Append("}").ToString();
82 public override int GetHashCode()
87 public override bool Equals(object obj)
89 Debug.Fail("call typed Equals");
90 return base.Equals(obj);
95 /// A DNF clause is of the form:
97 /// Literal1 . Literal2 . ...
99 /// Each literal is of the form:
107 /// <typeparam name="T_Identifier">Type of normal form literal.</typeparam>
108 internal sealed class DnfClause<T_Identifier> : Clause<T_Identifier>,
109 IEquatable<DnfClause<T_Identifier>>
112 /// Initialize a DNF clause.
114 /// <param name="literals">Literals in clause.</param>
115 internal DnfClause(Set<Literal<T_Identifier>> literals)
116 : base(literals, ExprType.And)
120 public bool Equals(DnfClause<T_Identifier> other)
122 return null != other &&
123 other.Literals.SetEquals(Literals);
128 /// A CNF clause is of the form:
130 /// Literal1 + Literal2 . ...
132 /// Each literal is of the form:
140 /// <typeparam name="T_Identifier">Type of normal form literal.</typeparam>
141 internal sealed class CnfClause<T_Identifier> : Clause<T_Identifier>,
142 IEquatable<CnfClause<T_Identifier>>
145 /// Initialize a CNF clause.
147 /// <param name="literals">Literals in clause.</param>
148 internal CnfClause(Set<Literal<T_Identifier>> literals)
149 : base(literals, ExprType.Or)
153 public bool Equals(CnfClause<T_Identifier> other)
155 return null != other &&
156 other.Literals.SetEquals(Literals);