blob: c65078ddebde9fee815bbd7806e170ba00247951 [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 QVT 1.0 specification
-- E.D.Willink - contributions to drafts of the above
--------------------------------------------------------------------------------
transformation relToCore(relations:QVTMM, core:QVTMM)
{
key QVTMM::Mapping{name, _'transformation'};
key QVTMM::GuardPattern{area};
key QVTMM::BottomPattern{area};
key QVTMM::Variable{name, type};
key QVTMM::Type{name};
key QVTMM::Class{name};
key QVTMM::Property{name, class};
key QVTMM::CoreDomain{name, rule};
key QVTMM::TypedModel{name, usedPackage, _'transformation'};
key QVTMM::Package{name};
key QVTMM::Transformation{name};
key QVTMM::Operation{name};
key QVTMM::Predicate{pattern, conditionExpression};
query getSharedDomainVars(r:QVTMM::Relation):Set(QVTMM::Variable)
{
r._'domain'->iterate(d; vars: Set(QVTMM::Variable) = Set{} |
if (vars->isEmpty())
then
vars->union(d.oclAsType(QVTMM::RelationDomain).pattern.bindsTo)
else
vars->intersection(d.oclAsType(QVTMM::RelationDomain).pattern.bindsTo)
endif
)
}
query getWhenVars(r:QVTMM::Relation):Set(QVTMM::Variable)
{
let
vs:Set(QVTMM::Variable) = Set{}
in
r._'domain'->iterate(d; vars: Set(QVTMM::Variable) = Set{} |
if (vars->isEmpty())
then
vars->union(d.oclAsType(QVTMM::RelationDomain).pattern.bindsTo)
else
vars->intersection(d.oclAsType(QVTMM::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:QVTMM::OclExpression):Set(QVTMM::Variable)
{
-- Walk the expr tree of the OclExpression and
-- collect the variables used in those expressions
let
vs:Set(QVTMM::Variable) = Set{}
in
if (e.oclIsTypeOf(QVTMM::VariableExp))
then
vs->including(e.oclAsType(QVTMM::VariableExp).referredVariable)
else
if (e.oclIsTypeOf(QVTMM::OperationCallExp))
then
let
oc:QVTMM::OperationCallExp = e.oclAsType(QVTMM::OperationCallExp)
in
vs->union(getVarsOfExp(oc.source))->union(
oc.argument->iterate(a; avs:Set(QVTMM::Variable)=Set{} | avs->union(getVarsOfExp(a)))
)
else
if (e.oclIsTypeOf(QVTMM::PropertyCallExp))
then
vs->union(getVarsOfExp(e.oclAsType(QVTMM::PropertyCallExp).source))
else
if (e.oclIsTypeOf(QVTMM::RelationCallExp))
then
let
rc:QVTMM::RelationCallExp = e.oclAsType(QVTMM::RelationCallExp)
in
vs->union(rc.argument->iterate(a; avs:Set(QVTMM::Variable)=Set{} |
avs->union(getVarsOfExp(a)))
)
else
vs
endif
endif
endif
endif
}
query filterOutPredicatesThatReferToVars(rpSet:Set(QVTMM::Predicate),
ownrdVars:Set(QVTMM::Variable)) :Set(QVTMM::Predicate)
{
rpSet->iterate(p:QVTMM::Predicate; fpSet:Set(QVTMM::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:QVTMM::ObjectTemplateExp,
skipTe:QVTMM::ObjectTemplateExp, v:QVTMM::Variable):Boolean
{
if (rootTe = skipTe)
then
false
else
if (rootTe.bindsTo = v)
then
true
else
rootTe.part.value->select(pe | pe.oclIsKindOf(QVTMM::ObjectTemplateExp))->exists(pet |
isVarBoundToSomeOtherTemplate(pet.oclAsType(QVTMM::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(QVTMM::Variable);
sharedDomainVars: Set(QVTMM::Variable);
unsharedWhereVars: Set(QVTMM::Variable);
whenVars: Set(QVTMM::Variable);
whereVars: Set(QVTMM::Variable);
rn: String;
mbVars:Set(QVTMM::Variable);
rt: QVTMM::RelationalTransformation;
mt: QVTMM::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(QVTMM::RelationDomain)=Set{} |
acc->including(md.oclAsType(QVTMM::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(QVTMM::Variable);
oppositeDomainVars: Set(QVTMM::Variable);
sharedDomainVars: Set(QVTMM::Variable);
predicatesWithVarBindings: Set(QVTMM::Predicate);
predicatesWithoutVarBindings: Set(QVTMM::Predicate);
unsharedWhenVars: Set(QVTMM::Variable);
unsharedWhereVars: Set(QVTMM::Variable);
domainVarsSharedWithWhen: Set(QVTMM::Variable);
domainBottomUnSharedVars: Set(QVTMM::Variable);
rdSeq, rdtSeq, relImplSeq: Sequence(QVTMM::Element);
rdSet: Set(QVTMM::Element);
rdVarsSeq: Sequence(Set(QVTMM::Element));
rdtSet: Set(QVTMM::Element);
rdtVarsSeq: Sequence(Set(QVTMM::Element));
rn, dn, tmn: String;
rOppositeDomains:Set(QVTMM::RelationDomain);
oppDomainSeq:Sequence(QVTMM::Element);
whenVars: Set(QVTMM::Variable);
whereVars: Set(QVTMM::Variable);
mbVars: Set(QVTMM::Variable);
rpSet: Set(QVTMM::Predicate);
rt: QVTMM::RelationalTransformation;
mt: QVTMM::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(QVTMM::RelationDomain)=Set{} |
acc->including(md.oclAsType(QVTMM::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(QVTMM::RelationCallExp));
oppositeDomainVars = rOppositeDomains->iterate(d; vars: Set(QVTMM::Variable) = Set{} |
vars->union(d.oclAsType(QVTMM::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);
rdSeq = Sequence{r, rd};
rdSet = Set{r, rd};
rdVarsSeq = Sequence{rdSet, oppositeDomainVars};
rdtSet = Set{r, rd, te};
rdtVarsSeq = Sequence{rdtSet, predicatesWithoutVarBindings, domainBottomUnSharedVars};
oppDomainSeq = Sequence{r, rd};
relImplSeq = Sequence{r, rd};
RelationDomainToTraceClassVar(rdSeq, 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(rdtVarsSeq, db);
ROppositeDomainVarsToTraceClassProps(rdVarsSeq, mb);
TROppositeDomainsToMappingForEnforcement(oppDomainSeq, m);
RRelImplToMBottomEnforcementOperation(relImplSeq, 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(QVTMM::Variable);
sharedDomainVars: Set(QVTMM::Variable);
unsharedWhereVars: Set(QVTMM::Variable);
seqForInvoker: Sequence(QVTMM::Element);
rn, irn: String;
mbVars:Set(QVTMM::Variable);
rt: QVTMM::RelationalTransformation;
mt: QVTMM::Transformation;
whenVars: Set(QVTMM::Variable);
whereVars: Set(QVTMM::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(QVTMM::RelationDomain)=Set{} |
acc->including(md.oclAsType(QVTMM::RelationDomain))).pattern.bindsTo->asSet();
whenVars = r._'when'.bindsTo;
whereVars = r._'where'.bindsTo;
sharedDomainVars = getSharedDomainVars(r);
unsharedWhereVars =
(whereVars - whenVars - allDomainVars)->union(sharedDomainVars);
seqForInvoker = Sequence{ ir, ri, r};
RelationToTraceClassVar(r, tcv);
RWhenPatternToMGuardPattern(r, mg);
RInvokerToMGuard(seqForInvoker, 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(QVTMM::Variable);
oppositeDomainVars: Set(QVTMM::Variable);
sharedDomainVars: Set(QVTMM::Variable);
predicatesWithVarBindings: Set(QVTMM::Predicate);
predicatesWithoutVarBindings: Set(QVTMM::Predicate);
unsharedWhenVars: Set(QVTMM::Variable);
unsharedWhereVars: Set(QVTMM::Variable);
domainTopVars: Set(QVTMM::Variable);
domainBottomUnSharedVars: Set(QVTMM::Variable);
rdSeq, relImplSeq: Sequence(QVTMM::Element);
rdSet: Set(QVTMM::Element);
rdVarsSeq: Sequence(Set(QVTMM::Element));
rdtSet: Set(QVTMM::Element);
rdtVarsSeq: Sequence(Set(QVTMM::Element));
seqForInvoker: Sequence(QVTMM::Element);
rn, irn, dn, tmn: String;
rOppositeDomains:Set(QVTMM::RelationDomain);
oppDomainSeq:Sequence(QVTMM::Element);
whenVars: Set(QVTMM::Variable);
whereVars: Set(QVTMM::Variable);
mbVars: Set(QVTMM::Variable);
rpSet: Set(QVTMM::Predicate);
rt: QVTMM::RelationalTransformation;
mt: QVTMM::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(QVTMM::RelationDomain)=Set{} |
acc->including(md.oclAsType(QVTMM::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(QVTMM::RelationCallExp));
oppositeDomainVars = rOppositeDomains->iterate(d; vars: Set(QVTMM::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);
rdSeq = Sequence{r, rd};
rdSet = Set{r, rd};
rdVarsSeq = Sequence{rdSet, oppositeDomainVars};
rdtSet = Set{r, rd, te};
rdtVarsSeq = Sequence{rdtSet, predicatesWithoutVarBindings, domainBottomUnSharedVars};
oppDomainSeq = Sequence{r, ir, rd};
seqForInvoker = Sequence{ir, ri, r};
relImplSeq = Sequence{r, rd};
RelationDomainToTraceClassVar(rdSeq, tcv);
if (unsharedWhereVars->isEmpty())
then
mbVars = Set{}
else
RVarSetToMVarSet(unsharedWhereVars->asSequence(), mbVars)
endif;
RPredicateSetToMBPredicateSet(predicatesWithVarBindings->asSequence(), mb);
RWhenPatternToMGuardPattern(r, mg);
RInvokerToMGuard(seqForInvoker, mg);
RVarSetToMVarSet(domainTopVars->asSequence(), dgVars);
RDomainToMDBottomForEnforcement(rdtVarsSeq, db);
ROppositeDomainVarsToTraceClassProps(rdVarsSeq, mb);
IROppositeDomainsToMappingForEnforcement(oppDomainSeq, m);
RRelImplToMBottomEnforcementOperation(relImplSeq, mb);
}
}
relation RDomainToMDomainForChecking
{
sharedDomainVars: Set(QVTMM::Variable);
domainVarsSharedWithWhen: Set(QVTMM::Variable);
domainBottomUnSharedVars: Set(QVTMM::Variable);
seqForDomainPtrn: Sequence(QVTMM::Element);
whenVars: Set(QVTMM::Variable);
dn, tmn: String;
rt: QVTMM::RelationalTransformation;
mt: QVTMM::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;
seqForDomainPtrn = Sequence{r, te};
DomainVarsSharedWithWhenToDgVars(domainVarsSharedWithWhen, dg);
DomainBottomUnSharedVarsToDbVars(domainBottomUnSharedVars, db);
RDomainPatternToMDBottomPattern(seqForDomainPtrn, 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(QVTMM::Variable);
domainTopVars: Set(QVTMM::Variable);
domainBottomUnSharedVars: Set(QVTMM::Variable);
domainBottomSharedVars: Set(QVTMM::Variable);
seqForDomainPtrn: Sequence(QVTMM::Element);
dn, tmn: String;
c: Boolean;
mbVars:Set(QVTMM::Variable);
whenVars:Set(QVTMM::Variable);
rt: QVTMM::RelationalTransformation;
mt: QVTMM::Transformation;
up: QVTMM::Package;
domain relations oppDomainSeq:Sequence(Element) {
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);
seqForDomainPtrn = Sequence{r, te};
RVarSetToMVarSet(domainTopVars->asSequence(), dgVars);
RVarSetToMVarSet(domainBottomUnSharedVars->asSequence(), dbVars);
RVarSetToMBVarSet(domainBottomSharedVars->asSequence(), mb);
RDomainPatternToMDBottomPattern(seqForDomainPtrn, db);
}
}
-- opposite domains of an invoked relation's enforced domain are mapped as per rules
-- 4.2 and 4.5
--
relation TROppositeDomainsToMappingForEnforcement
{
sharedDomainVars:Set(QVTMM::Variable);
domainTopVars: Set(QVTMM::Variable);
domainBottomUnSharedVars: Set(QVTMM::Variable);
domainBottomSharedVars: Set(QVTMM::Variable);
seqForDomainPtrn: Sequence(QVTMM::Element);
dn, tmn: String;
c: Boolean;
mbVars:Set(QVTMM::Variable);
whenVars:Set(QVTMM::Variable);
rt: QVTMM::RelationalTransformation;
mt: QVTMM::Transformation;
up: QVTMM::Package;
domain relations oppDomainSeq:Sequence(Element) {
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 {
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);
seqForDomainPtrn = Sequence{r, te};
RelationalTransformationToMappingTransformation(rt, mt);
RVarSetToMVarSet(domainTopVars->asSequence(), dgVars);
RVarSetToMVarSet(domainBottomUnSharedVars->asSequence(), dbVars);
RVarSetToMBVarSet(domainBottomSharedVars->asSequence(), mb);
RDomainPatternToMDBottomPattern(seqForDomainPtrn, db);
}
}
relation RWhenPatternToMGuardPattern
{
allDomainVars: Set(QVTMM::Variable);
unsharedWhenVars: Set(QVTMM::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(QVTMM::RelationDomain)=Set{} |
acc->including(md.oclAsType(QVTMM::RelationDomain))).pattern.bindsTo->asSet();
unsharedWhenVars = whenVars - allDomainVars;
RWhenRelCallToMGuard(whenp, mg);
RSimplePatternToMPattern(whenp, mg);
UnsharedWhenVarsToMgVars(unsharedWhenVars, mg);
}
}
relation RVarSetToMVarSet
{
rvRest: Sequence(QVTMM::Variable);
mvRest: Set(QVTMM::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(QVTMM::Variable);
mvRest: Set(QVTMM::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(QVTMM::Variable);
mvRest: Set(QVTMM::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( Sequence{ r, a, dseq->at(aseq->indexOf(a)) }, mp) );
}
}
relation RWhenRelCallArgToMGuardPredicate
{
tc: QVTMM::Class;
dvn: String;
mv:QVTMM::Variable;
domain relations daSeq:Sequence(Element) {
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(QVTMM::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 seqForInvoker:Sequence(Element) {
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( Sequence{ ir, a, dseq->at(aseq->indexOf(a)) }, mg) );
}
}
relation RInvokerToMGuardPredicate
{
vn: String;
tc: QVTMM::Class;
mdv: QVTMM::Variable;
domain relations seqForInvoker:Sequence(Element) {
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(QVTMM::Class)}
},
referredOperation = eo:Operation{name = '='},
argument = ave:VariableExp{referredVariable = mdv}
}
}
};
when {
RelationToTraceClass(ir, tc);
}
where {
RVarToMVar(dv, mdv);
}
}
relation RDomainPatternToMDBottomPattern
{
domain relations seqForDomainPtrn:Sequence(Element) {};
enforce domain core db:BottomPattern {
area = cd:CoreDomain{
rule = m:Mapping {
bottomPattern = mb:BottomPattern{area = m}
}
}
}; -- domain bottom
where {
RDomainPatternToMDBottomPatternComposite(seqForDomainPtrn, db);
RDomainPatternToMDBottomPatternSimpleNonVarExpr(seqForDomainPtrn, db);
RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr(seqForDomainPtrn, db);
RDomainPatternToMDBottomPatternSimpleSharedVarExpr(seqForDomainPtrn, mb);
}
}
relation RDomainToMDBottomForEnforcement
{
remainingUnBoundDomainVars: Set(QVTMM::Variable);
predicatesWithVarBindings:Set(QVTMM::Predicate);
remainingPredicatesWithoutVarBindings:Set(QVTMM::Predicate);
rdSeq, rtSeq, rtdSeq: Sequence(QVTMM::Element);
rdtVarsSeqRest: Sequence(Set(QVTMM::Element));
predicatesWithoutVarBindings:Set(QVTMM::Predicate);
unboundDomainVars:Set(QVTMM::Variable);
tcv, mv: QVTMM::Variable;
domain relations rdtVarsSeq:Sequence(Set(Element)) {
rdtSet:Set(Element) {
r:Relation{},
rd:RelationDomain{},
te:ObjectTemplateExp {bindsTo = v:Variable {}}
++ _
}
++ _
};
enforce domain core db:BottomPattern { -- domain bottom
area = cd:CoreDomain {
rule = m:Mapping {
bottomPattern = mb:BottomPattern {
area = m
}
}
}
};
where {
predicatesWithoutVarBindings = rdtVarsSeq->at(2)->iterate(md; acc:Set(QVTMM::Predicate)=Set{} |
acc->including(md.oclAsType(QVTMM::Predicate)));
unboundDomainVars = rdtVarsSeq->at(3)->iterate(md; acc:Set(QVTMM::Variable)=Set{} |
acc->including(md.oclAsType(QVTMM::Variable)));
remainingUnBoundDomainVars = unboundDomainVars - Set{v};
predicatesWithVarBindings = filterOutPredicatesThatReferToVars(
predicatesWithoutVarBindings, remainingUnBoundDomainVars);
remainingPredicatesWithoutVarBindings =
predicatesWithoutVarBindings - predicatesWithVarBindings;
rtSeq = Sequence{r, te};
rtdSeq = Sequence{r, te, rd};
rdtVarsSeqRest = Sequence{rdtSet, remainingPredicatesWithoutVarBindings, remainingUnBoundDomainVars};
RDomainToMDBottomForEnforcementOfIdentityProp(rtSeq, db);
RDomainVarToMDBottomAssignmnetForEnforcement(rdtVarsSeq, mb);
--RDomainToMDBottomForEnforcementOfIdentityPropObject(rdtSeq, mb);
RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive(rtdSeq, m);
RDomainToMDBottomForEnforcementOfNonIdentityPropObject(rdtVarsSeqRest, m);
RDomainToMBottomPredicateForEnforcement(rdtVarsSeq, mb);
}
}
relation RDomainVarToMDBottomAssignmnetForEnforcement
{
rdSeq : Sequence(QVTMM::Element);
tcv, mv: QVTMM::Variable;
domain relations rdtVarsSeq:Sequence(Set(Element)) {
rdtSet:Set(Element) {
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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mv}
}
};
where {
rdSeq = Sequence{r, rd};
RelationDomainToTraceClassVar(rdSeq, tcv);
RVarToMVar(v, mv);
}
}
relation RDomainToMBottomPredicateForEnforcement
{
remainingUnBoundDomainVars: Set(QVTMM::Variable);
predicatesWithVarBindings:Set(QVTMM::Predicate);
rdSeq: Sequence(QVTMM::Element);
predicatesWithoutVarBindings:Set(QVTMM::Predicate);
unboundDomainVars:Set(QVTMM::Variable);
tcv, mv: QVTMM::Variable;
domain relations rdtVarsSeq:Sequence(Set(Element)) {
rdtSet:Set(Element) {
r:Relation{},
rd:RelationDomain{},
te:ObjectTemplateExp {bindsTo = v: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(QVTMM::Class)
}
},
referredOperation = eo:Operation{name = '='},
argument = ave:VariableExp{referredVariable = mv}
}
}
};
where {
rdSeq = let s : Sequence(QVTMM::Element) = Sequence{} in s->append(r)->append(rd);
RelationDomainToTraceClassVar(rdSeq, tcv);
RVarToMVar(v, mv);
predicatesWithoutVarBindings = rdtVarsSeq->at(2)->iterate(md; acc:Set(QVTMM::Predicate)=Set{} |
acc->including(md.oclAsType(QVTMM::Predicate)));
rdtVarsSeq->at(3) = unboundDomainVars;
remainingUnBoundDomainVars = unboundDomainVars - Set{v};
predicatesWithVarBindings = filterOutPredicatesThatReferToVars(
predicatesWithoutVarBindings, remainingUnBoundDomainVars);
RPredicateSetToMBPredicateSet(predicatesWithVarBindings->asSequence(), mb);
}
}
relation RPredicateSetToMBPredicateSet
{
rpRest: Sequence(QVTMM::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
{
seqForAssignment: Sequence(QVTMM::Element);
domain relations rtSeq:Sequence(Element) {
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 {
seqForAssignment = Sequence{r, v, pp, e};
RDomainPatternExprToMappingDomainAssignment(seqForAssignment, db);
RDomainPatternExprToMappingDomainVarAssignment(seqForAssignment, db);
RDomainPatternExprToMappingDomainTemplateVarAssignment(seqForAssignment, db);
RDomainPatternExprToMappingBottomVarAssignment(seqForAssignment, mb);
}
}
relation RDomainToMDBottomForEnforcementOfIdentityPropObject
{
seqForAssignment: Sequence(QVTMM::Element);
mtv, tcv : QVTMM::Variable;
rdSeq : Sequence(QVTMM::Element);
domain relations rtSeq:Sequence(Element) {
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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mtv}
}
}; -- domain bottom
where {
rdSeq = Sequence{r, rd};
RelationDomainToTraceClassVar(rdSeq, tcv);
RVarToMVar(tv, mtv);
}
}
relation RDomainPatternExprToMappingDomainAssignment
{
pn: String;
mv: QVTMM::Variable;
domain relations seqForAssignment: Sequence(Element) {
_,
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(QVTMM::Class)},
value = me:OclExpression{}
}
};
where {
RVarToMVar(v, mv);
RExpToMExp(e, me);
}
}
relation RDomainPatternExprToMappingDomainVarAssignment
{
sharedDomainVars: Set(QVTMM::Variable);
rev, mev : QVTMM::Variable;
pn: String;
domain relations seqForAssignment: Sequence(Element) {
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(QVTMM::Class)},
value = me:VariableExp{referredVariable = mev}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMRealizedVar(v, mv);
RVarToMVar(rev, mev);
}
}
relation RDomainPatternExprToMappingDomainTemplateVarAssignment
{
sharedDomainVars: Set(QVTMM::Variable);
rev, mev: QVTMM::Variable;
pn: String;
domain relations seqForAssignment: Sequence(Element) {
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(QVTMM::Class)},
value = me:VariableExp{referredVariable = mev}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMRealizedVar(v, mv);
RVarToMVar(rev, mev);
}
}
relation RDomainPatternExprToMappingBottomVarAssignment
{
sharedDomainVars: Set(QVTMM::Variable);
rev, mev : QVTMM::Variable;
pn: String;
domain relations seqForAssignment: Sequence(Element) {
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(QVTMM::Class)},
value = me:VariableExp{referredVariable = mev}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMRealizedVar(v, mv);
RVarToMVar(rev, mev);
}
}
relation RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
{
pn: String;
mv: QVTMM::Variable;
rtdeSeq: Sequence(QVTMM::Element);
domain relations rtdSeq:Sequence(Element) {
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(QVTMM::Class)},
value = me:OclExpression{}
}
}
}
};
when {
RelationalTransformationToMappingTransformation(rt, mt);
}
where {
RVarToMVar(v, mv);
RExpToMExp(e, me);
rtdeSeq = Sequence{r, te, rd, e};
RDomainToMComposedMappingGuard(rtdeSeq, cm);
}
}
relation RDomainToMComposedMappingGuard
{
pn, dn, tmn: String;
tcv, mv: QVTMM::Variable;
rdSeq: Sequence(QVTMM::Element);
mt: QVTMM::Transformation;
domain relations rtdSeq:Sequence(Element) {
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(QVTMM::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 {
rdSeq = Sequence{r, rd};
RelationDomainToTraceClassVar(rdSeq, tcv);
RVarToMVar(v, mv);
}
}
relation RDomainToMDBottomForEnforcementOfNonIdentityPropObject
{
rdtSetNext: Set(QVTMM::Element);
rdtVarsSeqRest: Sequence(Set(QVTMM::Element));
predicatesWithoutVarBindings:Set(QVTMM::Predicate);
unboundDomainVars:Set(QVTMM::Variable);
dn, pn, tmn: String;
mv: QVTMM::Variable;
domain relations rdtVarsSeq:Sequence(Set(Element)) {
rdtSet:Set(Element) {
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 {}}
}
} {
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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mpv}
}
}
},
bottomPattern = mb:BottomPattern {
area = cm
}
}
};
when {
RelationalTransformationToMappingTransformation(rt, mt);
}
where {
RVarToMVar(v, mv);
RVarToMRealizedVar(pv, mpv);
predicatesWithoutVarBindings = rdtVarsSeq->at(2)->iterate(md; acc:Set(QVTMM::Predicate)=Set{} |
acc->including(md.oclAsType(QVTMM::Predicate)));
unboundDomainVars = rdtVarsSeq->at(3)->iterate(md; acc:Set(QVTMM::Variable)=Set{} |
acc->including(md.oclAsType(QVTMM::Variable)));
rdtSetNext = Set{r, rd, pte};
rdtVarsSeqRest = Sequence{rdtSetNext, predicatesWithoutVarBindings, unboundDomainVars};
RDomainToMDBottomForEnforcement(rdtVarsSeqRest, cmdb);
}
}
relation RDomainPatternToMDBottomPatternComposite
{
nextSeqForDomainPtrn: Sequence(QVTMM::Element);
sharedDomainVars:Set(QVTMM::Variable);
pn: String;
mvte, mvpte: QVTMM::Variable;
domain relations seqForDomainPtrn:Sequence(Element) {
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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mvpte}
}
};
where {
RVarToMVar(vte, mvte);
RVarToMVar(vpte, mvpte);
nextSeqForDomainPtrn = Sequence{r, pte};
RDomainPatternToMDBottomPattern(nextSeqForDomainPtrn, db);
}
}
relation RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr
{
sharedDomainVars: Set(QVTMM::Variable);
pn: String;
mvte, mvpte: QVTMM::Variable;
domain relations seqForDomainPtrn:Sequence(Element) {
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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mvpte}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMVar(vte, mvte);
RVarToMVar(vpte, mvpte);
}
}
relation RDomainPatternToMDBottomPatternSimpleSharedVarExpr
{
sharedDomainVars: Set(QVTMM::Variable);
pn: String;
mvte, mvpte: QVTMM::Variable;
domain relations seqForDomainPtrn:Sequence(Element) {
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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mvpte}
}
};
when {
sharedDomainVars = getSharedDomainVars(r);
}
where {
RVarToMVar(vte, mvte);
RVarToMVar(vpte, mvpte);
}
}
relation RDomainPatternToMDBottomPatternSimpleNonVarExpr
{
pn: String;
mvte: QVTMM::Variable;
domain relations seqForDomainPtrn:Sequence(Element) {
_,
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(QVTMM::Class)},
value = me:OclExpression{}
}
};
where {
RVarToMVar(vte, mvte);
RExpToMExp(e, me);
}
}
relation RDomainVarsToTraceClassProps
{
tcv, mdv: QVTMM::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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mdv}
}
};
where {
RelationToTraceClassVar(r, tcv);
RVarToMVar(dv, mdv);
}
}
relation ROppositeDomainVarsToTraceClassProps
{
rdSeq: Sequence(QVTMM::Element);
tcv, mdv: QVTMM::Variable;
domain relations rdVarsSeq:Sequence(Set(Element)) {
rdSet: Set(Element) {
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(QVTMM::Class)},
value = ve2:VariableExp{referredVariable = mdv}
}
};
where {
rdSeq = let s : Sequence(QVTMM::Element) = Sequence{} in s->append(r)->append(rd);
RelationDomainToTraceClassVar(rdSeq, tcv);
RVarToMVar(dv, mdv);
}
}
relation RRelImplToMBottomEnforcementOperation
{
emptySet:Set(QVTMM::EnforcementOperation);
domain relations repImplSeq:Sequence(Element) {
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: QVTMM::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: QVTMM::Class;
domain relations rdSeq:Sequence(Element) {
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);
}
}