/// <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> /// Create a new partition /// </summary> /// <param name="symCard">The symbol alphabet cardinality</param> internal Partition(int symCard) { CharRange.Init(symCard); PartitionElement.Reset(); bSingletons = new BitArray(symCard); tSingletons = new TreeSet(); 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; } } } } }