Issues for MOF QVT 1.2 Revision Task Force

To comment on any of these issues, send email to qvt-rtf@omg.org. (Please include the issue number in the Subject: header, thusly: [Issue ###].) To submit a new issue, send email to issues@omg.org.

List of issues (green=resolved, yellow=pending Board vote, red=unresolved)

List options: All ; Open Issues only; or Closed Issues only

Issue 10646: Missing explanations in BNF
Issue 10947: 7.13.1 Multiple transformation extension
Issue 10948: 7.13.1 Qualified query name
Issue 11341: QVT 1.0 Section 7,8,9,10 : Navigating non-navigable opposite roles
Issue 12173: Section: 8.2.1.6
Issue 12198: Section: 8.2.1.7
Issue 12362: Section: 8.4.7
Issue 12373: Section: 8.2.2.22
Issue 12374: MOF QVT 1.0, 8.2.2.22, Unclear specification of Unpack notation shorthand
Issue 12375: Section: 8.1.14
Issue 13331: QVTo Standard Lybrary and typedefs Issue. Extending OCL predefined types

Issue 10646: Missing explanations in BNF (qvt-rtf)

Click here for this issue's archive.
Source: Nomos Software (Dr. Edward Willink, ed(at)willink.me.uk)
Nature: Uncategorized Issue
Severity:
Summary:
The OCL 2.0 spec has a 32 page section on concrete semantics.
QVTr has 1.5 pages of BNF but no explanation.

In particular:
What are the semantics of 'import' which has no abstract counterpart?
Where is the explanation of the role of [ '{' <oclExpressionCS> '}' ] in a <domain>?
Where is the instruction on how to treat the "_" identifier?


Resolution:
Revised Text: Add a sub-section in section 7.13 with the following content: The mapping is specified using attribute grammar similar to how OCL' concrete to abstract syntax mapping is specified. topLevelCS topLevelCS ::= importListCS? transformationListCS? Abstract syntax mapping topLevelCS.ast : Set(RelationalTransformation) Synthesized attributes topLevelCS.ast = TransformationListCS.ast Inherited attributes transformationListCS.env = if (importListCS.ast.notEmpty()) then Environment.EMPTY_ENV.addElement('imported transformation', importListCS.ast) else Environment.EMPTY_ENV endif importListCS importListCS[1] ::= 'import' unitCS ';' importListCS[2]? Abstract syntax mapping importListCS[1].ast : Set(RelationalTransformation) Synthesized attributes importListCS[1].ast = unitCS.ast->union(importListCS[2].ast) unitCS unitCS ::= identifierCS ('.' identifierCS)* Abstract syntax mapping unitCS.ast : Set(RelationalTransformation) Synthesized attributes <left unspecified> The dot separated identifiers identify a compilation unit that is expected to contain transformation specifications. As explained in section 7.13.1 of the spec, how the dot separated identifiers are mapped to, say, a file system hierarchy is implementation specific. transformationListCS transformationListCS[1] ::= transformationCS transformationListCS[2]? Abstract syntax mapping transformationListCS[1].ast : Set(RelationalTransformation) Synthesized attributes transformationListCS[1].ast = Set{transformationCS.ast}->union(transformationListCS[2].ast) Inherited attributes transformationCS[1].env = transformationListCS[1].env transformationListCS[2].env = transformationListCS[1].env transformationCS transformationCS ::= 'transformation' identifierCS[1] '(' modelDeclListCS ')' ('extends' identifierCS[2])? '{' keyDeclListCS? relQueryListCS? '}' Abstract syntax mapping transformationCS.ast : RelationalTransformation Synthesized attributes transformationCS.ast.name = identifierCS[1].ast transformationCS.ast.modelParameter = modelDeclListCS.ast if (not identifierCS[2].ast.oclIsUndefined()) then transformationCS.ast.extends = let importedTransformationSet:Set(RelationalTransformation) = transformationCS.env.lookup('imported transformations').referredElement.oclAsType(SetType) in importedTransformationSet->any(t | t.name = identifierCS[2].ast) endif transformationCS.ast.rule = relQueryListCS->select(r | r.OclIsTypeOf(Relation)) transformationCS.ast.ownedOperation = relQueryListCS->select(r | r.OclIsTypeOf(Function)) transformationCS.ast.ownedKey = keyDeclListCS.ast Inherited attributes identifierCS[1].env = transformationCS.env modelDeclListCS.env = transformationCS.env identifierCS[2].env = transformationCS.env let env:Environment = transformationCS.env.addElement('context transformation', transformationCS.ast) in keyDeclListCS.env = env and relQueryListCS.env = env modelDeclListCS modelDeclListCS[1] ::= modelDeclCS (',' modelDeclListCS[2])? Abstract syntax mapping modelDeclListCS[1].ast : Sequence(TypedModel) Synthesized attributes modelDeclListCS[1].ast = Sequence{modelDeclCS.ast}->union(modelDeclListCS[2].ast) Inherited attributes modelDeclCS.env = modelDeclListCS[1].env modelDeclListCS[2].env = modelDeclListCS[1].env keyDeclListCS keyDeclListCS[1] ::= keyDeclCS keyDeclListCS[2]? Abstract syntax mapping keyDeclListCS[1].ast : Set(Key) Synthesized attributes keyDeclListCS[1].ast = Set{keyDeclCS.ast}->union(keyDeclListCS[2].ast) Inherited attributes keyDeclCS.env = keyDeclListCS[1].env keyDeclListCS[2].env = keyDeclListCS[1].env relQueryListCS relQueryListCS[1] ::= relQueryCS relQueryListCS[2]? Abstract syntax mapping relQueryListCS[1].ast : Set(ModelElement) Synthesized attributes relQueryListCS[1].ast = Set{relQueryCS.ast}->union(relQueryListCS[2].ast) Inherited attributes relQueryCS.env = relQueryListCS[1].env relQueryListCS[2].env = relQueryListCS[1].env relQueryCS [A] relQueryCS ::= relationCS [B] relQueryCS ::= queryCS Abstract syntax mapping relQueryCS.ast : ModelElement Synthesized attributes [A] relQueryCS.ast = relationCS.ast [B] relQueryCS.ast = queryCS.ast Inherited attributes [A] relationCS.env = relQueryCS.env [B] queryCS.env = relQueryCS.env modelDeclCS modelDeclCS ::= modelIdCS ':' metaModelIdCS Abstract syntax mapping modelDeclCS.ast : TypedModel Synthesized attributes modelDeclCS.ast.name = modelIdCS.ast modelDeclCS.ast.usedPackage = metaModelIdCS.ast Inherited attributes modelIdCS.env = modelDeclCS.env metaModelIdCS.env = modelDeclCS.env modelIdCS modelIdCS ::= identifierCS Abstract syntax mapping modelIdCS.ast : String Synthesized attributes modelIdCS.ast = identifierCS.ast metaModelIdCS metaModelIdCS ::= identifierCS Abstract syntax mapping metaModelIdCS.ast : Package Synthesized attributes metaModelIdCS.ast = loadMetaModelPackage(identifierCS.ast) // How the package is located and loaded is tool specific and so left unspecified. keyDeclCS keyDeclCS ::= 'key' classIdCS '{' keyPropertyListCS '}' ';' Abstract syntax mapping keyDeclCS.ast : Key Synthesized attributes keyDeclCS.ast.identifies = classIdCS.ast keyDeclCS.ast.part->union(keyDeclCS.ast.oppositePart) = keyPropertyListCS.ast Inherited attributes classIdCS.env = keyDeclCS.env keyPropertyListCS.env = keyDeclCS.env.addElement('context key', keyDeclCS.ast) keyPropertyListCS keyPropertyListCS[1] ::= keyPropertyCS (',' keyPropertyListCS[2])? Abstract syntax mapping keyPropertyListCS[1].ast : Set(Property) Synthesized attributes keyPropertyListCS[1].ast : Set{keyPropertyCS.ast}->union(keyPropertyListCS[2].ast) Inherited attributes keyPropertyCS.env = keyPropertyListCS[1].env keyPropertyListCS[2].env = keyPropertyListCS[1].env classIdCS classIdCS ::= pathNameCS Abstract syntax mapping classIdCS.ast : Class Synthesized attributes classIdCS.ast = let trans:RelationalTransformation = classIdCS.env.lookup('context transformation'). referredElement.oclAsType(RelationalTransformation) in trans.lookupClassName(pathNameCS.ast) keyPropertyCS [A] keyPropertyCS ::= identifierCS [B] keyPropertyCS ::= 'opposite' '(' classIdCS '.' identifierCS ')' Abstract syntax mapping: keyPropertyCS.ast : Property Synthesized attributes: [A] keyPropertyCS.ast = let cls:Class = keyPropertyCS.env.lookup('context key'). referredElement.oclAsType(Key).identifies in cls.lookupProperty(identifierCS.ast) keyPropertyCS.env.lookup('context key').referredElement.oclAsType(Key). part->includes(keyPropertyCS.ast) [B] keyPropertyCS.ast = classIdCS.ast.lookupProperty(identifierCS.ast) keyPropertyCS.env.lookup('context key').referredElement.oclAsType(Key). oppositePart->includes(keyPropertyCS.ast) Inherited attributes: [B] classIdCS.env = keyPropertyCS.env relationCS relationCS ::= topQualifierCS? 'relation' identifierCS[1] ('overrides' identifierCS[2])? '{' varDeclListCS? domainListCS whenCS? whereCS? '}' Abstract syntax mapping relationCS.ast : Relation Synthesized attributes relationCS.ast.isTopLevel = if (not topQualifierCS.ast.oclIsUndefined() and topQualifierCS.ast = 'top') then true else false endif relationCS.ast.name = identifierCS[1].ast if (not identifierCS[2].ast.oclIsUndefined()) then relationCS.ast.overrides = let currTrans:RelationTransformation = relationCS.env.lookup('context transformation'). referredElement.oclAsType(RelationalTransformation) in currTrans.extends.rule->any(r | r.name = identifierCS[2].ast) endif relationCS.ast.variable = varDeclListCS.ast->union( domainListCS->iterate(d:RelationDomain; domainVars:Set(Variable)={} | domainVars->including(d.rootVariable)) ) relationCS.ast.domain = domainListCS.ast relationCS.ast.when = whenCS.ast relationCS.ast.where = whereCS.ast Inherited attributes let env:Environment = relationCS.env.addElement('context relation', relationCS.ast) in varDeclListCS.env = env domainListCS.env = env whenCS.env = env whereCS.env = env topQualifierCS topQualifierCS ::= 'top' Abstract syntax mapping topQualifierCS.ast : String Synthesized attributes topQualifierCS.ast = 'top' varDeclListCS varDeclListCS[1] ::= varDeclarationCS varDeclListCS[2]? Abstract syntax mapping varDeclListCS[1].ast : Set(Variable) Synthesized attributes varDeclListCS[1].ast ::= varDeclarationCS.ast->union(varDeclListCS[2].ast) Inherited attributes varDeclarationCS.env = varDeclListCS[1].env varDeclListCS[2].env = varDeclListCS[1].env varDeclarationCS varDeclarationCS ::= varListCS ':' TypeCS ';' Abstract syntax mapping varDeclarationCS.ast : Set(Variable) Synthesized attributes varDeclarationCs.ast->size() = varListCS.ast->size() varListCS.ast->forAll(vn | varDeclarationCS.ast->exists(v | v.name = vn and v.type = TypeCS.ast) ) Inherited attributes TypeCS.env = varDeclarationCS.env varListCS varListCS[1] ::= identifierCS (',' varListCS[2])? Abstract syntax mapping varListCS[1].ast : Set(String) Synthesized attributes varListCS[1].ast : Set{identifierCS.ast}->union(varListCS[2].ast) domainListCS domainListCS[1] ::= domainCS domainListCS[2]? Abstract syntax mapping domainListCS[1].ast : Sequence(RelationDomain) Synthesized attributes domainListCS[1].ast = Sequence{domainCS.ast}->union(domainListCS[2].ast) Inherited attributes domainCS.env = domainListCS[1].env domainListCS[2].env = domainListCS[1].env domainCS domainCS[A] ::= modelDomainCS domainCS[B] ::= primitiveDomainCS Abstract syntax mapping domainCS.ast : RelationDomain Synthesized attributes [A] domainCS.ast = modelDomainCS.ast [B] domainCS.ast = primitiveDomainCS.ast Inherited attributes [A] modelDomainCS.env = domainCS.env [B] primitiveDomainCS.env = domainCS.env modelDomainCS modelDomainCS ::= checkEnforceQualifierCS? 'domain' modelIdCS templateCS ('implementedby' OperationCallExpCS)? ('default_values' '{' assignmentExpListCS '}')? ';' Abstract syntax mapping modelDomainCS.ast : RelationDomain Synthesized attributes if (checkEnforceQualifierCS.ast.oclIsUndefined()) then modelDomainCS.ast.isCheckable = false and modelDomainCS.ast.isEnforceable = false else if (checkEnforceQualifierCS.ast = 'checkonly') then modelDomainCS.ast.isCheckable = true and modelDomainCS.ast.isEnforceable = false else modelDomainCS.ast.isCheckable = true and modelDomainCS.ast.isEnforceable = true endif endif modelDomainCS.ast.typedModel = modelDomainCS.env.lookup('context transformation').modelParameter-> any(t | t.name = modelIdCS.ast) modelDomainCS.ast.pattern.templateExpression = templateCS.ast modelDomainCS.ast.rootVariable = templateCS.ast.bindsTo if (not OperationCallExpCS.ast.oclIsUndefined()) then let rel:Relation = modelDomainCS.env.lookup('context relation'). referredElement.oclAsType(Relation) in rel.operationalImpl.impl = OperationCallExpCS.ast.referredOperation and rel.operationalImpl.inDirectionOf = modelDomainCS.ast.typedModel endif if (assignmentExpListCS.ast.notEmpty()) then modelDomainCS.ast.defaultAssignment = assignmentExpListCS.ast endif Inherited attributes let env:Environment = modelDomainCS.env.addElement('context domain', modelDomainCS.ast) in templateCS.env = env OperationCallExpCS.env = env assignmentExpListCS.env = env primitiveTypeDomainCS primitiveTypeDomainCS ::= 'primitive' 'domain' identifierCS ':' TypeCS ';' Abstract syntax mapping primitiveTypeDomainCS.ast : RelationDomain Synthesized attributes primitiveTypeDomainCS.ast.rootVariable.name = identifierCS.ast primitiveTypeDomainCS.ast.rootVariable.type = TypeCS.ast Inherited attributes TypeCS.env = primitiveTypeDomainCS.env checkEnforceQualifierCS [A] checkEnforceQualifierCS ::= 'checkonly' [B] checkEnforceQualifierCS ::= 'enforce' Abstract syntax mapping checkEnforceQualifierCS.ast : String Synthesized attributes [A] checkEnforceQualifierCS.ast = 'checkonly' [B] checkEnforceQualifierCS.ast = 'enforce' templateCS [A] templateCS ::= objectTemplateCS ('{' OclExpressionCS '}')? [B] templateCS ::= collectionTemplateCS ('{' OclExpressionCS '}')? Abstract syntax mapping templateCS.ast : TemplateExp Synthesized attributes [A] templateCS.ast = objectTemplateCS.ast if (not OclExpressionCS.ast.oclIsUndefined()) then templateCS.ast.where = OclExpressionCS.ast endif [B] templateCS.ast = collectionTemplateCS.ast if (not OclExpressionCS.ast.oclIsUndefined()) then templateCS.ast.where = OclExpressionCS.ast endif Inherited attributes [A] objectTemplateCS.env = templateCS.env OclExpressionCS.env = templateCS.env [B] collectionTemplateCS.env = templateCS.env OclExpressionCS.env = templateCS.env objectTemplateCS objectTemplateCS ::= identifierCS? ':' pathNameCS '{' propertyTemplateListCS? '}' Abstract syntax mapping objectTemplateCS.ast : ObjectTemplateExp Synthesized attributes let cls:Class = objectTemplateCS.env.lookup('context domain'). referredElement.typedModel.usedPackage.getEnvironmentWithoutParents(). lookupPathName(pathNameCS.ast).referredElement.oclAsType(Class) in if (not identifierCS.ast.oclIsUndefined) then objectTemplateCS.ast.bindsTo.name = identifierCS.ast and objectTemplateCS.ast.bindsTo.type = cls and objectTemplateCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable-> exists(v | v = objectTemplateCS.ast.bindsTo) endif and objectTemplateCS.ast.referredClass = cls objectTemplateCS.ast.part = propertyTemplateListCS.ast Inherited attributes propertyTemplateListCS.env = objectTemplateCS.env.addElement('context template', objectTemplateCS.ast) propertyTemplateListCS propertyTemplateListCS[1] ::= propertyTemplateCS (',' propertyTemplateListCS[2])? Abstract syntax mapping propertyTemplateListCS[1].ast : Set(PropertyTemplateItem) Synthesized attributes propertyTemplateListCS[1].ast = Set{propertyTemplateCS.ast}-> union(propertyTemplateListCS[2].ast) Inherited attributes propertyTemplateCS.env = propertyTemplateListCS[1].env propertyTemplateListCS[2].env = propertyTemplateListCS[1].env propertyTemplateCS [A] propertyTemplateCS ::= identifierCS '=' ExtOclExpressionCS [B] propertyTemplateCS ::= 'opposite' '(' classIdCS '.' identifierCS ')' '=' ExtOclExpressionCS Abstract syntax mapping: propertyTemplateCS.ast : PropertyTemplateItem Synthesized attributes: [A] propertyTemplateCS.ast.referredProperty = propertyTemplateCS.env.lookup('context template'). referredElement.oclAsType(ObjectTemplateExp). referredClass.lookupProperty(identifierCS.ast) propertyTemplateCS.ast.isOpposite = false propertyTemplateCS.ast.value = ExtOclExpressionCS.ast [A] propertyTemplateCS.ast.referredProperty = classIdCS.ast.lookupProperty(identifierCS.ast) propertyTemplateCS.ast.isOpposite = true propertyTemplateCS.ast.value = ExtOclExpressionCS.ast Inherited attributes: [A] ExtOclExpressionCS.env = propertyTemplateCS.env [B] ExtOclExpressionCS.env = propertyTemplateCS.env classIdCS.env = propertyTemplateCS.env collectionTemplateCS collectionTemplateCS ::= identifierCS? ':' CollectionTypeIdentifierCS '(' TypeCS ')' '{' (memberListCS '++' restCS)? '}' Abstract syntax mapping collectionTemplateCS.ast : CollectionTemplateExp Synthesized attributes if (CollectionTypeIdentifierCS.ast = CollectionKind::Set) then collectionTemplateCS.ast.referredCollectionType.oclIsTypeOf(SetType) else if (CollectionTypeIdentifierCS.ast = CollectionKind::Sequence) then collectionTemplateCS.ast.referredCollectionType.oclIsTypeOf(SequenceType) else if (CollectionTypeIdentifierCS.ast = CollectionKind::Bag) then collectionTemplateCS.ast.referredCollectionType.oclIsTypeOf(BagType) else if (CollectionTypeIdentifierCS.ast = CollectionKind::OrderedSet) then collectionTemplateCS.ast.referredCollectionType. oclIsTypeOf(OrderedSetType) endif endif endif endif collectionTemplateCS.ast.referredCollectionType.elementType = TypeCS.ast if (not identifierCS.ast.oclIsUndefined) then collectionTemplateCS.ast.bindsTo.name = identifierCS.ast and collectionTemplateCS.ast.bindsTo.type = collectionTemplateCS.ast.referredCollectionType and collectionTemplateCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable-> exists(v | v = collectionTemplateCS.ast.bindsTo) endif if (memberListCS->notEmpty()) then collectionTemplateCS.ast.member = memberListCS.ast endif if (not restCS.oclIsUndefined()) then collectionTemplateCS.ast.rest = restCS.ast endif Inherited attributes TypeCS.env = collectionTemplateCS.env memberListCS.env = collectionTemplateCS.env restCS.env = collectionTemplateCS.env memberListCS memberListCS[1] ::= memberCS (',' memberListCS[2])? Abstract syntax mapping memberListCS[1].ast : Sequence(OclExpression) Synthesized attributes memberListCS[1].ast = Sequence{memberCS.ast}->union(memberListCS[2].ast) Inherited attributes memberCS.env = memberListCS[1].env memberListCS[2].env = memberListCS[1].env restCS [A] restCS ::= identifierCS [B] restCS ::= '_' Abstract syntax mapping restCS.ast : Variable Synthesized attributes [A] restCS.ast = restCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable->any(v | v.name = identifierCS.ast) [B] restCS.ast.name = '_' memberCS [A] memberCS ::= identifierCS [B] memberCS ::= templateCS [C] memberCS ::= '_' Abstract syntax mapping memberCS.ast : OclExpression Synthesized attributes [A] memberCS.ast = memberCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable->any(v | v.name = identifierCS.ast) [B] memberCS.ast = templateCS.ast [C] memberCS.ast.oclIsTypeOf(Variable) memberCS.ast.oclAsType(Variable).name = '_' Inherited attributes [B] templateCS.env = memberCS.env assignmentExpListCS assignmentExpListCS[1] ::= assignmentExpCS assignmentExpListCS[2]? Abstract syntax mapping assignmentExpListCS[1].ast : Set(RelationDomainAssignment) Synthesized attributes assignmentExpListCS[1].ast = Set{assignmentExpCS.ast}-> union(assignmentExpListCS[2].ast) Inherited attributes assignmentExpListCS[2].env = assignmentExpListCS[1].env assignmentExpCS.env = assignmentExpListCS[1].env assignmentExpCS assignmentExpCS ::= identifierCS '=' OclExpressionCS ';' Abstract syntax mapping assignmentExpCS.ast : RelationDomainAssignment Synthesized attributes assignmentExpCS.ast.variable = assignmentExpCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable-> any(v | v.name = identifierCS.ast) assignmentExpCS.ast.valueExp = OclExpressionCS.ast Inherited attributes OclExpressionCS.env = assignmentExpCS.env whenCS whenCS ::= 'when' '{' predicateListCS '}' Abstract syntax mapping whenCS.ast : Pattern Synthesized attributes whenCS.ast.predicate = predicateListCS.ast Inherited attributes predicateListCS.env = whenCS.env whereCS whereCS ::= 'where' '{' predicateListCS '}' Abstract syntax mapping whereCS.ast : Pattern Synthesized attributes whereCS.ast.predicate = predicateListCS.ast Inherited attributes predicateListCS.env = whereCS.env predicateListCS predicateListCS[1] ::= predicateCS ';' predicateListCS[2]? Abstract syntax mapping predicateListCS[1].ast : Set(Predicate) Synthesized attributes predicateListCS[1].ast = Set{predicateCS.ast}->union(predicateListCS[2].ast) Inherited attributes predicateCS.env = predicateListCS[1].env predicateListCS[2].env = predicateListCS[1].env predicateCS predicateCS ::= ExtOclExpressionCS Abstract syntax mapping predicateCS.ast : Predicate Synthesized attributes predicateCS.ast.conditionExpression = ExtOclExpressionCS.ast Inherited attributes ExtOclExpressionCS.env = predicateCS.env queryCS queryCS ::= 'query' identifierCS '(' paramDeclListCS? ')' ':' TypeCS queryBodyCS Abstract syntax mapping queryCS.ast : Function Synthesized attributes queryCS.ast.name = identifierCS.ast queryCS.ast.ownedParameter = paramDeclListCS.ast queryCS.ast.type = TypeCS.ast queryCS.ast.queryExpression = queryBodyCS.ast Inherited attributes paramDeclListCS.env = queryCS.env queryBodyCS.env = queryCS.env paramDeclListCS paramDeclListCS[1] ::= paramDeclarationCS (',' paramDeclListCS[2])? Abstract syntax mapping paramDeclListCS[1].ast : Sequence(Parameter) Synthesized attributes paramDeclListCS[1].ast = Sequence{paramDeclarationCS.ast}-> union(paramDeclListCS[2].ast) Inherited attributes paramDeclarationCS.env = paramDeclListCS[1].env paramDeclListCS[2].env = paramDeclListCS[1].env paramDeclarationCS paramDeclarationCS ::= identifierCS ':' TypeCS Abstract syntax mapping paramDeclarationCS.ast : Parameter Synthesized attributes paramDeclarationCS.ast.name = identifierCS.ast paramDeclarationCS.ast.type = typeCS.ast Inherited attributes typeCS.env = paramDeclarationCS.env queryBodyCS [A] queryBodyCS ::= ';' [B] queryBodyCS ::= '{' OclExpressionCS '}' Abstract syntax mapping queryBodyCS.ast : OclExpression Synthesized attributes [B] queryBodyCS.ast = OclExpressionCS.ast Inherited attributes [B] OclExpressionCS.env = queryBodyCS.env ExtOclExpressionCS [A] ExtOclExpressionCS ::= OclExpressionCS [B] ExtOclExpressionCS ::= templateCS [C] ExtOclExpressionCS ::= RelationCallExpCS Abstract syntax mapping ExtOclExpressionCS.ast : OclExpressionCS Synthesized attributes [A] ExtOclExpressionCS.ast = OclExpressionCS.ast [B] ExtOclExpressionCS.ast = templateCS.ast [C] ExtOclExpressionCS.ast = RelationCallExpCS.ast Inherited attributes [A] OclExpressionCS.env = ExtOclExpressionCS.env [B] templateCS.env = ExtOclExpressionCS.env [C] RelationCallExpCS.env = ExtOclExpressionCS.env RelationCallExpCS RelationCallExpCS ::= (identifierCS[1] '.')? identifierCS[2] '(' argumentsCS? ')' Abstract syntax mapping RelationCallExpCS.ast : RelationCallExp Synthesized attributes RelationCallExpCS.ast.referredRelation = let trans:RelationalTransformation = if (not identifierCS[1].ast.oclIsUndefined) then RelationCallExpCS.env.lookup('imported transformation'). referredElement.oclAsType(CollectionType)-> any(t | t.name = identifierCS[1].ast) else RelationCallExpCS.env.lookup('context transformation'). referredElement.oclAsType(RelationalTransformation) endif in trans.rule->any(r | r.name = identifierCS[2].ast). oclAsType(RelationalTransformation) RelationCallExpCS.ast.argument = argumentsCS.ast Inherited attributes argumentsCS.env = RelationCallExpCS.env argumentsCS argumentsCS[1] ::= OclExpressionCS (',' argumentsCS[2])? Abstract syntax mapping argumentsCS[1].ast : Sequence(OclExpression) Synthesized attributes argumentsCS[1].ast = Sequence{OclExpressionCS.ast}->union(argumentsCS[2].ast) Inherited attributes OclExpressionCS.env = argumentsCS[1].env argumentsCS[2].env = argumentsCS[1].env Operations context RelationalTransformation::lookupClassName(names: Sequence(String)) : Class post: result = let typesPackage:Package = self.modelParameter.usedPackage->any(p| not p.getEnvironmentWithoutParents().lookupPathName(names).oclIsUndefined()) in typesPackage.getEnvironmentWithoutParents().lookupPathName(names).oclAsType(Class)
Actions taken:
February 6, 2007: received issue
April 26, 2010: closed issue

Discussion:
Resolution: Deferred

Comment: 
Specifying more formally the mapping between the concrete syntax and the metamodel - as it was achieved for the OCL language - could be interesting. However it is a very time expensive task. Also, may be difficult to maintain. We prefer defer such decision to a future RTF.


Issue 10947: 7.13.1 Multiple transformation extension (qvt-rtf)

Click
here for this issue's archive.
Source: Nomos Software (Dr. Edward Willink, ed(at)willink.me.uk)
Nature: Uncategorized Issue
Severity:
Summary:
The concrete syntax for transformation supports multiple extension.
The abstract syntax supports only single extension.


Suggest: change the concrete syntax.

Resolution: Comment: Concrete syntax is incorrect. Resolution: The concrete syntax of the production <transformation> given in Appendix A of this report is changed as follows: <transformation> ::= 'transformation' <identifier> '(' <modelDecl> (';' <modelDecl>)* ')' ['extends' <identifier>] '{' <keyDecl>* ( <relation> | <query> )* '}' Replace the content of section 7.13.1 and 7.13.2 by the new content given in Appendix A of this report.
Revised Text:
Actions taken:
March 26, 2007: received issue
November 7, 2007: closed issue

Issue 10948: 7.13.1 Qualified query name (qvt-rtf)

Click
here for this issue's archive.
Source: Nomos Software (Dr. Edward Willink, ed(at)willink.me.uk)
Nature: Uncategorized Issue
Severity:
Summary:
The concrete syntax for a query uses a pathNameCS, yet the query is defined
within the scope of a transformation.


How should a scoped name be interpreted?


? is a scoped name only applicable for declaring externally definedc queries ?


Resolution: Comment: Concrete syntax is incorrect. Resolution: The concrete syntax of the production <query> given in Appendix A of this report is changed as follows: <query> ::= 'query' <identifier> '(' [<paramDeclaration> (',' <paramDeclaration>)*] ')' ':' <TypeCS> (';' | '{' <OclExpressionCS> '}') Replace the content of section 7.13.1 and 7.13.2 by the new content given in Appendix A of this report.
Revised Text:
Actions taken:
March 26, 2007: received issue
November 7, 2007: closed issue

Issue 11341: QVT 1.0 Section 7,8,9,10 : Navigating non-navigable opposite roles (qvt-rtf)

Click
here for this issue's archive.
Source: Nomos Software (Dr. Edward Willink, ed(at)willink.me.uk)
Nature: Uncategorized Issue
Severity:
Summary:
Issue : QVT 1.0 Section 7,8,9,10 : Navigating non-navigable opposite roles


UML models drawn with Rose allow an opposite role to be defined for a
uni-directional role. This practice is common but haphazard in UML Infrastructure,
EMOF, OCL and QVT specification diagrams.


However EMOF provides only the (run-time) usage of the model and so any
EMOF (or Ecore) model generator must strip non-navigable opposite roles.


QVT matches models at compile-time and matching has no inherent need to
observe navigation constraints. This is amply demonstrated by the Rel2Core
transformation that makes extensive use of, for instance, the inverse Key to Class
relationship.


----------------------------------


Problem: some QVT transformations require names for non-navigable opposite roles,
but those names cannot be present in layered multi-package EMOF meta-models.


The Rel2Core transformation of Section 10.3 cannot be implemented with QVT 1.0.


----------------------------------


Abandoning EMOF (or Ecore) compliance in favour of perhaps CMOF seems unacceptable.


Changing EMOF (or Ecore) to incorporate opposite roles is not possible because
an EMOF specification cannot be extended to include the opposite role of every
meta-model that will ever exist.


Even if it was, there would be a substantial delay until meta-modelling tools
adopted the change and a problem with poor standardisation and global
non-interference of opposite rolenames.


QVT must therefore support definition of non-navigable role names as part of a
transformation. ModelMorf provided a very practical concrete syntax solution,
whereby the reserved operation opposite(qualified-role-name) could be used as
the missing opposite role-name wherever a forward role-name could be used.


An upward compatible abstract syntax requires an additional is-opposite qualifier
for each referred property.


So for


QVTCore::PropertyAssignment add isOpposite:Boolean[0..1] default false.


QVTTemplate::PropertyTemplateItem add isOpposite:Boolean[0..1] default false.


QVTRelation::Key add oppositeParts:Property[0..*] { composed } 
and possibly relax the lower bound for
QVTRelation::Key add parts:Property[0..*] { composed }
with the constraint that parts.size() + oppositeParts.size() > 0 


Perhaps QVTOperational::Module needs an additional oppositeConfigProperty and
QVTOperational::ContextualProperty needs an additional isOpposite too.

Resolution:
Revised Text: (1) Replace the definition of Key (Section 7.11.3.5) by the following text: 7.11.3.5 Key A key defines a set of properties of a class that uniquely identify an instance of the class in a model extent. A class may have multiple keys (as in relational databases). Sometimes it may be necessary to specify a key in terms of opposite properties that are not navigable from the class. Please refer to section 7.4 for a detailed description of the role played by keys in the enforcement semantics of relations. Superclasses Element Associations identifies: Class [1] The class that is identified by the key. part: Property [0..*] Properties of the class that make up the key. oppositePart: Property [0..*] Opposite properties of the class that make up the key. (2) In the definition of PropertyTemplateItem (Section 7.11.2.4), add the following attribute definition: Attributes isOpposite:Boolean Specifies whether the referred property is owned by the opposite end class. An opposite property template item selects an object of the opposite end class that has this object as the value of the specified property. The default value of this property is false. Please refer to section 7.3 for an example that uses an opposite property in template specification. (3) Modify the grammar rule <keyDecl>, <classId>, <keyproperty> and <propertyTemplate> in section 7.13.5 as follows: <keyDecl> ::= 'key' <classId> '{' <keyProperty> (, <keyProperty>)* '}' ';' <classId> ::= <pathNameCS> <keyProperty> ::= <identifier> | 'opposite' '(' <classId> '.' <identifier> ')' <propertyTemplate> ::= <identifier> '=' <OclExpressionCS> | 'opposite' '(' <classId> '.' <identifier> ')' '=' <OclExpressionCS> (4) At the end of section 7.4 describing keys add the following text: Sometimes it may be necessary to use a non-navigable opposite role in the specification of a key. For instance, an attribute is identified by a combination of its name and the owning class. Suppose we have a meta model in which the 'Class' to 'Attribute' association 'attribute' is only navigable from Class to Attribute. We should still be able to use this association in the key specification of Attribute. E.g. key Attribute {name, opposite(Class.attribute)}; This specifies that an attribute is uniquely identified by its name and the class it belongs to. (5) At the end of section 7.3, just before the last sentence, add the following text: Sometimes it may be necessary to use a non-navigable opposite role in the specification of object templates. E.g. domain myModel a:Attribute {name = n, opposite(Class.attribute) = c:Class{}}; This specifies that the pattern will only match if the class the attribute belongs to is equal to 'c'. This is equivalent to the following template definition with condition: domain myModel a:Attribute {name = n} {c.attribute.includes(a)}; But the 'opposite' notation allows this to be specified in the template itself, leading to more compact specifications (6) In figure 7.6, add the new 'isOpposite : Boolean' attribute to the PropertyTemplateItem metaclass. (7) In Figure 7.7, add the additional 'oppositePart: Property [0..*]' association from Key metaclass to the Property metaclass.
Actions taken:
September 10, 2007: received issue
April 26, 2010: closed issue

Discussion:
Agree with the suggested extensions to the key and property template parts of the relations language. As for a more general support in other expressions, we should perhaps wait until the next OCL revision. 

Sometimes it may be necessary to use a non-navigable opposite role in the specification of a key. For instance, an attribute is identified by a combination of its name and the owning class. Suppose we have a meta model in which the 'Class' to 'Attribute' association 'attribute' is only navigable from Class to Attribute. We should still be able to use this association in the key specification of Attribute.
E.g.
	key Attribute {name, opposite(Class.attribute)};
This specifies that an attribute is uniquely identified by its name and the class it belongs to.

Similarly, it is useful to be able to specify object templates in terms of opposite properties.
E.g.
domain myModel a:Attribute {name = n, opposite(Class.attribute) = c:Class{}};
This specifies that the pattern will only match if the class the attribute belongs to is equal to 'c'. This is equivalent to the following template definition with condition:
domain myModel a:Attribute {name = n} {c.attribute.includes(a)};
But the 'opposite' notation allows this to be specified in the template itself, leading to more compact specifications.


Issue 12173: Section: 8.2.1.6 (qvt-rtf)

Click
here for this issue's archive.
Nature: Revision
Severity: Minor
Summary:
The extraCondition association needs revision: 1. The name does match with the diagram. 2. The cardinality is incorrect. Suggestion: Change the text with the following line: additionalCondition: OclExpression [*] {composes, ordered} 

Resolution:
Revised Text: In Section 8.2.1.6, replace extraCondition: OclExpression [1..*] {composes, ordered} By: additionalCondition: OclExpression [*] {composes, ordered}
Actions taken:
January 14, 2008: received issue
April 26, 2010: closed issue

Discussion:
That's true. The class description is obsolete in respect with the role naming found in Figure 8.1.


Issue 12198: Section: 8.2.1.7 (qvt-rtf)

Click
here for this issue's archive.
Nature: Clarification
Severity: Minor
Summary:
A clarification is needed in the text because it says "A variable parameter is an abstract concept..." and it can lead to confussion. A variable parameter can not be abstract because we could not create VarParameters for Helpers or Constructors (We could just create ModelParameters or MappingParameters). Suggestion: Remove the word "abstract". 

Resolution:
Revised Text: In Section 8.2.1.7, replace "A variable parameter is an abstract concept…" By: "A variable parameter is a concept…"
Actions taken:
January 25, 2008: received issue
April 26, 2010: closed issue

Issue 12362: Section: 8.4.7 (qvt-rtf)

Click
here for this issue's archive.
Nature: Revision
Severity: Minor
Summary:
The grammar rule used to produce a forExp doesn't coincide with the notation specified in the abstract syntax section for it (Pag 89, Section 8.2.2.6). The rule production in the grammar is wrong. Suggestion: Change the production rule: <for_exp> ::= ('forEach' | 'forOne') '(' <iter_declarator_list> ('|' <expression> )? ')' <expression_block> 

Resolution:
Revised Text: Revised Text: In Section 8.2.2.6, at the end of the "Notation" sub-section add the following text. """ When using a forEach expression in conjunction with a compute expression the following shorthand can be used: mylist->forEach(i;x:X=...|cond) { … } This is equivalent to: compute (x:X=...) mylist->forEach(i|cond) { … } This is similar to the shorthand notation for while expression (see 8.2.2.4). """
Actions taken:
April 1, 2008: received issue
April 26, 2010: closed issue

Discussion:
The intent of syntax rule: 
<for_exp> ::= ('forEach' | 'forOne') '(' <iter_declarator_list> (';' <declarator>)? ('|' <expression>)? ')' <expression_block> 
was to allow shorthand with the computeExp 
compute (x:X) mylist->forEach(i|cond) { … } 
<==> mylist->forEach(i;x|cond) { … } 
Similarly with what happens with While expression. 
However the explanation was missing in the notation sub-section. 


Issue 12373: Section: 8.2.2.22 (qvt-rtf)

Click
here for this issue's archive.
Nature: Revision
Severity: Critical
Summary:
UnpackExp should not compose targetVariable There are a lot of issues in this section: 1. name of Variable association was not updated to targetVariable. 2. {ordered} is missed. 3. variable should not compose. They should refer for instance a previously defined VarInitExp::referredVariable. 4. Parenthesis are missed in the first example (notation section). 5. Remember to update the diagram in figure 8.6 (pag 86). Note: These proposed changes are needed if you want to allow unpacking OrderedTuples using previously defined variables (which makes sense). Another (worst) alternative is forcing to declare new variables . In this case, the notation section should be changed. 

Resolution:
Revised Text: (1) Replace: variable : Variable [1..*] {composes} by targetVariable : Variable [1..*] {ordered} (2) Replace var x, y , z := self.foo(); // assuming foo returns a tuple of three elements. By var (x,y,z) := self.foo(); // assuming foo returns a tuple of three elements. (3) Update diagram 8.6 to reflect that targetVariable is not a composition
Actions taken:
April 7, 2008: received issue
April 26, 2010: closed issue

Issue 12374: MOF QVT 1.0, 8.2.2.22, Unclear specification of Unpack notation shorthand (qvt-rtf)

Click
here for this issue's archive.
Source: Nomos Software (Dr. Edward Willink, ed(at)willink.me.uk)
Nature: Uncategorized Issue
Severity:
Summary:
Section 8.2.2.22 provides no guidance on the meaning of:


var x:X;
var y:Y;
var z:Z;
...
var (x:X,y,z) := self.foo();


[If one of the variables in the left hand side, does exist ...]


Possible interpretations


a) x:X is always a syntactical shorthand.


Therefore the above is a shorthand for:


var x:X;
var y:Y;
var z:Z;
...
var x:X; var (x,y,z) := self.foo();


and consequently there is duplicate variable definition to be
reported as a semantic error.


b) x:X is a convenience type check assertion


Therefore the above is a shorthand for:


var x:X;
var y:Y;
var z:Z;
...
var (x,y,z) := self.foo();


with a successful validation of type consistency.


c) x:X is not available as a shorthand


Therefore the above is a syntax error.


------------------------------------


Interpretations b) and c) require semantic knowledge to resolve syntactic
sugar.


Interpretation a) is an unambiguous syntax shorthand that could be more
clearly
described by:


"The following example demonstrates a shorthand in which variables are both
declared
and assigned.


        var (x:X,y:Y,z) := self.foo();


Any variable name qualified by a type name is both a declaration and an
assignment,
with all declarations proceding the unapack assignment. 
The above example should therefore be analyzed as:


        var x:X; var y:Y; var (x,y,z) := self.foo();"


---------------------------------------------------------------------


Recommend interpretation a) with the above textual clarification.

Resolution:
Revised Text: (1) Replace the text: """If one of the variables in the left hand side does not exist, the notation is a shorthand for declaring the missing variables prior to the unpack expression. In such case, the type of the variables can be given. For instance, in the example above, if 'x' and 'y' does not exist, the expression var (x:X,y:Y,z) := self.foo(); is equivalent to: var x:X; var y:Y; var (x,y,z) := foo(); """ By the following text: """The following example demonstrates a shorthand in which variables are both declared and assigned. var (x:X,y:Y,z) := self.foo(); Any variable name which specifies a type name is both a declaration and an assignment, with all declarations proceding the unpack assignment. The above example should therefore be analyzed as: var x:X; var y:Y; var (x,y,z) := self.foo();" """
Actions taken:
April 8, 2008: received issue
April 26, 2010: closed issue

Issue 12375: Section: 8.1.14 (qvt-rtf)

Click
here for this issue's archive.
Nature: Revision
Severity: Significant
Summary:
QVT Operational Mappings claims in the overview section, the use of ListLiteralExpression (for instance to initialize a list), as in the section 8.1.14 (Pag 55) is shown. However, there is no way to represent this literal expression in the abstract syntax, due to: 1. There is no ListLiteralExp in the imperativeOCL package. 2. CollectionLiteralExp (from EssentialOCL) can't be used. There is a way to initialize lists, making use of the asList operator which appears in the Standard Library section (8.3.85 / Pag 112), however this should be clarified. Therefore, two possible solutions could be taken: Suggestion 1: Create a ListLiteralExp which should extend CollectionLiteralExp (From EssentialOCL). Suggestion 2: Update the overview examples, to properly ilustrate how to initialize lists. Besides, the grammar ( Pag 124) )should be consequently changed as well. (List { 1, 2, 3, } literal expressions wouldn't be supported). 

Resolution:
Revised Text: (1) Add a new subsection 8.2.2.33 ListLiteralExp, with the following content: A list literal expression is a literal definition for a mutable list type (see 8.2.2.25) . Superclasses: CollectionLiteralExp (From EssentialOCL) Associations: element : OclExpression [*] {composes,ordered} The values of the literal list. (2) Update the Figure 8.7 with the ListLiteralExp definition (3) Add the 'List' keyword in 8.4.7.1.
Actions taken:
April 8, 2008: received issue
April 26, 2010: closed issue

Discussion:


Issue 13331: QVTo Standard Lybrary and typedefs Issue. Extending OCL predefined types (qvt-rtf)

Click
here for this issue's archive.
Source: Open Canarias, SL (Mr. Adolfo Sanchez-Barbudo Herrera, adolfosbh(at)opencanarias.com)
Nature: Uncategorized Issue
Severity:
Summary:
As interpretation from the especification (pag 104), the way of adding new operations to OCL predefined types is creating new Typedef instances
which must have the OCL predefined type as the base type. The new operations are added to this new typedef. However there are several problems:
1. The specification doesn't provide any name for these typedefs.
2. The specification doesn't specify which type (QVT typedef or OCL predefined type) should be used when referencing such OCL predefined types in a QVTo transformation.


Solution for 1).
Suggestion a: Name the typedef with the same name of the base type. This provokes name's clash with the predefined type's name, due to there are two different types from two standard libraries
which have the same name. A possible solution, would be expliciting that typedefs (aliases) will never clash its name with its base type.

Suggestion b: Name the tpyedef with a different name, such as QVToXXXXXX or XXXX_Alias.

Solution for 2).
Suggestion a: Taking the typedef as the referenced type in QVTo transformations.
Suggestion b: Taking the OCL predefined type as the referenced type in QVTo transformations.
Suggestion c: Considering resolution of issue 13168, so that only OCL predefined exists, and therefore, the only type which can be referenced.

It's a little bit weird having 2 different types (a type, and its alias typedef) which represent just the same type, specially when they are related by a reference. 
My solution's preference in order are:
c) Just having one type to refer.
a) Since the typedef "extends" the behaviour of the predefined type (adding new operations), the former must be the referred one.
b) The OCL predefined type is referenced, but we must taking into account that operations added to the typedef are available.

Resolution: issue closed, duplicate of issue # 13252
Revised Text:
Actions taken:
December 22, 2008: received issue
January 26, 2009: issue closed, duplicate of issue # 13252