General (#1) - iterate construct (#26) - Message List

iterate construct
 unsolved

hi all!

i'm wondering what is wrong with the following expression:

alt.nodeElements->iterate(elem; coll : String = '' | atom2Reference(alt, class, elem));

the error is "variable 'elem' is not assigned! "

an attempt to avoid the iterate construct was doing the same with forAll:

alt.nodeElements->forAll(elem | atom2Reference(alt, class, elem) or true);

but this reverses the order of the nodeElements :/

any thoughts?
glad for any help!

Martin

  • Message #65

    Do you mean, the order of the elements in the alt.nodeElements collection is reverted? This is actually a bug.. is it also true for executing

    alt.nodeElements->forAll(elem | true);
    

    ?

  • Message #66

    first question: i'm pretty sure the collection is still in the right order, but the evaluation is not corresponding to that order.

    second question: not quite sure if i understood you right.

    alt.nodeElements->forAll(elem | true);
    

    evaluates to true. so yes.

    of course the result of a forAll is independent of the order in which the elements of the collection are evaluated. but i was guessing that iterating the collection with iterate and forAll both use the same mechanism (if the collection is ordered). then it would probably be a bug.

  • Message #67

    have you tried assigning a type to elem ?

    ->iterate(elem : String; coll : String = '' | atom2Reference(alt, class, elem));
    
  • Message #68

    yes, i tried. it worked with primitive types such as String; but wouldn't with my "Element" type (which is an abstract class with concrete sub-classes Atom and Block btw.)

  • Message #70

    Here's another interesting observation concerning iterate expressions: in a sub query, the exact same iterate expression worked fine, i.e.:

    top relation foo {
    	(...)
    	where {
    		alt.nodeElements->iterate(elem; coll : String = '' | atom2Reference(alt, class, elem));
    	}
    

    produces the variable 'elem' is not assigned! error. But instead of that, the following is valid:

    top relation foo {
    	(...)
    	where {
    		iterateElements(alt, class);
    	}
    }
    query iterateElements(alt : Alternative, class : EClass) : Boolean {
    	alt.nodeElements->iterate(elem; coll : String = '' | atom2Reference(alt, class, elem))
    	or true -- EDIT: removed ';' (erroneously snuck in while copying)
    }
    

    HOW'S THAT????? -- smells like a bug :/

    cheers

    • Message #80

      Hi Martin,

      where do you know from, that the second solution is valid ? At least the ";" at the end of the query-statement is syntactically wrong, isn't it ?

      Hi anybody else,

      I have a similar problem and don't know what to do:

      transformation HelloOCL ( source : MyUML, target : MyRDBM  )
      {
         top relation package2schema
         {
            packageName: String;
            classes : OrderedSet (Class);
            checkonly domain source srcPkg : Package
            {
               name = packageName,
               ownedElement = classes
            };
            enforce   domain target tgtSma  : Schema
            {
               name  = packageName
            };
            where
            {
               classes->iterate ( cls:Class; tbl:Table | class2table(cls, tbl));
               -- => variable 'cls' is not assigned
               -- I think that's what you, Martin, started with.
               -- Is it a medini bug or just a bug in our heads ?
               -- I know, this - not working - attempt is a bit academical,
               -- but I want to to learn something about QVT/RL and OCL.
            }
         }
         relation class2table
         {
            className : String;
            checkonly domain source cls : Class { name = className };
            enforce   domain target tbl : Table { name = className };
         }
      }
      

      I took the entire context because it is pretty hard for me to follow your discussion without the context. This solution does not work´. Though, the second trial, the query way, does not work either.

      Siegfried

      • Message #81

        siegfried, qvt-folks,

        my problem was not about the syntactic error. valid for me means: no exception thrown running the transformation. but thanks anyway! (that was the good news :) the bad news is: i guess you're having the exact same problem that i encountered... :/ any help here???

        cheers, Martin

        • Message #85

          It would help if you can quote a complete transformation, since one can not see from which context you call the OCL expressions (e.g. which variables are bound from the outer context).

      • Message #84

        Variable 'cls' has to be assigned because it is used in relation call class2table(cls, tbl) and all source domains must be assigned (only the target domains can be unassigned and will be bound by the relation call) and the first domain is a source domain. So it is a "bug in your heads".

        • Message #87

          whoa :) thanks! that was really helpful. i imagine people not sure about the exact semantics of WHERE (you know, like me ;) make stupid things up.

          imho the OMG QVT spec is too short in section 7.2.1 and too technical in annex B :/ so it wasnt quite a help.

      • Message #88

        Siegfried,

        have you tried

        srcPkg.ownedElement->iterate ( cls:Class; tbl:Table | class2table(cls, tbl));
        

        instead of

        classes->iterate ( cls:Class; tbl:Table | class2table(cls, tbl));
        

        from what I know now, this could solve the variable-not-assigned-thing. cause i found a similar use of it in the Relation2Core Transformation in section 10.3 of the QVT spec.

        • Message #89

          I wonder whether the variable tbl shall be bound when executing the relation call. Remembering the uml2rdbms transformation, I guess it shall not be bound! So it should be

          classes->iterate ( cls:Class | class2table(cls, tbl));

          and tbl being a variable declared by the relation.

  • Message #91

    Martin began this discussion, but first of all thanks from my side, too, for his and your contributions.

    (1) My main question, does anybody has a working solution for iterations in relations language scripts to construct soem target model elements ?

    (2) The other question, does anybody has a solution for iteration constructs in RL scripts anyway ?

    I know the question is academic because relations do iteration implicitely. Anyway, the question is interesting in my eyes.

    What I got working is the following:

        top relation package2schema
        {
        packageName: String; classes : OrderedSet (Class);
        checkonly domain source srcPkg : Package
        {
        name = packageName, ownedElement = classes
        };
        enforce domain target tgtSma : Schema
        {
        name = packageName,
        table = t1 : Table { name = classes->at(1).name },
        table = t2 : Table { name = classes->at(2).name }
        };
        }
    

    Yet it is not really an iteration for creating tables (and I'm able to solve this with a relation of its own). All the other trials of doing this with iteration constructs in where-clauses don't work. At least it is possible to build some syntactical correct ones (to solve the "variable 'cls' is not assigned" problem) but I don't get any tables from them. They are not working; worst case, they result in some java exceptions.

    (3) So let me assume, there is no way to create model elements with OCL iteration.

    I can't get any clue for this assumption from the specification (though this might be helpful. Martin is right, the QVT RL specification is pretty poor with some facts). For any other things I may use OCL iteration, for example in when/where-clauses, in queries, but I don't know really what for?

    So I'm back to my academic point of view.

    Siegfried

Attachments

No attachments created.