From: <mcu...@us...> - 2007-08-15 01:37:12
|
Revision: 1083 http://orm.svn.sourceforge.net/orm/?rev=1083&view=rev Author: mcurland Date: 2007-08-14 18:37:14 -0700 (Tue, 14 Aug 2007) Log Message: ----------- Various further tweaks to ORM/OIAL Bridge. refs #327 Modified Paths: -------------- trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs Modified: trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs =================================================================== --- trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs 2007-08-15 01:06:22 UTC (rev 1082) +++ trunk/Oial/ORMOialBridge/ORMOialBridgePermuter.cs 2007-08-15 01:37:14 UTC (rev 1083) @@ -10,35 +10,37 @@ namespace Neumont.Tools.ORMToORMAbstractionBridge { #region Chain calculator - sealed class UndecidedMappingChains + sealed class FactTypeChainer { - private readonly FactTypeMappingListDictionary myUndecided; + private readonly FactTypeMappingDictionary myPredecidedManyToOneFactTypeMappings; private readonly FactTypeMappingDictionary myPredecidedOneToOneFactTypeMappings; + private readonly FactTypeMappingListDictionary myUndecidedOneToOneFactTypeMappings; private readonly ChainList myChains; - public UndecidedMappingChains(FactTypeMappingListDictionary undecided, FactTypeMappingDictionary predecidedOneToOneFactTypeMappings) + public FactTypeChainer(FactTypeMappingDictionary predecidedManyToOneFactTypeMappings, FactTypeMappingDictionary predecidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings) { myChains = new ChainList(); - myUndecided = undecided; + + myPredecidedManyToOneFactTypeMappings = predecidedManyToOneFactTypeMappings; myPredecidedOneToOneFactTypeMappings = predecidedOneToOneFactTypeMappings; + myUndecidedOneToOneFactTypeMappings = undecidedOneToOneFactTypeMappings; } public int Run() { BuildChains(); - //DeleteEmptyChains(); // Delete empty chains and find the largest chain. int largestChainCount = 0; for (int i = myChains.Count - 1; i >= 0; i--) { Chain chain = myChains[i]; - if (chain.UndecidedFactTypeMappings.Count <= 0) + if (chain.UndecidedOneToOneFactTypeMappings.Count <= 0) { myChains.RemoveAt(i); continue; } - int chainCount = chain.FactTypeCount; + int chainCount = chain.OneToOneFactTypeCount; if (chainCount > largestChainCount) { largestChainCount = chainCount; @@ -55,13 +57,13 @@ private void BuildChains() { - int factTypesCount = myUndecided.Count + myPredecidedOneToOneFactTypeMappings.Count; + int factTypesCount = myUndecidedOneToOneFactTypeMappings.Count + myPredecidedOneToOneFactTypeMappings.Count; Dictionary<FactType, object> visitedFactTypes = new Dictionary<FactType, object>(factTypesCount); Dictionary<ObjectType, object> visitedObjectTypes = new Dictionary<ObjectType, object>(factTypesCount * 2); FactTypeMappingDictionary.Enumerator predecidedEnumerator = myPredecidedOneToOneFactTypeMappings.GetEnumerator(); - FactTypeMappingListDictionary.Enumerator undecidedEnumerator = myUndecided.GetEnumerator(); + FactTypeMappingListDictionary.Enumerator undecidedEnumerator = myUndecidedOneToOneFactTypeMappings.GetEnumerator(); while (true) { KeyValuePair<FactType, FactTypeMapping> predecidedPair; @@ -92,7 +94,7 @@ } } - // We're following a new path, so clear the current dictionary. + // We've found a new path, so create a chain for it. Chain chain = new Chain(); myChains.Add(chain); @@ -120,14 +122,18 @@ FactTypeMapping mapping; FactTypeMappingList mappingList; - if (myUndecided.TryGetValue(factType, out mappingList)) + if (myUndecidedOneToOneFactTypeMappings.TryGetValue(factType, out mappingList)) { - chain.UndecidedFactTypeMappings.Add(mappingList); + chain.UndecidedOneToOneFactTypeMappings.Add(mappingList); } else if (myPredecidedOneToOneFactTypeMappings.TryGetValue(factType, out mapping)) { chain.PredecidedOneToOneFactTypeMappings.Add(mapping); } + else if (myPredecidedManyToOneFactTypeMappings.TryGetValue(factType, out mapping)) + { + chain.PredecidedManyToOneFactTypeMappings.Add(mapping); + } else { continue; @@ -146,12 +152,15 @@ } } #endregion + #region FactTypeMappingPermuter sealed class FactTypeMappingPermuter { + private readonly FactTypeMappingDictionary myPredecidedManyToOneFactTypeMappings; + private readonly FactTypeMappingDictionary myPredecidedOneToOneFactTypeMappings; + private readonly FactTypeMappingListDictionary myUndecidedOneToOneFactTypeMappings; + private readonly FactTypeMappingDictionary myDecidedFactTypeMappings; - private readonly FactTypeMappingDictionary myDecidedOneToOneFactTypeMappings; - private readonly FactTypeMappingListDictionary myUndecidedFactTypeMappings; // Stores a list of object types that had been considered valid top-level, but was later found to be deeply mapped away private readonly ObjectTypeDictionary myInvalidObjectTypes; @@ -161,61 +170,45 @@ private readonly ObjectTypeDictionary myPossibleConceptTypes; - public FactTypeMappingPermuter(FactTypeMappingDictionary decidedFactTypeMappings, FactTypeMappingListDictionary undecidedFactTypeMappings) + public FactTypeMappingPermuter(FactTypeMappingDictionary predecidedManyToOneFactTypeMappings, FactTypeMappingDictionary predecidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings) { - myDecidedFactTypeMappings = decidedFactTypeMappings; - myUndecidedFactTypeMappings = undecidedFactTypeMappings; + myPredecidedManyToOneFactTypeMappings = predecidedManyToOneFactTypeMappings; + myPredecidedOneToOneFactTypeMappings = predecidedOneToOneFactTypeMappings; + myUndecidedOneToOneFactTypeMappings = undecidedOneToOneFactTypeMappings; - myDecidedOneToOneFactTypeMappings = new FactTypeMappingDictionary(myDecidedFactTypeMappings.Count); + int oneToOneFactTypeCount = predecidedOneToOneFactTypeMappings.Count + undecidedOneToOneFactTypeMappings.Count; + myDecidedFactTypeMappings = new FactTypeMappingDictionary(predecidedManyToOneFactTypeMappings.Count + oneToOneFactTypeCount); + foreach (KeyValuePair<FactType, FactTypeMapping> pair in predecidedManyToOneFactTypeMappings) + { + myDecidedFactTypeMappings.Add(pair.Key, pair.Value); + } + foreach (KeyValuePair<FactType, FactTypeMapping> pair in predecidedOneToOneFactTypeMappings) + { + myDecidedFactTypeMappings.Add(pair.Key, pair.Value); + } + // Stores a list of object types that had been considered valid top-level, but was later found to be deeply mapped away - myInvalidObjectTypes = new ObjectTypeDictionary(myDecidedFactTypeMappings.Count); - myPossibleTopLevelConceptTypes = new ObjectTypeDictionary(myDecidedFactTypeMappings.Count); - myPossibleConceptTypes = new ObjectTypeDictionary(myDecidedFactTypeMappings.Count); + myInvalidObjectTypes = new ObjectTypeDictionary(oneToOneFactTypeCount); + myPossibleTopLevelConceptTypes = new ObjectTypeDictionary(oneToOneFactTypeCount); + myPossibleConceptTypes = new ObjectTypeDictionary(oneToOneFactTypeCount); } /// <summary> /// Runs the permuter, and adds the final decided mapping to the decidedFactTypeMappings dictionary specified when this instance was constructed. /// </summary> - public void Run() + public FactTypeMappingDictionary Run() { - FindDecidedOneToOneMappings(); - PermuteFactTypeMappings(); + return myDecidedFactTypeMappings; } - private void FindDecidedOneToOneMappings() - { - FactTypeMapping mapping; - Role firstRole; - Role secondRole; - UniquenessConstraint firstRoleUniquenessConstraint; - UniquenessConstraint secondRoleUniquenessConstraint; - bool firstRoleIsUnique; - bool secondRoleIsUnique; - foreach (KeyValuePair<FactType, FactTypeMapping> pair in myDecidedFactTypeMappings) - { - mapping = pair.Value; - firstRole = mapping.FromRole; - secondRole = mapping.TowardsRole; - firstRoleUniquenessConstraint = (UniquenessConstraint)firstRole.SingleRoleAlethicUniquenessConstraint; - secondRoleUniquenessConstraint = (UniquenessConstraint)secondRole.SingleRoleAlethicUniquenessConstraint; - firstRoleIsUnique = (firstRoleUniquenessConstraint != null); - secondRoleIsUnique = (secondRoleUniquenessConstraint != null); - - if (firstRoleIsUnique && secondRoleIsUnique) - { - myDecidedOneToOneFactTypeMappings.Add(pair.Key, pair.Value); - } - } - } - private void PermuteFactTypeMappings() { int largestChainCount; - // Break up the chains of contiguous undecided fact types - UndecidedMappingChains chains = new UndecidedMappingChains(myUndecidedFactTypeMappings, myDecidedOneToOneFactTypeMappings); - largestChainCount = chains.Run(); + // Break up the chains of contiguous one-to-one fact types + FactTypeChainer chainer = new FactTypeChainer(myPredecidedManyToOneFactTypeMappings, myPredecidedOneToOneFactTypeMappings, myUndecidedOneToOneFactTypeMappings); + largestChainCount = chainer.Run(); // Perform one-time pass of top-level types for the decided mappings PrecalculateDecidedConceptTypes(); @@ -227,7 +220,7 @@ Dictionary<ObjectType, object> deeplyMappedObjectTypes = new Dictionary<ObjectType, object>(largestChainCount); // Loop through each chain, calculating the permutations. - foreach (Chain chain in chains.Chains) + foreach (Chain chain in chainer.Chains) { // Find the object types that we already know have deep mappings away from them. foreach (FactTypeMapping decidedMapping in chain.PredecidedOneToOneFactTypeMappings) @@ -240,9 +233,9 @@ // UNDONE: Eventually we should actually check this and warn the user if it would take too long on their machine. // This would need to be calculated, though. A hard-coded limit wouldn't be appropriate here. - //int maxPermutations = CalculateMaxNumberOfPermutations(chain.UndecidedFactTypeMappings); + //int maxPermutations = CalculateMaxNumberOfPermutations(chain.UndecidedOneToOneFactTypeMappings); - PermuteFactTypeMappings(chain.PossiblePermutations, chain.UndecidedFactTypeMappings, newlyDecidedFactTypeMappings, deeplyMappedObjectTypes, 0); + PermuteFactTypeMappings(chain.PossiblePermutations, chain.UndecidedOneToOneFactTypeMappings, newlyDecidedFactTypeMappings, deeplyMappedObjectTypes, 0); EliminateInvalidPermutations(chain); CalculateTopLevelConceptTypes(chain); @@ -259,6 +252,7 @@ private static FactTypeMapping FindDeepMappingAwayFromObjectType(ObjectType objectType, FactTypeMappingList predecidedOneToOneFactTypeMappings, FactTypeMappingList permutationFactTypeMappings) { + // UNDONE: Figure out a way we can do this off of PlayedRoles instead, which should be faster. foreach (FactTypeMapping mapping in predecidedOneToOneFactTypeMappings) { if (mapping.MappingDepth == MappingDepth.Deep && mapping.FromObjectType == objectType) @@ -300,7 +294,7 @@ /// 2. It is a subtype, or /// 3. Another object type (B) is mapped to it, and /// a. There exists a role being mapped to object type A on which there are no constraints, or - /// b. There exists a role being mapped to object type A on which there is a uniqueness that is not preferred. + /// b. There exists a role being mapped to object type A on which there is not a preferred uniqueness. /// /// A concept type is a top-level concept type when: /// 1. It is not deeply mapped towards any other concept type. @@ -374,9 +368,6 @@ /// <param name="chain"></param> private void CalculateTopLevelConceptTypes(Chain chain) { -#if PERMUTATION_DEBUG_OUTPUT - DateTime start = DateTime.Now; -#endif // The smallest overall mapping that we've found int smallest = int.MaxValue; // These dictionaries track the OTs that are temporarily removed or added for each permutation in the list @@ -437,32 +428,6 @@ myPossibleConceptTypes.Remove(ot); } } -#if PERMUTATION_DEBUG_OUTPUT - DateTime endat = DateTime.Now; - // Output values to a file - StreamWriter s = new StreamWriter("output_combinations.txt"); - s.WriteLine("Smallest mapping: " + smallest.ToString()); - s.WriteLine("# calculated as smallest (efficiency): " + mySmallestPermutationsList.Count); - s.WriteLine("Time: " + endat.Subtract(start).ToString()); - /* - int p = 0; - foreach (FinalMappingState state in smallestList) - { - p++; - sw.WriteLine("\t" + p.ToString() + " (" + state.TopLevelConceptTypes.ToString() + " TLCTs)"); - foreach (KeyValuePair<FactType, FactTypeMapping> pair in myDecidedFactTypeMappings) - { - FactTypeMapping mapping = pair.Value; - s.WriteLine("\t\t" + mapping.FromObjectType.ToString() + " to " + mapping.TowardsObjectType.ToString() + " (" + mapping.MappingType.ToString() + ")"); - } - foreach (DecidedMappingStateEntry mapping in state.Mappings) - { - s.WriteLine("\t\t" + mapping.Mapping.FromObjectType.ToString() + " to " + mapping.Mapping.TowardsObjectType.ToString() + " (" + mapping.Mapping.MappingType.ToString() + ")"); - } - } - */ - s.Close(); -#endif } /// <summary> @@ -537,9 +502,9 @@ /// </param> private static void EliminateInvalidPermutations(Chain chain) { - Debug.Assert(chain.UndecidedFactTypeMappings.Count > 0); + Debug.Assert(chain.UndecidedOneToOneFactTypeMappings.Count > 0); - int factTypeCount = chain.FactTypeCount; + int factTypeCount = chain.OneToOneFactTypeCount; FactTypeMappingList predecidedOneToOneFactTypeMappings = chain.PredecidedOneToOneFactTypeMappings; PermutationList possiblePermutations = chain.PossiblePermutations; @@ -624,4 +589,4 @@ } } #endregion -} \ No newline at end of file +} Modified: trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs =================================================================== --- trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs 2007-08-15 01:06:22 UTC (rev 1082) +++ trunk/Oial/ORMOialBridge/ORMOialBridgeStructures.cs 2007-08-15 01:37:14 UTC (rev 1083) @@ -287,31 +287,44 @@ [Serializable] sealed class Chain { + private readonly FactTypeMappingList myPredecidedManyToOneFactTypeMappings; private readonly FactTypeMappingList myPredecidedOneToOneFactTypeMappings; - private readonly FactTypeMappingListList myUndecidedFactTypeMappings; + private readonly FactTypeMappingListList myUndecidedOneToOneFactTypeMappings; private readonly PermutationList myPossiblePermutations; private readonly PermutationList mySmallestPermutations; public Chain() { + myPredecidedManyToOneFactTypeMappings = new FactTypeMappingList(); myPredecidedOneToOneFactTypeMappings = new FactTypeMappingList(); - myUndecidedFactTypeMappings = new FactTypeMappingListList(); + myUndecidedOneToOneFactTypeMappings = new FactTypeMappingListList(); myPossiblePermutations = new PermutationList(); mySmallestPermutations = new PermutationList(); } /// <summary> - /// Returns the number of FactTypes in this Chain. + /// Returns the number of one-to-one FactTypes in this Chain. /// </summary> - public int FactTypeCount + public int OneToOneFactTypeCount { get { - return myPredecidedOneToOneFactTypeMappings.Count + myUndecidedFactTypeMappings.Count; + return myPredecidedOneToOneFactTypeMappings.Count + myUndecidedOneToOneFactTypeMappings.Count; } } /// <summary> + /// Many-to-one FactTypeMappings that are part of this chain but were decided before the permutation phase. + /// </summary> + public FactTypeMappingList PredecidedManyToOneFactTypeMappings + { + get + { + return myPredecidedManyToOneFactTypeMappings; + } + } + + /// <summary> /// One-to-one FactTypeMappings that are part of this chain but were decided before the permutation phase. /// </summary> public FactTypeMappingList PredecidedOneToOneFactTypeMappings @@ -323,11 +336,11 @@ } /// <summary> - /// The potential mappings of the undecided FactTypes that are in this Chain. + /// The potential mappings of the undecided one-to-one FactTypes that are in this Chain. /// </summary> - public FactTypeMappingListList UndecidedFactTypeMappings + public FactTypeMappingListList UndecidedOneToOneFactTypeMappings { - get { return myUndecidedFactTypeMappings; } + get { return myUndecidedOneToOneFactTypeMappings; } } /// <summary> Modified: trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs =================================================================== --- trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-08-15 01:06:22 UTC (rev 1082) +++ trunk/Oial/ORMOialBridge/OialModelIsForORMModel.cs 2007-08-15 01:37:14 UTC (rev 1083) @@ -183,16 +183,18 @@ private void TransformORMtoOial() { ORMModel model = this.ORMModel; - FactTypeMappingDictionary decidedFactTypeMappings = null; - FactTypeMappingListDictionary undecidedFactTypeMappings = null; LinkedElementCollection<FactType> modelFactTypes = model.FactTypeCollection; - InitialFactTypeMappings(modelFactTypes, out decidedFactTypeMappings, out undecidedFactTypeMappings); - FilterFactTypeMappings(decidedFactTypeMappings, undecidedFactTypeMappings); + FactTypeMappingDictionary decidedManyToOneFactTypeMappings = new FactTypeMappingDictionary(); + FactTypeMappingDictionary decidedOneToOneFactTypeMappings = new FactTypeMappingDictionary(); + FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings = new FactTypeMappingListDictionary(); - FactTypeMappingPermuter permuter = new FactTypeMappingPermuter(decidedFactTypeMappings, undecidedFactTypeMappings); - permuter.Run(); + PerformInitialFactTypeMappings(modelFactTypes, decidedManyToOneFactTypeMappings, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings); + FilterFactTypeMappings(decidedManyToOneFactTypeMappings, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings); + FactTypeMappingPermuter permuter = new FactTypeMappingPermuter(decidedManyToOneFactTypeMappings, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings); + FactTypeMappingDictionary decidedFactTypeMappings = permuter.Run(); + GenerateOialModel(decidedFactTypeMappings); } @@ -200,13 +202,11 @@ /// Determines the obvious fact type mappings, and all other potential mappings. /// </summary> /// <param name="modelFactTypes">The <see cref="FactType"/> objects of the model</param> - /// <param name="decidedFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param> - /// <param name="undecidedFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param> - private void InitialFactTypeMappings(IList<FactType> modelFactTypes, out FactTypeMappingDictionary decidedFactTypeMappings, out FactTypeMappingListDictionary undecidedFactTypeMappings) + /// <param name="decidedManyToOneFactTypeMappings">The decided many-to-one <see cref="FactTypeMapping"/> objects.</param> + /// <param name="decidedOneToOneFactTypeMappings">The decided one-to-one <see cref="FactTypeMapping"/> objects.</param> + /// <param name="undecidedOneToOneFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param> + private void PerformInitialFactTypeMappings(LinkedElementCollection<FactType> modelFactTypes, FactTypeMappingDictionary decidedManyToOneFactTypeMappings, FactTypeMappingDictionary decidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings) { - decidedFactTypeMappings = new FactTypeMappingDictionary(); - undecidedFactTypeMappings = new FactTypeMappingListDictionary(); - // For each fact type in the model... foreach (FactType factType in modelFactTypes) { @@ -225,7 +225,7 @@ // Map deeply toward the supertype. FactTypeMapping factTypeMapping = new FactTypeMapping(subtypeFact, subtypeRole, supertypeRole, MappingDepth.Deep); - decidedFactTypeMappings.Add(subtypeFact, factTypeMapping); + decidedOneToOneFactTypeMappings.Add(subtypeFact, factTypeMapping); } else { @@ -242,28 +242,31 @@ bool firstRoleIsUnique = (firstRoleUniquenessConstraint != null); bool secondRoleIsUnique = (secondRoleUniquenessConstraint != null); + // We don't need to worry about shallow mappings towards preferred identifiers on many-to-ones, since the preferred + // identifier pattern ensures that these cases will always map towards the object type being identified anyway. + // If only firstRole is unique... if (firstRoleIsUnique && !secondRoleIsUnique) { // Shallow map toward firstRolePlayer. FactTypeMapping factTypeMapping = new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow); - decidedFactTypeMappings.Add(factType, factTypeMapping); + decidedManyToOneFactTypeMappings.Add(factType, factTypeMapping); } else if (!firstRoleIsUnique && secondRoleIsUnique) // ...only secondRole is unique... { // Shallow map toward secondRolePlayer. FactTypeMapping factTypeMapping = new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow); - decidedFactTypeMappings.Add(factType, factTypeMapping); + decidedManyToOneFactTypeMappings.Add(factType, factTypeMapping); } else if (firstRoleIsUnique && secondRoleIsUnique) // ...both roles are unique... { - bool firstRoleIsMandatory = null != firstRole.SingleRoleAlethicMandatoryConstraint; - bool secondRoleIsMandatory = null != secondRole.SingleRoleAlethicMandatoryConstraint; + bool firstRoleIsMandatory = (firstRole.SingleRoleAlethicMandatoryConstraint != null); + bool secondRoleIsMandatory = (secondRole.SingleRoleAlethicMandatoryConstraint != null); // If this is a ring fact type... - if (firstRolePlayer.Id == secondRolePlayer.Id) + if (firstRolePlayer == secondRolePlayer) { // If only firstRole is mandatory... if (firstRoleIsMandatory && !secondRoleIsMandatory) @@ -271,60 +274,88 @@ // Shallow map toward firstRolePlayer (mandatory role player). FactTypeMapping factTypeMapping = new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow); - decidedFactTypeMappings.Add(factType, factTypeMapping); + decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping); } else if (!firstRoleIsMandatory && secondRoleIsMandatory) // ...only secondRole is mandatory... { // Shallow map toward secondRolePlayer (mandatory role player). FactTypeMapping factTypeMapping = new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow); - decidedFactTypeMappings.Add(factType, factTypeMapping); + decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping); } else // ...otherwise... { // Shallow map toward firstRolePlayer. FactTypeMapping factTypeMapping = new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow); - decidedFactTypeMappings.Add(factType, factTypeMapping); + decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping); } } else // ...not a ring fact type... { + // These are used to make sure that we never shallowly map towards a preferred identifier. + bool firstRoleIsUniqueAndPreferred = firstRoleIsUnique && firstRoleUniquenessConstraint.IsPreferred; + bool secondRoleIsUniqueAndPreferred = secondRoleIsUnique && secondRoleUniquenessConstraint.IsPreferred; + FactTypeMappingList potentialFactTypeMappings = new FactTypeMappingList(); // If neither role is mandatory... - if (!(firstRoleIsMandatory || secondRoleIsMandatory)) + if (!firstRoleIsMandatory && !secondRoleIsMandatory) { - // Shallow map toward firstRolePlayer. - potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow)); - // Shallow map toward secondRolePlayer. - potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow)); + // If firstRole is not preferred... + if (!firstRoleIsUniqueAndPreferred) + { + // Shallow map toward firstRolePlayer. + potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow)); + } + + // If seccondRole is not preferred... + if (!secondRoleIsUniqueAndPreferred) + { + // Shallow map toward secondRolePlayer. + potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow)); + } } - // If exactly one role is mandatory, we only allow shallow towards that role or deep away from it. - // This is an optimization, but at this point I don't remember with 100% confidence that it is correct. - // -Kevin else if (firstRoleIsMandatory && !secondRoleIsMandatory) // ...only firstRole is mandatory... { - // Shallow map toward firstRolePlayer. - potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow)); + // If firstRole is not preferred... + if (!firstRoleIsUniqueAndPreferred) + { + // Shallow map toward firstRolePlayer. + potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow)); + } + + // If seccondRole is not preferred... + if (!secondRoleIsUniqueAndPreferred) + { + // Shallow map toward secondRolePlayer. + potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow)); + } + // Deep map toward secondRolePlayer. potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Deep)); } else if (!firstRoleIsMandatory && secondRoleIsMandatory) // ...only secondRole is mandatory... { + // If firstRole is not preferred... + if (!firstRoleIsUniqueAndPreferred) + { + // Shallow map toward firstRolePlayer. + potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Shallow)); + } + // Deep map toward firstRolePlayer. potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Deep)); - // Shallow map toward secondRolePlayer. - potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow)); + + // If seccondRole is not preferred... + if (!secondRoleIsUniqueAndPreferred) + { + // Shallow map toward secondRolePlayer. + potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Shallow)); + } } else // ...both roles are mandatory... { - bool firstRoleIsUniqueAndPreferred = firstRoleIsUnique && firstRoleUniquenessConstraint.IsPreferred; - bool secondRoleIsUniqueAndPreferred = secondRoleIsUnique && secondRoleUniquenessConstraint.IsPreferred; - - // We do this to make sure that we never shallowly map towards a preferred identifier. - // UNDONE: Should we be doing this for the less-than-two mandatories cases as well? -Kevin - // If firstRole is not preferred... if (!firstRoleIsUniqueAndPreferred) { @@ -341,11 +372,20 @@ // Deep map toward firstRolePlayer. potentialFactTypeMappings.Add(new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Deep)); + // Deep map toward secondRolePlayer. potentialFactTypeMappings.Add(new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Deep)); } - undecidedFactTypeMappings.Add(factType, potentialFactTypeMappings); + Debug.Assert(potentialFactTypeMappings.Count > 0); + if (potentialFactTypeMappings.Count == 1) + { + decidedOneToOneFactTypeMappings.Add(factType, potentialFactTypeMappings[0]); + } + else + { + undecidedOneToOneFactTypeMappings.Add(factType, potentialFactTypeMappings); + } } } } @@ -355,16 +395,17 @@ /// <summary> /// Runs various algorithms on the undecided fact type mappings in an attempt to decide as many as possible. /// </summary> - /// <param name="decidedFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param> - /// <param name="undecidedFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param> - private void FilterFactTypeMappings(FactTypeMappingDictionary decidedFactTypeMappings, FactTypeMappingListDictionary undecidedFactTypeMappings) + /// <param name="decidedManyToOneFactTypeMappings">The decided many-to-one <see cref="FactTypeMapping"/> objects.</param> + /// <param name="decidedOneToOneFactTypeMappings">The decided one-to-one <see cref="FactTypeMapping"/> objects.</param> + /// <param name="undecidedOneToOneFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param> + private void FilterFactTypeMappings(FactTypeMappingDictionary decidedManyToOneFactTypeMappings, FactTypeMappingDictionary decidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings) { - RemoveImpossiblePotentialFactTypeMappings(decidedFactTypeMappings, undecidedFactTypeMappings); + RemoveImpossiblePotentialFactTypeMappings(decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings); int changeCount = 0; do { - changeCount = MapTrivialOneToOneFactTypesWithTwoMandatories(decidedFactTypeMappings, undecidedFactTypeMappings); + changeCount = MapTrivialOneToOneFactTypesWithTwoMandatories(decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings); } while (changeCount > 0); } @@ -373,14 +414,14 @@ /// Filters out deep potential mappings that are from an <see cref="ObjectType"/> that already has a decided deep /// mapping from it. /// </summary> - /// <param name="decidedFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param> - /// <param name="undecidedFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param> - private void RemoveImpossiblePotentialFactTypeMappings(FactTypeMappingDictionary decidedFactTypeMappings, FactTypeMappingListDictionary undecidedFactTypeMappings) + /// <param name="decidedOneToOneFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param> + /// <param name="undecidedOneToOneFactTypeMappings">The undecided <see cref="FactTypeMapping"/> possibilities.</param> + private void RemoveImpossiblePotentialFactTypeMappings(FactTypeMappingDictionary decidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings) { ObjectTypeList deeplyMappedObjectTypes = new ObjectTypeList(); // For each decided fact type mapping... - foreach (KeyValuePair<FactType, FactTypeMapping> decidedFactTypeMapping in decidedFactTypeMappings) + foreach (KeyValuePair<FactType, FactTypeMapping> decidedFactTypeMapping in decidedOneToOneFactTypeMappings) { FactTypeMapping factTypeMapping = decidedFactTypeMapping.Value; @@ -393,7 +434,7 @@ FactTypeList factsPendingDeletion = new FactTypeList(); - foreach (KeyValuePair<FactType, FactTypeMappingList> undecidedFactTypeMapping in undecidedFactTypeMappings) + foreach (KeyValuePair<FactType, FactTypeMappingList> undecidedFactTypeMapping in undecidedOneToOneFactTypeMappings) { FactType factType = undecidedFactTypeMapping.Key; FactTypeMappingList potentialFactTypeMappings = undecidedFactTypeMapping.Value; @@ -415,7 +456,7 @@ if (potentialFactTypeMappings.Count == 1) { // Mark it decided. - decidedFactTypeMappings.Add(factType, potentialFactTypeMappings[0]); + decidedOneToOneFactTypeMappings.Add(factType, potentialFactTypeMappings[0]); factsPendingDeletion.Add(factType); } } @@ -423,7 +464,7 @@ // Delete each undecided (now decided) fact type mapping marked for deletion. foreach (FactType key in factsPendingDeletion) { - undecidedFactTypeMappings.Remove(key); + undecidedOneToOneFactTypeMappings.Remove(key); } } @@ -432,15 +473,15 @@ /// (potential or decided) deep mappings away from it. If both role players meet this criteria then no action is /// taken. /// </summary> - /// <param name="decidedFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param> - /// <param name="undecidedFactTypeMappings">The undecided <see cref="FactTypeMapping"/> posibilities.</param> - /// <returns>The number of previously undecided fact type mappings that are now decided.</returns> - private int MapTrivialOneToOneFactTypesWithTwoMandatories(FactTypeMappingDictionary decidedFactTypeMappings, FactTypeMappingListDictionary undecidedFactTypeMappings) + /// <param name="decidedOneToOneFactTypeMappings">The decided <see cref="FactTypeMapping"/> objects.</param> + /// <param name="undecidedOneToOneFactTypeMappings">The undecided <see cref="FactTypeMapping"/> posibilities.</param> + /// <returns>The number of previously potential one-to-one fact type mappings that are now decided.</returns> + private int MapTrivialOneToOneFactTypesWithTwoMandatories(FactTypeMappingDictionary decidedOneToOneFactTypeMappings, FactTypeMappingListDictionary undecidedOneToOneFactTypeMappings) { int changeCount = 0; FactTypeList factsPendingDeletion = new FactTypeList(); - foreach (KeyValuePair<FactType, FactTypeMappingList> undecidedFactTypeMapping in undecidedFactTypeMappings) + foreach (KeyValuePair<FactType, FactTypeMappingList> undecidedFactTypeMapping in undecidedOneToOneFactTypeMappings) { FactType factType = undecidedFactTypeMapping.Key; FactTypeMappingList potentialFactTypeMappings = undecidedFactTypeMapping.Value; @@ -452,16 +493,14 @@ Role secondRole = roles[1].Role; ObjectType firstRolePlayer = firstRole.RolePlayer; ObjectType secondRolePlayer = secondRole.RolePlayer; - bool firstRoleIsUnique = (firstRole.SingleRoleAlethicUniquenessConstraint != null); - bool secondRoleIsUnique = (secondRole.SingleRoleAlethicUniquenessConstraint != null); bool firstRoleIsMandatory = null != firstRole.SingleRoleAlethicMandatoryConstraint; bool secondRoleIsMandatory = null != secondRole.SingleRoleAlethicMandatoryConstraint; // If this is a one-to-one fact type with two simple alethic mandatories... - if (firstRoleIsUnique && secondRoleIsUnique && firstRoleIsMandatory && secondRoleIsMandatory) + if (firstRoleIsMandatory && secondRoleIsMandatory) { - bool firstRolePlayerHasPossibleDeepMappingsAway = ObjectTypeHasPossibleDeepMappingsAway(firstRolePlayer, factType, decidedFactTypeMappings, undecidedFactTypeMappings); - bool secondRolePlayerHasPossibleDeepMappingsAway = ObjectTypeHasPossibleDeepMappingsAway(secondRolePlayer, factType, decidedFactTypeMappings, undecidedFactTypeMappings); + bool firstRolePlayerHasPossibleDeepMappingsAway = ObjectTypeHasPossibleDeepMappingsAway(firstRolePlayer, factType, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings); + bool secondRolePlayerHasPossibleDeepMappingsAway = ObjectTypeHasPossibleDeepMappingsAway(secondRolePlayer, factType, decidedOneToOneFactTypeMappings, undecidedOneToOneFactTypeMappings); // UNDONE: I think we need to be checking that the deep mappings we decide on here are actually in the list of potentials... // UNDONE: Also, this can create new decided deep mappings, so we need to be applying the related filters after this runs. @@ -473,7 +512,7 @@ // Deep map toward firstRolePlayer FactTypeMapping factTypeMapping = new FactTypeMapping(factType, secondRole, firstRole, MappingDepth.Deep); - decidedFactTypeMappings.Add(factType, factTypeMapping); + decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping); factsPendingDeletion.Add(factType); ++changeCount; } @@ -482,7 +521,7 @@ // Deep map toward secondRolePlayer FactTypeMapping factTypeMapping = new FactTypeMapping(factType, firstRole, secondRole, MappingDepth.Deep); - decidedFactTypeMappings.Add(factType, factTypeMapping); + decidedOneToOneFactTypeMappings.Add(factType, factTypeMapping); factsPendingDeletion.Add(factType); ++changeCount; } @@ -492,7 +531,7 @@ // Delete each undecided (now decided) fact type mapping marked for deletion. foreach (FactType key in factsPendingDeletion) { - undecidedFactTypeMappings.Remove(key); + undecidedOneToOneFactTypeMappings.Remove(key); } return changeCount; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |