-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDDIIntegrationHelpers.eol
187 lines (160 loc) · 7.71 KB
/
DDIIntegrationHelpers.eol
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
MIT License
Copyright (c) 2019 DEIS Project
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
Script must be executed against the following models:
1. ownDDI: the integrator DDI (ETCS in this example)
ownDDI is updated with integrated information
2. supplierDDI: the supplier DDI (Trackside in this example)
*/
import "DDIBuilderHelpers.eol";
// Integration Operations
/**
@BuildARGPInterface
@param ARGPI
@type Any
The ArgumentPackageInterface being built
@param ModelElements
@type Collection
Collection of ModelElements which should be considered for inclusion in the ARGPI
@comments
Adds to the ArgumentPackageInterface the ModelElements from the input that have a TaggedValue 'isPublic'
<br> The check for the tag is performed using DDIBuilderHelpers.eol : HasTaggedValue operation
<br> Included elements are cloned and set as citations of the originals
<br> (isCitation = true and set the ModelElement as the citedElement)
*/
operation BuildARGPInterface(ARGPI : Any, ModelElements : Collection) {
// Collect ModelElements with property 'isPublic'
var publishedElements = ModelElements.select(e | e.HasTaggedValue('isPublic'));
for(e in publishedElements) {
var copy = e.Clone();
// TODO: Should generalize for publishing other types of elements too
// Assume all published elements are claims for now -> ArgumentPackage
ARGPI.argumentationElement.add(copy);
ARGPI.argumentationElement.last().isCitation = true;
ARGPI.argumentationElement.last().citedElement = e;
}
}
/**
@BuildACPBinding
@param alphaARGPI
@type ArgumentPackageInterface
The first ARGPI to be bound
@param betaARGPI
@type ArgumentPackageInterface
The second ARGPI to be bound
@param bindingMap
@type Map
A Map used to associate elements from one ARGPI to the other
@comments
Binds two ArgumentPackageInterfaces under a AssuranceCasePackageBinding, indirectly
<br> the ACPB also contains a ArgumentPackageBinding under which the interfaces are directly bound
*/
operation BuildACPBinding(
alphaARGPI : ownDDI!ArgumentPackageInterface,
betaARGPI : supplierDDI!ArgumentPackageInterface,
bindingMap : Map) :
ownDDI!AssuranceCasePackageBinding {
var result : new m!AssuranceCasePackageBinding;
var argP : new m!ArgumentPackageBinding;
// TODO: These need to be collected via declarations in the input
var originalG1 = m!Claim.all().selectOne(c | c.name.content = "G1");
var originalG2 = m!Claim.all().selectOne(c | c.name.content = "G2");
var originalG4 = supplierDDI!Claim.all().selectOne(c | c.name.content = "G4");
var originalS1 = m!AssertedInference.all().selectOne(ai | ai.reasoning.name.content = "S1");
// TODO: These can be autogenerated from ETCS ACP
// Normally, these should cite the interface packages but
// the citations in the latter are not defined, see bug in BuildARGPInterface
// Current workaround is to cite directly to original Claims/AssertedInferences
var G1 = argP.BuildGoal("G1","The European Train Control System (ETCS) is accepted as adequately safe");
var G2 = argP.BuildGoal("G2", "On-board functions are acceptably safe");
var G4 = argP.BuildGoal("G4", "Trackside functions are acceptably safe");
var G1SubGoals = Collection {G2, G4};
var S1 = argP.LinkGoalToGoals(G1, G1SubGoals, "S1", "Argument of compliance with applicable safety standards & regulations (this includes system decomposition and identification of relevant hazards)");
G1.isCitation = true; G1.citedElement = originalG1;
G2.isCitation = true; G2.citedElement = originalG2;
G4.isCitation = true; G4.citedElement = originalG4;
S1.isCitation = true; S1.citedElement = originalS1;
argP.participantPackage.add(alphaARGPI);
argP.participantPackage.add(betaARGPI);
result.argumentPackage.add(argP);
result.participantPackage.add(ownDDI!AssuranceCasePackage.all().first());
result.participantPackage.add(supplierDDI!AssuranceCasePackage.all().first());
return result;
}
/**
@IntegrateArchitecture
@param systemName
@type String
The name of the parent system
@param subSystemName
@type String
The name of the subsystem
@param inputPortMapping
@type Map
Maps parent system's input ports to the subsystem's output ports
@param outputPortMapping
@type Map
Maps the parent system's output ports to the subsystem's input ports
@comments
Integrates a system with a subsystem, mapping I/O ports
<br> Searches parent system from ownDDI for a placeholder subsystem with the provided subsystem name
<br> Then removes references and signals from/to that subsystem (from just the parent system)
<br> Then retrieves the subsystem from the supplierDDI, clones and adds it to the parent system's subsystems
<br> Also adds it to the design package containing the parent system
<br> Connects the parent system's input ports to the subsystem's output ports and vice versa
*/
operation IntegrateArchitecture(
systemName : String, subSystemName : String,
inputPortMapping : Map, outputPortMapping : Map) {
// Find system, DesignPackage from ownDDI
var system = ownDDI!System.all().selectOne(s | s.name = systemName);
var parentSystem = ownDDI!System.all().selectOne(s | s.subSystems.includes(system));
var designPackage = ownDDI!DesignPackage.all().selectOne(d | d.systems.includes(system));
// Need to remove/update references
// Remove existing subsystem
var existingSub = parentSystem.subSystems.selectOne(s | s.name = subSystemName);
// Remove signals referencing ports to be removed
var signalsToBeRemoved = parentSystem.signals.select(s |
(existingSub.ports.includes(s.fromPort))
or (existingSub.ports.includes(s.toPort)));
for(signal in signalsToBeRemoved)
parentSystem.signals.remove(signal);
parentSystem.subSystems.remove(existingSub);
designPackage.systems.remove(existingSub);
// Find system from supplierDDI
var subSystemRef = supplierDDI!System.all().selectOne(s | s.name = subSystemName);
// TODO: Currently only deep-copying in subsystem reference from supplierDDI
// Should instead deep-copy all information cross-referenced by subsystem reference as well
// This will involve deep-copying cross-references into other ODEProductPackages as well
var newSubSystem = subSystemRef.Clone();
parentSystem.subSystems.add(newSubSystem);
designPackage.systems.add(newSubSystem);
// Link input/output ports
for (sysKey in inputPortMapping.keySet()) {
var systemInPort = system.ports.selectOne(p | p.name = sysKey);
var subSystemOutPort = newSubSystem.ports.selectOne(p | p.name = inputPortMapping.get(sysKey));
parentSystem.BuildSignal(systemInPort, subSystemOutPort);
}
for (subKey in outputPortMapping.keySet()) {
var systemOutPort = system.ports.selectOne(p | p.name = outputPortMapping.get(subKey));
var subSystemInPort = newSubSystem.ports.selectOne(p | p.name = subKey);
parentSystem.BuildSignal(subSystemInPort, systemOutPort);
}
}