//---------------------------------------------------------------------
//
// 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
{
///
/// Base class for clauses, which are (constrained) combinations of literals.
///
/// Type of normal form literal.
internal abstract class Clause : NormalFormNode
{
private readonly Set> _literals;
private readonly int _hashCode;
///
/// Initialize a new clause.
///
/// Literals contained in the clause.
/// Type of expression tree to produce from literals.
protected Clause(Set> literals, ExprType treeType)
: base(ConvertLiteralsToExpr(literals, treeType))
{
_literals = literals.AsReadOnly();
_hashCode = _literals.GetElementsHashCode();
}
///
/// Gets the literals contained in this clause.
///
internal Set> Literals
{
get { return _literals; }
}
// Given a collection of literals and a tree type, returns an expression of the given type.
private static BoolExpr ConvertLiteralsToExpr(Set> literals, ExprType treeType)
{
bool isAnd = ExprType.And == treeType;
Debug.Assert(isAnd || ExprType.Or == treeType);
IEnumerable> literalExpressions = literals.Select(
new Func, BoolExpr>(ConvertLiteralToExpression));
if (isAnd)
{
return new AndExpr(literalExpressions);
}
else
{
return new OrExpr(literalExpressions);
}
}
// Given a literal, returns its logical equivalent expression.
private static BoolExpr ConvertLiteralToExpression(Literal literal)
{
return literal.Expr;
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.Append("Clause{");
builder.Append(_literals);
return builder.Append("}").ToString();
}
public override int GetHashCode()
{
return _hashCode;
}
public override bool Equals(object obj)
{
Debug.Fail("call typed Equals");
return base.Equals(obj);
}
}
///
/// A DNF clause is of the form:
///
/// Literal1 . Literal2 . ...
///
/// Each literal is of the form:
///
/// Term
///
/// or
///
/// !Term
///
/// Type of normal form literal.
internal sealed class DnfClause : Clause,
IEquatable>
{
///
/// Initialize a DNF clause.
///
/// Literals in clause.
internal DnfClause(Set> literals)
: base(literals, ExprType.And)
{
}
public bool Equals(DnfClause other)
{
return null != other &&
other.Literals.SetEquals(Literals);
}
}
///
/// A CNF clause is of the form:
///
/// Literal1 + Literal2 . ...
///
/// Each literal is of the form:
///
/// Term
///
/// or
///
/// !Term
///
/// Type of normal form literal.
internal sealed class CnfClause : Clause,
IEquatable>
{
///
/// Initialize a CNF clause.
///
/// Literals in clause.
internal CnfClause(Set> literals)
: base(literals, ExprType.Or)
{
}
public bool Equals(CnfClause other)
{
return null != other &&
other.Literals.SetEquals(Literals);
}
}
}