|
Let's look at the simplest case first: you want the collection to look the same at both ends. Here's an example for two UML Classes, with a generator in the symbol for the relationship between them, to show whether they are the same. Test by deep copying the same class and connecting the copies.
do ~Whole.Class [UML] { $wholeAttrs = :Attributes } do ~Part.Class [UML] { if :Attributes = $wholeAttrs then 'ok' else 'wrong' endif }
If you need more in-depth comparison, you can store the details of the first collection in separate variables, e.g. one per element. I'll store id's here, since I've deep-copied the collection; you probably want to store oid's, if you want to check if it is exactly the same element, not just one with the same name.
Note how we make associative variables: variable ... write ... close. Anything in the first block of commands goes to make up the name of the variable, e.g. here wholeAttr0. You can think of that as wholeAttr[0] if you like - arrays are just a special case of associative variables, and a very limited one at that.
to '%null' newline '* $' endto $ix1='0' do ~Whole.Class [UML]:Attributes { variable 'wholeAttr' $ix1++ write id close } $ix2='0' do ~Part.Class [UML]:Attributes { variable 'oldAttr' write variable 'wholeAttr' $ix2++ read close if id <> $oldAttr then $errors++%null endif } if $ix1 <> $ix2 then $errors++%null endif if $errors then 'wrong' else 'ok' endif
I guess that what you were trying to do was iterate over one collection, and in the middle of that iterate over the other. That's slower, because it's O(N^2) - for each element on the left, you have to navigate across to the object on the right, then iterate through its elements to find the right one. You can do it though:
to '%null' newline '* $' endto $ix1='0' do ~Whole.Class [UML]:Attributes { $ix1++%null $ix2='0' do ~Part;1.Class [UML]:Attributes { if $++ix2 = $ix1 and id;1 <> id then $errors++%null endif } } if $ix1 <> $ix2 then $errors++%null endif if $errors then 'wrong' else 'ok' endif
Note the ;1 which says to evaluate the preceding command in the context one level higher in the stack, i.e. one {} block out. Otherwise if we tried to navigate to the ~Part role from the first Attribute, MERL would correctly say that there are no roles attached to the Attribute. Instead we ask the question one level further out, where we are still in the relationship.
All these comparisons require both collections to be in the same order. If you want to compare as sets, just sort the do loops with "orderby".
|