1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
module statics-comm
imports
signatures/Poosl-sig
signatures/Common-sig
statics-opt
statics-names
statics-expr-stat
statics-typing
rules // === Ports and messages =======
maps okPort(*, list(*))
: scope * Port
okPort(s, Port(name, _)) :- declarePort(s, name).
okMessageSignatures maps okMessageSignature(*, list(*))
: scope * MessageSignature
okMessageSignature(, MessageReceiveSignature(, message, parameters, _)) :-
typeOfPort(s, port),
{} typesParameters == okOptMessageParameterList(s, parameters),
declareReceiveMessage(s, port, message, TypeMessage(typesParameters)).
okMessageSignature(, MessageSendSignature(, message, parameters, _)) :-
typeOfPort(s, port),
{} typesParameters == okOptMessageParameterList(s, parameters),
declareSendMessage(s, port, message, TypeMessage(typesParameters)).
: scope * OptMessageParameterList -> list(TypeDataClass)
okOptMessageParameterList(s, MessageParameters(types)) = typeOfDataClasses(s, types).
okOptMessageParameterList(s, NoMessageParameters()) = [].
rules // === Instances and channels =======
maps okInstance(*, list(*))
: scope * Instance
okInstance(, Instance(annotationList, name, class, optParameterInstantiations)) :-
{} T == typeOfProcessOrClusterClass(s, class),
declareInstance(s, name, T),
okInstanceParameters(s, externalScopeOfTypeProcessOrClusterClass(T), stripOptInstanceParameterList(optParameterInstantiations)).
okInstanceParameters maps okInstanceParameter(*, *, list(*))
: scope * scope * InstanceParameter
okInstanceParameter(s, s_instance, InstanceParameter(name, )) :-
{} T_var == typeOfVariable(s_instance, name),
{} T_expr == okExpression(s, TypeDataClassRoot(), expr),
try { compatibleType(T_var, T_expr) } | warning $[Incompatible type] @expr.
maps okChannel(*, list(*))
: scope * Channel
okChannel(, Channel(annotationList, PortInstanceList())) :-
{} count_ext_ports == countExternalPorts(portInstances),
try { atMostOne(count_ext_ports) } | error $[There should be at most 1 external port],
okPortInstances(s, portInstances),
okChannelClosure(s, portInstances, count_ext_ports).
: scope * list(PortInstance) * int
okChannelClosure(s, pis, 0).
okChannelClosure(s, pis, _).
// TODO check unconnected messages
// TODO check type compatibility of messages
okPortInstances maps okPortInstance(*, list(*))
: scope * PortInstance
okPortInstance(s, InternalPort(instanceName, portName)) :-
{} T_instance == typeOfInstance(s, instanceName),
{} T_instance_scope == externalScopeOfTypeProcessOrClusterClass(T_instance),
typeOfPort(T_instance_scope, portName).
okPortInstance(s, ExternalPort(portName)) :-
typeOfPort(s, portName).
rules
: TypeProcessOrClusterClass -> scope
externalScopeOfTypeProcessOrClusterClass(TypeClusterClass(s_external)) = s_external.
externalScopeOfTypeProcessOrClusterClass(TypeProcessClass(s_external, s_internal)) = s_external.
rules
: list(PortInstance) -> int
countExternalPorts([]) = 0.
countExternalPorts([ExternalPort(_)|Cs]) = len :- {t_len}
t_len == countExternalPorts(Cs),
len #= t_len + 1.
countExternalPorts([_|Cs]) = countExternalPorts(Cs).
: int
atMostOne(0).
atMostOne(1).
|