namespace uml; import nemf.packages.uml; machine validation { // *** VIOLATION Patterns // TODO elminate B<->C automorphism, e.g. by check(name(B) >= name(C)); pattern inheritanceDiamond(A, B, C, D) = { find transitiveSuperClass(A, B); find transitiveSuperClass(A, C); neg find transitiveSuperClass(B, C); neg find transitiveSuperClass(C, B); find transitiveSuperClass(B, D); find transitiveSuperClass(C, D); } shareable pattern messageWithoutAssociation(Message, SourceType, TargetType) = { find messageEvents(Message, SourceEvent, TargetEvent); find messageEndType(SourceEvent, SourceType); find messageEndType(TargetEvent, TargetType); neg find potentialAssociationBetween(SourceType, TargetType); } pattern unreferencedClass(C) = { Class(C); // Not referenced by Parameter, Variable Property (including Association End), etc. neg find hasType(Typed, C); } // *** Useful Queries // The name of a property is "name" shareable pattern classWithID(C) = { find hasProperty(C, IDProperty); find hasName(IDProperty, IDName); check(value(IDName) == "ID"); } // *** HELPERS pattern directSuperClass(Sub, Super) = { Class(Sub); Generalization.specific(GS, Gen, Sub); Generalization(Gen); Generalization.general(GG, Gen, Super); Class(Super); } pattern transitiveSuperClass(Sub, Super) = { find directSuperClass(Sub, Super); } or { find transitiveSuperClass(Sub, MiddleMan); find directSuperClass(MiddleMan, Super); } pattern superOrEqualClass(Sub, Super) = { Class(Sub); Sub = Super; } or { find transitiveSuperClass(Sub, Super); } pattern ownsOperation(C, O) = { Class(C); Class.ownedOperation(OO, C, O); Operation(O); } pattern ownsProperty(C, P) = { Class(C); StructuredClassifier.ownedAttribute(SCOA, C, P); Property(P); } shareable pattern hasOperation(C, Operation) = { find superOrEqualClass(C, OwnerClass); find ownsOperation(OwnerClass, Operation); } shareable pattern hasProperty(C, P) = { find superOrEqualClass(C, OwnerClass); find ownsProperty(OwnerClass, P); } pattern hasType(Typed, Type) = { TypedElement(Typed); TypedElement.type(TET, Typed, Type); Type(Type); } pattern hasName(Named, Name) = { NamedElement(Named); NamedElement.name(NEN, Named, Name); String(Name); } pattern messageEndType(MessageEndEvent, EndType) = { MessageOccurrenceSpecification(MessageEndEvent); //OccurrenceSpecification.event(OSE, MessageEndEvent, MessageEndEvent); Lifeline.coveredBy(CB, Line, MessageEndEvent); Lifeline(Line); Lifeline.represents(LR, Line, Param); Parameter(Param); find hasType(Param, EndType); } shareable pattern associationEndType(Assoc, MemberEnd, EndType) = { Association(Assoc); Association.memberEnd(SME, Assoc, MemberEnd); Property(MemberEnd); TypedElement.type(TET, MemberEnd, EndType); Type(EndType); } shareable pattern potentialAssociationBetween(SourceType, TargetType) = { find superOrEqualClass(SourceType, SourceEndType); find superOrEqualClass(TargetType, TargetEndType); find associationEndType(Assoc, SourceMemberEnd, SourceEndType); find associationEndType(Assoc, TargetMemberEnd, TargetEndType); SourceMemberEnd =/= TargetMemberEnd; // To avoid having the same class twice by virtue of the same property } pattern messageEvents(Message, SourceEvent, TargetEvent) = { Message(Message); Message.sendEvent(SE, Message, SourceEvent); Message.receiveEvent(RE, Message, TargetEvent); MessageOccurrenceSpecification(SourceEvent); MessageOccurrenceSpecification(TargetEvent); } }