Bug 480194 - [qvti] Introduce an IfStatement
Summary: [qvti] Introduce an IfStatement
Status: NEW
Alias: None
Product: QVTd
Classification: Modeling
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows NT
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 546617 500369
Blocks: 508267
  Show dependency tree
 
Reported: 2015-10-20 06:32 EDT by Ed Willink CLA
Modified: 2020-01-27 09:08 EST (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 2015-10-20 06:32:40 EDT
/org.eclipse.qvtd.cs2as.compiler.tests/src/org/eclipse/qvtd/cs2as/compiler/tests/models/example4

has a simple metamodel with unit multiplicity containment.

The Composition descent in the schedule needs a 0/1 if test to guard the nested call.

It can be fudged by a MappingLoop over 0/1 element, but it's not very elegant.
Comment 1 Ed Willink CLA 2016-08-27 03:56:02 EDT
Bug 500369 suggests a QVTi to QVTa migration.

An IfStatement naturally forms part of a testing capability for e.g. a TypeCheckPredicate.
Comment 2 Ed Willink CLA 2016-09-16 04:41:21 EDT
Migrating get dependencies from a domain-level checkingProperties to an AccessStatement requires an IF to enable the AccessStatement to be on a conditional path. This in turn requires the very strong SSA characteristic of all variables are initialized at the point of declaration to be weakened to initialized exactly once before use, allowing declaration outside an IF, with variant initialization inside the IF. This is relatively straightforward in the interpreter but is harder in the CG.

For now an 'observe' capability per-statement avoids the need for domains and can probably be narrowed by multiple intermediate temporaries.

WIP on IF etc on ewillink/480194
Comment 3 Ed Willink CLA 2016-09-22 05:27:41 EDT
(In reply to Ed Willink from comment #0)
> The Composition descent in the schedule needs a 0/1 if test to guard the
> nested call.

Does it? Surely it can just be invoked and the "check" qualifier will perform the type check automatically.
Comment 4 Ed Willink CLA 2016-11-01 09:27:30 EDT
Bug 506806 demonstrates that conditional execution is mandatory to avoid

var csElseIsNull : Boolean[1] := csElse = null;
var asElse : astm::Visitable := csElse.ast;
var asElse2 : astm::Visitable := if csElseIsNull then null else asElse 

evaluating csElse.ast when csElse is null.

Must do

var csElseIsNull : Boolean[1] := csElse = null;
var asElse2 : astm::Visitable;
if (if csElseIsNull) {
    asElse2 := null;
}
else {
    var asElse : astm::Visitable := csElse.ast;
    asElse2 := asElse;
}

We can require a strong exactly-once-on-each-path assignment rule.
Comment 5 Ed Willink CLA 2016-11-04 07:50:23 EDT
(In reply to Ed Willink from comment #4)
> Bug 506806 demonstrates that conditional execution is mandatory to avoid

The actual Bug 506806 problem was inaccurate analysis of the conditional sub-graphs. 

Yet another abortive attempt at introducing (CG)IfStatement(CS) is therefore on ewillink/480194a.
Comment 6 Ed Willink CLA 2017-08-25 03:17:01 EDT
An if capability would be needed if we need to be able to implement a single mapping override dispatcher. See Bug 515327.
Comment 7 Ed Willink CLA 2017-10-02 07:03:03 EDT
Two convincing use cases, both soluble inefficiently by multiple mappings with distinct matches.

a) merge optimization

Given two similar micromappings M1, M2, it may be appropriate to merge them. It may then be necessary to:

if (...isM1...) then
    new-statements of m1
else 
    new-statements of M2
endif.

b) recursion termination

Given a recursion it may be appropriate to:

if (...recursion-done...) then
    new-statements of end case
else
    new-statements of recursion case
    recursive call
endif
    
Arguably the if-statement is procedual so an else may be redundant. Probably easier to mandate a perhaps empty else in the CS/AS.
Comment 8 Ed Willink CLA 2018-03-05 07:17:23 EST
A related use case comes from a need to provide a try-catch handler so that what happens following a failure is programmed rather than magically built-in.
Comment 9 Ed Willink CLA 2018-05-19 03:25:13 EDT
(In reply to Ed Willink from comment #7)
> a) merge optimization
> 
> Given two similar micromappings M1, M2, it may be appropriate to merge them.

This is exactly what is necessary to optimize the override dispatch so that instead of one activator per override creating one derived trace per override and all but one subsequent executions failing, the first stage of each override can be merged to share control variables, create just one trace and execute just one path.

While this could be done as a magic bit of CG for a connection dispatcher, that requires considerable insight in the CG. The QVTs graphical visualization has been consistently useful, so better to allow a QVTs merge. This also may offer 'single step' visual debugging.

The challenge is providing a conditional control on green edges/nodes. Simplistic extra control edges could be very klunky. A sub-region with a guard could be clearer. The guards could come from conventional and/not logic but each elseif level requires two ands and a not; again klunky. Perhaps a 2-input enable+condition, 2-output then+else diamond. The Boolean enable input is routed to then/else by the Boolean condition input.
Comment 10 Ed Willink CLA 2018-11-10 03:30:27 EST
(In reply to Ed Willink from comment #9)
> Perhaps a 2-input enable+condition, 2-output then+else diamond.

Multi-semantic graphical inputs will be confusing.

Perhaps an arbitrary number of enable inputs that are and-ed together and a single fail output per sub-region. The fail output can contribute to daisy-chain successors.

QVTs: a new graphical sub-region - relatively straightforward.

QVTi: a new IfStatement - relatively straightforward.

CG: a new IfStatement  - relatively straightforward.

QVTs2QVTi the sub-region control is reified as boolean expressions.

QVTi2Java, the main challenge is the CSE that we need to correctly exploit the shared code. The CSE is poorly documented/hard to understand. Perhaps this can be an early vehicle for auto-generated code.

---

The efficient Dispatch region is 'just' the current inefficient realize-all-possible-traces with the local predicate partition for each possuble trace folded into a sub-region with its realize. The sub-regions are linked according to the overrides relationships. If we hoist common code at the QVTs-level, CSE at the CG level can be deferred.
Comment 11 Ed Willink CLA 2019-04-21 15:51:01 EDT
Bug 546617 allows unique activator regions to be folded as unique trace variables.
Comment 12 Ed Willink CLA 2020-01-27 09:08:49 EST
Surely IfStatement can be adequately emulated by

let dummy = if cond-exp then true-exp else false-exp endif
in ...

No need for syntax bloat.