-
Key: QVT13-8
-
Legacy Issue Number: 13082
-
Status: closed
-
Source: Anonymous
-
Summary:
Major Problem:
{ ... }
(1) The current abstract syntax of ImperativeOCL introduces a couple of
unclear situations. This may lead to incompatible QVT implementations.
Further Problems:
(2) Control flow constructs introduced by ImperativeOCL are redundant
compared with existing conventional OCL constructs.
(3) Several OCL equivalence rules break when ImperativeOCL is present.
Detailed problem description:
(1) The current abstract syntax of ImperativeOCL introduces a couple of
unclear situations. This may lead to incompatible QVT implementations.
In the abstract syntax, ImperativeOCL expressions / statements are
inherited from OclExpression. Therefore, conventional OCL
expressions may (and will) contain sub-expressions that are
actually ImperativeOCL expressions.
In conventional OCL, the interpretation of an expression under a
given environment is a value. In ImperativeOCL, the interpretation
of an expression is a value and a new environment
(state,variables). This extended interpretation is not given for
conventional OCL expressions, leading to undefined operational
semantics of those expressions.
Example: Given the following compute expression:
compute(z:Boolean) {
var x : Boolean := true
var y : Boolean := true
if ((x:=false) and (y:=false))z := y
{ c.salary := c.salary * 1.1}
}
What is the value of this expression: is it true or false (It
depends on whether the 'and' operator is evaluated short-circuit
or strict). The situation is similar for the evaluation of the
other logical connectives, forAll, and exists when these
expressions contain imperative sub-expressions.
(2) Control flow constructs introduced by ImperativeOCL are redundant
compared with existing conventional OCL constructs.
Some of the new language features in ImperativeOCL such as forEach
and the imperative conditional are not really necessary. Their
effect can already be achieved using conventional OCL expressions:
For example:
company.employees->forEach(c)has the same effect as
{ x := 0 }
company.employees->iterate(c; r:OclAny=Undefined |
c.salary := c.salary * 1.1
)
and
if ( x < 0 )else
{ x := 1 }endif is the same as
{ all occurences of x replaced by e1 }
if x < 0 then x := 0 else x := 1 endif
(3) Several OCL equivalence rules break when ImperativeOCL is present.
In conventional OCL, several equivalence rules well known from
logic hold. Allowing OCL expression to contain imperative
sub-expressions breaks these equivalence rules.
Examples:
let x=e1 in e2 equiv. e2e1 and e2 equiv. e2 and e1
These equivalences do not necessarily hold if e1 or e2 are allowed
to have side-effects.
Proposed solution:
(A) - (The cheap solution.) State textually that conventional OCL
expressions (as described in the OMG OCL spec.) are not
allowed to have side effects unless used as part of a top
level ImperativeOCL expression. Therefore, even in a system
supporting ImperativeOCL, class invariants, and pre- and
postconditions (e.g.) will not be allowed to contain
ImperativeOCL sub-expressions.
State explicitly that the redundant flow control statements
have been introduced (solely) to write concise imperative
programs and that the side-effect free forms of conditional
evaluation ( 'if-then-else-endif' and 'iterate' ) shall not be
used to program side-effects (instead, the ImperativeOCL forms
shall be used).
(B) - (Major rework.) Rework the abstract syntax to reuse OCL
expressions by composition rather than by inheritance.
Imperative expressions ( => rename to 'statements' ) then may
contain sub-statements and OCL expressions; OCL expressions
are reused unchanged from the OCL spec (no imperative
sub-expressions, no side-effects).
These issues have been discussed on the MoDELS 2008 OCL Workshop,
more details can be found at
http://www.fots.ua.ac.be/events/ocl2008/PDF/OCL2008_9.pdf -
Reported: QVT 1.0 — Sat, 15 Nov 2008 05:00 GMT
-
Disposition: Resolved — QVT 1.3
-
Disposition Summary:
current abstract syntax of ImperativeOCL introduces a couple of unclear situations
Major Problem:
{ ... }
(1) The current abstract syntax of ImperativeOCL introduces a couple of unclear situations. This may lead to incompatible QVT implementations.
Further Problems:
(2) Control flow constructs introduced by ImperativeOCL are redundant compared with existing conventional OCL constructs.
(3) Several OCL equivalence rules break when ImperativeOCL is present.
Detailed problem description:
(1) The current abstract syntax of ImperativeOCL introduces a couple of unclear situations. This may lead to incompatible QVT implementations.
In the abstract syntax, ImperativeOCL expressions / statements are inherited from OclExpression. Therefore, conventional OCL expressions may (and will) contain sub-expressions that are actually ImperativeOCL expressions. In conventional OCL, the interpretation of an expression under a given environment is a value. In ImperativeOCL, the interpretation of an expression is a value and a new environment (state,variables). This extended interpretation is not given for conventional OCL expressions, leading to undefined operational semantics of those expressions.
Example: Given the following compute expression:
compute(z:Boolean) {
var x : Boolean := true
var y : Boolean := true
if ((x:=false) and (y:=false))z := y
}
What is the value of this expression: is it true or false (It depends on whether the 'and' operator is evaluated short-circuit or strict). The situation is similar for the evaluation of the other logical connectives, forAll, and exists when these expressions contain imperative sub-expressions.(2) Control flow constructs introduced by ImperativeOCL are redundant compared with existing conventional OCL constructs.
{ c.salary := c.salary * 1.1}
Some of the new language features in ImperativeOCL such as forEach and the imperative conditional are not really necessary. Their effect can already be achieved using conventional OCL expressions:
For example:
company.employees->forEach(c)has the same effect as
{ x := 0 }
company.employees->iterate(c; r:OclAny=Undefined |
c.salary := c.salary * 1.1
)
and
if ( x < 0 )else
{ x := 1 }endif is the same as
if x < 0 then x := 0 else x := 1 endif(3) Several OCL equivalence rules break when ImperativeOCL is present.
{ all occurences of x replaced by e1 }
In conventional OCL, several equivalence rules well known from logic hold. Allowing OCL expression to contain imperative sub-expressions breaks these equivalence rules.
Examples:
let x=e1 in e2 equiv. e2e1 and e2 equiv. e2 and e1
These equivalences do not necessarily hold if e1 or e2 are allowed to have side-effects.
Proposed solution:
(A) - (The cheap solution.) State textually that conventional OCL expressions (as described in the OMG OCL spec.) are not allowed to have side effects unless used as part of a top level ImperativeOCL expression. Therefore, even in a system supporting ImperativeOCL, class invariants, and pre- and postconditions (e.g.) will not be allowed to contain ImperativeOCL sub-expressions.
State explicitly that the redundant flow control statements have been introduced (solely) to write concise imperative programs and that the side-effect free forms of conditional evaluation ( 'if-then-else-endif' and 'iterate' ) shall not be used to program side-effects (instead, the ImperativeOCL forms shall be used).
(B) - (Major rework.) Rework the abstract syntax to reuse OCL expressions by composition rather than by inheritance.
Imperative expressions ( => rename to 'statements' ) then may contain sub-statements and OCL expressions; OCL expressions are reused unchanged from the OCL spec (no imperative sub-expressions, no side-effects).
These issues have been discussed on the MoDELS 2008 OCL Workshop, more details can be found at http://www.fots.ua.ac.be/events/ocl2008/PDF/OCL2008_9.pdfDiscussion - 1 short circuit semantics
It is possible to weasel out of this narrowly described problem by observing that OCL only supports short-circuit semantics once it is proven that no invalid lurks beyond the short-circuit. An extension to this could inhibit short-circuit semantics if any imperative expression is involved.
Discussion - (2) redundant control flow
The first suggestion is contradictory. The replacement for forEach is noticeably longer and uses a side effect within an iterate, which the author argues against elsewhere.
The second suggestion incorrectly assumes that an else clause is present. The imperative if (SwitchExp) allows one-sided functionality including selective control flow adjustment.
Discussion - (3) broken equivalence
The example is unreadable, but the point is unarguable; imperative semantics within functional semantics subvert the functional.
(A) - (The cheap solution.) is simple and adopted here.
(B) - (Major rework.) is a breaking structural change and so forked off to http://solitaire.omg.org/browse/QVT13-87 for consideration by QVT 2.0.
-
Updated: Tue, 29 Mar 2016 15:09 GMT
QVT13 — QVTo: ImperativeOCL conflicts with EssentialOCL semantics
- Key: QVT13-8
- OMG Task Force: QVT 1.3 RTF