public override bool Equals(object obj)
        {
            if (Object.ReferenceEquals(this, obj))
            {
                return(true);
            }
            DomainConstraint <T_Variable, T_Element> other = obj as DomainConstraint <T_Variable, T_Element>;

            if (null == other)
            {
                return(false);
            }
            if (_hashCode != other._hashCode)
            {
                return(false);
            }
            return(_range.SetEquals(other._range) && _variable.Equals(other._variable));
        }
        internal override IEnumerable <LiteralVertexPair <DomainConstraint <T_Variable, T_Element> > > GetSuccessors(Vertex vertex)
        {
            InitializeInverseMap();
            var domainVariable = _inverseMap[vertex.Variable];

            // since vertex children are ordinally aligned with domain, handle domain as array
            var domain = domainVariable.Domain.ToArray();

            // foreach unique successor vertex, build up range
            Dictionary <Vertex, Set <T_Element> > vertexToRange = new Dictionary <Vertex, Set <T_Element> >();

            for (int i = 0; i < vertex.Children.Length; i++)
            {
                Vertex          successorVertex = vertex.Children[i];
                Set <T_Element> range;
                if (!vertexToRange.TryGetValue(successorVertex, out range))
                {
                    range = new Set <T_Element>(domainVariable.Domain.Comparer);
                    vertexToRange.Add(successorVertex, range);
                }
                range.Add(domain[i]);
            }

            foreach (var vertexRange in vertexToRange)
            {
                var successorVertex = vertexRange.Key;
                var range           = vertexRange.Value;

                // construct a DomainConstraint including the given range
                var constraint = new DomainConstraint <T_Variable, T_Element>(domainVariable, range.MakeReadOnly());
                var literal    = new Literal <DomainConstraint <T_Variable, T_Element> >(
                    new TermExpr <DomainConstraint <T_Variable, T_Element> >(constraint), true);

                yield return(new LiteralVertexPair <DomainConstraint <T_Variable, T_Element> >(successorVertex, literal));
            }
        }