Bug 525710 - [qvtr] Support collected mappings
Summary: [qvtr] Support collected mappings
Status: NEW
Alias: None
Product: QVTd
Classification: Modeling
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows NT
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 490172 509281
  Show dependency tree
 
Reported: 2017-10-07 04:09 EDT by Ed Willink CLA
Modified: 2017-10-07 05:02 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Willink CLA 2017-10-07 04:09:46 EDT
QVTr is bidirectional and so the unidirectional

    out := in.SomeMapping(...);

is expressed as

    when/where { SomeMapping(in, out, ...) }

For collections the unidirectional

    outs := ins->SomeMapping(...),

has no counterpart making collection manipulation hard unless an ordering is lost by each SomeMapping enforcing its containment.

Why not allow:

    when/where { SomeMapping(ins, outs, ...) }

Arguments must either be consistent with the corresponding root-variable or a consistent N-dimensional collection of a consistent type for the corresponding root-variable. The invocation therefore determines a single rather than a permutation of 1:1 element mappings. 

Implementation: just some careful QVTr2QVTc synthesis - cannot be realized by a QVTr2QVTr mapping.
Comment 1 Ed Willink CLA 2017-10-07 04:37:24 EDT
(In reply to Ed Willink from comment #0)
> Why not allow:
> 
>     when/where { SomeMapping(ins, outs, ...) }

> Implementation: just some careful QVTr2QVTc synthesis

But if any elemental SomeMapping fails, the collected SomeMapping must fail without any model changes. Must therefore synthesize a collected micromapping that evaluates all predicates before any commits.

> - cannot be realized by a QVTr2QVTr mapping.

?? when/where
{
 let iMax = ins->size().max(outs->size()) in
 let indexes = Sequence{1..iMax} in
 indexes->forAll(i, SomeMapping(ins->at(i), outs->at(i), ...)
}

Declaratively, iMax = ins->size().max(outs->size()) is fine but redundant since both collections are finally same-sized. For execution, the transient nature is a bit suspect, perhaps requiring special treatment of the idiom.

A Transformation::forAll variant iteration could be clearer, e.g.

?? when/where
{
 this.forAll(i, j, SomeMapping(ins->at(i)->at(j), outs->at(i)->at(j), ...))
}

-------

But we still have the problem of making a multi-mapping atomic.

If the components of the multi-mapping can somehow be linked in the QVTc...QVTm the QVTs partitioner could ensure correct semantics.

If QVTc...QVTm support multi-dimensional arguments with extra iterators, the atomic functionality never gets iterated prematurely.
Comment 2 Ed Willink CLA 2017-10-07 05:01:46 EDT
(In reply to Ed Willink from comment #1)
> But we still have the problem of making a multi-mapping atomic.

This is just another variant of the non-top when hazard. There is no hazard for tops since they happen independently. The collected mapping invocation just collates from the traces. No hazard for wheres since they happen independently.

If a collected mapping assigns a container and ordering while each mapping also assigns a container without ordering, we probably need a WFR diagnosis. See Bug 509281.