Issue 10646: Missing explanations in BNF
Issue 10934: 9.18 Undefined syntax
Issue 10935: 9.18 Identifiers
Issue 10936: 9.18 Undefined semantics
Issue 10937: 9.18: Realized
Issue 10938: 9.17 Variable composition
Issue 10939: 9.18 Trailing |
Issue 10940: 9.18 GuardPattern assignments
Issue 10941: 9.18 The middle direction packages
Issue 10942: 9.18 Top-level syntax
Issue 10943: 9.18 Anonymous Maps
Issue 10944: 9.18 EnforcementOperation
Issue 10945: 9.18 Typographics Issues
Issue 10947: 7.13.1 Multiple transformation extension
Issue 10948: 7.13.1 Qualified query name
Issue 11056: Provide the list of reflective MOF operations that are available
Issue 11058: Consider renaming collectselect as xcollectselect
Issue 11061: Consider using asTuple instead of tuple keyword for TupleExp
Issue 11108: Assignment.slotExpression
Issue 11341: QVT 1.0 Section 7,8,9,10 : Navigating non-navigable opposite roles
Issue 11602: Section: 7.13
Issue 11685: Section: 7.11.3
Issue 11686: Section: A1.1.1
Issue 11690: Section: 7.13.5
Issue 11708: 9.17.12, EnforcementOperation.operationCallExp should be composes
Issue 11825: Inconsistent Rule.transformation multiplicity/composes for Mapping
Issue 11826: Section 7.11.2.3: Empty CollectionTemplateExp is useful
Issue 12173: Section: 8.2.1.6
Issue 12198: Section: 8.2.1.7
Issue 12200: There is a reference to a figure that does not exist : figure 1.
Issue 12213: Relations Language: how will metamodels get into a transformation scrip
Issue 12260: Section: 7.13.3 / 8.4.2
Issue 12362: Section: 8.4.7
Issue 12367: Issue against QVT ptc/07-07-07 : relational grammar
Issue 12368: Issue against QVT ptc/07-07-07 : clause 7.2.3
Issue 12370: Section 8.7.1a production rule seems to be missing
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 10646: Missing explanations in BNF (qvt-rtf)
Click here for this issue's archive.
Source: THALES (Dr. Edward Willink, ed.willink@thalesgroup.com ed@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: 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.
9.18 Undefined syntax
---------------------
The syntax for TransformationName, DirectionName, MappingName, PropertyName and VariableName
is undefined. Presumably each of these is an Identifier (below) when defining, but a PathNameCS
when referencing.
The syntax for PackageName is undefined. Presumably it is an OCL PathNameCS.
The syntax for ValueOCLExpr is undefined. This is presumably an OclExpressionCS.
The syntax for BooleanOCLExpr is undefined. This could be an OclExpressionCS of Boolean type but ...
The syntax for SlotOwnerOCLExpr is undefined. This could be an OclExpressionCS of Class type but ...
If BooleanOCLExpr and SlotOwnerOCLExpr are parsed as OclExpressionCS the 'default' prefix
causes a major ambiguity for 'default(...).xx' as a parenthesised slot owner or function call.
It is necessary to make 'default' a reserved word within OCL expressions.
Suggest: define BooleanOCLExpr and SlotOwnerOCLExpr very narrowly.
Predicate ::= SimpleNameCS ("." SimpleNameCS)* "=" OclExpressionCS
Assignment ::= ["default"] SimpleNameCS ("." SimpleNameCS)* ":=" OclExpressionCS
Resolution: DEFERRED
The syntax of identifiers is undefined. The syntax for mapping clearly prohibits the use of a direction named 'where'. Suggest: identifier is an OCL simpleName, less the new reserved words (check default enforce imports map realize refines transformation uses where) Suggest: a string-literal may be used as an identifier to support awkward identifiers such as 'where'.
Resolution: DEFERRED
The whole Concrete Syntax section deserves a much more substantial description. In particular... The mechanism by which a package name is located is unresolved, perhaps deliberately, but the omission should be explicit. What constraints exist on forward referencing of names? Transformations and mappings could be ordered so that forward references are avoided, but large modules benefit from an alphabetical ordering of elements, so requiring a parser friendly order is not user friendly.
Resolution: DEFERRED
The concrete syntax defines 'realized', but section 10 consistently uses 'realize'. Suggest: 'realize' The concrete syntax defines 'realized' for a single element of a comma-separated list. Section 10 appears to expect that 'realized' is a prefix to a comma-separated list. Suggest: 'realize' is a comma-separated list prefix. (semi-colon separation is available for distinct realize/not-realize.)
Resolution: DEFERRED
Issue 9379 made Pattern.bindsTo a non-composition. This deprives Core of any parent for its non-realized variables. Suggest: move BottomPattern.realizedVariables to CorePattern.variables. CorePattern.variables then composes all variables declared for the pattern. A class-type check of RealizedVariable/Variable derives the 'isRealized' property.
Resolution: DEFERRED
GuardPatterns and BottomPatterns with Variables but without Constraints must end with a '|'.
This is inelegant. Better to only require '|' as prefix to constraints (or to require it always).
Suggest:
GuardPattern ::= Variable ("," Variable)* ["|" (Constraint ";")+]
similarly BottomPattern
Resolution: DEFERRED
The concrete sysntax allows guard patterns to have assignments. The abstract syntax does not. Suggest: GuardPattern uses Predicate rather than Constraint
Resolution: DEFERRED
A Direction defines the packages used by each direction domain.
Nothing defines the (additional) packages used by the middle area. For instance
there is no place to specify the trace class model generated by the RelationToCore
transformation. With many transformations and mappings in a QVTcore it does not
seem appropriate to overload TransformationName or MappingName as a hook to
reference the appropriate middle meta-models; different Mappings may have distinct
middle meta-models; multiple transformations may share the same middle meta-model.
(Core should be a first class programming language, not just one that supports
the eccentricities of a RelationToCore conversion.)
Suggest: a DirectionName between "where" and "(" in Mapping.
This reads very naturally:
map ...
check left (...
enforce right (...
where middle (...
But we also need to fix the Abstract Syntax. As a minimum a Mapping needs a
middle-typed-model property to capture the missing information. With this addition
a Mapping duplicates so much of a CoreDomain/Area, that it is more appropriate
to eliminate Area altogether, merging it into CoreDomain. Area is eliminated
from Mapping, and added as an additional CoreDomain referenced by the middleDomain
property.
So:
CoreDomain extends Domain
CoreDomain.variables : RealizedVariable [0..*] composed
CoreDomain.bottomPattern : BottomPattern [1] composed
CoreDomain.guardPattern : GuardPattern [1] composed
Mapping extends Rule
Rule.domain : Domain [0..*] composed (must be at least CoreDomain[3])
Mapping.specification - no change
Mapping.local - no change
Mapping.context - no change
Mapping.middle : CoreDomain [1] (must be in Rule.domain)
Resolution: DEFERRED
The concrete syntax does not specify a parsing goal. If the first element (Transformation) is taken to be the goal, most of the rest of the grammar is orphaned. Suggest: TopLevel ::= (Transformation | Mapping)*
Resolution: DEFERRED
Section 10 uses anonymous maps for composed mappings. The Concrete Syntax does not allow this. Similarly, an 'in' is not appropriate for a composed mapping. Suggest: ComposedMapping ::= "map" [MappingName] ["refines" MappingName] MappingPatterns where MappingPatterns is the common part of Mapping.
Resolution: DEFERRED
There is no concrete syntax for enforcement operations.
Suggest: a BottomPattern Constraint may also be
'create' OperationCallExpCS
'delete' OperationCallExpCS
Resolution: DEFERRED
Style. Use same font and presentation as 7.12.3, 8.4.
Typo. Remove '(' preceding '","' in BottomPattern.
Typo. Remove 'e' in 'Assignement'.
Resolution: DEFERRED
The concrete syntax for transformation supports multiple extension. The abstract syntax supports only single extension. Suggest: change the concrete syntax.
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 ?
Is not very clear what are the reflective MOF operations that are available to QVT operational transformation writers
deferred
For uniformity, collectselect should be renamed xcollectselect following the distinction between collect and xcollect (imperative version).
Resolution: Deferred
Consider using asTuple instead of tuple keyword for TupleExp since asX() is usually used for conversions.
Comment:
The TupleExp metaclass can in fact be replaced by a simple operation in the standard library.
Resolution
(1) Remove the TupleExp metaclass section description 8.2.2.21
(2) Within section 8.3.3 add the description of a new operation named asOrderedTuple defined as:
Object::asOrderedTuple : OrderedTuple(T).
Converts the object into an ordered tuple. If the object is a already an ordered type no change is done. If the object is a OCL Tuple, the list of attributes become the anonymous content of the ordered tuple. Otherwise, the operation creates a new tuple with a unique element being the object.
(3) Apply diagram update described in Appendix D.
9.3 Assignment.slotExpression should be PropertyAssignment.slotExpression (VariableAssignments have no slot)
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.
have built a transformation engine based on QVT relations. The QVT relations example in Annex A contains a 'function' PrimitiveTypeToSqlType at the end of the example in textual syntax. This example is the only relations example in the whole spec. Nowhere is the semantics of 'function' defined nor contains the grammar of the concrete syntax a function keyword. However, 'query' is defined. Is 'function' another name for 'query'?
It is not clear when and how you choose a top-level and not-top-level relation. Primitive domains, the reason for them and the use of them, are not explained although they are used in the Relation language example A1.1.1
top relation AssocToFKey { pKey : Key; ... when { ...; pKey = destTbl.key; } ... } In my opinion that doesn't work. pKey is of type Key, destTbl.key is of type OrderedSet key, isn't it ?
The "import" feature of Relations Language is not yet explained. And there is no example for it, too. For instance what does the "unit" in "import <unit>;" mean ?
9.17.12 EnforcementOperation, Figure 9.3
----------------------------------------
The definition: "operationCallExp : OperationCallExp[1]"
and the corresponding "*" enforcementOperation multiplicity in
Figure 9.3 provides a consistent definition of a shared reference
to a Call expression. There is no indication of where this
expression might be contained. It is unlikely that such
expressions can usefully be shared since they must refer to
invocation-site-specific variables.
Therefore:
Change the definition to:
operationCallExp : OperationCallExp[1] {composes}
and draw the composition with 0..1 parent multiplicity.
Mapping is a Rule and Rule.transformation has unit multiplicity and is a container.
Therefore Rule.context can never be a container.
This could be fixed in a number of ways:
Fix 1: Change Rule.transformation to 0..1
--> allow hierarchical Rule containment
--> all Transformation rules are distinctly named
-- no representation change
-- minor semantic relaxation for QVTr/QVTo
-- minor semantic surprise for QVTc - composed mapping has null Mapping.transformation.
Fix 2: Change Rule.context to not composes
--> require flat Rule containment
--> Transformation can have multiple unnamed rules
-- no change for QVTc/QVTo
-- representation change for QVTc
Fix 3: Change opposite of Transformation.rule from Rule.transformation[1] to Rule.context[1]
Redefine Rule.transformation[1] as a derived property
Remove mapping.context (inherited from Rule)
-- Doesn't work: context needs to be NamedElement to be either Rule or Transformation
Fix 4: Change opposite of Transformation.rule from Rule.transformation[1] to Rule.owningTransformation[0..1]
Redefine Rule.transformation[1] as a derived property
Rule.transformation := owningTransformation
Mapping.transformation := if context then context.transformation else owningTransformation endif
-- no representation change
-- minor semantic relaxation for QVTr/QVTo
Recommend 4.
7.11.2.3 and Figure 7.6 both impose a lowerBound of 1 on CollectionTemplateExp.member and CollectionTemplateExp.rest. However, the concrete syntax permits an empty match. This empty match is exploited in the UnsharedWhenVarsToMgVars relation in Section 10. Suggest: Change CollectionTemplateExp.member to [0..*] Change CollectionTemplateExp.rest to [0..1] Add a sentence to clarify the empty match semantics.
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}
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".
There is a reference to a figure that does not exist : figure 1.
Concerning to Relations Language, how will the metamodels get into a transformation script ? Is there a technique similar to Operational Mappings using metamodel declaration and modeltypes ? The RL sample transformation script in annex A.1 (pp 164) doesn't declare the metamodels. The OM sample (A.2.3) does. There is some syntax for declaring and using metamodels and modeltypes in OM (pp118), there isn't for RL (pp38).
The specification introduces comments by concrete syntax. Comments within the abstract syntax are not considered. This is i.e. undesirable for automated analysis of software product quality to which transformations are subject. One would again need to analyze the AST instead of the transformation metamodel. So I propose to introduce comments for transformations.
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>
Section 7.13.5 Relation BNF The grammar rule for template is incorrect (It does not allow a template to have embedded within it another template. The example in Appendix A will not compile with such a grammar.) It says: <propertyTemplate> ::= <identifier> '=' <OclExpressionCS> It should says: <propertyTemplate> ::= <identifier> '=' ( <template> | <oclExpressionCS
Text of Clause 7.2.3 is unclear: Suggested rewrite: (1) Add the following as the first two sentences of the first paragraph. "In the evaluation of a Transformation, one or more domains are specified as target. The phrase 'executing in the direction of [some domain]' refers to these domains." Then change a few words in the paragraph as suggest by the text in [] below: "Whether or not the [change "the" to "a"] relationship maybe [should be "is"] enforced is determined by the target domain, which may be marked as checkonly or enforced. When a transformation [change "transformation" to "relation"] is enforced [change "enforced" to "evaluated"] in the direction of a checkonly domain, it is simply checked to see if [change "if" to "whether"] there exists a valid match in the relevant model that satisfies the relationship. When a transformation executes in the direction of the model of an enforced domain, if checking fails, the target model is modified so as to satisfy the relationship, i.e. a check-before-enforce semantics." [Strike the words beginning with "i.e." "check-before-enforce" is new terminology that is neither defined nor helpful.]
a production rule seems to be missing: <module_element> ::= <modeltype> Since, a transformation file can define several transformations and libraries (modules), it is desirable having the possibility of defining modeltypes exclusively to a module. These "local" modelTypes should belong to the scope of a module, and it shouldn't be accessible to the remaining defined modules (unless the use of extension mechanisms is specified).
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.
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.
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).