diff options
author | Ed Willink | 2015-03-15 16:48:10 +0000 |
---|---|---|
committer | Ed Willink | 2015-03-15 16:48:10 +0000 |
commit | 963addbcb63fed1ef1c17103b40fb2875d85f2d3 (patch) | |
tree | 675fa37c036e8e8be1f3138ac1ae1c306f656195 | |
parent | 24175021ca807571c9a6f9b6c2f423f8faafc134 (diff) | |
download | org.eclipse.qvtd-963addbcb63fed1ef1c17103b40fb2875d85f2d3.tar.gz org.eclipse.qvtd-963addbcb63fed1ef1c17103b40fb2875d85f2d3.tar.xz org.eclipse.qvtd-963addbcb63fed1ef1c17103b40fb2875d85f2d3.zip |
[462166] Exploit multiple patterns for RelToCore
-rw-r--r-- | examples/org.eclipse.qvtd.examples.qvtrelation.reltocore/qvtrsrc/SimplerRelToCore.qvtr | 1891 |
1 files changed, 1891 insertions, 0 deletions
diff --git a/examples/org.eclipse.qvtd.examples.qvtrelation.reltocore/qvtrsrc/SimplerRelToCore.qvtr b/examples/org.eclipse.qvtd.examples.qvtrelation.reltocore/qvtrsrc/SimplerRelToCore.qvtr new file mode 100644 index 000000000..bd97d59dd --- /dev/null +++ b/examples/org.eclipse.qvtd.examples.qvtrelation.reltocore/qvtrsrc/SimplerRelToCore.qvtr @@ -0,0 +1,1891 @@ +-------------------------------------------------------------------------------- +-- Copyright (c) 2008 Tata Consultancy Services and others. +-- All rights reserved. This program and the accompanying materials +-- are made available under the terms of the Eclipse Public License v1.0 +-- which accompanies this distribution, and is available at +-- http://www.eclipse.org/legal/epl-v10.html +-- +-- Contributors: +-- S.Reddy - Section 10.3 of the OMG MOF-QVT 1.0 specification +-- E.D.Willink - contributions to drafts of the above +-- E.D.Willink - adaptation to comply with QVT specification +-------------------------------------------------------------------------------- +import emof : 'platform:/resource/org.eclipse.qvt/model/ecore/EMOF.ecore'::EMOF; +import essentialocl : 'platform:/resource/org.eclipse.qvt/model/ecore/EssentialOCL.ecore'::EssentialOCL; +import qvtbase : 'platform:/resource/org.eclipse.qvt/model/ecore/QVTBase.ecore'::QVTBase; +import qvttemplate : 'platform:/resource/org.eclipse.qvt/model/ecore/QVTTemplate.ecore'::QVTTemplate; +import qvtrelation : 'platform:/resource/org.eclipse.qvt/model/ecore/QVTRelation.ecore'::QVTRelation; +import qvtcore : 'platform:/resource/org.eclipse.qvt/model/ecore/QVTCore.ecore'::QVTCore; + +transformation relToCore(relations:{qvtrelation,qvttemplate,qvtbase,essentialocl,emof}, core:{qvtcore,qvtbase,essentialocl,emof}) +{ + +key qvtcore::Mapping{name, transformation}; +key qvtcore::GuardPattern{area}; +key qvtcore::BottomPattern{area}; +key essentialocl::Variable{name, type}; +key emof::Type{name}; +key emof::Class{name}; +key emof::Property{name, class}; +key qvtcore::CoreDomain{name, rule}; +key qvtbase::TypedModel{name, usedPackage, transformation}; +key emof::Package{name}; +key qvtbase::Transformation{name}; +key emof::Operation{name}; +key qvtbase::Predicate{pattern, conditionExpression}; + +query getSharedDomainVars(r:qvtrelation::Relation):Set(essentialocl::Variable) +{ + r.domain->iterate(d; vars: Set(essentialocl::Variable) = Set{} | + if (vars->isEmpty()) + then + vars->union(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo) + else + vars->intersection(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo) + endif + ) +} + +query getWhenVars(r:qvtrelation::Relation):Set(essentialocl::Variable) +{ + let + vs:Set(essentialocl::Variable) = Set{} + in + r.domain->iterate(d; vars: Set(essentialocl::Variable) = Set{} | + if (vars->isEmpty()) + then + vars->union(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo) + else + vars->intersection(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo) + endif + ) +} + +-- Get variables occuring in an ocl expression +-- Note: this function is not complete! It needs to be completed for other expressions +query getVarsOfExp(e:essentialocl::OclExpression):Set(essentialocl::Variable) +{ + -- Walk the expr tree of the OclExpression and + -- collect the variables used in those expressions + let + vs:Set(essentialocl::Variable) = Set{} + in + if (e.oclIsTypeOf(essentialocl::VariableExp)) + then + vs->including(e.oclAsType(essentialocl::VariableExp).referredVariable) + else + if (e.oclIsTypeOf(essentialocl::OperationCallExp)) + then + let + oc:essentialocl::OperationCallExp = e.oclAsType(essentialocl::OperationCallExp) + in + vs->union(getVarsOfExp(oc.source))->union( + oc.argument->iterate(a; avs:Set(essentialocl::Variable)=Set{} | avs->union(getVarsOfExp(a))) + ) + else + if (e.oclIsTypeOf(essentialocl::PropertyCallExp)) + then + vs->union(getVarsOfExp(e.oclAsType(essentialocl::PropertyCallExp).source)) + else + if (e.oclIsTypeOf(qvtrelation::RelationCallExp)) + then + let + rc:qvtrelation::RelationCallExp = e.oclAsType(qvtrelation::RelationCallExp) + in + vs->union(rc.argument->iterate(a; avs:Set(essentialocl::Variable)=Set{} | + avs->union(getVarsOfExp(a))) + ) + else + vs + endif + endif + endif + endif +} + +query filterOutPredicatesThatReferToVars(rpSet:Set(qvtbase::Predicate), + ownrdVars:Set(essentialocl::Variable)) :Set(qvtbase::Predicate) +{ + rpSet->iterate(p:qvtbase::Predicate; fpSet:Set(qvtbase::Predicate) = Set{}| + if (getVarsOfExp(p.conditionExpression)->intersection(ownrdVars)->isEmpty()) + then + fpSet->including(p) + else + fpSet + endif + ) +} + +--Check if the given variable is bound to any template other than the one to be skipped +query isVarBoundToSomeOtherTemplate(rootTe:qvttemplate::ObjectTemplateExp, + skipTe:qvttemplate::ObjectTemplateExp, v:essentialocl::Variable):Boolean +{ + if (rootTe = skipTe) + then + false + else + if (rootTe.bindsTo = v) + then + true + else + rootTe.part.value->select(pe | pe.oclIsKindOf(qvttemplate::ObjectTemplateExp))->exists(pet | + isVarBoundToSomeOtherTemplate(pet.oclAsType(qvttemplate::ObjectTemplateExp), skipTe, v)) + endif + + endif +} + +top relation RelationalTransformationToMappingTransformation +{ + rtn, tmn:String; + + domain relations rt:RelationalTransformation { + name = rtn, + modelParameter = rtm:TypedModel { + name = tmn, + usedPackage = up:Package{} + } + }; + + enforce domain core mt:Transformation { + name = rtn, + modelParameter = mtm:TypedModel { + name = tmn, + usedPackage = up + } + }; +} + +-- Rule 1: Corresponding to each relation there exists a trace class in core. +-- The trace class contains a property corresponding to each object node in the +-- pattern of each domain of the relation. +-- +top relation RelationToTraceClass +{ + rn, vn:String; + + domain relations r:Relation { + name = rn, + domain = rd:RelationDomain { + pattern = rdp:DomainPattern { + templateExpression = t:ObjectTemplateExp { + bindsTo = tv:Variable { + name = vn, + type = c:Class {} + } + } + } + } + }; + enforce domain core rc:Class { + name = 'T'+rn, + ownedAttribute = a:Property { + name = vn, + type = c + } + }; + where { + SubTemplateToTraceClassProps(t, rc); + } +} + +relation SubTemplateToTraceClassProps +{ + vn: String; + + domain relations t:ObjectTemplateExp { + part = pt:PropertyTemplateItem { + value = tp:ObjectTemplateExp { + bindsTo = tv:Variable { + name = vn, + type = c:Class {} + } + } + } + }; + enforce domain core rc:Class { + ownedAttribute = a:Property { + name=vn, + type=c + } + }; + where { + SubTemplateToTraceClassProps(tp, rc); + } +} + +-- For mapping to core we distinguish between two kinds of relations of a transformation: +-- - top-level relations and invoked relations. +-- Top-level relations are not invoked by any other relation in the transformation. +-- There exists a single mapping (with perhaps contained mappings) for a top-level relation, +-- whereas for an invoked relation there exists a separate mapping for each invoker-invoked +-- combination. + +-- For mapping to core we also distinguish between check-only relations and enforceable +-- relations. A check-only relation maps to a single core mapping, whereas an enforceable +-- relation typically maps to a composite hierarchy of mappings in core. +-- + +-- Rule 2: +-- The following are the common translation rules between +-- a relation and a core mapping. +-- 2.1: Variables of a RelationDomain that occur in the when clause become +-- PatternVarables of the core domain guard. +-- 2.2: All other Variables of a relationDomain become PatternVars +-- of the core domain bottom pattern. +-- 2.3: An instance variable corresponding to the trace class of the relation becomes part of +-- the core mapping bottom pattern with its properties set(assigned or equated) to the +-- corresponding core domain pattern variables. +-- 2.4: A property template item in the relation domain pattern becomes an +-- assignment (or equation in the case of check-only domains) in the core domain bottom pattern. +-- 2.5: Predicates of the when clause become predicates of the core mapping guard. +-- 2.6: Non relation invocation predicates of the where clause become predicates of the core +-- mapping bottom. +-- 2.6.1: relation invocation predicates of the where clause are ignored in this mapping, but +-- are reflected in the mapping corresponding to the invoked relation. +-- + +-- All Object template expressions (at the top level of the DomainPattern) +-- become assignments in the core domain bottom. Nested +-- ObjectTemplateExpressions become assignments in composed mappings. +-- + +-- Rule 3 (extends Rule 2): +-- 3.1: A relation is 'check-only' if it does not have any enforceable domains. +-- 3.2: Only the trace class variable in the mapping bottom is 'realized'; there are no +-- other 'realized' variables in any of the mapping areas. +-- 3.3: A property template item in a relation domain becomes an equation in the core domain +-- bottom. +-- 3.4: A property template item in a relation domain that refers to a shared variable +-- becomes an equation in the mapping bottom. +-- 3.5: Shared variables referenced in property template items of relation domains become +-- variables of the mapping bottom. +-- +top relation TopLevelRelationToMappingForChecking +{ + allDomainVars: Set(essentialocl::Variable); + sharedDomainVars: Set(essentialocl::Variable); + unsharedWhereVars: Set(essentialocl::Variable); + whenVars: Set(essentialocl::Variable); + whereVars: Set(essentialocl::Variable); + rn: String; + mbVars:Set(essentialocl::Variable); + rt: qvtrelation::RelationalTransformation; + mt: qvtbase::Transformation; + + domain relations r:Relation { + transformation = rt, + isTopLevel = true, + name = rn + } { + not r.domain->exists(d| d.isEnforceable = true) + }; + enforce domain core m:Mapping { + transformation = mt, + name = rn, + guardPattern = mg:GuardPattern { + area = m + }, + bottomPattern = mb:BottomPattern { + bindsTo = vs:Set(Variable) { + tcv:RealizedVariable {} ++ mbVars + } + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + allDomainVars = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} | + acc->including(md.oclAsType(qvtrelation::RelationDomain))).pattern.bindsTo->asSet(); + whenVars = r.when.bindsTo; + whereVars = r.where.bindsTo; + + sharedDomainVars = getSharedDomainVars(r); + unsharedWhereVars = + (whereVars - whenVars - allDomainVars)->union(sharedDomainVars); + + RelationToTraceClassVar(r, tcv); + RWhenPatternToMGuardPattern(r, mg); + if (unsharedWhereVars->isEmpty()) + then + mbVars = Set{} + else + RVarSetToMVarSet(unsharedWhereVars->asSequence(), mbVars) + endif; + -- Only non relation invocation predicates are copied from where clause to mapping + -- bottom. + RWherePatternToMPattern(r, mb); + RDomainToMDomainForChecking(r, m); + } +} + +relation RWherePatternToMPattern +{ + domain relations r:Relation{ + where = wherep:Pattern { } + }; + enforce domain core mp:Pattern {}; + where { + RSimplePatternToMPattern(wherep, mp); + } +} + +relation UnsharedWhenVarsToMgVars +{ + domain relations unsharedWhenVars:Set(Variable) {_++_}; + enforce domain core mg:GuardPattern { + bindsTo = mgVars:Set(Variable) {} + }; + where { + RVarSetToMVarSet(unsharedWhenVars->asSequence(), mgVars); + } +} + +relation DomainVarsSharedWithWhenToDgVars +{ + domain relations domainVarsSharedWithWhen:Set(Variable) {_++_}; + enforce domain core dg:GuardPattern { + bindsTo = dgVars:Set(Variable) {} + }; + where { + RVarSetToMVarSet(domainVarsSharedWithWhen->asSequence(), dgVars); + } +} + +relation DomainBottomUnSharedVarsToDbVars +{ + domain relations domainBottomUnSharedVars:Set(Variable) {_++_}; + enforce domain core db:BottomPattern { + bindsTo = dbVars:Set(Variable) {} + }; + where { + RVarSetToMVarSet(domainBottomUnSharedVars->asSequence(), dbVars); + } +} + +-- Rule 4 (extends Rule 2): +-- 4.1: A separate mapping is generated for each enforced domain of the relation. +-- 4.2: In this mapping only the enforced domain in question is marked as enforced in core; +-- all its opposite domains are marked in core as checked at most (i.e. either left as +-- they are or downgraded to checked if marked as enforced). +-- 4.3: The enforced domain's pattern gets decomposed into nested mappings as follows: +-- - root pattern object variable becomes a realized variable in the domain bottom +-- pattern of the current mapping. +-- - all identifying property template items become assignments in the domain bottom +-- pattern of the current mapping. +-- - all non identifying property template items of primitive type become assignments +-- in the bottom pattern of a nested mapping. +-- - each non identifying property template item of object type results in a nested +-- mapping which will have: +-- - a realized variable in the domain bottom, corresponding to the variable of the +-- property value object. +-- - a property assignment from parent object variable to this variable in the +-- domain bottom. +-- - and its own nested mappings as above recursively. +-- 4.4: Predicates of the where clause that refer to variables of the enforced domain get +-- distributed down to the nested mappings as variable bindings accumulate in the nested +-- mappings. +-- 4.5: all other opposite domains are mapped to their respective core domain parts as +-- described in Rule 3, i.e. their patterns are not decomposed down into nested mappings. +-- 4.6: A black-box operational implementation, if any, that the relation has for the +-- enforced domain becomes a pair of enforcement operations (one for creation and one for +-- deletion) in the domain-bottom pattern, both pointing to the same operation call +-- expression that takes its arguments from the variables corresponding to the root objects +-- of the domains of the relation. +-- +top relation TopLevelRelationToMappingForEnforcement +{ + allDomainVars: Set(essentialocl::Variable); + oppositeDomainVars: Set(essentialocl::Variable); + sharedDomainVars: Set(essentialocl::Variable); + predicatesWithVarBindings: Set(qvtbase::Predicate); + predicatesWithoutVarBindings: Set(qvtbase::Predicate); + unsharedWhenVars: Set(essentialocl::Variable); + unsharedWhereVars: Set(essentialocl::Variable); + domainVarsSharedWithWhen: Set(essentialocl::Variable); + domainBottomUnSharedVars: Set(essentialocl::Variable); + rn, dn, tmn: String; + rOppositeDomains:Set(qvtrelation::RelationDomain); + whenVars: Set(essentialocl::Variable); + whereVars: Set(essentialocl::Variable); + mbVars: Set(essentialocl::Variable); + rpSet: Set(qvtbase::Predicate); + rt: qvtrelation::RelationalTransformation; + mt: qvtbase::Transformation; + + domain relations r:Relation { + transformation = rt, + isTopLevel = true, + name = rn, + domain = rds:Set(RelationDomain) { + rd:RelationDomain { + isEnforceable = true, + name = dn, + typedModel = dir:TypedModel { + name = tmn, + usedPackage = up:Package{}, + transformation = rt + }, + pattern = dp:DomainPattern { + bindsTo = domainVars:Set(Variable) {}, + templateExpression = te:ObjectTemplateExp { + bindsTo = tev:Variable {} + } + } + } ++ rOppositeDomains + } + }; + enforce domain core m:Mapping { + transformation = mt, + name = rn+'_'+dn, + guardPattern = mg:GuardPattern { + area = m + }, + bottomPattern = mb:BottomPattern { + bindsTo = vs:Set(Variable) { + tcv:RealizedVariable {} ++ mbVars + } + }, + domain = md:CoreDomain { + name = dn, + isEnforceable = true, + typedModel = mdir:TypedModel { + name = tmn, + usedPackage = up, + transformation = mt + }, + guardPattern = dg:GuardPattern { + area = md + }, + bottomPattern = db:BottomPattern { + bindsTo = mtev:Variable {} + } + } --TODO: add var only if tev not in whenVars + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + allDomainVars = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} | + acc->including(md.oclAsType(qvtrelation::RelationDomain))).pattern.bindsTo->asSet(); + whenVars = r.when.bindsTo; + whereVars = r.where.bindsTo; + + -- Exclude where clause relation calls. + -- The predicate corresponding to a where clause relation call is included not in this + -- mapping but in the one corresponding to the invoked relation (refer to rule 2.6.1) + rpSet = r.where.predicate->reject(p | + p.conditionExpression.oclIsTypeOf(qvtrelation::RelationCallExp)); + + oppositeDomainVars = rOppositeDomains->iterate(d; vars: Set(essentialocl::Variable) = Set{} | + vars->union(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo)); + sharedDomainVars = getSharedDomainVars(r); + domainBottomUnSharedVars = domainVars - whenVars - sharedDomainVars; + + unsharedWhereVars = + (whereVars - whenVars - allDomainVars)->union(sharedDomainVars); + + predicatesWithVarBindings = + filterOutPredicatesThatReferToVars(rpSet, domainBottomUnSharedVars); + predicatesWithoutVarBindings = rpSet - predicatesWithVarBindings; + unsharedWhenVars = whenVars - allDomainVars; + domainVarsSharedWithWhen = domainVars->intersection(whenVars); + + RelationDomainToTraceClassVar(r, rd, tcv); + RWhenPatternToMGuardPattern(r, mg); + DomainVarsSharedWithWhenToDgVars(domainVarsSharedWithWhen, dg); + RVarToMRealizedVar(tev, mtev); + if (unsharedWhereVars->isEmpty()) + then + mbVars = Set{} + else + RVarSetToMVarSet(unsharedWhereVars->asSequence(), mbVars) + endif; + RPredicateSetToMBPredicateSet(predicatesWithVarBindings->asSequence(), mb); + RDomainToMDBottomForEnforcement(r, rd, te, predicatesWithoutVarBindings, domainBottomUnSharedVars, db); + ROppositeDomainVarsToTraceClassProps(r, rd, oppositeDomainVars, mb); + TROppositeDomainsToMappingForEnforcement(r, rd, m); + RRelImplToMBottomEnforcementOperation(r, rd, mb); + } +} + +-- Rule 5 (extends Rule 3): +-- 5.1: an invoked relation maps to as many core mappings as the relations that invoke it. +-- i.e. there exists a separate core mapping for each invoker-invoked pair. +-- 5.2: The guard pattern of the mapping will have a variable corresponding to the trace +-- class of the invoker relation, with root object variables of all the patterns of all the +-- domains of the invoked relation being equated with corresponding properties of this +-- trace class . +-- 5.3: The root object variable of a relation domain's pattern becomes a pattern variable +-- in the core domain guard (this is in addition to the variables that occur in the when clause +-- as per rule 2.1). +-- +top relation InvokedRelationToMappingForChecking +{ + allDomainVars: Set(essentialocl::Variable); + sharedDomainVars: Set(essentialocl::Variable); + unsharedWhereVars: Set(essentialocl::Variable); + rn, irn: String; + mbVars:Set(essentialocl::Variable); + rt: qvtrelation::RelationalTransformation; + mt: qvtbase::Transformation; + whenVars: Set(essentialocl::Variable); + whereVars: Set(essentialocl::Variable); + + domain relations r:Relation { + transformation = rt, + isTopLevel = false, + name = rn, + relationCallExp = ri:RelationCallExp { + predicate = p:Predicate { + pattern = pt:Pattern { + whereOwner = ir:Relation {name = irn} + } + } + } + } { + not r.domain->exists(d| d.isEnforceable = true) + }; + enforce domain core m:Mapping { + transformation = mt, + name = rn+'_'+irn, + guardPattern = mg:GuardPattern { + area = m + }, + bottomPattern = mb:BottomPattern { + bindsTo = vs:Set(Variable) { + tcv:RealizedVariable {} ++ mbVars + } + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + allDomainVars = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} | + acc->including(md.oclAsType(qvtrelation::RelationDomain))).pattern.bindsTo->asSet(); + whenVars = r.when.bindsTo; + whereVars = r.where.bindsTo; + sharedDomainVars = getSharedDomainVars(r); + unsharedWhereVars = + (whereVars - whenVars - allDomainVars)->union(sharedDomainVars); + + RelationToTraceClassVar(r, tcv); + RWhenPatternToMGuardPattern(r, mg); + RInvokerToMGuard(ir, ri, r, mg); + if (unsharedWhereVars->isEmpty()) + then + mbVars = Set{} + else + RVarSetToMVarSet(unsharedWhereVars->asSequence(), mbVars) + endif; + RWherePatternToMPattern(r, mb); + RDomainToMDomainForChecking(r, m); + } +} + +-- Rule 6 (extends Rule 4): +-- 6.1: an invoked relation maps to as many core mappings as the relations that invoke it. +-- i.e. there exists a separate core mapping for each invoker-invoked pair. +-- 6.2: The guard pattern of the mapping will have a variable corresponding to the trace +-- class of the invoker relation, with root object variables of all the patterns of all the +-- domains of the invoked relation being equated with corresponding properties of this +-- trace class . +-- 6.3: The root object variable of a relation domain's pattern becomes a pattern variable +-- in the core domain guard (this is in addition to the variables that occur in the when clause +-- as per rule 2.1). +-- +top relation InvokedRelationToMappingForEnforcement +{ + allDomainVars: Set(essentialocl::Variable); + oppositeDomainVars: Set(essentialocl::Variable); + sharedDomainVars: Set(essentialocl::Variable); + predicatesWithVarBindings: Set(qvtbase::Predicate); + predicatesWithoutVarBindings: Set(qvtbase::Predicate); + unsharedWhenVars: Set(essentialocl::Variable); + unsharedWhereVars: Set(essentialocl::Variable); + domainTopVars: Set(essentialocl::Variable); + domainBottomUnSharedVars: Set(essentialocl::Variable); + rn, irn, dn, tmn: String; + rOppositeDomains:Set(qvtrelation::RelationDomain); + whenVars: Set(essentialocl::Variable); + whereVars: Set(essentialocl::Variable); + mbVars: Set(essentialocl::Variable); + rpSet: Set(qvtbase::Predicate); + rt: qvtrelation::RelationalTransformation; + mt: qvtbase::Transformation; + + domain relations r:Relation { + transformation = rt, + isTopLevel = false, + name = rn, + relationCallExp = ri:RelationCallExp { + predicate = p:Predicate { + pattern = pt:Pattern { + whereOwner = ir:Relation {name = irn} + } + } + }, + domain = rds:Set(RelationDomain) { + rd:RelationDomain { + isEnforceable = true, + name = dn, + typedModel = dir:TypedModel { + name = tmn, + usedPackage = up:Package{}, + transformation = rt + }, + pattern = dp:DomainPattern { + bindsTo = domainVars:Set(Variable) {}, + templateExpression = te:ObjectTemplateExp { + bindsTo = tev:Variable {} + } + } + } ++ rOppositeDomains + } + }; + enforce domain core m:Mapping { + transformation = mt, + name = rn+'_'+irn+'_'+dn, + guardPattern = mg:GuardPattern { + area = m + }, + bottomPattern = mb:BottomPattern { + bindsTo = vs:Set(Variable) { + tcv:RealizedVariable {} ++ mbVars + } + }, + domain = md:CoreDomain { + name = dn, + isEnforceable = true, + typedModel = mdir:TypedModel { + name = tmn, + usedPackage = up, + transformation = mt + }, + guardPattern = dg:GuardPattern { + bindsTo = dgVars:Set(Variable) {} + }, + bottomPattern = db:BottomPattern { + area = md + } + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + allDomainVars = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} | + acc->including(md.oclAsType(qvtrelation::RelationDomain))).pattern.bindsTo->asSet(); + whenVars = r.when.bindsTo; + whereVars = r.where.bindsTo; + + -- Exclude where clause relation calls. + -- The predicate corresponding to a where clause relation call is included not in this + -- mapping but in the one corresponding to the invoked relation (refer to rule 2.6.1) + rpSet = r.where.predicate->reject(p | + p.conditionExpression.oclIsTypeOf(qvtrelation::RelationCallExp)); + + oppositeDomainVars = rOppositeDomains->iterate(d; vars: Set(essentialocl::Variable) = Set{} | + vars->union(d.pattern.bindsTo)); + sharedDomainVars = getSharedDomainVars(r); + domainBottomUnSharedVars = + (domainVars - whenVars - sharedDomainVars)->excluding(tev); + unsharedWhereVars = + (whereVars - whenVars - allDomainVars)->union(sharedDomainVars); + predicatesWithVarBindings = + filterOutPredicatesThatReferToVars(rpSet, domainBottomUnSharedVars); + predicatesWithoutVarBindings = rpSet - predicatesWithVarBindings; + unsharedWhenVars = whenVars - allDomainVars; + domainTopVars = domainVars->intersection(whenVars)->including(tev); + + RelationDomainToTraceClassVar(r, rd, tcv); + if (unsharedWhereVars->isEmpty()) + then + mbVars = Set{} + else + RVarSetToMVarSet(unsharedWhereVars->asSequence(), mbVars) + endif; + RPredicateSetToMBPredicateSet(predicatesWithVarBindings->asSequence(), mb); + RWhenPatternToMGuardPattern(r, mg); + RInvokerToMGuard(ir, ri, r, mg); + RVarSetToMVarSet(domainTopVars->asSequence(), dgVars); + RDomainToMDBottomForEnforcement(r, rd, te, predicatesWithoutVarBindings, domainBottomUnSharedVars, db); + ROppositeDomainVarsToTraceClassProps(r, rd, oppositeDomainVars, mb); + IROppositeDomainsToMappingForEnforcement(r, ir, rd, m); + RRelImplToMBottomEnforcementOperation(r, rd, mb); + } +} + +relation RDomainToMDomainForChecking +{ + sharedDomainVars: Set(essentialocl::Variable); + domainVarsSharedWithWhen: Set(essentialocl::Variable); + domainBottomUnSharedVars: Set(essentialocl::Variable); + whenVars: Set(essentialocl::Variable); + dn, tmn: String; + rt: qvtrelation::RelationalTransformation; + mt: qvtbase::Transformation; + + domain relations r:Relation { + domain = rd:RelationDomain { + name = dn, + isCheckable = true, + typedModel = dir:TypedModel { + name = tmn, + usedPackage = up:Package{}, + transformation = rt + }, + pattern = dp:DomainPattern { + bindsTo = domainVars:Set(Variable){}, + templateExpression = te:ObjectTemplateExp {} + } + } + }; + enforce domain core m:Mapping { + bottomPattern = mb:BottomPattern { + area = m + }, + domain = md:CoreDomain { + name = dn, + isCheckable = true, + typedModel = mdir:TypedModel { + name = tmn, + usedPackage = up, + transformation = mt + }, + guardPattern = dg:GuardPattern { + area = md + }, + bottomPattern = db:BottomPattern { + area = md + } + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + whenVars = r.when.bindsTo; + sharedDomainVars = getSharedDomainVars(r); + domainVarsSharedWithWhen = domainVars->intersection(whenVars); + domainBottomUnSharedVars = domainVars - whenVars - sharedDomainVars; + + DomainVarsSharedWithWhenToDgVars(domainVarsSharedWithWhen, dg); + DomainBottomUnSharedVarsToDbVars(domainBottomUnSharedVars, db); + RDomainPatternToMDBottomPattern(r, te, db); + RDomainVarsToTraceClassProps(rd, mb); + } +} + +-- opposite domains of a top-level relation's enforced domain are mapped as per rules +-- 4.2 and 4.5 +-- In addition, as per rule 6.3 the root object variable of a relation domain's pattern +-- becomes a pattern variable in the core domain guard (this is in addition to the variables +-- that occur in the when clause as per rule 2.1). +-- +relation IROppositeDomainsToMappingForEnforcement +{ + sharedDomainVars:Set(essentialocl::Variable); + domainTopVars: Set(essentialocl::Variable); + domainBottomUnSharedVars: Set(essentialocl::Variable); + domainBottomSharedVars: Set(essentialocl::Variable); + dn, tmn: String; + c: Boolean; + mbVars:Set(essentialocl::Variable); + whenVars:Set(essentialocl::Variable); + rt: qvtrelation::RelationalTransformation; + mt: qvtbase::Transformation; + up: emof::Package; + + domain relations r:Relation { + domain = rds:Set(RelationDomain) { + ord:RelationDomain { -- opposite domain + name = dn, + typedModel = dir:TypedModel { + name = tmn, + usedPackage = up, + transformation = rt + }, + isCheckable = c, + pattern = dp:DomainPattern { + bindsTo = domainVars:Set(Variable) {}, + templateExpression = te:ObjectTemplateExp { + bindsTo = tev:Variable {} + } + } + } ++ _ + } + }, + ir:Relation{}, + rd:RelationDomain{} + { + ord <> rd + }; + enforce domain core m:Mapping { + domain = cd:CoreDomain { + name = dn, + typedModel = mdir:TypedModel { + name = tmn, + usedPackage = up, + transformation = mt + }, + isCheckable = c, + isEnforceable = false, + guardPattern = dg:GuardPattern { + bindsTo = dgVars:Set(Variable) {} + }, + bottomPattern = db:BottomPattern { + bindsTo = dbVars:Set(Variable) {} + } + }, + bottomPattern = mb:BottomPattern { + area = m + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + whenVars = r.when.bindsTo; + domainTopVars = domainVars->intersection(whenVars)->including(tev); + sharedDomainVars = getSharedDomainVars(r); + domainBottomUnSharedVars = (domainVars - whenVars - sharedDomainVars)->excluding(tev); + domainBottomSharedVars = + (domainVars - whenVars)->intersection(sharedDomainVars)->excluding(tev); + + RVarSetToMVarSet(domainTopVars->asSequence(), dgVars); + RVarSetToMVarSet(domainBottomUnSharedVars->asSequence(), dbVars); + RVarSetToMBVarSet(domainBottomSharedVars->asSequence(), mb); + RDomainPatternToMDBottomPattern(r, te, db); + } +} + +-- opposite domains of an invoked relation's enforced domain are mapped as per rules +-- 4.2 and 4.5 +-- +relation TROppositeDomainsToMappingForEnforcement +{ + sharedDomainVars:Set(essentialocl::Variable); + domainTopVars: Set(essentialocl::Variable); + domainBottomUnSharedVars: Set(essentialocl::Variable); + domainBottomSharedVars: Set(essentialocl::Variable); + dn, tmn: String; + c: Boolean; + mbVars:Set(essentialocl::Variable); + whenVars:Set(essentialocl::Variable); + rt: qvtrelation::RelationalTransformation; + mt: qvtbase::Transformation; + up: emof::Package; + + domain relations r:Relation { + domain = rds:Set(RelationDomain) { + ord:RelationDomain { + name = dn, + typedModel = dir:TypedModel { + name = tmn, + usedPackage = up, + transformation = rt + }, + isCheckable = c, + pattern = dp:DomainPattern { + bindsTo = domainVars:Set(Variable) {}, + templateExpression = te:ObjectTemplateExp {} + } + } ++ _ + } + }, + rd:RelationDomain{} + { + ord <> rd + }; + enforce domain core m:Mapping { + domain = cd:CoreDomain { + name = dn, + typedModel = mdir:TypedModel { + name = tmn, + usedPackage = up, + transformation = mt + }, + isCheckable = c, + isEnforceable = false, + guardPattern = dg:GuardPattern { + bindsTo = dgVars:Set(Variable) {}, + area = cd + }, + bottomPattern = db:BottomPattern { + bindsTo = dbVars:Set(Variable) {} + } + }, + bottomPattern = mb:BottomPattern { + area = m + } + }; + where { + whenVars = r.when.bindsTo; + domainTopVars = domainVars->intersection(whenVars); + sharedDomainVars = getSharedDomainVars(r); + domainBottomUnSharedVars = domainVars - whenVars - sharedDomainVars; + domainBottomSharedVars = + (domainVars - whenVars)->intersection(sharedDomainVars); + + RelationalTransformationToMappingTransformation(rt, mt); + RVarSetToMVarSet(domainTopVars->asSequence(), dgVars); + RVarSetToMVarSet(domainBottomUnSharedVars->asSequence(), dbVars); + RVarSetToMBVarSet(domainBottomSharedVars->asSequence(), mb); + RDomainPatternToMDBottomPattern(r, te, db); + } +} + +relation RWhenPatternToMGuardPattern +{ + allDomainVars: Set(essentialocl::Variable); + unsharedWhenVars: Set(essentialocl::Variable); + + domain relations r:Relation{ + when = whenp:Pattern { + bindsTo = whenVars:Set(Variable) {} + } + }; + enforce domain core mg:GuardPattern {}; + where { + allDomainVars = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} | + acc->including(md.oclAsType(qvtrelation::RelationDomain))).pattern.bindsTo->asSet(); + unsharedWhenVars = whenVars - allDomainVars; + + RWhenRelCallToMGuard(whenp, mg); + RSimplePatternToMPattern(whenp, mg); + UnsharedWhenVarsToMgVars(unsharedWhenVars, mg); + } +} + +relation RVarSetToMVarSet +{ + rvRest: Sequence(essentialocl::Variable); + mvRest: Set(essentialocl::Variable); + + domain relations rvSeq:Sequence(Variable) {rv:Variable {}++rvRest}; + enforce domain core mvSet:Set(Variable) {mv:Variable {}++mvRest}; + where { + RVarToMVar(rv, mv); + if (rvRest->isEmpty()) + then + mvRest = Set{} + else + RVarSetToMVarSet(rvRest, mvRest) + endif; + } +} + +relation RVarSetToMBVarSet +{ + rvRest: Sequence(essentialocl::Variable); + mvRest: Set(essentialocl::Variable); + + domain relations rvSeq:Sequence(Variable) {rv:Variable {}++rvRest}; + enforce domain core mb:BottomPattern { + bindsTo = mv:Variable {} + }; + where { + RVarToMVar(rv, mv); + RVarSetToMBVarSet(rvRest, mb); + } +} + +relation RVarSetToDGVarSet +{ + rvRest: Sequence(essentialocl::Variable); + mvRest: Set(essentialocl::Variable); + + domain relations rvSeq:Sequence(Variable) {rv:Variable {}++rvRest}; + enforce domain core dg:GuardPattern { + bindsTo = mv:Variable {} + }; + where { + RVarToMVar(rv, mv); + RVarSetToDGVarSet(rvRest, dg); + } +} + +relation RVarToMVar +{ + n: String; + + domain relations rv:Variable {name=n, type=t:Type {}}; + enforce domain core mv:Variable {name=n, type=t}; +} + +relation RVarToMRealizedVar +{ + n: String; + + domain relations rv:Variable {name=n, type=t:Type {}}; + enforce domain core mv:RealizedVariable {name=n, type=t}; +} + +relation RSimplePatternToMPattern +{ + domain relations rp:Pattern { + predicate = pd:Predicate { + conditionExpression = re:OclExpression {} + } + } + { + not re.oclIsTypeOf(RelationCallExp) + }; + enforce domain core mp:Pattern { + predicate = mpd:Predicate{ + conditionExpression = me:OclExpression {} + } + }; + where { + RExpToMExp(re, me); + } +} + +-- Relation invocation in when clause maps to a trace class pattern in mapping guard. +-- Relation call argument position corresponds to the domain position in the invoked relation. +-- Domain's root pattern object var gives us the corresponding trace class prop. +-- +relation RWhenRelCallToMGuard +{ + domain relations rp:Pattern { + predicate = pd:Predicate { + conditionExpression = e:RelationCallExp { + referredRelation = r:Relation { + domain = dseq:Sequence(RelationDomain) {} + }, + argument = aseq:Sequence(VariableExp) {} + } + } + }; + enforce domain core mp:GuardPattern {}; + + where { + aseq->forAll( a | RWhenRelCallArgToMGuardPredicate(r, a, dseq->at(aseq->indexOf(a)), mp) ); + } +} + +relation RWhenRelCallArgToMGuardPredicate +{ + tc: emof::Class; + dvn: String; + mv:essentialocl::Variable; + + domain relations r:Relation{}, + ve:VariableExp { + referredVariable = v:Variable {} + }, + d:RelationDomain { + rootVariable = dv:Variable {name = dvn} + }; + enforce domain core mp:GuardPattern { + bindsTo = vd:Variable { + name = tc.name+'_v', + type = tc + }, + predicate = mpd:Predicate { + conditionExpression = ee:OperationCallExp { -- vd.dvn = mv + source = pe:PropertyCallExp { + source = pve:VariableExp{referredVariable = vd}, + referredProperty = pep:Property{name = dvn, class = vd.type.oclAsType(emof::Class)} + }, + referredOperation = eo:Operation{name = '='}, + argument = ave:VariableExp{referredVariable = mv} + } + } + }; + when { + RelationToTraceClass(r, tc); + } + where { + RVarToMVar(v, mv); + } +} + +-- invocation argument position corresponds to the domain position in invoked relation. +-- Invocation argument variable name gives the invoker trace class prop name; +-- Domain's root pattern object var gives us core domain guard var +-- +relation RInvokerToMGuard +{ + domain relations ir:Relation {}, -- invoking relation + ri:RelationCallExp { + argument = aseq:Sequence(VariableExp) {} + }, + r:Relation { -- invoked relation + domain = dseq:Sequence(RelationDomain) {} + }; + enforce domain core mg:GuardPattern {}; + where { + aseq->forAll( a | RInvokerToMGuardPredicate(ir, a, dseq->at(aseq->indexOf(a)), mg) ); + } +} + +relation RInvokerToMGuardPredicate +{ + vn: String; + tc: emof::Class; + mdv: essentialocl::Variable; + + domain relations ir:Relation {}, -- invoking relation + ve:VariableExp {referredVariable = v:Variable {name=vn}}, + d:RelationDomain { rootVariable = dv:Variable {} }; + enforce domain core mg:GuardPattern { + bindsTo = vd:Variable { + name = tc.name+'_v', + type = tc + }, + predicate = pd:Predicate { + conditionExpression = ee:OperationCallExp { -- vd.vn = mdv + source = pe:PropertyCallExp { + source = mve:VariableExp{referredVariable = vd}, + referredProperty = pep:Property{name = vn, class = vd.type.oclAsType(emof::Class)} + }, + referredOperation = eo:Operation{name = '='}, + argument = ave:VariableExp{referredVariable = mdv} + } + } + }; + when { + RelationToTraceClass(ir, tc); + } + where { + RVarToMVar(dv, mdv); + } +} + +relation RDomainPatternToMDBottomPattern +{ + domain relations r:Relation {}, te:ObjectTemplateExp {}; + enforce domain core db:BottomPattern { + area = cd:CoreDomain{ + rule = m:Mapping { + bottomPattern = mb:BottomPattern{area = m} + } + } + }; -- domain bottom + where { + RDomainPatternToMDBottomPatternComposite(r, te, db); + RDomainPatternToMDBottomPatternSimpleNonVarExpr(te, db); + RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr(r, te, db); + RDomainPatternToMDBottomPatternSimpleSharedVarExpr(r, te, mb); + } +} + +relation RDomainToMDBottomForEnforcement +{ + remainingUnBoundDomainVars: Set(essentialocl::Variable); + remainingPredicatesWithoutVarBindings:Set(qvtbase::Predicate); + predicatesWithoutVarBindings:Set(qvtbase::Predicate); + tcv, mv: essentialocl::Variable; + + domain relations r:Relation{}, + rd:RelationDomain{}, + te:ObjectTemplateExp {bindsTo = v:Variable {}}, + predicatesWithVarBindings:Set(qvtbase::Predicate) {}, + unboundDomainVars:Set(essentialocl::Variable) {}; + enforce domain core db:BottomPattern { -- domain bottom + area = cd:CoreDomain { + rule = m:Mapping { + bottomPattern = mb:BottomPattern { + area = m + } + } + } + }; + where { + remainingUnBoundDomainVars = unboundDomainVars - Set{v}; + predicatesWithVarBindings = filterOutPredicatesThatReferToVars( + predicatesWithoutVarBindings, remainingUnBoundDomainVars); + + remainingPredicatesWithoutVarBindings = + predicatesWithoutVarBindings - predicatesWithVarBindings; + + RDomainToMDBottomForEnforcementOfIdentityProp(r, te, db); + RDomainVarToMDBottomAssignmnetForEnforcement(r, rd, te, mb); + --RDomainToMDBottomForEnforcementOfIdentityPropObject(r, rd, te, mb); + RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive(r, te, rd, m); + RDomainToMDBottomForEnforcementOfNonIdentityPropObject(r, rd, te, remainingPredicatesWithoutVarBindings, remainingUnBoundDomainVars, m); + RDomainToMBottomPredicateForEnforcement(r, rd, te, predicatesWithVarBindings, unboundDomainVars, mb); + } +} + +relation RDomainVarToMDBottomAssignmnetForEnforcement +{ + tcv, mv: essentialocl::Variable; + + domain relations r:Relation{}, + rd:RelationDomain{}, + te:ObjectTemplateExp {bindsTo = v:Variable {}}; + enforce domain core mb:BottomPattern { -- domain bottom + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = tcv}, + targetProperty = tp:Property{name = v.name, class = tcv.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mv} + } + }; + where { + RelationDomainToTraceClassVar(r, rd, tcv); + RVarToMVar(v, mv); + } +} + +relation RDomainToMBottomPredicateForEnforcement +{ + remainingUnBoundDomainVars: Set(essentialocl::Variable); + predicatesWithVarBindings:Set(qvtbase::Predicate); + tcv, mv: essentialocl::Variable; + + domain relations r:Relation{}, + rd:RelationDomain{}, + te:ObjectTemplateExp {bindsTo = v:Variable {}}, + predicatesWithoutVarBindings:Set(qvtbase::Predicate){}, + unboundDomainVars:Set(essentialocl::Variable){}; + enforce domain core mb:BottomPattern { + predicate = pd:Predicate { + conditionExpression = ee:OperationCallExp { -- tcv.(v.name) = mv + source = pe:PropertyCallExp { + --source = tcv, + source = pve:VariableExp{referredVariable = tcv}, + referredProperty = pep:Property{ + name = v.name, + class = tcv.type.oclAsType(emof::Class) + } + }, + referredOperation = eo:Operation{name = '='}, + argument = ave:VariableExp{referredVariable = mv} + } + } + }; + where { + RelationDomainToTraceClassVar(r, rd, tcv); + RVarToMVar(v, mv); + remainingUnBoundDomainVars = unboundDomainVars - Set{v}; + predicatesWithVarBindings = filterOutPredicatesThatReferToVars( + predicatesWithoutVarBindings, remainingUnBoundDomainVars); + + RPredicateSetToMBPredicateSet(predicatesWithVarBindings->asSequence(), mb); + } +} + +relation RPredicateSetToMBPredicateSet +{ + rpRest: Sequence(qvtbase::Predicate); + + domain relations predSeq:Sequence(Predicate) { + rp:Predicate { + conditionExpression = re:OclExpression {} + } + ++ rpRest + }; + enforce domain core mb:BottomPattern { + predicate = mp:Predicate { + conditionExpression = me:OclExpression {} + } + }; + where { + RExpToMExp(re, me); + RPredicateSetToMBPredicateSet(rpRest, mb); + } +} + +relation RDomainToMDBottomForEnforcementOfIdentityProp +{ + domain relations r:Relation{}, + te:ObjectTemplateExp { + bindsTo = v:Variable {type=c:Class {}}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {}, + value = e:OclExpression {} + } + { + c.key.part->includes(pp) + } + }; + enforce domain core db:BottomPattern { + area = cd:CoreDomain { + rule = m:Mapping { + bottomPattern = mb:BottomPattern{ + area = m + } + } + } + }; -- domain bottom + where { + RDomainPatternExprToMappingDomainAssignment(v, pp, e, db); + RDomainPatternExprToMappingDomainVarAssignment(r, v, pp, e, db); + RDomainPatternExprToMappingDomainTemplateVarAssignment(r, v, pp, e, db); + RDomainPatternExprToMappingBottomVarAssignment(r, v, pp, e, mb); + } +} + +relation RDomainToMDBottomForEnforcementOfIdentityPropObject +{ + seqForAssignment: Sequence(emof::Element); + mtv, tcv : essentialocl::Variable; + + domain relations r:Relation{}, + rd:RelationDomain{}, + te:ObjectTemplateExp { + bindsTo = v:Variable {type=c:Class {}}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {}, + value = e:ObjectTemplateExp {bindsTo = tv:Variable{}} + } + } { + c.key.part->includes(pp) + }; + enforce domain core mb:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = tcv}, + targetProperty = tp:Property{name = tv.name, class = tcv.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mtv} + } + }; -- domain bottom + where { + RelationDomainToTraceClassVar(r, rd, tcv); + RVarToMVar(tv, mtv); + } +} + +relation RDomainPatternExprToMappingDomainAssignment +{ + pn: String; + mv: essentialocl::Variable; + + domain relations v:Variable {}, + pp:Property {name = pn}, + e:OclExpression {} { + not e.oclIsTypeOf(VariableExp) and not e.oclIsTypeOf(ObjectTemplateExp) + }; + enforce domain core db:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve:VariableExp{referredVariable = mv}, + targetProperty = tp:Property{name = pn, class = mv.type.oclAsType(emof::Class)}, + value = me:OclExpression{} + } + }; + where { + RVarToMVar(v, mv); + RExpToMExp(e, me); + } +} + +relation RDomainPatternExprToMappingDomainVarAssignment +{ + sharedDomainVars: Set(essentialocl::Variable); + rev, mev : essentialocl::Variable; + pn: String; + + domain relations r:Relation {}, + v:Variable {}, + pp:Property {name = pn}, + e:VariableExp {referredVariable = rev} + { + not sharedDomainVars->includes(e.referredVariable) + }; + enforce domain core db:BottomPattern { + realizedVariable = mv:RealizedVariable {}, + assignment = a:PropertyAssignment { + slotExpression = ve:VariableExp{referredVariable = mv}, + targetProperty = tp:Property{name = pn, class = mv.type.oclAsType(emof::Class)}, + value = me:VariableExp{referredVariable = mev} + } + }; + when { + sharedDomainVars = getSharedDomainVars(r); + } + where { + RVarToMRealizedVar(v, mv); + RVarToMVar(rev, mev); + } +} + +relation RDomainPatternExprToMappingDomainTemplateVarAssignment +{ + sharedDomainVars: Set(essentialocl::Variable); + rev, mev: essentialocl::Variable; + pn: String; + + domain relations r:Relation {}, + v:Variable {}, + pp:Property {name = pn}, + e:ObjectTemplateExp {bindsTo = rev} + { + not sharedDomainVars->includes(rev) + }; + enforce domain core db:BottomPattern { + realizedVariable = mv:RealizedVariable {}, + assignment = a:PropertyAssignment { + slotExpression = ve:VariableExp{referredVariable = mv}, + targetProperty = tp:Property{name = pn, class = mv.type.oclAsType(emof::Class)}, + value = me:VariableExp{referredVariable = mev} + } + }; + when { + sharedDomainVars = getSharedDomainVars(r); + } + where { + RVarToMRealizedVar(v, mv); + RVarToMVar(rev, mev); + } +} + +relation RDomainPatternExprToMappingBottomVarAssignment +{ + sharedDomainVars: Set(essentialocl::Variable); + rev, mev : essentialocl::Variable; + pn: String; + + domain relations r:Relation {}, + v:Variable {}, + pp:Property {name = pn}, + e:VariableExp {referredVariable = rev} + { + sharedDomainVars->includes(e.referredVariable) + }; + enforce domain core mb:BottomPattern { + realizedVariable = mv:RealizedVariable {}, + assignment = a:PropertyAssignment { + slotExpression = ve:VariableExp{referredVariable = mv}, + targetProperty = tp:Property{name = pn, class = mv.type.oclAsType(emof::Class)}, + value = me:VariableExp{referredVariable = mev} + } + }; + when { + sharedDomainVars = getSharedDomainVars(r); + } + where { + RVarToMRealizedVar(v, mv); + RVarToMVar(rev, mev); + } +} + +relation RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive +{ + pn: String; + mv: essentialocl::Variable; + + domain relations r:Relation{ + transformation = rt:RelationalTransformation{} + }, + te:ObjectTemplateExp { + bindsTo = v:Variable {type = c:Class {}}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {name = pn}, + value = e:OclExpression {} + } + } { + (not c.key.part->includes(pp)) and (not e.oclIsKindOf(TemplateExp)) + }, + rd:RelationDomain { + pattern = rdp:DomainPattern { + templateExpression = rdt:ObjectTemplateExp {} + } + }; + enforce domain core m:Mapping { + local = cm:Mapping { + name = m.name+'_forNonIdentityProp', + transformation = mt:Transformation{}, + bottomPattern = bp:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve:VariableExp{referredVariable = mv}, + targetProperty = tp:Property{name = pn, class = mv.type.oclAsType(emof::Class)}, + value = me:OclExpression{} + } + } + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + RVarToMVar(v, mv); + RExpToMExp(e, me); + RDomainToMComposedMappingGuard(r, te, rd, e, cm); + } +} + +relation RDomainToMComposedMappingGuard +{ + pn, dn, tmn: String; + tcv, mv: essentialocl::Variable; + mt: qvtbase::Transformation; + + domain relations r:Relation{ + transformation = rt:RelationalTransformation{} + }, + te:ObjectTemplateExp {}, + rd:RelationDomain { + name = dn, + typedModel = dir:TypedModel { + name = tmn, + usedPackage = up:Package{}, + transformation = rt + }, + pattern = rdp:DomainPattern { + templateExpression = rdt:ObjectTemplateExp {} + } + }, + ve:VariableExp {referredVariable = v:Variable {}} + { + isVarBoundToSomeOtherTemplate(rdt, te, v) + }; + enforce domain core cm:Mapping { + guardPattern = mg:GuardPattern { + predicate = pd:Predicate { + conditionExpression = ee:OperationCallExp { -- vd.vn = mdv + source = pe:PropertyCallExp { + source = ve1:VariableExp{referredVariable = tcv}, + referredProperty = tp:Property { + name = mv.name, + class = mv.type.oclAsType(emof::Class) + } + }, + referredOperation = eo:Operation{name = '='}, + argument = ve2:VariableExp{referredVariable = mv} + } + } + }, + domain = cd:CoreDomain { + name = dn, + typedModel = mdir:TypedModel { + name = tmn, + usedPackage = up, + transformation = mt + }, + guardPattern = cmdg:GuardPattern { + bindsTo = mv + } + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + RelationDomainToTraceClassVar(r, rd, tcv); + RVarToMVar(v, mv); + } +} + +relation RDomainToMDBottomForEnforcementOfNonIdentityPropObject +{ + dn, pn, tmn: String; + mv: essentialocl::Variable; + + domain relations r:Relation{ + transformation = rt:RelationalTransformation{} + }, + rd:RelationDomain { + name = dn, + typedModel = dir:TypedModel { + name = tmn, + usedPackage = up:Package{}, + transformation = rt + } + }, + te:ObjectTemplateExp { + bindsTo = v:Variable {type = c:Class {}}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {name = pn}, + value = pte:ObjectTemplateExp {bindsTo = pv:Variable {}} + } + }, + predicatesWithoutVarBindings:Set(qvtbase::Predicate){}, + unboundDomainVars:Set(essentialocl::Variable){} + { + not c.key.part->includes(pp) + }; + enforce domain core m:Mapping { + local = cm:Mapping { + name = m.name+'_for_'+pv.name, + transformation = mt:Transformation{}, + domain = cd:CoreDomain { + name = dn, + isEnforceable = true, + typedModel = mdir:TypedModel { + name = tmn, + usedPackage = up, + transformation = mt + }, + bottomPattern = cmdb:BottomPattern { + realizedVariable = mpv:RealizedVariable {}, + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = mv}, + targetProperty = tp:Property{name = pn, class = mv.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mpv} + } + } + }, + bottomPattern = mb:BottomPattern { + area = cm + } + } + }; + when { + RelationalTransformationToMappingTransformation(rt, mt); + } + where { + RVarToMVar(v, mv); + RVarToMRealizedVar(pv, mpv); + RDomainToMDBottomForEnforcement(r, rd, pte, predicatesWithoutVarBindings, unboundDomainVars, cmdb); + } +} + +relation RDomainPatternToMDBottomPatternComposite +{ + sharedDomainVars:Set(essentialocl::Variable); + pn: String; + mvte, mvpte: essentialocl::Variable; + + domain relations r:Relation{}, + te:ObjectTemplateExp { + bindsTo = vte:Variable {}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {name = pn}, + value = pte:ObjectTemplateExp {bindsTo = vpte:Variable {}} + } + }; + enforce domain core db:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = mvte}, + targetProperty = tp:Property{name = pn, class = mvte.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mvpte} + } + }; + where { + RVarToMVar(vte, mvte); + RVarToMVar(vpte, mvpte); + RDomainPatternToMDBottomPattern(r, pte, db); + } +} + +relation RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr +{ + sharedDomainVars: Set(essentialocl::Variable); + pn: String; + mvte, mvpte: essentialocl::Variable; + + domain relations r:Relation{}, + te:ObjectTemplateExp { + bindsTo = vte:Variable {}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {name = pn}, + value = e:VariableExp {referredVariable = vpte:Variable {}} + } + } { + not sharedDomainVars->includes(vpte) + }; + enforce domain core db:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = mvte}, + targetProperty = tp:Property{name = pn, class = mvte.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mvpte} + } + }; + when { + sharedDomainVars = getSharedDomainVars(r); + } + where { + RVarToMVar(vte, mvte); + RVarToMVar(vpte, mvpte); + } +} + +relation RDomainPatternToMDBottomPatternSimpleSharedVarExpr +{ + sharedDomainVars: Set(essentialocl::Variable); + pn: String; + mvte, mvpte: essentialocl::Variable; + + domain relations r:Relation{}, + te:ObjectTemplateExp { + bindsTo = vte:Variable {}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {name = pn}, + value = e:VariableExp {referredVariable=vpte:Variable {}} + } + } { + sharedDomainVars->includes(vpte) + }; + enforce domain core mb:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = mvte}, + targetProperty = tp:Property{name = pn, class = mvte.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mvpte} + } + }; + when { + sharedDomainVars = getSharedDomainVars(r); + } + where { + RVarToMVar(vte, mvte); + RVarToMVar(vpte, mvpte); + } +} + +relation RDomainPatternToMDBottomPatternSimpleNonVarExpr +{ + pn: String; + mvte: essentialocl::Variable; + + domain relations + te:ObjectTemplateExp { + bindsTo = vte:Variable {}, + part = pt:PropertyTemplateItem { + referredProperty = pp:Property {name = pn}, + value = e:OclExpression {} + } + } { + not e.oclIsKindOf(TemplateExp) and not e.oclIsTypeOf(VariableExp) + }; + enforce domain core db:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve:VariableExp{referredVariable = mvte}, + targetProperty = tp:Property{name = pn, class = mvte.type.oclAsType(emof::Class)}, + value = me:OclExpression{} + } + }; + where { + RVarToMVar(vte, mvte); + RExpToMExp(e, me); + } +} + +relation RDomainVarsToTraceClassProps +{ + tcv, mdv: essentialocl::Variable; + + domain relations rd:RelationDomain { + rule = r:Relation{}, + pattern = dp:DomainPattern { + bindsTo = domainVars:Set(Variable) {dv:Variable {templateExp = te: TemplateExp{}}++_} + } + }; + enforce domain core mb:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = tcv}, + targetProperty = tp:Property{name = dv.name, class = tcv.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mdv} + } + }; + where { + RelationToTraceClassVar(r, tcv); + RVarToMVar(dv, mdv); + } +} + +relation ROppositeDomainVarsToTraceClassProps +{ + tcv, mdv: essentialocl::Variable; + + domain relations r:Relation {}, + rd:RelationDomain {}, + domainVars:Set(Variable) {dv:Variable{templateExp = te:TemplateExp{}} ++ _}; + enforce domain core mb:BottomPattern { + assignment = a:PropertyAssignment { + slotExpression = ve1:VariableExp{referredVariable = tcv}, + targetProperty = tp:Property{name = dv.name, class = tcv.type.oclAsType(emof::Class)}, + value = ve2:VariableExp{referredVariable = mdv} + } + }; + where { + RelationDomainToTraceClassVar(r, rd, tcv); + RVarToMVar(dv, mdv); + } +} + +relation RRelImplToMBottomEnforcementOperation +{ + emptySet:Set(qvtcore::EnforcementOperation); + + domain relations r:Relation { + operationalImpl = ri:RelationImplementation { + inDirectionOf = tm:TypedModel{}, + impl = op:Operation{} + } + }, + rd:RelationDomain {typedModel = tm:TypedModel{}}; + enforce domain core mb:BottomPattern { + enforcementOperation = eoSet:Set(EnforcementOperation) { + eoc:EnforcementOperation { + enforcementMode = EnforcementMode::Creation, + operationCallExp = oce:OperationCallExp { + referredOperation = op + } + }, + eod:EnforcementOperation { + enforcementMode = EnforcementMode::Deletion, + operationCallExp = oce + } + ++ emptySet + } + } + default_values + { + emptySet = Set{}; + }; + where { + RRelDomainsToMOpCallArg(r, oce); + } +} + +relation RRelDomainsToMOpCallArg +{ + domain relations r:Relation { + domain = rd:RelationDomain { + pattern = p:DomainPattern{bindsTo = rv:Variable{}} + } + }; + enforce domain core oce:OperationCallExp { + argument = ar:VariableExp { + referredVariable = mv:Variable {} + } + }; + where { + RVarToMVar(rv, mv); + } +} + +relation RelationToTraceClassVar +{ + rn: String; + tc: emof::Class; + + domain relations r:Relation {name = rn}; + enforce domain core tcv:RealizedVariable { + name = rn+'_v', + type = tc + }; + when { + RelationToTraceClass(r, tc); + } +} + +relation RelationDomainToTraceClassVar +{ + rn, dn: String; + tc: emof::Class; + + domain relations r:Relation {name = rn}, + d:RelationDomain{name = dn}; + enforce domain core tcv:RealizedVariable { + name = rn+'_'+dn+'_v', + type = tc + }; + when { + RelationToTraceClass(r, tc); + } +} + +-- copy an ocl expression +-- For space reasons this relation is not expanded out here +relation RExpToMExp +{ + domain relations re:OclExpression{}; + enforce domain core me:OclExpression{} /*implementedby CopyOclExpession(re, me)*/; +} + +}
\ No newline at end of file |