/// <summary>
        /// Create a new partition
        /// </summary>
        /// <param name="symCard">The symbol alphabet cardinality</param>
        internal Partition(int symCard, TaskState task)
        {
            this.myTask = task;
            CharRange.Init(symCard);
            PartitionElement.Reset();

            elements.Add(PartitionElement.AllChars());
        }
        /// <summary>
        /// Refine the current partition with respect
        /// to the given range literal "lit".
        /// </summary>
        /// <param name="lit">The Range Literal</param>
        internal void Refine(RangeLiteral lit)
        {
            int idx;
            int max = elements.Count; // because this varies inside the loop

            //
            // For each of the *current* elements of the partition do:
            //
            for (idx = 0; idx < max; idx++)
            {
                PartitionElement elem         = elements[idx];
                RangeList        intersection = lit.list.AND(elem.list);
                //
                // There are four cases here:
                // (1) No intersection of lit and elem ... do nothing
                // (2) Literal properly contains the partition element ...
                //     Add this element to the equivClasses list of this lit.
                //     Add this lit to the list of literals dependent on "elem".
                //     The intersection of other parts of the literal with other
                //     elements will be processed by other iterations of the loop.
                // (3) Literal is properly contained in the partition element ...
                //     Split the element into two: a new element containing the
                //     intersection, and an updated "elem" with the intersection
                //     subtracted. All literals dependent on the old element are
                //     now dependent on the new element and (the new version of)
                //     this element. The literal cannot overlap with any other
                //     element, so the iteration can be terminated.
                // (4) Literal partially overlaps the partition element ...
                //     Split the element as for case 2.  Overlaps of the rest
                //     of the literal with other elements will be dealt with by
                //     other iterations of the loop.
                //
                if (!intersection.IsEmpty) // not empty intersection
                {
                    // Test if elem is properly contained in lit
                    // If so, intersection == elem ...
                    if (intersection.EQU(elem.list))
                    {
                        elem.literals.Add(lit);
                        lit.equivClasses.Add(elem.ord);
                    }
                    else
                    {
                        PartitionElement newElem =
                            new PartitionElement(intersection.Ranges, false);
                        elements.Add(newElem);
                        lit.equivClasses.Add(newElem.ord);
                        newElem.literals.Add(lit);
                        //
                        //  We are about to split elem.
                        //  All literals that include elem
                        //  must now also include newElem
                        //
                        foreach (RangeLiteral rngLit in elem.literals)
                        {
                            rngLit.equivClasses.Add(newElem.ord);
                            newElem.literals.Add(rngLit);
                        }
                        elem.list = elem.list.SUB(intersection);
                        //
                        // Test if lit is a subset of elem
                        // If so, intersection == lit and we can
                        // assert that no other loop iteration has
                        // a non-empty intersection with this lit.
                        //
                        if (intersection.EQU(lit.list))
                        {
                            return;
                        }
                    }
                }
            }
        }