Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "QVTd Relation Overriding"

(Rewrite reification in QVTc, QVTu, QVTm, QVTs)
(QVTr2QVTc Overrides 'Rewrite')
Line 19: Line 19:
 
Given a transformation comprising Mx mappings/relations, Gx guard functions, and Bx bottom actions:
 
Given a transformation comprising Mx mappings/relations, Gx guard functions, and Bx bottom actions:
  
  MA: if GA() BA();
+
  MA: when { GA(); } BA();
  MB overrides MA: if GB() BB();
+
  MB overrides MA: when { GB(); } BB();
  MC overrides MB: if GC() BC();
+
  MC overrides MB: when { GC(); } BC();
  MD overrides MA: if GD() BD();
+
  MD overrides MA: when { GD(); } BD();
  
we can rewrite as:
+
we can rewrite the polymorphs (relation that participate in an overrides hierarchy) as siblings (relations that share a similar structural interface), refined guard functions and dispatchers:
  
  MA: if GAdash() BA();
+
  MAdash: when { GAdash(); } BA();
  MB: if GBdash() BB();
+
  MBdash: when { GBdash(); } BB();
  MC: if GCdash() BC();
+
  MCdash: when { GCdash(); } BC();
  MD: if GDdash() BD();
+
  MDdash: when { GDdash(); } BD();
  
 
  GAdash() = !GBdash() && !GDdash() && GA();
 
  GAdash() = !GBdash() && !GDdash() && GA();
Line 36: Line 36:
 
  GDdash() = GD();
 
  GDdash() = GD();
  
i.e. introduce and use Gxdash() equal to Gx() anded with the Gxdash()es of all directly overriding relations.
+
MA: where { MAdash(); MBdash(); MCdash(); MDdash(); }
 +
MB: where { MBdash(); MCdash(); }
 +
MC: where { MCdash(); }
 +
MD: where { MDdash(); }
 +
 
 +
* introduce Gxdash() equal to Gx() anded with the Gxdash()es of all directly overriding relations.
 +
* introduce Mxdash() equal to Mx() using Gxdash() to replace the override.
 +
* replace Mx by a dispatcher to all the new siblings
  
 
===Rewrite reification in QVTr2QVTc===
 
===Rewrite reification in QVTr2QVTc===
Line 46: Line 53:
 
Should relations that are not overridden also have their predicates structured as guard functions?
 
Should relations that are not overridden also have their predicates structured as guard functions?
 
* pro: a simplification reducing QVTr2QVTc complexity
 
* pro: a simplification reducing QVTr2QVTc complexity
* pro: sibling (similar input, distinct predicate) mappings are also exposed to QVTi dispatch optimization
+
* pro: sibling mappings are also exposed to QVTi dispatch optimization
 
* con: increases stress on QVTs deep operation analysis - needs to work anyway
 
* con: increases stress on QVTs deep operation analysis - needs to work anyway
 
* con: further deviation from RelToCore
 
* con: further deviation from RelToCore

Revision as of 04:57, 17 May 2017

The QVT specification has a relatively clear specification that QVTr relation may override, but no clues as to how this is mapped to QVTc that has no overrides concrete syntax, even though it inherits an overrides capability from QVTb.

This working document considers how overriding might be supported. It takes over from

QVTc Choices

QVTc refinement syntax is an additive capability and therefore not suitable for implementing the QVTr replacement semantics of QVTr overrides.

We could add overrides syntax and semantics to QVTc, which then passes the buck to QVTi. But since we already need an 'alternator' to dispatch multiple similar but differently predicated mappings efficiently, we may be able to kill two birds with one stone.

QVTc is relatively simple. It solves the mapping sequencing problem by inter-trace class references/dependencies. Can it solve the overrides problem as-is? Let's go with this.

QVTr2QVTc Overrides 'Rewrite'

There is a simple rewrite that reifies overrides in QVTc without requiring any new capabilities, although it may stress some existing ones.

Given a transformation comprising Mx mappings/relations, Gx guard functions, and Bx bottom actions:

MA: when { GA(); } BA();
MB overrides MA: when { GB(); } BB();
MC overrides MB: when { GC(); } BC();
MD overrides MA: when { GD(); } BD();

we can rewrite the polymorphs (relation that participate in an overrides hierarchy) as siblings (relations that share a similar structural interface), refined guard functions and dispatchers:

MAdash: when { GAdash(); } BA();
MBdash: when { GBdash(); } BB();
MCdash: when { GCdash(); } BC();
MDdash: when { GDdash(); } BD();
GAdash() = !GBdash() && !GDdash() && GA();
GBdash() = !GCdash() && GB();
GCdash() = GC();
GDdash() = GD();
MA: where { MAdash(); MBdash(); MCdash(); MDdash(); }
MB: where { MBdash(); MCdash(); }
MC: where { MCdash(); }
MD: where { MDdash(); }
  • introduce Gxdash() equal to Gx() anded with the Gxdash()es of all directly overriding relations.
  • introduce Mxdash() equal to Mx() using Gxdash() to replace the override.
  • replace Mx by a dispatcher to all the new siblings

Rewrite reification in QVTr2QVTc

We need to synthesize Gx() as a Function/Operation invoked from the Mapping Guard rather than being inlined in the Mapping Guard. All type checks must use explicit oclIsKindOf's since we cannot exploit 'mismatch is predicate fail' semantics within Function/Operations.

Whether Function/Operation should be used to exploit/bypass uniqueness optimizations is unclear. Probably doesn't matter. If QVTi understands what's happening, QVTi can optimize merged invocations behind the uniqueness of the polymorphic dispatcher.

Should relations that are not overridden also have their predicates structured as guard functions?

  • pro: a simplification reducing QVTr2QVTc complexity
  • pro: sibling mappings are also exposed to QVTi dispatch optimization
  • con: increases stress on QVTs deep operation analysis - needs to work anyway
  • con: further deviation from RelToCore

2 strong pro's, 2 weak con's => always create guard functions.

A distinct guard function may allow a failed guard to have a distinct and more optimum trace class for incremental update.

Rewrite reification in QVTc, QVTu, QVTm, QVTs

There should be no change, but deep operation dependency analysis will need to work for QVTs.

But, what about partitioning? Is it necessary to partition guard functions?

Rewrite reification in QVTi / run-time

Nothing necessary, but significant optimizations available.

The dispatch of one or Micromappings from a Connection currently invokes each relevant Micromapping. No change since each synthetic override has full exclusions in its own predicate. However there may be many available Micromappings each with a guard function. These can be hoisted into a dispatcher and CSE applied to dramatically reduce recomputation. Since the failed guard functions are invoked by the dispatcher, the failures do not need to be traced, incremental redispatch from the Connection will redetermine what needs to be done correctly. These optimizations apply to siblings as well as polymorphs.

If we add a QVTi syntax to support the decision tree, the optimized dispatch can work in interpreted as well as code generated execution.

The CSE will need to work on the OCL expressions and so we need to generalize CSE support from CG-only. [1]

Back to the top