8.3.7 表达式包的良构规则
定义在抽象语法的元类具有如下的良构规则:
PropertyCallExp
该调用表达式的类型是所引用属性的类型。
context PropertyCallExp
inv: type = referredProperty.type
BooleanLiteralExp
布尔字面量表达式的类型是Boolean。
context BooleanLiteralExp
inv: self.type.name = 'Boolean'
CollectionLiteralExp
[1] 'Collection'是M1层的抽象类,没有M0实例。
context CollectionLiteralExp
inv: kind <> CollectionKind::Collection
[2] 集合字面量表达式的类型由选择的集合种类和所有元素的公共超类决定。注意下面的定义隐式地声明了空集合以OclVoid作为它的elementType。
context CollectionLiteralExp
inv: kind = CollectionKind::Set implies type.oclIsKindOf (SetType)
inv: kind = CollectionKind::OrderedSet implies type.oclIsKindOf (OrderedSetType)
inv: kind = CollectionKind::Sequence implies type.oclIsKindOf (SequenceType)
inv: kind = CollectionKind::Bag implies type.oclIsKindOf (BagType)
inv: type.oclAsType (CollectionType).elementType = part->iterate (p; c : Classifier = OclVoid |
c.commonSuperType (p.type))
CollectionLiteralPart
没有额外的良构规则。
CollectionItem
[1] CollectionItem的类型是item表达式的类型。
context CollectionItem
inv: type = item.type
CollectionRange
[1] CollectionRange的类型是区间成员表达式的公共超类。
context CollectionRange
inv: type = first.type.commonSuperType(last.type)
[2] last值要在first值后面。
context CollectionRange
inv IncreasingRange: first <= last
EnumLiteralExp
[1] 枚举字面量表达式的类型是所引用的字面量的类型。
context EnumLiteralExp
inv: self.type = referredEnumLiteral.enumeration
IfExp
[1] if表达式的条件类型必须是Boolean。
context IfExp
inv: self.condition.type.oclIsKindOf(PrimitiveType) and self.condition.type.name = 'Boolean'
[2] if 表达式的类型是else和then表达式的超类。
context IfExp
inv: self.type = thenExpression.type.commonSuperType(elseExpression.type)
IntegerLiteralExp
[1] 整型表达式的类型是Integer。
context IntegerLiteralExp
inv: self.type.name = 'Integer'
IteratorExp any
[1] 只有一个迭代器。
context IteratorExp
inv: name='any' implies iterator->size() = 1
[2] 类型与源元素类型相同。
context IteratorExp
inv: name='any' implies type = source.type.oclAsType(CollectionType).elementType
[3] body的类型必须是Boolean。
context IteratorExp
inv: name='any' implies body.type.oclIsKindOf(PrimitiveType) and body.type.name='Boolean'
IteratorExp closure
[1] 只有一个迭代器
context InteratorExp
inv: name = 'closure' implies iterator->size() = 1
[2] OrderedSet或Sequence 源类型的计划类型是OrderSet。对于任何其它的源,集合类型是Set。
context IteratorExp
inv: name = 'closure' implies
if source.type.oclIsKindOf(SequenceType) or source.type.oclIsKindOf(OrderedSetType) then
type.oclIsKindOf(OrderedSetType)
else
type.oclIsKindOf(SetType)
endif
[3] source 元素类型与body 元素或element的类型是相同的。
context IteratorExp
inv: name = 'closure' implies
source.type.oclAsType(CollectionType).elementType =
if body.type.oclIsKindOf(CollectionType) then
body.type.oclAsType(CollectionType).elementType
else
body.type
endif
[4] element类型与source lement类型是相同的。
context IteratorExp
inv: name = 'closure' implies
type.oclAsType(CollectionType).elementType =
source.type.oclAsType(CollectionType).elementType
IteratorExp collect
[1] 只有一个迭代器。
context IteratorExp
inv: name = 'collect' implies iterator->size() = 1
[2] 用于OrderedSet或Sequence类型的集合类型是Sequence,用于其它集合类型的结果类型是Bag。
context IteratorExp
inv: name = 'collect' implies
if source.type.oclIsKindOf(SequenceType) or source.type.oclIsKindOf(OrderedSet) then
type.oclIsKindOf(SequenceType)
else
type.oclIsKindOf(BagType)
endif
[3] 元素类型是body元素的类型。
context IteratorExp
inv: name = 'collect' implies
type.oclAsType(CollectionType).elementType =
body.type.oclAsType(CollectionType).elementType
IteratorExp collectNested
[1] 只有一个迭代器。
context IteratorExp
inv: name = 'collectNested' implies iterator->size() = 1
[2] 类型是Bag。
context IteratorExp
inv: name = 'collectNested' implies type.oclIsKindOf(BagType)
[3] 类型是source的类型。
context IteratorExp
inv: name = 'collectNested' implies type = body.type
IteratorExp exists
[1] 类型必须是Boolean。
context IteratorExp
inv: name = 'exists' implies type.oclIsKindOf(PrimitiveType) and type.name = 'Boolean'
[2] body的类型必须是Boolean
context IteratorExp
inv: name='exists' implies body.type.oclIsKindOf(PrimitiveType) and body.type.name='Boolean'
IteratorExp forAll
[1] 类型必须是Boolean。
context IteratorExp
inv: name = 'forAll' implies type.oclIsKindOf(PrimitiveType) and type.name = 'Boolean'
[2] body的类型必须是Boolean。
context IteratorExp
inv: name = 'forAll' implies body.type.oclIsKindOf(PrimitiveType) and body.type.name='Boolan'
IteratorExp isUnique
[1] 只有一个迭代器。
context IteratorExp
inv: name = ‘isUnique’ implies iterator->size() = 1
[2] 类型必须是Boolean。
context IteratorExp
inv: name = ‘isUnique’ implies type.oclIsKindOf(PrimitiveType) and type.name = ‘Boolean’
IteratorExp one
[1] 只有一个迭代器。
context IteratorExp
inv: name = ‘one’ implies iterator->size() = 1
[2] 类型是Boolean。
context IteratorExp
inv: name = ‘one’ implies type.oclIsKindOf(PrimitiveType) and type.name = ‘Boolean’
[3] body的类型必须是Boolean。
context IteratorExp
inv: name = ‘one’ implies body.type.oclIsKindOf(PrimitiveType) and body.type.name = ‘Boolean’
IteratorExp reject或select
[1] 只有一个迭代器。
context IteratorExp
inv: name = ‘reject’ or name = ‘select’ implies iterator->size() = 1
[2] 类型与source的相同。
context IteratorExp
inv: name = ‘reject’ or name = ‘select’ implies type = source.type
[3] body类型必须是Boolean。
context IteratorExp
inv: name = ‘reject’ or name = ‘select’ implies
body.type.oclIsKindOf(PrimitiveType) and body.type.name = ‘Boolean’
IteratorExp sortedBy
[1] 只有一个迭代器。
context IteratorExp
inv: name = 'sortedBy' implies iterator->size() = 1
[2] 用于OrderedSet或Sequence类型的集合类型是Sequence,用于其它集合类型的结果类型是Bag。
context IteratorExp
inv: name = 'sortedBy' implies
if source.type.oclIsKindOf(SequenceType) or source.type.oclIsKindOf(BagType) then
type.oclIsKindOf(SequenceType)
else
type.oclIsKindOf(OrderedSetType)
endif
[3] 元素类型是body元素的类型。
context IteratorExp
inv: name = 'sortedBy' implies
type.oclAsType(CollectionType).elementType =
body.type.oclAsType(CollectionType).elementType
IterateExp
[1] 迭代的类型是结果变量的类型。
context IterateExp
inv: type = result.type
[2] body表达式的类型必须符合结果变量所声明的类型。
context IterateExp
inv: body.type.conformsTo(result.type)
[3] 结果变量必须有一个初始值表达式。
context IterateExp
inv: self.result.initExpression->size() = 1
LetExp
[1] Let表达式的类型是in 表达式的类型。
context LetExp
inv: type = in.type
LiteralExp
没有额外的良构规则。
LoopExp
[1] source表达式的类型必须是一个集合。
context LoopExp
inv: source.type.oclIsKindOf (CollectionType)
[2] 迭代器的循环变量没有初始化表达式。
context LoopExp
inv: self.iterator->forAll(initExpression->isEmpty())
[3] 每个迭代器变量的类型必须是源集合的元素类型。
context IteratorExp
inv: self.iterator->forAll(type = source.type.oclAsType (CollectionType).elementType)
FeatureCallExp
没有额外的良构规则。
NumericLiteralExp
没有额外的良构规则。
OclExpression
没有额外的良构规则。
MessageExp
[1] 如果消息是操作调用动作,实参必须与操作参数相符合。
context MessageExp
inv: calledOperation->notEmpty() implies
argument->forAll (a | a.type.conformsTo
(self.calledOperation.operation.ownedParameter->
select( kind = ParameterDirectionKind::in )
->at (argument->indexOf (a)).type))
[2] 如果消息是一个信号发送动作,实参必须与该信号的属性相符合。
context MessageExp
inv: sentSignal->notEmpty() implies
argument->forAll (a | a.type.conformsTo
(self.sentSignal.signal.ownedAttribute
->at (argument->indexOf (a)).type))
[3] 如果消息是一个操作调用动作,该操作必须是目标表达式类型的操作。
context MessageExp
inv: calledOperation->notEmpty() implies
target.type.allOperations()->includes(calledOperation.operation)
[4] OCL消息要么是已调用的操作,要么是已发送的信号。
context MessageExp
inv: calledOperation->size() + sentSignal->size() = 1
[5] OCL消息的目标不能是一个集合。
context MessageExp
inv: not target.type.oclIsKindOf (CollectionType)
OperationCallExp
[1] 所有的实参必须符合所引用操作的参数。
context OperationCallExp
inv: arguments->forAll (a | a.type.conformsTo
(self.refParams->at (arguments->indexOf (a)).type))
[2] 实参数目要与所引用操作的参数数目一致。
context OperationCallExp
inv: arguments->size() = refParams->size()
[3] 额外的属性refParams列举所引用操作的所有参数(除了返回和输出参数)。
context OperationCallExp
def: refParams: Sequence(Parameter) = referredOperation.ownedParameter->select (p |
p.kind <> ParameterDirectionKind::return or
p.kind <> ParameterDirectionKind::out)
CallExp
没有额外的良构规则。
RealLiteralExp
[1] 实数字面量表达式的类型是Real。
context RealLiteralExp
inv: self.type.name = íRealí
StateExp
没有额外的良构规则。
StringLiteralExp
[1] 字符串字面量表达式的类型是String。
context StringLiteralExp
inv: self.type.name = ‘String’
TypeExp
没有额外的良构规则。
TupleLiteralExp
[1] TupleLiteralExp的类型是一个具有指定成员的TupleType。
context TupleLiteralExp
inv: type.oclIsKindOf(TupleType) and
part-size() = type.allProperties()->size() and
part->forAll(tlep |
type.allProperties()->exists(tp| tlep.attribute.name=tp.name and tlep.attribute.type=tp.type))
[2] 一个元组字面量表达式中的所有成员具有唯一的名字。
context TupleLiteralExp
inv: part->isUnique (attribute.name)
TupleLiteralPart
[1] attribute的类型符合该值表达式的类型。
context TupleLiteralPart
inv: attribute.type.conformsTo(value.type)
UnlimitedNaturalLiteralExp
[1] 无限自然数字面量表达式的类型是UnlimitedNatural。
context UnlimitedNaturalLiteralExp
inv: self.type.name = ‘UnlimitedNatural’
UnspecifiedValueExp
没有额外的良构规则。
Variable
[1] 对于初始化后的变量声明,initExpression的类型必须符合所声明的变量类型。
context Variable
inv: initExpression->notEmpty() implies initExpression.type.conformsTo (type)
VariableExp
[1] VariableExp的类型是其所引用变量的类型。
context VariableExp
inv: type = referredVariable.type