1 //---------------------------------------------------------------------
2 // <copyright file="DomainConstraint.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System.Collections.Generic;
14 using System.Diagnostics;
16 namespace System.Data.Common.Utils.Boolean
19 /// Represents a variable with finite domain, e.g., c in {1, 2, 3}
21 /// <typeparam name="T_Element">Type of domain variables (int in the above example).</typeparam>
22 /// <typeparam name="T_Variable">Type of the identifier (c above -- it need not be int).</typeparam>
23 internal class DomainVariable<T_Variable, T_Element>
25 private readonly T_Variable _identifier;
26 private readonly Set<T_Element> _domain;
27 private readonly int _hashCode;
28 private readonly IEqualityComparer<T_Variable> _identifierComparer;
31 /// Constructs a new domain variable.
33 /// <param name="identifier">Identifier </param>
34 /// <param name="domain">Domain of variable.</param>
35 /// <param name="identifierComparer">Comparer of identifier</param>
36 internal DomainVariable(T_Variable identifier, Set<T_Element> domain, IEqualityComparer<T_Variable> identifierComparer)
38 Debug.Assert(null != identifier && null != domain);
39 _identifier = identifier;
40 _domain = domain.AsReadOnly();
41 _identifierComparer = identifierComparer ?? EqualityComparer<T_Variable>.Default;
42 int domainHashCode = _domain.GetElementsHashCode();
43 int identifierHashCode = _identifierComparer.GetHashCode(_identifier);
44 _hashCode = domainHashCode ^ identifierHashCode;
46 internal DomainVariable(T_Variable identifier, Set<T_Element> domain) : this(identifier, domain, null) { }
49 /// Gets the variable.
51 internal T_Variable Identifier { get { return _identifier; } }
54 /// Gets the domain of this variable.
56 internal Set<T_Element> Domain { get { return _domain; } }
58 public override int GetHashCode()
63 public override bool Equals(object obj)
65 if (Object.ReferenceEquals(this, obj)) { return true; }
66 DomainVariable<T_Variable, T_Element> other = obj as DomainVariable<T_Variable, T_Element>;
67 if (null == other) { return false; }
68 if (_hashCode != other._hashCode) { return false; }
69 return (_identifierComparer.Equals(_identifier, other._identifier) && _domain.SetEquals(other._domain));
72 public override string ToString()
74 return StringUtil.FormatInvariant("{0}{{{1}}}",
75 _identifier.ToString(), _domain);
80 /// Represents a constraint of the form:
84 /// <typeparam name="T_Element">Type of range elements.</typeparam>
85 /// <typeparam name="T_Variable">Type of the variable.</typeparam>
86 internal class DomainConstraint<T_Variable, T_Element>
88 private readonly DomainVariable<T_Variable, T_Element> _variable;
89 private readonly Set<T_Element> _range;
90 private readonly int _hashCode;
93 /// Constructs a new constraint for the given variable and range.
95 /// <param name="variable">Variable in constraint.</param>
96 /// <param name="range">Range of constraint.</param>
97 internal DomainConstraint(DomainVariable<T_Variable, T_Element> variable, Set<T_Element> range)
99 Debug.Assert(null != variable && null != range);
100 _variable = variable;
101 _range = range.AsReadOnly();
102 _hashCode = _variable.GetHashCode() ^ _range.GetElementsHashCode();
106 /// Constructor supporting a singleton range domain constraint
108 internal DomainConstraint(DomainVariable<T_Variable, T_Element> variable, T_Element element)
109 : this(variable, new Set<T_Element>(new T_Element[] { element }).MakeReadOnly())
114 /// Gets the variable for this constraint.
116 internal DomainVariable<T_Variable, T_Element> Variable { get { return _variable; } }
119 /// Get the range for this constraint.
121 internal Set<T_Element> Range { get { return _range; } }
124 /// Inverts this constraint (this iff. !result)
125 /// !(Var in Range) iff. Var in (Var.Domain - Range)
127 /// <returns></returns>
128 internal DomainConstraint<T_Variable, T_Element> InvertDomainConstraint()
130 return new DomainConstraint<T_Variable, T_Element>(_variable,
131 _variable.Domain.Difference(_range).AsReadOnly());
134 public override bool Equals(object obj)
136 if (Object.ReferenceEquals(this, obj)) { return true; }
137 DomainConstraint<T_Variable, T_Element> other = obj as DomainConstraint<T_Variable, T_Element>;
138 if (null == other) { return false; }
139 if (_hashCode != other._hashCode) { return false; }
140 return (_range.SetEquals(other._range) && _variable.Equals(other._variable));
143 public override int GetHashCode()
148 public override string ToString()
150 return StringUtil.FormatInvariant("{0} in [{1}]",