/// <summary> /// Checks that only one role is played by the value type, that it has a boolean data type, and that /// if it has a value constraint, that value constraint is alethic and only allows the value 'true'. /// </summary> private static bool ValidateImplicitBooleanValueType(ObjectType implicitBooleanValueType) { if (!implicitBooleanValueType.IsValueType || !implicitBooleanValueType.IsImplicitBooleanValue || implicitBooleanValueType.IsIndependent || implicitBooleanValueType.PlayedRoleCollection.Count != 1 || !(implicitBooleanValueType.DataType is TrueOrFalseLogicalDataType)) { return(false); } ValueTypeValueConstraint valueConstraint = implicitBooleanValueType.ValueConstraint; if (valueConstraint != null) { // UNDONE: We need to check for alethic here once ValueTypeValueConstraint supports Modality... LinkedElementCollection <ValueRange> valueRangeCollection = valueConstraint.ValueRangeCollection; ValueRange valueRange; bool value; if (valueRangeCollection.Count != 1 || !bool.TryParse((valueRange = valueRangeCollection[0]).MinValue, out value) || !value || !bool.TryParse(valueRange.MaxValue, out value) || !value) { return(false); } } else { // UNDONE: We are only allowing open-world assumption for now, so the value constraint is required. return(false); } return(true); }
/// <summary> /// Binarizes the unary <see cref="FactType"/> specified by <paramref name="unaryFactType"/>, defaulting /// to using open-world assumption. The caller is responsible for making sure <paramref name="unaryFactType"/> /// is in fact a unary fact type. /// </summary> public static void BinarizeUnary(FactType unaryFactType, INotifyElementAdded notifyAdded) { Partition partition = unaryFactType.Partition; Store store = partition.Store; IHasAlternateOwner <FactType> toAlternateOwner; IAlternateElementOwner <FactType> alternateFactTypeOwner = (null == (toAlternateOwner = unaryFactType as IHasAlternateOwner <FactType>)) ? null : toAlternateOwner.AlternateOwner; LinkedElementCollection <RoleBase> roleCollection = unaryFactType.RoleCollection; Debug.Assert(roleCollection.Count == 1, "Unaries should only have one role."); Role unaryRole = (Role)roleCollection[0]; string implicitBooleanValueTypeName = GetImplicitBooleanValueTypeName(unaryRole); // UNDONE: We are using open-world assumption now // Setup the mandatory constraint (for closed-world assumption) //MandatoryConstraint mandatoryConstraint = MandatoryConstraint.CreateSimpleMandatoryConstraint(unaryRole); //mandatoryConstraint.Model = unaryFactType.Model; //if (notifyAdded != null) //{ // notifyAdded.ElementAdded(mandatoryConstraint, true); //} // Setup the uniqueness constraint (to make the newly binarized FactType valid) if (unaryRole.SingleRoleAlethicUniquenessConstraint == null) { UniquenessConstraint uniquenessConstraint = UniquenessConstraint.CreateInternalUniquenessConstraint(unaryFactType); uniquenessConstraint.RoleCollection.Add(unaryRole); if (notifyAdded != null) { notifyAdded.ElementAdded(uniquenessConstraint, true); } } // Setup the boolean role (to make the FactType a binary) Role implicitBooleanRole = new Role(partition, null); implicitBooleanRole.Name = unaryRole.Name; // Setup the boolean value type (because the boolean role needs a role player) IAlternateElementOwner <ObjectType> alternateObjectTypeOwner = null; DomainClassInfo alternateCtor = (null != alternateFactTypeOwner && null != (alternateObjectTypeOwner = alternateFactTypeOwner as IAlternateElementOwner <ObjectType>)) ? alternateObjectTypeOwner.GetOwnedElementClassInfo(typeof(ObjectType)) : null; PropertyAssignment implicitBooleanProperty = new PropertyAssignment(ObjectType.IsImplicitBooleanValueDomainPropertyId, true); ObjectType implicitBooleanValueType = (alternateCtor != null) ? (ObjectType)partition.ElementFactory.CreateElement(alternateCtor, implicitBooleanProperty) : new ObjectType(partition, implicitBooleanProperty); Dictionary <object, object> contextInfo = store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo; object duplicateNamesKey = ORMModel.AllowDuplicateNamesKey; bool removeDuplicateNamesKey = false; object duplicateSignaturesKey = ORMModel.BlockDuplicateReadingSignaturesKey; bool addDuplicateSignaturesKey = false; try { if (!contextInfo.ContainsKey(duplicateNamesKey)) { contextInfo[duplicateNamesKey] = null; removeDuplicateNamesKey = true; } if (contextInfo.ContainsKey(duplicateSignaturesKey)) { contextInfo[duplicateSignaturesKey] = null; addDuplicateSignaturesKey = true; } implicitBooleanValueType.Name = implicitBooleanValueTypeName; if (alternateCtor != null) { ((IHasAlternateOwner <ObjectType>)implicitBooleanValueType).AlternateOwner = alternateObjectTypeOwner; } else { implicitBooleanValueType.Model = unaryFactType.ResolvedModel; } if (notifyAdded != null) { notifyAdded.ElementAdded(implicitBooleanValueType, true); } } finally { if (removeDuplicateNamesKey) { contextInfo.Remove(duplicateNamesKey); } if (addDuplicateSignaturesKey) { contextInfo[duplicateSignaturesKey] = null; } } implicitBooleanValueType.DataType = store.ElementDirectory.FindElements <TrueOrFalseLogicalDataType>(false)[0]; // Set value constraint on implicit boolean ValueType for open-world assumption ValueTypeValueConstraint implicitBooleanValueConstraint = implicitBooleanValueType.ValueConstraint = new ValueTypeValueConstraint(partition, null); // Add the true-only ValueRange to the value constraint for open-world assumption implicitBooleanValueConstraint.ValueRangeCollection.Add(new ValueRange(partition, new PropertyAssignment(ValueRange.MinValueDomainPropertyId, bool.TrueString), new PropertyAssignment(ValueRange.MaxValueDomainPropertyId, bool.TrueString))); // Make the boolean value type the role player for the implicit boolean role implicitBooleanRole.RolePlayer = implicitBooleanValueType; // Add the boolean role to the FactType roleCollection.Add(implicitBooleanRole); if (notifyAdded != null) { notifyAdded.ElementAdded(implicitBooleanRole, true); } }