Home » Modeling » M2T (model-to-text transformation) » a difficult query to solve(find all the routes between one class and another)
a difficult query to solve [message #1804554] |
Thu, 28 March 2019 13:06  |
Eclipse User |
|
|
|
I am doing my engineering thesis on code generation for C language and I'm evaluating acceleo.
I have the next problem:
We are in uml using multiple inheritance. Let's say we have the following class diagram:
A
/ | \
B C D
| | \ |
| | E
\ | /
F
And we want to get all possible paths from A to F
((A, B, F), (A, C, F), (A, C, E, F), (A, D, E, F))
How can I write an OCL query that throws that result for that diagram? is there a way to solve something like this with JAVA instead of OCL?
|
|
| | |
Re: a difficult query to solve [message #1805335 is a reply to message #1804620] |
Thu, 11 April 2019 22:01   |
Eclipse User |
|
|
|
Hello,
Thanks for the prompt reply.
I am not able to resolve the issue.
Based on your answer I coded the following query:
[query public superPaths(aClass: Class) : Sequence(Sequence(Class))=
if (aClass.superClass->isEmpty()) then
Sequence(Sequence(Class)){Sequence(Class){aClass}}
else
aClass.superClass->collectNested(superClass1 | superPaths(superClass1 ).prepend(aClass ))->asSequence()
endif
/]
And I generated the following template to verify the result
[for (classes:Sequence(Class) | superPaths())]
Route [i/]:
[for (class: uml::Class | classes)separator(',')][class.name/][/for]
[/for]
But with a simple model:
Class1 Class6
| / |
Class3 Class2
\ /
Class4
|
Class5
For Class4 I get:
Route 1:
Class4, Class3, Class6, Class4, Class3, Class1
Route 2:
Class4, Class2, Class6
And for Class5:
Route 1:
Class5, Class4, Class3, Class6, Class4, Class3, Class1, Class5, Class4, Class2, Class6
It is close, apparently after a second level of inheritance the sequences become flattened. I do not know if I'm facing a bug or there's something wrong with the query ...
[Updated on: Thu, 11 April 2019 22:04] by Moderator
|
|
| | |
Re: a difficult query to solve [message #1806040 is a reply to message #1806026] |
Wed, 01 May 2019 05:23   |
Eclipse User |
|
|
|
Hi
The problem is that in
Quote:Body something like: self.superClasses->collectNested(superClass | superPaths(superClass )->prepend(superClass ))->asSet()
collectNested is not a suitable operation for merging multiple Set(Sequence()) to give a larger Set; it gives a wrapped Set. You need to fall back on iterate.
You should find that the following works:
Quote:[comment encoding = UTF-8 /]
[module generate('http://www.eclipse.org/uml2/5.0.0/UML')]
[query public superPaths(aClass: uml::Class) : OrderedSet(Sequence(uml::Class))=
let superSuperPaths : Set(Sequence(uml::Class)) = if aClass.superClass->isEmpty()
then OrderedSet(Sequence(Class)){Sequence(Class){}}
else aClass.superClass->iterate(superClass1;
result : Set(Sequence(uml::Class)) = Set(Sequence(uml::Class)){}
| result->union(superPaths(superClass1)))
endif in
superSuperPaths->collectNested(superPath : Sequence(uml::Class) | superPath->prepend(aClass))->asOrderedSet()
/]
[template public main(aPackage : uml::Package)]
[comment @main /]
[file (aPackage.name + '.txt', false, 'UTF-8')]
[for (aClass : uml::Class | aPackage.ownedType->filter(uml::Class))]
[genClass(aClass)/]
[/for]
[/file]
[/template]
[template public genClass (aClass : uml::Class) ]
[aClass.name/]
[for (path : Sequence(uml::Class) | superPaths(aClass))]
Route [i/]:[for (class : uml::Class | path) separator(',')] [class.name/][/for]
[/for]
[/template]
At least the following looks like a plausible result:
Quote:Class4
Route 1: Class4, Class2, Class6
Route 2: Class4, Class3, Class6
Route 3: Class4, Class3, Class1
Class1
Route 1: Class1
Class5
Route 1: Class5, Class4, Class3, Class6
Route 2: Class5, Class4, Class3, Class1
Route 3: Class5, Class4, Class2, Class6
Class2
Route 1: Class2, Class6
Class6
Route 1: Class6
Class3
Route 1: Class3, Class1
Route 2: Class3, Class6
Regards
Ed Willink
|
|
|
Re: a difficult query to solve [message #1806110 is a reply to message #1806040] |
Thu, 02 May 2019 14:05  |
Eclipse User |
|
|
|
Thank you very much Ed!
To complete the answer I added this query to get all the paths from any class to another:
[query public getPaths(fromClass: uml::Class, toClass: uml::Class) : OrderedSet(Sequence(uml::Class))=
fromClass.superPaths()->select(path: Sequence(uml::Class) | path->includes(toClass))->collectNested(path: Sequence(uml::Class) | path->subSequence(2,path->indexOf(toClass)))->asOrderedSet()
/]
I think that the JAVA way is very necessary since it allows debugging.
If I had known before that it served to solve this type of queries I would have fought much less with them and do it the JAVA form. Any way, the queries in OCL enrich the thesis very much.
Regards!
|
|
|
Goto Forum:
Current Time: Fri Apr 18 16:23:09 EDT 2025
Powered by FUDForum. Page generated in 0.04995 seconds
|