Home » Modeling » OCL » Unexpected conversion from Sequence to OrderedSet
Unexpected conversion from Sequence to OrderedSet [message #1524161] |
Tue, 23 December 2014 09:01 |
Klaas Gadeyne Messages: 165 Registered: July 2009 |
Senior Member |
|
|
Hi,
Evaluating this in the xtext OCL console (luna SR1, MDT/OCL 5.0.3)
Evaluating:
let s = Sequence{1.0,2.0,3.0} in s->collect(r | r + Sequence{1.0,2.0,3.0}->at(s->indexOf(r)))
Results:
2.0
4.0
6.0
Evaluating:
let s = Sequence{0.0,0.0,0.0} in s->collect(r | r + Sequence{1.0,2.0,3.0}->at(s->indexOf(r)))
Results:
1.0
1.0
1.0
I don't understand (or better: I don't like ) the second result. Am I right when I guess the indexOf(0.0) operation always returns 1, no matter wat the value of r is, and that this is not an MDT/OCL bug?
Is this due to the fact that the indexOf is applied to a Sequence of "PrimitiveTypes" (vs. a sequence of "Classifiers"/objects) --- in UML speak?
And if so, is there another way of achieving the desired result [*] for the second case (in casu 1.0, 2.0, 3.0)?
Thx!
Klaas
[*] Context: this expression is nested in an iterate expression, and 0,0,0 is the initial value of the Accumulator
|
|
|
Re: Unexpected conversion from Sequence to OrderedSet [message #1524398 is a reply to message #1524161] |
Tue, 23 December 2014 12:10 |
Nils Przigoda Messages: 14 Registered: September 2013 Location: Bremen, Germany |
Junior Member |
|
|
In your second example the evaluation of s->indexOf(r) will be always 1, because the iterator r will be always 0.0 and indexOf will return the index of the first object which is 0.0. Thus, at(1) will always return 1.0 and adding 0.0 will not change the value.
Concerning about your last question, I think your are looking for something like:
let s = Sequence{0.0,0.0,0.0} in
Sequence{1..(s->size())}->collect( index |
s->at(index)
+ Sequence{1.0,2.0,3.0}->at(index)
)
But I've not tested the lines above.
[Updated on: Tue, 23 December 2014 12:23] Report message to a moderator
|
|
|
Re: Unexpected conversion from Sequence to OrderedSet [message #1524422 is a reply to message #1524161] |
Tue, 23 December 2014 12:26 |
Ed Willink Messages: 7655 Registered: July 2009 |
Senior Member |
|
|
Hi
No:
Evaluating:
Sequence{1.0,2.0,3.0}->indexOf(0.0)
Results:
Missing value for 'indexOf'
The correct second result should be invalid propagated from the first
indexOf miss.
See https://bugs.eclipse.org/bugs/show_bug.cgi?id=456057.
Workaround: do your own includes() test to avoid the malfunctioning invalid.
Regards
Ed Willink
On 23/12/2014 09:01, Klaas Gadeyne wrote:
> Hi,
>
> Evaluating this in the xtext OCL console (luna SR1, MDT/OCL 5.0.3)
>
> Evaluating:
> let s = Sequence{1.0,2.0,3.0} in s->collect(r | r +
> Sequence{1.0,2.0,3.0}->at(s->indexOf(r)))
> Results:
> 2.0
> 4.0
> 6.0
>
> Evaluating:
> let s = Sequence{0.0,0.0,0.0} in s->collect(r | r +
> Sequence{1.0,2.0,3.0}->at(s->indexOf(r)))
> Results:
> 1.0
> 1.0
> 1.0
>
> I don't understand (or better: I don't like :) ) the second result. Am
> I right when I guess the indexOf(0.0) operation always returns 1, no
> matter wat the value of r is, and that this is not an MDT/OCL bug?
> Is this due to the fact that the indexOf is applied to a Sequence of
> "PrimitiveTypes" (vs. a sequence of "Classifiers"/objects) --- in UML
> speak?
>
> And if so, is there another way of achieving the desired result [*] for
> the second case (in casu 1.0, 2.0, 3.0)?
>
> Thx!
>
> Klaas
>
>
> [*] Context: this expression is nested in an iterate expression, and
> 0,0,0 is the initial value of the Accumulator
>
|
|
|
Re: Unexpected conversion from Sequence to OrderedSet [message #1524441 is a reply to message #1524398] |
Tue, 23 December 2014 12:43 |
Ed Willink Messages: 7655 Registered: July 2009 |
Senior Member |
|
|
Hi
You are completely correct, and the OCL evaluator is tioo. (I should
have finished testing vbefore my delyed "SEnd" on my earlier reply.
The following JUnit tests all pass.
assertQueryInvalid(null, "let s = Sequence{0.0,0.0,0.0}, t =
Sequence{1.0,2.0,3.0} in s->collect(r | r + t->at(t->indexOf(r))) ");
assertQueryResults(null, "Sequence{1.0,1.0,1.0}", "let s =
Sequence{0.0,0.0,0.0} in s->collect(r | r +
Sequence{1.0,2.0,3.0}->at(s->indexOf(r)))");
assertQueryResults(null, "Sequence{2.0,4.0,6.0}", "let s =
Sequence{1.0,2.0,3.0} in s->collect(r | r +
Sequence{1.0,2.0,3.0}->at(s->indexOf(r)))");
The first test is what I and the author misread the test as. The second
is what it actually was.
So https://bugs.eclipse.org/bugs/show_bug.cgi?id=456057 resolved invalid.
However https://bugs.eclipse.org/bugs/show_bug.cgi?id=456058 remains
since using the debugger was not nearly as helpful as it should be.
Regards
Ed Willink
On 23/12/2014 12:10, Nils Przigoda wrote:
> In your second example the evaluation of s->indexOf(r) will be always 1,
> because the iterator r will be always 0.0 and indexOf will return the
> index of the first object which is 0.0. Thus, at(1) will always return
> 1.0 and adding 0.0 will not change the value.
|
|
|
Re: Unexpected conversion from Sequence to OrderedSet [message #1524776 is a reply to message #1524441] |
Tue, 23 December 2014 17:09 |
Klaas Gadeyne Messages: 165 Registered: July 2009 |
Senior Member |
|
|
Thx both!
For the record, and maybe also useful for others, using Nils' suggestion I was also able to create a working version of a sum() version for Sequence(Sequences(Real)). Here goes
Evaluating:
let forS = Sequence{1..3} in Sequence{Sequence{1.0,2.0,3.0},Sequence{2.0,3.0,4.0},Sequence{5.0,4.0,5.0}}->iterate(s, acc: Sequence(Real) = Sequence{0.0,0.0,0.0} | forS->collect( i | acc->at(i) + s->at(forS->indexOf(i))))
Results:
8.0
9.0
12.0
(I guess this expression shows either my lack of OCL knowledge, or the fact that OCL still has some accidental complexity in order to be easily applicable for describing particular constraint scenario's )
|
|
|
Re: Unexpected conversion from Sequence to OrderedSet [message #1524833 is a reply to message #1524776] |
Tue, 23 December 2014 17:52 |
Ed Willink Messages: 7655 Registered: July 2009 |
Senior Member |
|
|
Hi
Perhaps a bit more obvious, unless you have a deeper reason for the
redundant indexOf:
let seqSeq = Sequence{
Sequence{1.0,2.0,3.0},Sequence{2.0,3.0,4.0},Sequence{5.0,4.0,5.0}},
seqSize = seqSeq->first()->size()
in Sequence{1..seqSize}->collect(i | seqSeq->collect(at(i))->sum())
Regards
Ed Willink
On 23/12/2014 17:09, Klaas Gadeyne wrote:
> Thx both!
>
> For the record, and maybe also useful for others, using Nils' suggestion
> I was also able to create a working version of a sum() version for
> Sequence(Sequences(Real)). Here goes
>
>
> Evaluating:
> let forS = Sequence{1..3} in
> Sequence{Sequence{1.0,2.0,3.0},Sequence{2.0,3.0,4.0},Sequence{5.0,4.0,5.0}}->iterate(s,
> acc: Sequence(Real) = Sequence{0.0,0.0,0.0} | forS->collect( i |
> acc->at(i) + s->at(forS->indexOf(i))))
> Results:
> 8.0
> 9.0
> 12.0
>
>
> (I guess this expression shows either my lack of OCL knowledge, or the
> fact that OCL still has some accidental complexity in order to be easily
> applicable for describing particular constraint scenario's :) )
>
>
>
>
|
|
| |
Goto Forum:
Current Time: Tue Mar 19 13:20:30 GMT 2024
Powered by FUDForum. Page generated in 0.01953 seconds
|