Open eclipse-qvtd-bot opened 1 week ago
By Ed Willink on Feb 27, 2017 09:18
(In reply to Ed Willink from comment #0)
A non-trivial RelationCallExp therefore maps to a Txxxx._matched access.
This doesn't seem to be necessary. The _matched term can be an expression tree term, and'ing the '=' checks of each RelationCallExp argument.
By Ed Willink on Feb 28, 2017 05:27
(In reply to Ed Willink from comment #1)
and'ing the '=' checks of each RelationCallExp argument.
'=' for all inputs and outputs leads to a ridiculous search for a match; the inputs can use the already known values, potentially giving a simple lookup and test of the outputs. But only if there is input-to-middle navigability, which the complexity may inhibit, so there is still a search of all middle trace candidates.
Implementing each of the when-or terms in separate mappings gives simple efficient code. Why is the combination horrible?
By Ed Willink on Mar 02, 2017 04:23
But is it sound?
when { RClassToClass(c1sup, c2sup) or ClassToClass(c1sup, c2sup); }
is intended to try two alternate predecessors to discover c2sup.
What if both predecessors offer different c2sup? Presumably this is a predicate failure.
Does the relation wait for the second, that may never happen? No. 'when' is 'active' so both predecessors are attempted, the subtlety is that for an optional invocation, we wait for 'success' or 'failure' as opposed to failing immediately if the predicate fails,. The 'or' introduces an SSA tree
if RClassToClass(c1sup, c2supA) succeeded\ if ClassToClass(c1sup, c2supB) succeeded\ if c2supA == c2supA => c2sup = c2supA\ else => PREDICATE FAIL\ else => c2sup = c2supA\ else if ClassToClass(c1sup, c2supB) succeeded => c2sup = c2supB\ else => PREDICATE FAIL
A similar formulation for and/not/xor. The logic is wait for all invocations to succeed/fail then perform SSA logic flow to assign the results/fail.
In QVTc/QVTi-like primitives
// useful locals\ TRClassToClass i1 := c1Sup.TRClassToClass; \ TClassToClass i2 := c1Sup.TClassToClass;\ // or logic\ i1ori2 := (i1.$success xor i2.$success)\ or (i1.$success and i2.$success and i1.c2sup = i2.c2sup);\ c2sup1orc2sup2 := if i1.$success then i1.c2sup else i2.c2sup endif; \ // overall predicate,SSA\ i1ori1 = true;\ c2sup := c2sup1orc2sup2;
Unfortunately the c2sup1orc2sup2 is unlikely to be analyzed as not-null so we need a not-null cast. See Bug 512945.
Much more sensibly the two concrete relations could both override an 'abstract' Class2Class that is used as a simple when RelationCallExp.
By Ed Willink on Mar 03, 2017 15:16
Another important example is forAll/exists:
when {\ aCollection->forAll(e | AnotherRelation(e, _));\ }
to test whether something is true for all elememts. In contrast a CollectionTemplateExp member goves separate matches for each member.
By Ed Willink on Mar 03, 2017 15:44
Similarly
where {\ aCollection->forAll(e | AnotherRelation(e, _));\ }
solves the problem of how a parent relation descends to each child.
By Ed Willink on Mar 06, 2017 03:54
Bug 509404 suggests that we need
when { FlakyMapping(...).oclIsInvalid(); }
and of course also Bug 509713
when { FlakyMapping(...).oclIsError(); }
Clearly a RelationCallExp should be treated generally as a call returning:
true => success\ false => failure, predicates not satisfied\ ?? null => not-ready\ invalid => OCL invalid occurred\ (error => run-time error occurred)
Challenge: support RelationCallExp from within an Operation/Function
By Ed Willink on Mar 13, 2017 10:30
Copy support in Bug 462165#c4 requires that a middle object be testable as non-null to detect the execution/non-execution of a mapping.
By Ed Willink on Apr 14, 2017 03:52
Bug 515237 identifies that plumbing between multiple when's may benefit from 'executing' some relation variables.
By Ed Willink on Apr 20, 2017 03:33
A when if-tree such as "if A(...) then B(...) else C(...) endif" for non-top B/C may require a multi-level speculation by the partitioner to ensure that only B or C is invoked and only after the A predicate has been evaluated. Multi-level speculation handled by Bug 515490.
where clauses may also use arbitrary Boolean logic. However a where RelationCallExp unlike a when RelationCallExp may not test the result of the RelationCallExp. The logic surrounding a where RelationCallExp guards its invocation.
By Ed Willink on Oct 04, 2017 09:57
A non-top RelationCallExp as a then/else of an IF is dubious at least in QVTc since it is not possible to make conditional assignments to the invocation variable.
Unsuccessful example from ATL2QVTr:
top relation mapOperationCallExp_Helper overrides mapOperationCallExp { ...\ when {\ if atlOperations->notEmpty() then\ mapHelper_Operation(...) else false endif;\ }\ }
solvable with a domain predicate.
By Ed Willink on Feb 26, 2018 03:52
Since abandoning the QVTc intermediate between QVTr and QVTs, some difficult challenges vanish, but once each challenge is viewed through the is-this-a-helpful-final-truth-restriction rather than the is-this-straightforward-to-implement prism, some challenges remain. In particular
xor-predicate logic; the success of the first term must be invisible if the second term also succeeds (and is also invisible).
non-top whens / complex relation call expressions; a long cascade of partitioned micromappings my be necessary.
cycles; an entire cycle may need identification before a single subtle predicate may give a go/no-go on progress/rejection.
These are potentially soluble once the speculating logic is enhanced to cope with a global vote before progressing;else we would have to support roll-back.
By Ed Willink on Feb 02, 2020 10:19
(In reply to Ed Willink from comment #0)
A non-trivial RelationCallExp therefore maps to a Txxxx._matched access.
?? a similar field for speculation status ??
We currently have s0local and s0global status. But s0loacl us probably redundant wrt some early trace assignment.
(In reply to Ed Willink from comment #10)
Unsuccessful example from ATL2QVTr:
top relation mapOperationCallExp_Helper overrides mapOperationCallExp { ... when { if atlOperations->notEmpty() then mapHelper_Operation(...) else false endif; } }
solvable with a domain predicate.
Once we start implementing multiple problems arise:
when {\ atlOperations->notEmpty();\ mapHelper_Operation(atlOperations->any(true)...);\ }
does not impose any sequencing, so the any executes
when {\ atlOperations->notEmpty() and\ mapHelper_Operation(atlOperations->any(true)...);\ }
could have short circuiting but we build a commutative uncnditional graph. any() executes. Should QVTd convert and etc to if to force short circuit conditionality?
when {\ if atlOperations->notEmpty()\ then mapHelper_Operation(atlOperations->any(true)...)\ else false\ endif;\ }
might work but generates double code - investigate.
By Ed Willink on Feb 18, 2020 11:03
(Double code was a stupid typo.)
Any form of conditional when DoMap seems very dubious multiplicty-wise...
The trace.wDoMap will have to be [?] since it might not happen, and we will need to guarantee to assign null.
But the arguments for DoMap will want to be [1] giving a contradiction on the local node multiplicity.
We are dodging the desired
when {\ atlOperations->notEmpty();\ mapHelper_Operation(atlOperations->any(true)...);\ }
because QVTs has lost the sequencing. An InvalidityAnalaysis could compute it.
As a workaround:
when {\ -- atlOperations->notEmpty();\ mapHelper_Operation(if atlOperations->notEmpty() then atlOperations->any(true)... else ... endif);\ }
This avoids the awkward optionals and leaves the speculation exposedto the global speculator.
Either way we may be forced to require that a RelationCallExp must be a predicate root. If a complex predicate expression is required, maybe it must be manually expressed as multiple relations.
| --- | --- | | Bugzilla Link | 512738 | | Status | NEW | | Importance | P3 normal | | Reported | Feb 26, 2017 12:02 EDT | | Modified | Feb 18, 2020 11:03 EDT | | Depends on | 552823, 512945 | | Blocks | 513376, 515236, 462165, 509281, 512737 | | See also | 509404, 509713, 515237, 515490 | | Reporter | Ed Willink |
Description
The MiToSi example, Bug 512737, requires an alternation of when predicates.
We do not currently support logic on predicate validity.
If the middle model class has a Boolean _matched property, we can use this in logic expressions.
A non-trivial RelationCallExp therefore maps to a Txxxx._matched access.
?? a similar field for speculation status ??