Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Common / Utils / Boolean / DomainConstraint.cs
1 //---------------------------------------------------------------------
2 // <copyright file="DomainConstraint.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9
10 using System;
11 using System.Collections.Generic;
12 using System.Linq;
13 using System.Text;
14 using System.Diagnostics;
15
16 namespace System.Data.Common.Utils.Boolean
17 {
18     /// <summary>
19     /// Represents a variable with finite domain, e.g., c in {1, 2, 3}
20     /// </summary>
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>
24     {
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;
29
30         /// <summary>
31         /// Constructs a new domain variable.
32         /// </summary>
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)
37         {
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;
45         }
46         internal DomainVariable(T_Variable identifier, Set<T_Element> domain) : this(identifier, domain, null) { }
47
48         /// <summary>
49         /// Gets the variable.
50         /// </summary>
51         internal T_Variable Identifier { get { return _identifier; } }
52
53         /// <summary>
54         /// Gets the domain of this variable.
55         /// </summary>
56         internal Set<T_Element> Domain { get { return _domain; } }
57
58         public override int GetHashCode()
59         {
60             return _hashCode;
61         }
62
63         public override bool Equals(object obj)
64         {
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));
70         }
71
72         public override string ToString()
73         {
74             return StringUtil.FormatInvariant("{0}{{{1}}}",
75                 _identifier.ToString(), _domain);
76         }
77     }
78
79     /// <summary>
80     /// Represents a constraint of the form:
81     /// 
82     ///     Var1 in Range
83     /// </summary>
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>
87     {
88         private readonly DomainVariable<T_Variable, T_Element> _variable;
89         private readonly Set<T_Element> _range;
90         private readonly int _hashCode;
91
92         /// <summary>
93         /// Constructs a new constraint for the given variable and range.
94         /// </summary>
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)
98         {
99             Debug.Assert(null != variable && null != range);
100             _variable = variable;
101             _range = range.AsReadOnly();
102             _hashCode = _variable.GetHashCode() ^ _range.GetElementsHashCode();
103         }
104
105         /// <summary>
106         /// Constructor supporting a singleton range domain constraint
107         /// </summary>
108         internal DomainConstraint(DomainVariable<T_Variable, T_Element> variable, T_Element element)
109             : this(variable, new Set<T_Element>(new T_Element[] { element }).MakeReadOnly())
110         {
111         }
112
113         /// <summary>
114         /// Gets the variable for this constraint.
115         /// </summary>
116         internal DomainVariable<T_Variable, T_Element> Variable { get { return _variable; } }
117
118         /// <summary>
119         /// Get the range for this constraint.
120         /// </summary>
121         internal Set<T_Element> Range { get { return _range; } }
122
123         /// <summary>
124         /// Inverts this constraint (this iff. !result)
125         /// !(Var in Range) iff. Var in (Var.Domain - Range)
126         /// </summary>
127         /// <returns></returns>
128         internal DomainConstraint<T_Variable, T_Element> InvertDomainConstraint()
129         {
130             return new DomainConstraint<T_Variable, T_Element>(_variable,
131                 _variable.Domain.Difference(_range).AsReadOnly());
132         }
133
134         public override bool Equals(object obj)
135         {
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));
141         }
142
143         public override int GetHashCode()
144         {
145             return _hashCode;
146         }
147
148         public override string ToString()
149         {
150             return StringUtil.FormatInvariant("{0} in [{1}]",
151                 _variable, _range);
152         }
153     }
154 }