/// <summary> /// Split on a specific node. This gets a type and splits it into /// two subtypes. /// </summary> /// <param name="nodesInType"></param> /// <param name="typeParents"></param> /// <param name="node"></param> /// <returns></returns> public static SublatticeModification <T> SplitOn <T>(HashSet <LatticeNode <T> > nodesInType, HashSet <LatticeNode <T> > typeParents, LatticeNode <T> node) { //Debug.Assert(typeParents.Except(nodesInType).Count() == 0); HashSet <LatticeNode <T> > transitiveClosuresForNewType = AbstractColoredLattice <T> .GetTransitiveChildrenClosure(nodesInType, node); var modification = new SublatticeModification <T>() { Type = ModificationType.Split, Data = node, Before = new List <HashSet <LatticeNode <T> > >() { nodesInType }, BeforeParent = new List <HashSet <LatticeNode <T> > >() { typeParents }, After = new List <HashSet <LatticeNode <T> > >() { new HashSet <LatticeNode <T> >(nodesInType.Except(transitiveClosuresForNewType)), new HashSet <LatticeNode <T> >(transitiveClosuresForNewType) }, AfterParents = new List <HashSet <LatticeNode <T> > >() { new HashSet <LatticeNode <T> >(typeParents.Except(transitiveClosuresForNewType)), new HashSet <LatticeNode <T> >(transitiveClosuresForNewType.Where(n => typeParents.Contains(n) || n.Parents.Any(p => !transitiveClosuresForNewType.Contains(p))).Concat(new List <LatticeNode <T> >() { node })) } }; // Does this split a cycle? var parentCluster = modification.After[0]; var childrenCluster = modification.After[1]; Debug.Assert(parentCluster.Intersect(childrenCluster).Count() == 0); Debug.Assert(modification.AfterParents[0].Except(parentCluster).Count() == 0); Debug.Assert(modification.AfterParents[1].Except(childrenCluster).Count() == 0); var parClosure = AbstractColoredLattice <T> .GetTransitiveParentClosure(parentCluster); parClosure.IntersectWith(childrenCluster); if (parClosure.Count != 0) { return(null); // We are trying to split a circle } return(modification); }
protected static void ApplyModification(List <HashSet <LatticeNode <TData> > > currentColoring, List <HashSet <LatticeNode <TData> > > currentColoringParents, SublatticeModification <TData> modification) { for (int i = 0; i < modification.After.Count; i++) { Debug.Assert(modification.AfterParents[i].Except(modification.After[i]).Count() == 0); } var removed = true; foreach (var beforeType in modification.Before) { removed &= currentColoring.Remove(beforeType); } foreach (var beforeParents in modification.BeforeParent) { removed &= currentColoringParents.Remove(beforeParents); } Debug.Assert(removed); currentColoring.AddRange(modification.After); currentColoringParents.AddRange(modification.AfterParents); }