rule RootElement { from s : A!Product to t : B!BCModel ( -- add a category and pass all references to its rule categories <- thisModule.addArmature(s.references.asOrderedSet()) ) } lazy rule addArmature{ from s : OrderedSet(A!PartReference) to t : B!Category( name <- 'Armature', -- here we add distributors with a helper -- to avoid adding distributors with same name twice distributors <- thisModule.fetchDistributors(s) ) } lazy rule addDistri{ from s : A!PartReference to t : B!Distributor( name <- s.part.distributor, blocks <- thisModule.addBlock(s) ) } lazy rule addBlock{ from s : A!PartReference to t : B!PartBlock( name <- s.part.name, price <- s.part.cost * s.amount -- calc proper price ) } helper def : fetchDistributors(refs : OrderedSet(A!PartReference)) : OrderedSet(B!Distributor) = refs->iterate(e ; retValue : OrderedSet(B!Distributor) = OrderedSet{} | if e.part = OclUndefined then retValue else if e.part.distributorExists(retValue).oclIsTypeOf(B!Distributor) = false then retValue.append(thisModule.addDistri(e)) else -- how to catch the existing distributor -- and add a Partblock(how its done in addBlock rule) -- with information of the iterator ??? retValue endif endif ); -- this helper return OclUndefined if distributor does not exist, else the distributor instance helper context A!Part def: distributorExists(distris : OrderedSet(B!Distributor)) : B!Distributor = distris->iterate(e; retValue : B!Distributor = OclUndefined | if e.name = self.distributor then e else retValue endif);