-- @atlcompiler emftvm -- @nsURI UML2=http://www.eclipse.org/uml2/3.0.0/UML -- $Id$ -- Creates a report of the compatibility of a UML2 model -- with a reference version of the UML2 model. module UML2CompatibilityReport; create REPORT : UML2 -- The compatibility report model, containing any missing elements from IN : UML2, -- The reference model to compare against the dependencies model DEPS : UML2, -- The dependencies model that should be satisfied by the reference model CR : UML2; -- The CompatibilityReport profile uses UML2; uses UML2Comparison; -- ====================================================================== -- helper attributes begin -- ====================================================================== helper def : UML2CompatibilityReportVersionString : String = '$Id$'; -- CompatibilityReport Profile helper def : crProfile : UML2!"uml::Profile" = 'CompatibilityReport'.profileFrom('CR'); -- CompatibilityReport Stereotype helper def : stCompatibilityReport : UML2!"uml::Stereotype" = 'CompatibilityReport'.stereotypeFrom('CR'); -- Incampatible Stereotype helper def : stIncompatible : UML2!"uml::Stereotype" = 'Incompatible'.stereotypeFrom('CR'); -- Missing Stereotype helper def : stMissing : UML2!"uml::Stereotype" = 'Missing'.stereotypeFrom('CR'); -- All Models from IN helper def : allModelsFromIn : Sequence(UML2!"uml::Model") = UML2!"uml::Model".allInstancesFrom('IN'); -- All Packages from IN helper def : allPackagesFromIn : Sequence(UML2!"uml::Model") = UML2!"uml::Package".allInstancesFrom('IN'); -- All Classifiers from IN helper def : allClassifiersFromIn : Sequence(UML2!"uml::Model") = UML2!"uml::Classifier".allInstancesFrom('IN'); -- All NamedElements from IN helper def : allNamedElementsFromIn : Sequence(UML2!"uml::Model") = UML2!"uml::NamedElement".allInstancesFrom('IN'); -- ====================================================================== -- helper attributes for determining compatibility -- ====================================================================== -- ------------------------ hasAllCompatible ---------------------------- -- True iff for all Packages X (transitively) contained by self, -- there exists a Package Y that is compatible with X. helper context UML2!"uml::Model" def : hasAllCompatible : Boolean = self.allOwnedPackages ->reject(e|e.isInferred) ->forAll(p|p.compatibleWithSelf->notEmpty()) .debug(thisModule.modelName.prefix + self.qualifiedName + ' has all elements compatible'); -- ------------------------ locallyCompatibleWithSelf ------------------- -- All Packages other than self that are locally compatible with self, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Package" def : locallyCompatibleWithSelf : Sequence(UML2!"uml::Package") = self.allOther ->reject(e|e.isInferred) ->select(p|p.isLocallyCompatibleWith(self)); -- All Classifiers other than self that are locally compatible with self, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Classifier" def : locallyCompatibleWithSelf : Sequence(UML2!"uml::Classifier") = self.getNearestPackage().locallyCompatibleWithSelf ->collect(p|p.allOwnedClassifiers ->reject(e|e.isInferred) ->select(c|c.isLocallyCompatibleWith(self)) )->flatten(); -- ------------------------ compatibleWithSelf -------------------------- -- All Packages other than self that are compatible with self. helper context UML2!"uml::Package" def : compatibleWithSelf : Sequence(UML2!"uml::Package") = self.locallyCompatibleWithSelf ->select(p|p.hasElementsCompatibleWith(self)) .debug(thisModule.modelName.prefix + self.qualifiedName + ' compatible packages'); -- All Classifiers other than self that are compatible with self. helper context UML2!"uml::Classifier" def : compatibleWithSelf : Sequence(UML2!"uml::Classifier") = self.locallyCompatibleWithSelf ->select(c|c.hasElementsCompatibleWith(self)); -- ------------------------ incompGenerals ------------------------------ -- All generals X of all Classifiers that are locally compatible with self -- for which X is not compatible with any general of self, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Classifier" def : incompGenerals : Sequence(UML2!"uml::Classifier") = self.locallyCompatibleWithSelf ->collect(c|c.allGeneralsIncompatibleWith(self)) ->flatten(); -- ------------------------ incompFeatures ------------------------------ -- All Features X of all Classifiers that are locally compatible with self -- for which X is not compatible with any Feature of self, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Classifier" def : incompFeatures : Sequence(UML2!"uml::Feature") = self.locallyCompatibleWithSelf ->collect(c|c.allFeaturesIncompatibleWith(self)) ->flatten(); -- ------------------------ incompSuppliers ----------------------------- -- All suppliers X of all Classifiers that are locally compatible with self -- for which X is not compatible with any supplier of self, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Classifier" def : incompSuppliers : Sequence(UML2!"uml::NamedElement") = self.locallyCompatibleWithSelf ->collect(p|p.allSuppliersIncompatibleWith(self)) ->flatten(); -- ------------------------ isMissing ----------------------------------- -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context OclAny def : isMissing : Boolean = false; -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. -- The root Model is never missing. helper context UML2!"uml::Model" def : isMissing : Boolean = not self.isInferred and self.hasMissingOwner; -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Package" def : isMissing : Boolean = not self.isInferred and (self.hasMissingOwner or self.locallyCompatibleWithSelf->isEmpty()); -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Classifier" def : isMissing : Boolean = not self.isInferred and (self.hasMissingOwner or self.locallyCompatibleWithSelf->isEmpty()); -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Generalization" def : isMissing : Boolean = not self.isInferred and (self.specific.isMissing or self.specific.incompGenerals->includes(self.general)); -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::InterfaceRealization" def : isMissing : Boolean = not self.isInferred and (self.implementingClassifier.isMissing or self.implementingClassifier.incompSuppliers->exists(i|self.supplier->includes(i))); -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Property" def : isMissing : Boolean = not self.isInferred and (self.hasMissingOwner or (not self.class.oclIsUndefined() and self.class.incompFeatures->includes(self))); -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Operation" def : isMissing : Boolean = not self.isInferred and (self.hasMissingOwner or (not self.class.oclIsUndefined() and self.class.incompFeatures->includes(self)) or (not self.interface.oclIsUndefined() and self.interface.incompFeatures->includes(self))); -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::Parameter" def : isMissing : Boolean = not self.operation.oclIsUndefined() and self.operation.isMissing; -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::LiteralUnlimitedNatural" def : isMissing : Boolean = self.refImmediateComposite().isMissing; -- True iff there are no elements X other than self, -- for which self is locally compatible with X, -- where locally compatible means compatible without considering any contained elements. helper context UML2!"uml::LiteralInteger" def : isMissing : Boolean = self.refImmediateComposite().isMissing; -- ------------------------ hasElementsMissing -------------------------- -- True iff there are no elements X other than self, -- for which X contains all elements A such that -- there exists an element B contained in self that is compatible with A. helper context UML2!"uml::Element" def : hasElementsMissing : Boolean = false; -- True iff there are no elements X other than self, -- for which X contains all elements A such that -- there exists an element B contained in self that is compatible with A. helper context UML2!"uml::Package" def : hasElementsMissing : Boolean = not self.isInferred and not self.hasMissingOwner and (self.compatibleWithSelf->isEmpty() or self.allOwnedPackages->exists(p|p.compatibleWithSelf->isEmpty())); -- True iff there are no elements X other than self, -- for which X contains all elements A such that -- there exists an element B contained in self that is compatible with A. helper context UML2!"uml::Classifier" def : hasElementsMissing : Boolean = not self.isInferred and not self.hasMissingOwner and (self.compatibleWithSelf->isEmpty() or self.allOwnedClassifiers->exists(c|c.compatibleWithSelf->isEmpty())); -- ------------------------ hasMissingOwner ----------------------------- -- True iff an element that transitively contains self is missing. helper context UML2!"uml::Element" def : hasMissingOwner : Boolean = let owner : UML2!"uml::Element" = self.owner in not owner.oclIsUndefined() and (owner.isMissing or owner.hasMissingOwner); -- ====================================================================== -- helper attributes end -- ====================================================================== -- ====================================================================== -- helper methods begin -- ====================================================================== -- ------------------------ join ---------------------------------------- -- If self is a Sequence, a comma-separated list of the entries, -- otherwise, the empty string. helper context OclAny def : join(separator : String) : String = if self.oclIsKindOf(Sequence(OclAny)) then self->iterate(e; acc : String = '' | if acc = '' then acc + e.toString() else acc + separator + e endif) else '' endif; -- ====================================================================== -- helper methods end -- ====================================================================== -- ====================================================================== -- transformation rules begin -- ====================================================================== -- The root element of the compatibility report. rule Model { from s : UML2!"uml::Model" in DEPS using { provides : String = thisModule.allModelsFromIn ->collect(m|m.name) ->join(', '); } to t : UML2!"uml::Model" ( name <- (provides + ' provides ' + s.name.toString()).debug('Creating compatibility report'), eAnnotations <- s.eAnnotations, packagedElement <- s.packagedElement), a : UML2!"ecore::EAnnotation" ( eModelElement <- s, source <- 'PlatformKit', details <- Sequence{vi}), vi : UML2!"ecore::EStringToStringMapEntry" ( key <- 'versionInfo', value <- thisModule.UML2CompatibilityReportVersionString) do { t.applyProfile(thisModule.crProfile); t.applyStereotype(thisModule.stCompatibilityReport); } } -- Copy all EAnnotations in DEPS. rule EAnnotation { from s : UML2!"ecore::EAnnotation" in DEPS to t : UML2!"ecore::EAnnotation" ( source <- s.source, eAnnotations <- s.eAnnotations, details <- s.details, contents <- s.contents, references <- s.references) } -- Copy all EStringToMapEntries in DEPS. rule EStringToStringMapEntry { from s : UML2!"ecore::EStringToStringMapEntry" in DEPS to t : UML2!"ecore::EStringToStringMapEntry" ( key <- s.key, value <- s.value) } -- Copy all Packages in DEPS that are not missing or have missing elements. rule Package { from s : UML2!"uml::Package" in DEPS ( s.oclIsTypeOf(UML2!"uml::Package") and not s.isMissing and not s.hasElementsMissing) to t : UML2!"uml::Package" ( name <- s.name.debug('>>Package<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, packagedElement <- s.packagedElement) } -- Mark all Packages in DEPS that are not missing, but have missing elements, as <>. rule IncompatiblePackage { from s : UML2!"uml::Package" in DEPS ( s.oclIsTypeOf(UML2!"uml::Package") and not s.isMissing and s.hasElementsMissing) to t : UML2!"uml::Package" ( name <- s.name.debug('>>IncompatiblePackage<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, packagedElement <- s.packagedElement) do { t.applyStereotype(thisModule.stIncompatible); } } -- Mark all Packages in DEPS that are missing as <>. rule MissingPackage { from s : UML2!"uml::Package" in DEPS ( s.oclIsTypeOf(UML2!"uml::Package") and s.isMissing) to t : UML2!"uml::Package" ( name <- s.name.debug('>>MissingPackage<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, packagedElement <- s.packagedElement) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all Classes in DEPS that are not missing or have missing elements. rule Class { from s : UML2!"uml::Class" in DEPS ( s.oclIsTypeOf(UML2!"uml::Class") and not s.isMissing and not s.hasElementsMissing) to t : UML2!"uml::Class" ( name <- s.name.debug('>>Class<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, isActive <- s.isActive, generalization <- s.generalization, ownedAttribute <- s.ownedAttribute, interfaceRealization <- s.interfaceRealization, nestedClassifier <- s.nestedClassifier, ownedOperation <- s.ownedOperation) } -- Mark all Classes in DEPS that are not missing, but have missing elements, as <>. rule IncompatibleClass { from s : UML2!"uml::Class" in DEPS ( s.oclIsTypeOf(UML2!"uml::Class") and not s.isMissing and s.hasElementsMissing) to t : UML2!"uml::Class" ( name <- s.name.debug('>>IncompatibleClass<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, isActive <- s.isActive, generalization <- s.generalization, ownedAttribute <- s.ownedAttribute, interfaceRealization <- s.interfaceRealization, nestedClassifier <- s.nestedClassifier, ownedOperation <- s.ownedOperation) do { t.applyStereotype(thisModule.stIncompatible); } } -- Mark all Classes in DEPS that are missing as <>. rule MissingClass { from s : UML2!"uml::Class" in DEPS ( s.oclIsTypeOf(UML2!"uml::Class") and s.isMissing) to t : UML2!"uml::Class" ( name <- s.name.debug('>>MissingClass<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, isActive <- s.isActive, generalization <- s.generalization, ownedAttribute <- s.ownedAttribute, interfaceRealization <- s.interfaceRealization, nestedClassifier <- s.nestedClassifier, ownedOperation <- s.ownedOperation) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all Interfaces in DEPS that are not missing or have missing elements. rule Interface { from s : UML2!"uml::Interface" in DEPS ( not s.isMissing and not s.hasElementsMissing) to t : UML2!"uml::Interface" ( name <- s.name.debug('>>Interface<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, generalization <- s.generalization, ownedAttribute <- s.ownedAttribute, ownedOperation <- s.ownedOperation, nestedClassifier <- s.nestedClassifier) } -- Mark all Interfaces in DEPS that are not missing, but have missing elements, as <>. rule IncompatibleInterface { from s : UML2!"uml::Interface" in DEPS ( not s.isMissing and s.hasElementsMissing) to t : UML2!"uml::Interface" ( name <- s.name.debug('>>IncompatibleInterface<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, generalization <- s.generalization, ownedAttribute <- s.ownedAttribute, ownedOperation <- s.ownedOperation, nestedClassifier <- s.nestedClassifier) do { t.applyStereotype(thisModule.stIncompatible); } } -- Mark all Interfaces in DEPS that are missing as <>. rule MissingInterface { from s : UML2!"uml::Interface" in DEPS ( s.isMissing) to t : UML2!"uml::Interface" ( name <- s.name.debug('>>MissingInterface<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, generalization <- s.generalization, ownedAttribute <- s.ownedAttribute, ownedOperation <- s.ownedOperation, nestedClassifier <- s.nestedClassifier) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all DataTypes in DEPS that are not missing. rule DataType { from s : UML2!"uml::DataType" in DEPS ( s.oclIsTypeOf(UML2!"uml::DataType") and not s.isMissing) to t : UML2!"uml::DataType" ( name <- s.name.debug('>>DataType<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, ownedAttribute <- s.ownedAttribute, ownedOperation <- s.ownedOperation, generalization <- s.generalization) } -- Mark all DataTypes in DEPS that are missing as <>. rule MissingDataType { from s : UML2!"uml::DataType" in DEPS ( s.oclIsTypeOf(UML2!"uml::DataType") and s.isMissing) to t : UML2!"uml::DataType" ( name <- s.name.debug('>>MissingDataType<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, ownedAttribute <- s.ownedAttribute, ownedOperation <- s.ownedOperation, generalization <- s.generalization) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all PrimitiveTypes in DEPS that are not missing. rule PrimitiveType { from s : UML2!"uml::PrimitiveType" in DEPS ( not s.isMissing) to t : UML2!"uml::PrimitiveType" ( name <- s.name.debug('>>PrimitiveType<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, generalization <- s.generalization) } -- Mark all PrimitiveTypes in DEPS that are missing as <>. rule MissingPrimitiveType { from s : UML2!"uml::PrimitiveType" in DEPS ( s.isMissing) to t : UML2!"uml::PrimitiveType" ( name <- s.name.debug('>>MissingPrimitiveType<< ' + s.qualifiedName), eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, generalization <- s.generalization) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all Generalizations in DEPS that are not missing. rule Generalization { from s : UML2!"uml::Generalization" in DEPS ( not s.isMissing) to t : UML2!"uml::Generalization" ( eAnnotations <- s.eAnnotations, general <- s.general) } -- Mark all Generalizations in DEPS that are missing as <>. rule MissingGeneralization { from s : UML2!"uml::Generalization" in DEPS ( s.isMissing) to t : UML2!"uml::Generalization" ( eAnnotations <- s.eAnnotations, general <- s.general) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all InterfaceRealizations in DEPS that are not missing. rule InterfaceRealization { from s : UML2!"uml::InterfaceRealization" in DEPS ( not s.isMissing) to t : UML2!"uml::InterfaceRealization" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, supplier <- s.supplier, client <- s.client, contract <- s.contract, implementingClassifier <- s.implementingClassifier) } -- Mark all InterfaceRealizations in DEPS that are missing as <>. rule MissingInterfaceRealization { from s : UML2!"uml::InterfaceRealization" in DEPS ( s.isMissing) to t : UML2!"uml::InterfaceRealization" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, supplier <- s.supplier, client <- s.client, contract <- s.contract, implementingClassifier <- s.implementingClassifier) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all Properties in DEPS that are not missing. rule Property { from s : UML2!"uml::Property" in DEPS ( s.oclIsTypeOf(UML2!"uml::Property") and not s.isMissing) to t : UML2!"uml::Property" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isStatic <- s.isStatic, isOrdered <- s.isOrdered, isUnique <- s.isUnique, isReadOnly <- s.isReadOnly, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue) } -- Mark all Properties in DEPS that are missing as <>. rule MissingProperty { from s : UML2!"uml::Property" in DEPS ( s.oclIsTypeOf(UML2!"uml::Property") and s.isMissing) to t : UML2!"uml::Property" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isStatic <- s.isStatic, isOrdered <- s.isOrdered, isUnique <- s.isUnique, isReadOnly <- s.isReadOnly, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all LiteralUnlimitedNaturals in DEPS that are contained in a Property or Parameter. rule LiteralUnlimitedNatural { from s : UML2!"uml::LiteralUnlimitedNatural" in DEPS ( let p : UML2!"ecore::EObject" = s.refImmediateComposite() in p.oclIsTypeOf(UML2!"uml::Property") or p.oclIsKindOf(UML2!"uml::Parameter")) to t : UML2!"uml::LiteralUnlimitedNatural" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, value <- s.value) } -- Copy all LiteralIntegers in DEPS that are contained in a Property or Parameter. rule LiteralInteger { from s : UML2!"uml::LiteralInteger" in DEPS ( let p : UML2!"ecore::EObject" = s.refImmediateComposite() in p.oclIsTypeOf(UML2!"uml::Property") or p.oclIsKindOf(UML2!"uml::Parameter")) to t : UML2!"uml::LiteralInteger" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, value <- s.value) } -- Copy all Operations in DEPS that are not missing. rule Operation { from s : UML2!"uml::Operation" in DEPS ( not s.isMissing) to t : UML2!"uml::Operation" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isStatic <- s.isStatic, isAbstract <- s.isAbstract, concurrency <- s.concurrency, isQuery <- s.isQuery, ownedParameter <- s.ownedParameter, raisedException <- s.raisedException) } -- Mark all Operations in DEPS that are missing as <>. rule MissingOperation { from s : UML2!"uml::Operation" in DEPS ( s.isMissing) to t : UML2!"uml::Operation" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, isLeaf <- s.isLeaf, isStatic <- s.isStatic, isAbstract <- s.isAbstract, concurrency <- s.concurrency, isQuery <- s.isQuery, ownedParameter <- s.ownedParameter, raisedException <- s.raisedException) do { t.applyStereotype(thisModule.stMissing); } } -- Copy all Parameters in DEPS. rule Parameter { from s : UML2!"uml::Parameter" in DEPS to t : UML2!"uml::Parameter" ( name <- s.name, eAnnotations <- s.eAnnotations, visibility <- s.visibility, isOrdered <- s.isOrdered, isUnique <- s.isUnique, direction <- s.direction, isException <- s.isException, isStream <- s.isStream, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue) } -- Transformations returns true iff -- there exists a model other than the model in DEPS -- that is compatible with the model in DEPS. endpoint rule UML2CompatibilityComparison() { do { --nasty "pcall debug" throws away my return value! => wrap in let expression let result : Boolean = UML2!"uml::Model".allInstancesFrom('DEPS') ->forAll(m|m.hasAllCompatible).debug('Model is compatible with previous model') in result; } } -- ====================================================================== -- transformation rules end -- ======================================================================