VDM types as Smalltalk objects
Although types are not the first class objects in VDM-family, ViennaTalk provides classes to prepresent VDM types. The following table shows mapping from VDM types to corresponding Smalltalk expressions.
type | Smalltalk expression | class | class of value |
---|---|---|---|
nat | ViennaType nat | ViennaNatType | Integer |
nat1 | ViennaType nat1 | ViennaNat1Type | Integer |
int | ViennaType int | ViennaIntType | Integer |
real | ViennaType real | ViennaRealType | Float |
bool | ViennaType bool | ViennaBoolType | Boolean |
ViennaType quote: #quote | ViennaQuoteType | Symbol | |
[t] | t optional | ViennaOptionType | the class of t’s value or UndefinedObject |
t1 * t2 | t1 * t2 | ViennaProductType | Array |
t1 | t2 | t1 | t2 | ViennaUnionType | either the class of t1 or t2’s value |
set of t | t set | ViennaSetType | Set |
seq of t | t seq | ViennaSeqType | OrderedCollection |
seq1 of t | t seq1 | ViennaSeq1Type | OrderedCollection |
map t1 to t2 | t1 mapTo: t2 | ViennaMapType | Dictionary |
inmap t1 to t2 | t1 inmapTo: t2 | ViennaInmapType | Dictionary |
t1 -> t2 | t1 -> t2 | ViennaPartialFunctionType | BlockClosure |
t1 +> t2 | t1 +> t2 | ViennaTotalFunctionType | BlockClosure |
compose t of f1 : t1 f2 :- t2 t3 end |
ViennaType compose: ‘t’ of: {{f1 . false . t1}. {f2 . true . t2}. {nil . false . t3}} |
ViennaCompositeType | ViennaComposite |
t inv pattern==expr | t inv: [:v | expr] | ViennaConstrainedType | the class of t’s value |
Functionality of VDM types
As the first class objects of Smalltalk, VDM types in ViennaTalk provides protocols shown below.
Type discrimination
Types responds to the includes: message with a value as the argument.
ViennaType nat includes: 1
will return true, and
ViennaType nat includes: -1
will return false.
Type invariants are also taken into account.
| t |
t := ViennaType nat inv: [:n | n < 10].
t includes: 100
returns false.
Subtyping
You can check subtype relationship by sending <= message to a type object.
ViennaType nat <= ViennaType int
returns true as nat is a subtype of int in VDM.
Enumerating values
A type is a set of values. A type object can enumerate its value by sending the do: message if the type is a finite set.
| bools |
bools := OrderedCollection new.
ViennaType bool do: [ :b | bools add: b].
bools asArray
The result is an array of true and false. Other Collection protocols such as collect:, select: and detect: are also implemented.
You can check if a type is enumerable or not by sending the isEnumerable message.
| t |
t := ViennaType bool * ViennaType nat.
t isEnumerable
returns false because nat is infinite set.
Composing a value
A composite type can create a value by sending the applyTo: message.
| t |
t := ViennaType
compose: 'T'
of: { { 'f' . false . ViennaType nat}.
{ nil . false . ViennaType bool optional } }.
t applyTo: { 1 . nil }
returns a composite value that represents mk_T(1, nil).