blob: 44f8c9c2d6330f124b99a305411d2567455bf3fa [file] [log] [blame]
--------------------------------------------------------------------------------
-- 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
-- H. Hoyos - adaptation to comply with QVT 1.2 and bug fixes
--------------------------------------------------------------------------------
import pivotocl : 'platform:/resource/org.eclipse.ocl.pivot/model/Pivot.ecore'::pivot; -- HHR Use Pivot metamodels
import qvtbase : 'platform:/resource/org.eclipse.qvtd.pivot.qvtbase/model/QVTbase.ecore'::qvtbase; -- HHR Use Pivot metamodels
import qvttemplate : 'platform:/resource/org.eclipse.qvtd.pivot.qvttemplate/model/QVTtemplate.ecore'::qvttemplate; -- HHR Use Pivot metamodels
import qvtrelation : 'platform:/resource/org.eclipse.qvtd.pivot.qvtrelation/model/QVTrelation.ecore'::qvtrelation; -- HHR Use Pivot metamodels
import qvtcore : 'platform:/resource/org.eclipse.qvtd.pivot.qvtcore/model/QVTcore.ecore'::qvtcore; -- HHR Use Pivot metamodels
transformation relToCore(relations:{qvtrelation,qvttemplate,qvtbase,pivotocl}, core:{qvtcore,qvtbase,pivotocl}) -- HHR Use Pivot metamodels
{
key qvtcore::Mapping{name, transformation};
key qvtcore::GuardPattern{area}; -- HHR Use Pivot metamodels
key qvtcore::BottomPattern{area}; -- HHR Use Pivot metamodels
key pivotocl::Variable{name, type}; -- HHR Use Pivot metamodels
key pivotocl::Type{name}; -- HHR Use Pivot metamodels
key pivotocl::Class{name}; -- HHR Use Pivot metamodels
key pivotocl::Property{name, owningClass}; -- HHR Use Pivot metamodels
key qvtcore::CoreDomain{name, rule}; -- HHR Use Pivot metamodels
key qvtbase::TypedModel{name, usedPackage, transformation};
key pivotocl::Package{name}; -- HHR Use Pivot metamodels
key qvtbase::Transformation{name};
key pivotocl::Operation{name}; -- HHR Use Pivot metamodels
key qvtbase::Predicate{pattern, conditionExpression};
query getSharedDomainVars(r:qvtrelation::Relation):Set(pivotocl::Variable)
{
r.domain->iterate(d; vars: Set(pivotocl::Variable) = Set{} |
if (vars->isEmpty())
then
vars->union(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo->asSet())
else
vars->intersection(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo)
endif
)
}
query getWhenVars(r:qvtrelation::Relation):Set(pivotocl::Variable)
{
let
vs:Set(pivotocl::Variable) = Set{}
in
r.domain->iterate(d; vars: Set(pivotocl::Variable) = Set{} |
if (vars->isEmpty())
then
vars->union(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo->asSet())
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:pivotocl::OCLExpression[1]):Set(pivotocl::Variable)
{
-- Walk the expr tree of the OclExpression and
-- collect the variables used in those expressions
let
vs:Set(pivotocl::Variable) = Set{}
in
if (e.oclIsTypeOf(pivotocl::VariableExp))
then
vs->including(e.oclAsType(pivotocl::VariableExp).referredVariable)
else
if (e.oclIsTypeOf(pivotocl::OperationCallExp))
then
let
oc:pivotocl::OperationCallExp = e.oclAsType(pivotocl::OperationCallExp)
in
vs->union(getVarsOfExp(oc.ownedSource))->union(
oc.ownedArguments->iterate(a; avs:Set(pivotocl::Variable)=Set{} | avs->union(getVarsOfExp(a)))
)
else
if (e.oclIsTypeOf(pivotocl::PropertyCallExp))
then
vs->union(getVarsOfExp(e.oclAsType(pivotocl::PropertyCallExp).ownedSource))
else
if (e.oclIsTypeOf(qvtrelation::RelationCallExp))
then
let
rc:qvtrelation::RelationCallExp = e.oclAsType(qvtrelation::RelationCallExp)
in
vs->union(rc.argument->iterate(a; avs:Set(pivotocl::Variable)=Set{} |
avs->union(getVarsOfExp(a)))
)
else
vs
endif
endif
endif
endif
}
query filterOutPredicatesThatReferToVars(rpSet:Set(qvtbase::Predicate),
ownrdVars:Set(pivotocl::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:pivotocl::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,
ownedProperties = a:pivotocl::Property { -- HHR attributes renamed to properties
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 {
ownedProperties = a:pivotocl::Property { -- HHR attributes renamed to properties
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 = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} |
acc->including(md.oclAsType(qvtrelation::RelationDomain))
).pattern.bindsTo->asSet();
mbVars:Set(pivotocl::Variable);
mt: qvtbase::Transformation;
rn: String;
rt: qvtrelation::RelationalTransformation;
sharedDomainVars: Set(pivotocl::Variable) = getSharedDomainVars(r);
unsharedWhereVars: Set(pivotocl::Variable) = (whereVars - whenVars - allDomainVars)->union(sharedDomainVars);
whenVars: Set(pivotocl::Variable) = r.when.bindsTo;
whereVars: Set(pivotocl::Variable) = r.where.bindsTo;
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 {
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 = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} |
acc->including(md.oclAsType(qvtrelation::RelationDomain))
).pattern.bindsTo->asSet();
domainBottomUnSharedVars = domainVars - whenVars - sharedDomainVars;
domainVarsSharedWithWhen = domainVars->intersection(whenVars);
mbVars: Set(pivotocl::Variable);
mt: qvtbase::Transformation;
oppositeDomainVars = rOppositeDomains->iterate(d; vars: Set(pivotocl::Variable) = Set{} |
vars->union(d.oclAsType(qvtrelation::RelationDomain).pattern.bindsTo->asSet())
);
predicatesWithVarBindings = filterOutPredicatesThatReferToVars(rpSet, domainBottomUnSharedVars);
predicatesWithoutVarBindings = rpSet - predicatesWithVarBindings;
rOppositeDomains:Set(qvtrelation::RelationDomain);
rn, dn, tmn: String;
-- 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));
rt: qvtrelation::RelationalTransformation;
sharedDomainVars = getSharedDomainVars(r);
unsharedWhenVars = whenVars - allDomainVars;
unsharedWhereVars = (whereVars - whenVars - allDomainVars)->union(sharedDomainVars);
whenVars = r.when.bindsTo;
whereVars = r.where.bindsTo;
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 {
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 = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} |
acc->including(md.oclAsType(qvtrelation::RelationDomain))
).pattern.bindsTo->asSet();
mbVars:Set(pivotocl::Variable);
mt: qvtbase::Transformation;
rn, irn: String;
rt: qvtrelation::RelationalTransformation;
sharedDomainVars = getSharedDomainVars(r);
unsharedWhereVars = (whereVars - whenVars - allDomainVars)->union(sharedDomainVars);
whenVars = r.when.bindsTo;
whereVars = r.where.bindsTo;
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 {
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 = r.domain->iterate(md; acc:Set(qvtrelation::RelationDomain)=Set{} |
acc->including(md.oclAsType(qvtrelation::RelationDomain))
).pattern.bindsTo->asSet();
domainBottomUnSharedVars = (domainVars - whenVars - sharedDomainVars)->excluding(tev);
domainTopVars = domainVars->intersection(whenVars)->including(tev);
oppositeDomainVars = rOppositeDomains->iterate(d; vars: Set(pivotocl::Variable) = Set{} |
vars->union(d.pattern.bindsTo->asSet())
);
predicatesWithVarBindings = filterOutPredicatesThatReferToVars(rpSet, domainBottomUnSharedVars);
predicatesWithoutVarBindings = rpSet - predicatesWithVarBindings;
rOppositeDomains:Set(qvtrelation::RelationDomain);
rpSet = r.where.predicate->reject(p |
p.conditionExpression.oclIsTypeOf(qvtrelation::RelationCallExp)
);
sharedDomainVars = getSharedDomainVars(r);
unsharedWhenVars = whenVars - allDomainVars;
unsharedWhereVars = (whereVars - whenVars - allDomainVars)->union(sharedDomainVars);
whenVars = r.when.bindsTo;
whereVars = r.where.bindsTo;
rn, irn, dn, tmn: String;
mbVars: Set(pivotocl::Variable);
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 {
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
{
dn, tmn: String;
domainBottomUnSharedVars = domainVars - whenVars - sharedDomainVars;
domainVarsSharedWithWhen = domainVars->intersection(whenVars);
mt: qvtbase::Transformation;
rt: qvtrelation::RelationalTransformation;
sharedDomainVars = getSharedDomainVars(r);
whenVars = r.when.bindsTo;
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 {
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
{
c: Boolean;
dn, tmn: String;
domainBottomSharedVars = (domainVars - whenVars)->intersection(sharedDomainVars)->excluding(tev);
domainBottomUnSharedVars = (domainVars - whenVars - sharedDomainVars)->excluding(tev);
domainTopVars = domainVars->intersection(whenVars)->including(tev);
mbVars:Set(pivotocl::Variable);
mt: qvtbase::Transformation;
rt: qvtrelation::RelationalTransformation;
sharedDomainVars = getSharedDomainVars(r);
up: pivotocl::Package; -- HHR Use Pivot metamodels
whenVars = r.when.bindsTo;
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 {
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
{
c: Boolean;
dn, tmn: String;
domainBottomSharedVars = (domainVars - whenVars)->intersection(sharedDomainVars);
domainBottomUnSharedVars = domainVars - whenVars - sharedDomainVars;
domainTopVars = domainVars->intersection(whenVars);
mbVars:Set(pivotocl::Variable);
mt: qvtbase::Transformation;
rt: qvtrelation::RelationalTransformation;
sharedDomainVars = getSharedDomainVars(r);
up: pivotocl::Package; -- HHR Use Pivot metamodels
whenVars = r.when.bindsTo;
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 {
RelationalTransformationToMappingTransformation(rt, mt);
RVarSetToMVarSet(domainTopVars->asSequence(), dgVars);
RVarSetToMVarSet(domainBottomUnSharedVars->asSequence(), dbVars);
RVarSetToMBVarSet(domainBottomSharedVars->asSequence(), mb);
RDomainPatternToMDBottomPattern(r, te, db);
}
}
relation RWhenPatternToMGuardPattern
{
allDomainVars: Set(pivotocl::Variable);
unsharedWhenVars: Set(pivotocl::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
{
mvRest: Set(pivotocl::Variable);
rvRest: Sequence(pivotocl::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
{
mvRest: Set(pivotocl::Variable);
rvRest: Sequence(pivotocl::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
{
mvRest: Set(pivotocl::Variable);
rvRest: Sequence(pivotocl::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:pivotocl::OCLExpression {} -- HHR Use Pivot metamodels
}
} {
not re.oclIsTypeOf(RelationCallExp)
};
enforce domain core
mp:Pattern {
predicate = mpd:Predicate{
conditionExpression = me:pivotocl::OCLExpression {} -- HHR Use Pivot metamodels
}
};
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
{
dvn: String;
mv:pivotocl::Variable;
tc: pivotocl::Class; -- HHR Use Pivot metamodels
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
ownedSource = pe:PropertyCallExp { -- HHR added owned prefix
ownedSource = pve:VariableExp {
referredVariable = vd
}, -- HHR added owned prefix
referredProperty = pep:Property {
name = dvn,
owningClass = vd.type.oclAsType(pivotocl::Class)
} -- HHR added owned prefix, Use Pivot metamodels
},
referredOperation = eo:Operation {
name = '='
},
ownedArguments = ave:VariableExp {
referredVariable = mv
} -- HHR added owned prefix
}
}
};
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
{
mdv: pivotocl::Variable;
tc: pivotocl::Class; -- HHR Use Pivot metamodels
vn: String;
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
ownedSource = pe:PropertyCallExp { -- HHR added owned prefix
ownedSource = mve:VariableExp {
referredVariable = vd
}, -- HHR added owned prefix
referredProperty = pep:Property {
name = vn,
owningClass = vd.type.oclAsType(pivotocl::Class)
} -- HHR added owned prefix, Use Pivot metamodels
},
referredOperation = eo:Operation {
name = '='
},
ownedArguments = ave:VariableExp {
referredVariable = mdv
} -- HHR added owned prefix
}
}
};
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
{
predicatesWithVarBindings = filterOutPredicatesThatReferToVars(predicatesWithoutVarBindings, remainingUnBoundDomainVars);
remainingUnBoundDomainVars = unboundDomainVars - Set{v};
remainingPredicatesWithoutVarBindings = predicatesWithoutVarBindings - predicatesWithVarBindings;
tcv, mv: pivotocl::Variable;
domain relations
r:Relation {},
rd:RelationDomain {},
te:ObjectTemplateExp {
bindsTo = v:Variable {}
},
predicatesWithoutVarBindings:Set(qvtbase::Predicate) {},
unboundDomainVars:Set(pivotocl::Variable) {};
enforce domain
core db:BottomPattern { -- domain bottom
area = cd:CoreDomain {
rule = m:Mapping {
bottomPattern = mb:BottomPattern {
area = m
}
}
}
};
where {
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, predicatesWithoutVarBindings, unboundDomainVars, mb);
}
}
relation RDomainVarToMDBottomAssignmnetForEnforcement
{
tcv, mv: pivotocl::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,
owningClass = tcv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, Use Pivot metamodels
value = ve2:VariableExp {
referredVariable = mv
}
}
};
where {
RelationDomainToTraceClassVar(r, rd, tcv);
RVarToMVar(v, mv);
}
}
relation RDomainToMBottomPredicateForEnforcement
{
predicatesWithVarBindings:Set(qvtbase::Predicate);
remainingUnBoundDomainVars: Set(pivotocl::Variable);
tcv, mv: pivotocl::Variable;
domain relations
r:Relation {},
rd:RelationDomain {},
te:ObjectTemplateExp {
bindsTo = v:Variable {}
},
predicatesWithoutVarBindings:Set(qvtbase::Predicate) {},
unboundDomainVars:Set(pivotocl::Variable) {};
enforce domain core
mb:BottomPattern {
predicate = pd:Predicate {
conditionExpression = ee:OperationCallExp { -- tcv.(v.name) = mv
ownedSource = pe:PropertyCallExp { -- HHR added owned prefix
--source = tcv,
ownedSource = pve:VariableExp {
referredVariable = tcv
}, -- HHR added owned prefix
referredProperty = pep:Property {
name = v.name,
owningClass = tcv.type.oclAsType(pivotocl::Class) -- HHR added owned prefix, Use Pivot metamodels
}
},
referredOperation = eo:Operation {
name = '='
},
ownedArguments = ave:VariableExp {
referredVariable = mv
} -- HHR added owned prefix
}
}
};
where {
remainingUnBoundDomainVars = unboundDomainVars - Set{v};
predicatesWithVarBindings = filterOutPredicatesThatReferToVars(
predicatesWithoutVarBindings, remainingUnBoundDomainVars);
RelationDomainToTraceClassVar(r, rd, tcv);
RVarToMVar(v, mv);
RPredicateSetToMBPredicateSet(predicatesWithVarBindings->asSequence(), mb);
}
}
relation RPredicateSetToMBPredicateSet
{
rpRest: Sequence(qvtbase::Predicate);
domain relations
predSeq:Sequence(Predicate) {
rp:Predicate {
conditionExpression = re:OCLExpression {} -- HHR Use Pivot metamodels
} ++ rpRest
};
enforce domain core
mb:BottomPattern {
predicate = mp:Predicate {
conditionExpression = me:OCLExpression {} -- HHR Use Pivot metamodels
}
};
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 {} -- HHR Use Pivot metamodels
}
{
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
{
mtv, tcv : pivotocl::Variable;
seqForAssignment: Sequence(pivotocl::Element); -- HHR Use Pivot metamodels
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,
owningClass = tcv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = ve2:VariableExp{referredVariable = mtv}
}
}; -- domain bottom
where {
RelationDomainToTraceClassVar(r, rd, tcv);
RVarToMVar(tv, mtv);
}
}
relation RDomainPatternExprToMappingDomainAssignment
{
mv: pivotocl::Variable;
pn: String;
domain relations
v:Variable {},
pp:Property {
name = pn
},
e:OCLExpression {} { -- HHR Use Pivot metamodels
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,
owningClass = mv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = me:OCLExpression{} -- HHR Use Pivot metamodels
}
};
where {
RVarToMVar(v, mv);
RExpToMExp(e, me);
}
}
relation RDomainPatternExprToMappingDomainVarAssignment
{
pn: String;
rev, mev : pivotocl::Variable;
sharedDomainVars: Set(pivotocl::Variable);
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,
owningClass = mv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = me:VariableExp {
referredVariable = mev
}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMRealizedVar(v, mv);
RVarToMVar(rev, mev);
}
}
relation RDomainPatternExprToMappingDomainTemplateVarAssignment
{
pn: String;
rev, mev: pivotocl::Variable;
sharedDomainVars: Set(pivotocl::Variable);
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,
owningClass = mv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = me:VariableExp {
referredVariable = mev
}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMRealizedVar(v, mv);
RVarToMVar(rev, mev);
}
}
relation RDomainPatternExprToMappingBottomVarAssignment
{
pn: String;
rev, mev : pivotocl::Variable;
sharedDomainVars: Set(pivotocl::Variable);
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,
owningClass = mv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = me:VariableExp {
referredVariable = mev
}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMRealizedVar(v, mv);
RVarToMVar(rev, mev);
}
}
relation RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
{
mv: pivotocl::Variable;
pn: String;
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 {} -- HHR Use Pivot metamodels
}
}
{
(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,
owningClass = mv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = me:OCLExpression{} -- HHR Use Pivot metamodels
}
}
}
};
when {
RelationalTransformationToMappingTransformation(rt, mt);
}
where {
RVarToMVar(v, mv);
RExpToMExp(e, me);
RDomainToMComposedMappingGuard(r, te, rd, e, cm);
}
}
relation RDomainToMComposedMappingGuard
{
mt: qvtbase::Transformation;
pn, dn, tmn: String;
tcv, mv: pivotocl::Variable;
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
ownedSource = pe:PropertyCallExp { -- HHR added owned prefix
ownedSource = ve1:VariableExp {
referredVariable = tcv
}, -- HHR added owned prefix
referredProperty = tp:Property {
name = mv.name,
owningClass = mv.type.oclAsType(pivotocl::Class) -- HHR added owned prefix, use Pivot metamodels
}
},
referredOperation = eo:Operation {
name = '='
},
ownedArguments = ve2:VariableExp {
referredVariable = mv
} -- HHR added owned prefix
}
}
},
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: pivotocl::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(pivotocl::Variable) {} { -- TODO this should be moved to guard te
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,
owningClass = mv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
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
{
mvte, mvpte: pivotocl::Variable;
pn: String;
sharedDomainVars:Set(pivotocl::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,
owningClass = mvte.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = ve2:VariableExp {
referredVariable = mvpte
}
}
};
where {
RVarToMVar(vte, mvte);
RVarToMVar(vpte, mvpte);
RDomainPatternToMDBottomPattern(r, pte, db);
}
}
relation RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr
{
mvte, mvpte: pivotocl::Variable;
pn: String;
sharedDomainVars: Set(pivotocl::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,
owningClass = mvte.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = ve2:VariableExp {
referredVariable = mvpte
}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMVar(vte, mvte);
RVarToMVar(vpte, mvpte);
}
}
relation RDomainPatternToMDBottomPatternSimpleSharedVarExpr
{
mvte, mvpte: pivotocl::Variable;
pn: String;
sharedDomainVars: Set(pivotocl::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,
owningClass = mvte.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = ve2:VariableExp{referredVariable = mvpte}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMVar(vte, mvte);
RVarToMVar(vpte, mvpte);
}
}
relation RDomainPatternToMDBottomPatternSimpleNonVarExpr
{
mvte: pivotocl::Variable;
pn: String;
domain relations
te:ObjectTemplateExp {
bindsTo = vte:Variable {},
part = pt:PropertyTemplateItem {
referredProperty = pp:Property {
name = pn
},
value = e:OCLExpression {} -- HHR Use Pivot metamodels
}
} {
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,
owningClass = mvte.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = me:OCLExpression{} -- HHR Use Pivot metamodels
}
};
where {
RVarToMVar(vte, mvte);
RExpToMExp(e, me);
}
}
relation RDomainVarsToTraceClassProps
{
tcv, mdv: pivotocl::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,
owningClass = tcv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = ve2:VariableExp {
referredVariable = mdv
}
}
};
where {
RelationToTraceClassVar(r, tcv);
RVarToMVar(dv, mdv);
}
}
relation ROppositeDomainVarsToTraceClassProps
{
tcv, mdv: pivotocl::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,
owningClass = tcv.type.oclAsType(pivotocl::Class)
}, -- HHR added owned prefix, use Pivot metamodels
value = ve2:VariableExp {
referredVariable = mdv
}
}
};
where {
RelationDomainToTraceClassVar(r, rd, tcv);
RVarToMVar(dv, mdv);
}
}
relation RRelImplToMBottomEnforcementOperation
{
emptySet:Set(qvtcore::EnforcementOperation); -- HHR Use Pivot metamodels
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 {
ownedArguments = ar:VariableExp { -- HHR added owned prefix
referredVariable = mv:Variable {}
}
};
where {
RVarToMVar(rv, mv);
}
}
relation RelationToTraceClassVar
{
rn: String;
tc: pivotocl::Class; -- HHR Use Pivot metamodels
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: pivotocl::Class; -- HHR Use Pivot metamodels
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
default relation RExpToMExp
{
domain relations
re:OCLExpression {}; -- HHR Use Pivot metamodels
enforce domain core
me:OCLExpression {} /*implementedby CopyOclExpession(re, me)*/;-- HHR Use Pivot metamodels
}
}