10.4.2.1 AS-Domain-Mapping.exp-eval包的良构规则
AssociationClassCallExpEval
[1] 代表计算中referredAssociationClass的字符串必须等同于相应表达式中referredAssociationClass的名称。
context AssociationClassCallExpEval inv:
referredAssociationClass = model.referredAssociationClass.name
[2] 具有限定符的关联类调用表达式计算的结果值由如下规则来决定。一般性规则已经在10.3.2 Evaluations包的良构规则中给出。
let
-- the attributes that are the formal qualifiers. Because and association class has two or
-- more association ends, we must select the qualifiers from the other end(s), not from
-- the source of this expression. We allow only 2-ary associations.
formalQualifiers : Sequence(Attribute) =
self.model.referredAssociationClass.connection->any( c |
c <> self.navigationSource).qualifier.asSequence() ,
-- the attributes of the class at the qualified end. Here we already assume that an
-- AssociationEnd will be owned by a Classifier, as will most likely be the case in the
-- UML 2.0 Infrastructure.
objectAttributes: Sequence(Attribute) =
self.model.referredAssociationClass.connection->any( c |
c <> self.navigationSource).owner.feature->select( f |
f.oclIsTypeOf( Attribute ).asSequence() ,
-- the rolename of the qualified association end
qualifiedEnd: String = self.model.referredAssociationClass.connection->any( c |
c <> self.navigationSource).name ,
-- the values for the qualifiers given in the ocl expression
qualifierValues : Sequence( Value ) = self.qualifiers.asSequence()
-- the objects from which a subset must be selected through the qualifiers
normalResult = source.resultValue.getCurrentValueOf(referredAssociationClass.name)
in
-- if name of attribute of object at qualified end equals name of formal qualifier then
-- if value of attribute of object at qualified end equals the value given in the exp
-- then select this object and put it in the resultValue of this expression.
qualifiers->size <> 0 implies normalResult->select( obj |
Sequence{1..formalQualifiers->size()}->forAll( i |
objectAttributes->at(i).name = formalQualifiers->at(i).name and
obj.qualifiedEnd.getCurrentValueOf( objectAttributes->at(i).name ) = qualifiersValues->at(i)))
AssociationEndCallExpEval
[1] 代表计算中referredAssociationEnd的字符串必须等同于相应表达式中referredAssociationEnd的名称。
context AssociationEndCallExpEval inv:
referredAssociationEnd = model.referredAssociationEnd.name
[2] 具有限定符的关联端调用表达式计算的结果值由如下规则来决定。一般性规则已经在10.3.2 Evaluations包的良构规则中给出。
let
-- the attributes that are the formal qualifiers
formalQualifiers : Sequence(Attribute) = self.model.referredAssociationEnd.qualifier ,
-- the attributes of the class at the qualified end
objectAttributes: Sequence(Attribute) =
(if self.resultValue.model.oclIsKindOf( Collection ) implies
then self.resultValue.model.oclAsType(Collection).elementType->collect(feature->oclAsType(Attribute))
else self.resultValue.model->collect( feature->oclAsType( Attribute ) )
endif).asSequence() ,
-- the values for the qualifiers given in the ocl expression
qualifierValues : Sequence( Value ) = self.qualifiers.asSequence()
-- the objects from which a subset must be selected through the qualifiers
normalResult = source.resultValue.getCurrentValueOf(referredAssociationEnd.name)
in
-- if name of attribute of object at qualified end equals name of formal qualifier then
-- if value of attribute of object at qualified end equals the value given in the exp
-- then select this object and put it in the resultValue of this expression.
qualifiers->size <> 0 implies normalResult->select( obj |
Sequence{1..formalQualifiers->size()}->forAll( i |
objectAttributes->at(i).name = formalQualifiers->at(i).name and
obj.getCurrentValueOf( objectAttributes->at(i).name ) = qualifiersValues->at(i) ))
AttributeCallExpEval
[1] 代表计算中referredAttribute的字符串必须等同于相应表达式中referredAttribute的名称。
context AttributeCallExpEval inv:
referredAttribute = model.referredAttribute.name
BooleanLiteralExpEval
[1] 布尔字面量表达式计算的结果值等同于该字面量表达式自身(‘true’或'false')。因为抽象语法中的booleanSymbol属性是MOF中定义的布尔类型,并且resultValue是本章定义的Primitive类型,所以需要一个转换。此时,我们假定额外的操作MOFbooleanToOCLboolean()存在。当MOF和/或UML基础设施提案被最终定稿时这还需要重新审视。
context BooleanLiteralExpEval inv:
resultValue = model.booleanSymbol.MOFbooleanToOCLboolean()
CollectionItemEval
无额外良构规则。
CollectionLiteralExpEval
无额外良构规则。
CollectionLiteralPartEval
无额外良构规则。
CollectionRangeEval
无额外良构规则。
EvalEnvironment
因为没有对应的抽象语法概念映射,所以没有额外的良构规则。
LiteralExpEval
无额外良构规则。
LoopExpEval
无额外良构规则。
EnumLiteralExpEval
[1] EnumLiteralExpEval的结果值必须等同它的类型定义的字面量之一。
context EnumLiteralExpEval inv:
model.type->includes( self.resultValue )
IfExpEval
[1] 条件计算对应条件表达式,thenExpression和elseExpression类似。
context IfExpEval
inv: condition.model = model.condition
inv: thenExpression.model = model.thenExpression
inv: elseExpression.model = model.elseExpression
IntegerLiteralExpEval
context IntegerLiteralExpEval inv:
resultValue = model.integerSymbol
IterateExpEval
[1] 迭代表达式计算的结果模型等同于相关的IterateExp的结果模型。
context IterateExpEval
inv: result.model = model.result
IteratorExpEval
无额外良构规则。
LetExpEval
[1] let 表达式计算的所有成员对应与其相关的LetExp的所有成员。
context LetExpEval inv:
in.model = model.in and
initExpression.model = model.initExpression and variable = model.variable.varName
LoopExpEval
[1] 所有的子计算具有相同的模型,那就是与之关联的LoopExp的body。
context LoopExpEval
inv: bodyEvals->forAll( model = self.model )
ModelPropertyCallExpEval
无额外良构规则。
NumericLiteralExpEval
无额外良构规则。
NavigationCallExpEval
[1] 在计算中代表导航源的字符串必须等同于相应的表达式中navigationSource的名称。
context NavigationCallExpEval inv:
navigationSource = model.navigationSource.name
[2] 导航调用表达式计算的限定符必须对应相同表达式的限定符。
context NavigationCallExpEval inv:
Sequence{1..qualifiers->size()}->forAll( i |
qualifiers->at(i).model = model.qualifiers->at(i).type )
OclExpEval
[1] ocl表达式计算的结果值必须是该表达式类型的一个实例。
context OclExpEval
inv: resultValue.isInstanceOf( model.type )
OclMessageExpEval
[1] ocl消息表达式计算必须对应它的消息表达式。
context OclMessageExpEval
inv: target.model = model.target
inv: Set{1..arguments->size()}->forall (i | arguments->at(i) = model.arguments->at(i) )
[2] 结果ocl消息值的名称必须等同于消息表达式中所指的操作或信号名称。
context OclMessageExpEval inv:
if model.operation->size() = 1 then
resultValue.name = model.operation.name
else
resultValue.name = model.signal.name
endif
[3] ocl消息表达式计算的结果值的isSignal, isSyncOperation和isAsyncOperation属性必须对应该ocl消息表达式所指的操作。
context OclMessageExpEval inv:
if model.calledOperation->size() = 1
then model.calledOperation.isAsynchronous = true implies
resultValue.isAsyncOperation = true
else -- message represents sending a signal
resultValue.isSignal = true
endif
[4] ocl消息表达式计算的实参必须对应该该ocl消息表达式所指示的操作的形式输入参数或者信号的属性。
context OclMessageExpEval
inv: model.calledOperation->size() = 1 implies Sequence{1.. arguments->size()} ->forAll( i |
arguments->at(i).variable->size() = 1 implies model.calledOperation.operation.parameter->
select( kind = ParameterDirectionKind::in )->at(i).name = arguments->at(i).variable
and
arguments->at(i).expression->size() = 1 implies model.calledOperation.operation.parameter->
select( kind = ParameterDirectionKind::in )->at(i).type = arguments->at(i).expression.model )
inv: model.sentSignal->size() = 1 implies Sequence{1.. arguments->size()} ->forAll( i |
arguments->at(i).variable->size() = 1 implies model.sentSignal.signal.feature->select(
arguments->at(i).variable )->notEmpty()
and
arguments->at(i).expression->size() = 1 implies
model.sentSignal.signal.feature.oclAsType(StructuralFeature).type =
arguments->at(i).expression.model )
[5] ocl消息表达式计算的返回消息实参必须对应ocl消息表达式所指示操作的形式输出参数和结果类型。注意参数类型在UML元模型中定义。
context OclMessageExpEval
inv: let returnArguments: Sequence( NameValueBindings ) = resultValue.returnMessage.arguments ,
formalParameters: Sequence( Parameter ) = model.calledOperation.operation.parameter
in
resultValue.returnMessage->size() = 1 and model.calledOperation->size() = 1 implies
-- ‘result’ must be present and have correct type
returnArguments->any( name = ‘result’ ).value.model =
formalParameters->select( kind = ParameterDirectionKind::return ).type
and
-- all ‘out’ parameters must be present and have correct type
Sequence{1.. returnArguments->size()} ->forAll( i | returnArguments->at(i).name =
formalParameters->select( kind = ParameterDirectionKind::out )->at(i).name
and
returnArguments->at(i).value.model =
formalParameters->select( kind = ParameterDirectionKind::out )->at(i).type )
OclMessageArgEval
[1] ocl消息实参计算必须对应它的实参表达式。
context OclMessageArgEval
inv: model.variable->size() = 1
implies variable->size() = 1 and variable.symbol = model.variable.name
inv: model.expression->size() = 1
implies expression and expression.model = model.expression
OperationCallExpEval
[1] 如果该操作没有输出参数,那么操作调用表达式的结果值将会以被调用的操作的类型给出,否则其结果是一个包含了所有输出参数和结果值的元组。
context OperationCallEval inv:
let outparameters : Set( Parameter ) = referredOperation.parameter->select( p |
p.kind = ParameterDirectionKind::in/out or
p.kind = ParameterDirectionKind::out)
in
if outparameters->isEmpty()
then resultValue.model = model.referredOperation.parameter
->select( kind = ParameterDirectionKind::result ).type
else resultValue.model.oclIsType( TupleType ) and outparameters->forAll( p |
resultValue.model.attribute->exist( a | a.name = p.name and a.type = p.type ))
endif
[2] 计算中代表所指操作的字符串必须等同于相应的表达式中referredOperation的名称。
context OperationCallExpEval inv:
referredOperation = model.referredOperation.name
[3] 操作调用表达式计算的实参必须对应相关表达式中的参数。
context OperationCallExpEval inv:
Sequence{1..arguments->size}->forAll( i | arguments->at(i).model = model.arguments->at(i) )
PropertyCallExpEval
[1] 属性调用计算的源对应相关的表达式的源。
context PropertyCallExpEval inv:
source.model = model.source
PrimitiveLiteralExpEval
无额外良构规则。
RealLiteralExpEval
context RealLiteralExpEval inv:
resultValue = model.realSymbol
StringLiteralExpEval
context StringLiteralExpEval inv:
resultValue = model.stringSymbol
TupleLiteralExpEval
context TupleLiteralExpEval inv:
model.tuplePart = tuplePart.model
UnlimitedNaturalLiteralExpEval
context UnlimitedNaturalLiteralExpEval inv:
resultValue = model.unlimitedNaturalSymbol
UnspecifiedValueExpEval
[1] 未规定值表达式的结果是一个随机选择的表达式类型的实例。
context UnspecifiedValueExpEval
inv: resultValue = model.type.allInstances()->any( true )
inv: resultValue.model = model.type
VariableDeclEval
context VariableDeclEval inv:
model.initExpression = initExpression.model
VariableExpEval
无额外良构规则。