math-spec-mapping 0.1.5__tar.gz → 0.2.1__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {math_spec_mapping-0.1.5/src/math_spec_mapping.egg-info → math_spec_mapping-0.2.1}/PKG-INFO +29 -5
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/README.md +28 -4
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/pyproject.toml +1 -1
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/Block.py +124 -15
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/Entity.py +2 -2
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/MathSpec.py +83 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/Parameter.py +5 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/Space.py +3 -2
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/State.py +5 -6
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/StatefulMetric.py +2 -0
- math_spec_mapping-0.2.1/src/Classes/Type.py +7 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/__init__.py +1 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/boundary_actions.py +10 -4
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/control_actions.py +13 -4
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/entities.py +7 -4
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/general.py +31 -7
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/load.py +8 -3
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/mechanism.py +25 -3
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/parameters.py +9 -3
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/policy.py +14 -2
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/spaces.py +10 -2
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/state_update_transmission_channels.py +4 -2
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/stateful_metrics.py +19 -4
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/states.py +10 -3
- math_spec_mapping-0.2.1/src/Load/type.py +24 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/wiring.py +31 -7
- math_spec_mapping-0.2.1/src/Reports/__init__.py +28 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/html.py +70 -21
- math_spec_mapping-0.2.1/src/Reports/markdown.py +547 -0
- math_spec_mapping-0.2.1/src/Reports/parameters.py +15 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/spaces.py +1 -1
- math_spec_mapping-0.2.1/src/Reports/state.py +88 -0
- math_spec_mapping-0.2.1/src/Reports/wiring.py +40 -0
- math_spec_mapping-0.2.1/src/__init__.py +28 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1/src/math_spec_mapping.egg-info}/PKG-INFO +29 -5
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/math_spec_mapping.egg-info/SOURCES.txt +5 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/math_spec_mapping.egg-info/top_level.txt +1 -0
- math_spec_mapping-0.2.1/src/schema.py +8 -0
- math_spec_mapping-0.1.5/src/Reports/__init__.py +0 -7
- math_spec_mapping-0.1.5/src/Reports/parameters.py +0 -11
- math_spec_mapping-0.1.5/src/Reports/state.py +0 -38
- math_spec_mapping-0.1.5/src/__init__.py +0 -4
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/LICENSE +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/setup.cfg +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/ActionTransmissionChannel.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/BoundaryAction.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/ControlAction.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/Mechanism.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/Policy.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Classes/StateUpdateTransmissionChannel.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Convenience/__init__.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Convenience/starter.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/__init__.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Load/action_transmission_channel.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/boundary_actions.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/control_actions.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/general.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/mechanisms.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/node_map.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/policies.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/Reports/tables.py +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/math_spec_mapping.egg-info/dependency_links.txt +0 -0
- {math_spec_mapping-0.1.5 → math_spec_mapping-0.2.1}/src/math_spec_mapping.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: math_spec_mapping
|
3
|
-
Version: 0.1
|
3
|
+
Version: 0.2.1
|
4
4
|
Summary: A library for easy mapping of mathematical specifications.
|
5
5
|
Author-email: Sean McOwen <Sean@Block.Science>
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -42,7 +42,31 @@ A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to
|
|
42
42
|
|
43
43
|
```
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
## Canonical Examples
|
46
|
+
|
47
|
+
[Dummy/Starter Repository](https://github.com/BlockScience/MSML/tree/main/examples/StarterRepo)
|
48
|
+
[Root Finding Simulation](https://github.com/SeanMcOwen/Root-Finding-Simulation)
|
49
|
+
|
50
|
+
### Comparison of Canonical Example Features
|
51
|
+
|
52
|
+
| Feature | Dummy | Root Finding |
|
53
|
+
| --- | --- | --- |
|
54
|
+
| Action Transmission Channels | X | X |
|
55
|
+
| Stack Block | X | X |
|
56
|
+
| Parallel Block | | X |
|
57
|
+
| Split Block | | |
|
58
|
+
| Boundary Actions | X | |
|
59
|
+
| Control Actions | X | X |
|
60
|
+
| Entities | X | |
|
61
|
+
| Mechanisms | X | X |
|
62
|
+
| Parameters | X | X |
|
63
|
+
| Policies | X | X |
|
64
|
+
| Spaces | X | X |
|
65
|
+
| State | X | X |
|
66
|
+
| Stateful Metrics | | |
|
67
|
+
| State Update Transmission Channels | X | X |
|
68
|
+
| Reports | X | X |
|
69
|
+
|
70
|
+
## Other Related Repositories
|
71
|
+
|
72
|
+
[GDS-MSML-cadCAD Repository](https://github.com/BlockScience/GDS-MSML-cadCAD)
|
@@ -27,7 +27,31 @@ A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to
|
|
27
27
|
|
28
28
|
```
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
## Canonical Examples
|
31
|
+
|
32
|
+
[Dummy/Starter Repository](https://github.com/BlockScience/MSML/tree/main/examples/StarterRepo)
|
33
|
+
[Root Finding Simulation](https://github.com/SeanMcOwen/Root-Finding-Simulation)
|
34
|
+
|
35
|
+
### Comparison of Canonical Example Features
|
36
|
+
|
37
|
+
| Feature | Dummy | Root Finding |
|
38
|
+
| --- | --- | --- |
|
39
|
+
| Action Transmission Channels | X | X |
|
40
|
+
| Stack Block | X | X |
|
41
|
+
| Parallel Block | | X |
|
42
|
+
| Split Block | | |
|
43
|
+
| Boundary Actions | X | |
|
44
|
+
| Control Actions | X | X |
|
45
|
+
| Entities | X | |
|
46
|
+
| Mechanisms | X | X |
|
47
|
+
| Parameters | X | X |
|
48
|
+
| Policies | X | X |
|
49
|
+
| Spaces | X | X |
|
50
|
+
| State | X | X |
|
51
|
+
| Stateful Metrics | | |
|
52
|
+
| State Update Transmission Channels | X | X |
|
53
|
+
| Reports | X | X |
|
54
|
+
|
55
|
+
## Other Related Repositories
|
56
|
+
|
57
|
+
[GDS-MSML-cadCAD Repository](https://github.com/BlockScience/GDS-MSML-cadCAD)
|
@@ -10,11 +10,15 @@ class Block:
|
|
10
10
|
self.domain = data["domain"]
|
11
11
|
self.codomain = data["codomain"]
|
12
12
|
self.parameters_used = data["parameters_used"]
|
13
|
+
self.metadata = data["metadata"]
|
13
14
|
if "label" in data:
|
14
15
|
self.label = data["label"]
|
15
16
|
else:
|
16
17
|
self.label = self.name
|
17
|
-
|
18
|
+
if "called_by" in data:
|
19
|
+
self.called_by = data["called_by"]
|
20
|
+
else:
|
21
|
+
self.called_by = []
|
18
22
|
self.calls = []
|
19
23
|
self.block_type = "Block"
|
20
24
|
# Will be overwritten in composite blocks to represent individual components
|
@@ -74,6 +78,7 @@ class ParallelBlock(Block):
|
|
74
78
|
self.components = data["components"]
|
75
79
|
self.description = data["description"]
|
76
80
|
self.constraints = data["constraints"]
|
81
|
+
self.mermaid_show_name = data["mermaid_show_name"]
|
77
82
|
self.domain = tuple(
|
78
83
|
[
|
79
84
|
i
|
@@ -119,6 +124,7 @@ class ParallelBlock(Block):
|
|
119
124
|
self.called_by = []
|
120
125
|
self.calls = []
|
121
126
|
self.block_type = "Paralell Block"
|
127
|
+
self.metadata = data["metadata"]
|
122
128
|
|
123
129
|
def render_mermaid(self, i):
|
124
130
|
multi = None
|
@@ -131,21 +137,75 @@ class ParallelBlock(Block):
|
|
131
137
|
nodes = []
|
132
138
|
|
133
139
|
# Render components
|
140
|
+
domain_map = {}
|
141
|
+
codomain_map = {}
|
134
142
|
for component in self.components:
|
143
|
+
domain = component.domain
|
144
|
+
codomain = component.codomain
|
145
|
+
domain = [
|
146
|
+
x.name
|
147
|
+
for x in domain
|
148
|
+
if x.name not in ["Empty Space", "Terminating Space"]
|
149
|
+
]
|
150
|
+
codomain = [
|
151
|
+
x.name
|
152
|
+
for x in codomain
|
153
|
+
if x.name not in ["Empty Space", "Terminating Space"]
|
154
|
+
]
|
155
|
+
|
135
156
|
component, i = component.render_mermaid(i)
|
136
157
|
out += component
|
137
158
|
out += "\n"
|
159
|
+
domain_map[i] = domain
|
160
|
+
codomain_map[i] = codomain
|
138
161
|
nodes.append(i)
|
139
|
-
|
162
|
+
|
163
|
+
# Add domain and codomain
|
164
|
+
i += 1
|
165
|
+
out += "X{}[Domain]".format(i)
|
166
|
+
out += "\n"
|
167
|
+
domain_i = i
|
168
|
+
i += 1
|
169
|
+
out += "X{}[Codomain]".format(i)
|
170
|
+
out += "\n"
|
171
|
+
codomain_i = i
|
172
|
+
|
173
|
+
out += "direction LR\n"
|
140
174
|
|
141
175
|
# Render invisible connections
|
142
|
-
for ix1, ix2 in zip(nodes[:-1], nodes[1:]):
|
143
|
-
|
176
|
+
# for ix1, ix2 in zip(nodes[:-1], nodes[1:]):
|
177
|
+
# out += "X{} ~~~~ X{}".format(ix1, ix2)
|
178
|
+
# out += "\n"
|
179
|
+
|
180
|
+
out += "direction TB\n"
|
181
|
+
|
182
|
+
for ix1 in nodes:
|
183
|
+
d = domain_map[ix1]
|
184
|
+
if len(d) > 0:
|
185
|
+
d = "\n".join(d)
|
186
|
+
d = '"{}"'.format(d)
|
187
|
+
out += "X{} --{}--> X{}".format(domain_i, d, ix1)
|
188
|
+
else:
|
189
|
+
out += "X{} --> X{}".format(domain_i, ix1)
|
190
|
+
out += "\n"
|
191
|
+
|
192
|
+
for ix1 in nodes:
|
193
|
+
d = codomain_map[ix1]
|
194
|
+
if len(d) > 0:
|
195
|
+
d = "\n".join(d)
|
196
|
+
d = '"{}"'.format(d)
|
197
|
+
out += "X{} --{}--> X{}".format(ix1, d, codomain_i)
|
198
|
+
else:
|
199
|
+
out += "X{} --> X{}".format(ix1, codomain_i)
|
144
200
|
out += "\n"
|
145
201
|
|
146
202
|
# Subgraph it
|
203
|
+
if self.mermaid_show_name:
|
204
|
+
name = self.name
|
205
|
+
else:
|
206
|
+
name = " "
|
147
207
|
i += 1
|
148
|
-
out = "subgraph X{}[{}]\ndirection
|
208
|
+
out = "subgraph X{}[{}]\ndirection TB\n".format(i, name) + out
|
149
209
|
|
150
210
|
out += "end"
|
151
211
|
|
@@ -158,6 +218,9 @@ class StackBlock(Block):
|
|
158
218
|
self.components = data["components"]
|
159
219
|
self.description = data["description"]
|
160
220
|
self.constraints = data["constraints"]
|
221
|
+
self.mermaid_show_name = data["mermaid_show_name"]
|
222
|
+
self.optional_indices = data["optional_indices"]
|
223
|
+
self.loop = data["loop"]
|
161
224
|
self._check_domain_mapping()
|
162
225
|
self.domain = self.components[0].domain
|
163
226
|
self.codomain = self.components[-1].codomain
|
@@ -177,9 +240,15 @@ class StackBlock(Block):
|
|
177
240
|
self.calls = []
|
178
241
|
|
179
242
|
self.block_type = "Stack Block"
|
243
|
+
self.metadata = data["metadata"]
|
180
244
|
|
181
245
|
def _check_domain_mapping(self):
|
182
|
-
|
246
|
+
x = self.components[:-1]
|
247
|
+
y = self.components[1:]
|
248
|
+
if self.loop:
|
249
|
+
x.append(self.components[-1])
|
250
|
+
y.append(self.components[0])
|
251
|
+
for a, b in zip(x, y):
|
183
252
|
assert [
|
184
253
|
x for x in a.codomain if x not in [EmptySpace, TerminatingSpace]
|
185
254
|
] == [
|
@@ -190,10 +259,17 @@ class StackBlock(Block):
|
|
190
259
|
|
191
260
|
def build_action_transmission_channels(self):
|
192
261
|
channels = []
|
193
|
-
|
262
|
+
x = self.components[:-1]
|
263
|
+
y = self.components[1:]
|
264
|
+
if self.loop:
|
265
|
+
x.append(self.components[-1])
|
266
|
+
y.append(self.components[0])
|
267
|
+
for a, b, c in zip(x, y, range(len(x))):
|
194
268
|
assert len(a.codomain_blocks) == len(b.domain_blocks) and len(
|
195
269
|
b.domain_blocks
|
196
270
|
) == len([x for x in b.domain if x not in [EmptySpace, TerminatingSpace]])
|
271
|
+
global_optional = c in self.optional_indices
|
272
|
+
|
197
273
|
for x, y, z in zip(
|
198
274
|
a.codomain_blocks,
|
199
275
|
b.domain_blocks,
|
@@ -204,7 +280,7 @@ class StackBlock(Block):
|
|
204
280
|
"origin": x.name,
|
205
281
|
"target": y.name,
|
206
282
|
"space": z.name,
|
207
|
-
"optional":
|
283
|
+
"optional": global_optional,
|
208
284
|
}
|
209
285
|
)
|
210
286
|
for x in a.codomain_blocks_empty:
|
@@ -214,7 +290,7 @@ class StackBlock(Block):
|
|
214
290
|
"origin": x.name,
|
215
291
|
"target": y.name,
|
216
292
|
"space": "Empty Space",
|
217
|
-
"optional":
|
293
|
+
"optional": global_optional,
|
218
294
|
}
|
219
295
|
)
|
220
296
|
return channels
|
@@ -229,9 +305,17 @@ class StackBlock(Block):
|
|
229
305
|
|
230
306
|
nodes = []
|
231
307
|
|
308
|
+
domain_map = {}
|
232
309
|
# Render components
|
233
310
|
for component in self.components:
|
311
|
+
domain = component.domain
|
312
|
+
domain = [
|
313
|
+
x.name
|
314
|
+
for x in domain
|
315
|
+
if x.name not in ["Empty Space", "Terminating Space"]
|
316
|
+
]
|
234
317
|
component, i = component.render_mermaid(i)
|
318
|
+
domain_map[i] = domain
|
235
319
|
out += component
|
236
320
|
out += "\n"
|
237
321
|
nodes.append(i)
|
@@ -240,19 +324,42 @@ class StackBlock(Block):
|
|
240
324
|
end_i = i
|
241
325
|
|
242
326
|
# Render connections
|
243
|
-
|
327
|
+
x = nodes[:-1]
|
328
|
+
y = nodes[1:]
|
329
|
+
if self.loop:
|
330
|
+
x.append(nodes[-1])
|
331
|
+
y.append(nodes[0])
|
332
|
+
for ix1, ix2, c in zip(x, y, range(len(x))):
|
333
|
+
global_optional = c in self.optional_indices
|
244
334
|
if type(ix1) != list:
|
245
335
|
ix1 = [ix1]
|
246
336
|
if type(ix2) != list:
|
247
337
|
ix2 = [ix2]
|
248
338
|
for ix3 in ix1:
|
249
339
|
for ix4 in ix2:
|
250
|
-
|
340
|
+
d = domain_map[ix4]
|
341
|
+
optional = global_optional
|
342
|
+
if len(d) > 0:
|
343
|
+
d = "\n".join(d)
|
344
|
+
d = '"{}"'.format(d)
|
345
|
+
if optional:
|
346
|
+
out += "X{}-.{}.->X{}".format(ix3, d, ix4)
|
347
|
+
else:
|
348
|
+
out += "X{}--{}-->X{}".format(ix3, d, ix4)
|
349
|
+
else:
|
350
|
+
if optional:
|
351
|
+
out += "X{}-.->X{}".format(ix3, ix4)
|
352
|
+
else:
|
353
|
+
out += "X{}--->X{}".format(ix3, ix4)
|
251
354
|
out += "\n"
|
252
355
|
|
253
356
|
# Subgraph it
|
357
|
+
if self.mermaid_show_name:
|
358
|
+
name = self.name
|
359
|
+
else:
|
360
|
+
name = " "
|
254
361
|
i += 1
|
255
|
-
out = "subgraph X{}[{}]\ndirection TB\n".format(i,
|
362
|
+
out = "subgraph X{}[{}]\ndirection TB\n".format(i, name) + out
|
256
363
|
out += "end"
|
257
364
|
|
258
365
|
return out, i
|
@@ -264,6 +371,7 @@ class SplitBlock(Block):
|
|
264
371
|
self.components = data["components"]
|
265
372
|
self.description = data["description"]
|
266
373
|
self.constraints = data["constraints"]
|
374
|
+
self.mermaid_show_name = data["mermaid_show_name"]
|
267
375
|
self.domain = tuple(
|
268
376
|
[
|
269
377
|
i
|
@@ -310,6 +418,7 @@ class SplitBlock(Block):
|
|
310
418
|
self.calls = []
|
311
419
|
|
312
420
|
self.block_type = "Split Block"
|
421
|
+
self.metadata = data["metadata"]
|
313
422
|
|
314
423
|
def render_mermaid(self, i):
|
315
424
|
multi = None
|
@@ -330,9 +439,9 @@ class SplitBlock(Block):
|
|
330
439
|
end_i = i
|
331
440
|
|
332
441
|
# Render invisible connections
|
333
|
-
for ix1, ix2 in zip(nodes[:-1], nodes[1:]):
|
334
|
-
|
335
|
-
|
442
|
+
# for ix1, ix2 in zip(nodes[:-1], nodes[1:]):
|
443
|
+
# out += "X{} ~~~ X{}".format(ix1, ix2)
|
444
|
+
# out += "\n"
|
336
445
|
out = out[:-1]
|
337
446
|
|
338
447
|
return out, nodes
|
@@ -9,6 +9,7 @@ class Entity:
|
|
9
9
|
self.name = data["name"]
|
10
10
|
self.notes = data["notes"]
|
11
11
|
self.state = data["state"]
|
12
|
+
self.metadata = data["metadata"]
|
12
13
|
|
13
14
|
if "label" in data:
|
14
15
|
self.label = data["label"]
|
@@ -25,7 +26,7 @@ class Entity:
|
|
25
26
|
|
26
27
|
def add_boundary_action(self, boundary_action) -> None:
|
27
28
|
self.boundary_actions.append(boundary_action)
|
28
|
-
|
29
|
+
|
29
30
|
def add_impacted_by_mechanism(self, mechanism) -> None:
|
30
31
|
self.impacted_by_mechanism.append(mechanism)
|
31
32
|
q = [mechanism]
|
@@ -36,4 +37,3 @@ class Entity:
|
|
36
37
|
self.impacted_by_actions.append(cur)
|
37
38
|
else:
|
38
39
|
q.extend([x[0] for x in cur.called_by])
|
39
|
-
|
@@ -26,6 +26,7 @@ class MathSpec:
|
|
26
26
|
self.stateful_metrics = ms_dict["Stateful Metrics"]
|
27
27
|
self.wiring = ms_dict["Wiring"]
|
28
28
|
self.blocks = ms_dict["Blocks"]
|
29
|
+
self.types = ms_dict["Types"]
|
29
30
|
|
30
31
|
self._check_parameters()
|
31
32
|
self._crawl_parameters()
|
@@ -259,3 +260,85 @@ class MathSpec:
|
|
259
260
|
out["Spaces"] = list(out["Spaces"])
|
260
261
|
out["Parameters"] = list(out["Parameters"])
|
261
262
|
return out
|
263
|
+
|
264
|
+
def crawl_wiring(self, wiring_name) -> dict:
|
265
|
+
wiring = self.wiring[wiring_name]
|
266
|
+
out = {}
|
267
|
+
|
268
|
+
out["Boundary Actions"] = []
|
269
|
+
out["Control Actions"] = []
|
270
|
+
out["Policies"] = []
|
271
|
+
out["Mechanisms"] = []
|
272
|
+
out["State Updates"] = []
|
273
|
+
out["Entities2"] = []
|
274
|
+
out["Spaces"] = set()
|
275
|
+
out["Parameters"] = set()
|
276
|
+
out["Wiring"] = []
|
277
|
+
q = [wiring.name]
|
278
|
+
while len(q) > 0:
|
279
|
+
x = q.pop()
|
280
|
+
if x in self.wiring:
|
281
|
+
if x not in out["Wiring"]:
|
282
|
+
x = self.wiring[x]
|
283
|
+
out["Wiring"].append(x)
|
284
|
+
q.extend([y.name for y in x.components])
|
285
|
+
else:
|
286
|
+
x = None
|
287
|
+
elif x in self.boundary_actions:
|
288
|
+
if x not in out["Boundary Actions"]:
|
289
|
+
x = self.boundary_actions[x]
|
290
|
+
out["Boundary Actions"].append(x)
|
291
|
+
else:
|
292
|
+
x = None
|
293
|
+
elif x in self.control_actions:
|
294
|
+
if x not in out["Control Actions"]:
|
295
|
+
x = self.control_actions[x]
|
296
|
+
out["Control Actions"].append(x)
|
297
|
+
else:
|
298
|
+
x = None
|
299
|
+
elif x in self.policies:
|
300
|
+
if x not in out["Policies"]:
|
301
|
+
x = self.policies[x]
|
302
|
+
out["Policies"].append(x)
|
303
|
+
else:
|
304
|
+
x = None
|
305
|
+
elif x in self.mechanisms:
|
306
|
+
if x not in out["Mechanisms"]:
|
307
|
+
x = self.mechanisms[x]
|
308
|
+
out["Mechanisms"].append(x)
|
309
|
+
for y in x.updates:
|
310
|
+
if y not in out["State Updates"]:
|
311
|
+
out["State Updates"].append(y)
|
312
|
+
if y[0] not in out["Entities2"]:
|
313
|
+
out["Entities2"].append(y[0])
|
314
|
+
else:
|
315
|
+
x = None
|
316
|
+
else:
|
317
|
+
assert False
|
318
|
+
|
319
|
+
if x:
|
320
|
+
out["Spaces"].update(x.codomain)
|
321
|
+
out["Spaces"].update(x.domain)
|
322
|
+
out["Parameters"].update(x.parameters_used)
|
323
|
+
|
324
|
+
out["Entities"] = self.find_relevant_entities(
|
325
|
+
[x.name for x in out["Boundary Actions"]]
|
326
|
+
)
|
327
|
+
|
328
|
+
out["State"] = [x.state for x in out["Entities"]]
|
329
|
+
out["State"] = list(set(out["State"]))
|
330
|
+
return out
|
331
|
+
|
332
|
+
def get_specific_stateful_metrics(self, metric):
|
333
|
+
for x in self.stateful_metrics.values():
|
334
|
+
for y in x.metrics:
|
335
|
+
if metric == y.name:
|
336
|
+
return y
|
337
|
+
print("Metric not found")
|
338
|
+
return None
|
339
|
+
|
340
|
+
def get_all_stateful_metric_names(self):
|
341
|
+
sm = []
|
342
|
+
for metrics in self.stateful_metrics.values():
|
343
|
+
sm.extend([x.name for x in metrics.metrics])
|
344
|
+
return sm
|
@@ -8,8 +8,11 @@ class ParameterContainer:
|
|
8
8
|
self.data = data
|
9
9
|
|
10
10
|
self.all_parameters = []
|
11
|
+
self.parameter_map = {}
|
11
12
|
for x in self.data.values():
|
12
13
|
x = x.parameters
|
14
|
+
for y in x:
|
15
|
+
self.parameter_map[y.name] = y
|
13
16
|
x = [y.name for y in x]
|
14
17
|
self.all_parameters.extend(x)
|
15
18
|
assert len(set(self.all_parameters)) == len(
|
@@ -25,6 +28,7 @@ class ParameterSet:
|
|
25
28
|
self.name = data["name"]
|
26
29
|
self.notes = data["notes"]
|
27
30
|
self.parameters = data["parameters"]
|
31
|
+
self.metadata = data["metadata"]
|
28
32
|
|
29
33
|
|
30
34
|
# Individual Parameter
|
@@ -40,3 +44,4 @@ class Parameter:
|
|
40
44
|
self.parameter_class = data[
|
41
45
|
"parameter_class"
|
42
46
|
] # I.e. behavioral, functional, system
|
47
|
+
self.metadata = data["metadata"]
|
@@ -5,10 +5,11 @@ class Space:
|
|
5
5
|
def __init__(self, data: Dict):
|
6
6
|
self.name = data["name"]
|
7
7
|
self.schema = data["schema"]
|
8
|
+
self.metadata = data["metadata"]
|
8
9
|
|
9
10
|
def __repr__(self):
|
10
11
|
return self.name
|
11
12
|
|
12
13
|
|
13
|
-
TerminatingSpace = Space({"name": "Terminating Space", "schema": {}})
|
14
|
-
EmptySpace = Space({"name": "Empty Space", "schema": {}})
|
14
|
+
TerminatingSpace = Space({"name": "Terminating Space", "schema": {}, "metadata": {}})
|
15
|
+
EmptySpace = Space({"name": "Empty Space", "schema": {}, "metadata": {}})
|
@@ -14,6 +14,7 @@ class State:
|
|
14
14
|
self.label = self.name
|
15
15
|
self._write_variable_map()
|
16
16
|
self.updated_by = []
|
17
|
+
self.metadata = data["metadata"]
|
17
18
|
|
18
19
|
def _write_variable_map(self) -> None:
|
19
20
|
"""
|
@@ -27,8 +28,9 @@ class State:
|
|
27
28
|
key = var.name
|
28
29
|
|
29
30
|
# Check variable name not repeated
|
30
|
-
assert
|
31
|
-
|
31
|
+
assert (
|
32
|
+
var.name not in self.variable_map
|
33
|
+
), "Variable name {} is already present in variables!".format(key)
|
32
34
|
|
33
35
|
self.variable_map[key] = var
|
34
36
|
|
@@ -43,10 +45,7 @@ class StateVariable:
|
|
43
45
|
self.domain = data["domain"]
|
44
46
|
self.updated_by = []
|
45
47
|
|
46
|
-
|
47
|
-
|
48
48
|
# Add check for type of List
|
49
49
|
if hasattr(self.type, "_name"):
|
50
50
|
if self.type._name == "List":
|
51
|
-
self.type.__name__ = self.type.__repr__().replace("typing.","")
|
52
|
-
|
51
|
+
self.type.__name__ = self.type.__repr__().replace("typing.", "")
|
@@ -15,6 +15,7 @@ class StatefulMetric:
|
|
15
15
|
self.label = data["label"]
|
16
16
|
else:
|
17
17
|
self.label = self.name
|
18
|
+
self.metadata = data["metadata"]
|
18
19
|
|
19
20
|
|
20
21
|
class StatefulMetricSet:
|
@@ -23,3 +24,4 @@ class StatefulMetricSet:
|
|
23
24
|
self.name = data["name"]
|
24
25
|
self.notes = data["notes"]
|
25
26
|
self.metrics = data["metrics"]
|
27
|
+
self.metadata = data["metadata"]
|
@@ -11,3 +11,4 @@ from .StatefulMetric import StatefulMetric, StatefulMetricSet
|
|
11
11
|
from .ControlAction import ControlAction, ControlActionOption
|
12
12
|
from .Space import Space, TerminatingSpace, EmptySpace
|
13
13
|
from .Block import ParallelBlock, Block, StackBlock, SplitBlock
|
14
|
+
from .Type import Type
|
@@ -13,6 +13,10 @@ def convert_boundary_action(data: Dict, ms: Dict) -> BoundaryAction:
|
|
13
13
|
Returns:
|
14
14
|
BoundaryAction: Boundary action object
|
15
15
|
"""
|
16
|
+
if "metadata" not in data:
|
17
|
+
data["metadata"] = {}
|
18
|
+
|
19
|
+
data["codomain"] = tuple(data["codomain"])
|
16
20
|
|
17
21
|
# Check the keys are correct
|
18
22
|
check_json_keys(data, "Boundary Action")
|
@@ -20,6 +24,9 @@ def convert_boundary_action(data: Dict, ms: Dict) -> BoundaryAction:
|
|
20
24
|
data["name"]
|
21
25
|
)
|
22
26
|
|
27
|
+
if len(data["codomain"]) == 0:
|
28
|
+
data["codomain"] = ("Empty Space",)
|
29
|
+
|
23
30
|
# Copy
|
24
31
|
data = data.copy()
|
25
32
|
|
@@ -53,9 +60,8 @@ def load_boundary_actions(ms: Dict, json: Dict) -> None:
|
|
53
60
|
"""
|
54
61
|
|
55
62
|
ms["Boundary Actions"] = {}
|
56
|
-
for
|
57
|
-
|
58
|
-
|
59
|
-
)
|
63
|
+
for ba in json["Boundary Actions"]:
|
64
|
+
key = ba["name"]
|
65
|
+
ms["Boundary Actions"][key] = convert_boundary_action(ba, ms)
|
60
66
|
for entity in ms["Boundary Actions"][key].called_by:
|
61
67
|
entity.add_boundary_action(ms["Boundary Actions"][key])
|
@@ -14,8 +14,19 @@ def convert_control_action(data: Dict, ms: Dict) -> ControlAction:
|
|
14
14
|
ControlAction: Control action object
|
15
15
|
"""
|
16
16
|
|
17
|
+
if "metadata" not in data:
|
18
|
+
data["metadata"] = {}
|
19
|
+
|
20
|
+
data["codomain"] = tuple(data["codomain"])
|
21
|
+
|
17
22
|
# Check the keys are correct
|
18
23
|
check_json_keys(data, "Control Action")
|
24
|
+
assert type(data["codomain"]) == tuple, "{} codomain is not a tuple".format(
|
25
|
+
data["name"]
|
26
|
+
)
|
27
|
+
|
28
|
+
if len(data["codomain"]) == 0:
|
29
|
+
data["codomain"] = ("Empty Space",)
|
19
30
|
|
20
31
|
# Copy
|
21
32
|
data = data.copy()
|
@@ -42,7 +53,5 @@ def load_control_actions(ms: Dict, json: Dict) -> None:
|
|
42
53
|
"""
|
43
54
|
|
44
55
|
ms["Control Actions"] = {}
|
45
|
-
for
|
46
|
-
ms["Control Actions"][
|
47
|
-
json["Control Actions"][key], ms
|
48
|
-
)
|
56
|
+
for ca in json["Control Actions"]:
|
57
|
+
ms["Control Actions"][ca["name"]] = convert_control_action(ca, ms)
|
@@ -14,6 +14,8 @@ def convert_entity(data: Dict, ms: Dict) -> Entity:
|
|
14
14
|
Entity: An entity object
|
15
15
|
"""
|
16
16
|
|
17
|
+
if "metadata" not in data:
|
18
|
+
data["metadata"] = {}
|
17
19
|
# Check the keys are correct
|
18
20
|
check_json_keys(data, "Entity")
|
19
21
|
|
@@ -23,8 +25,7 @@ def convert_entity(data: Dict, ms: Dict) -> Entity:
|
|
23
25
|
# Assert that the state is in the math spec and assign it here
|
24
26
|
if data["state"]:
|
25
27
|
name = data["state"]
|
26
|
-
assert name in ms["State"], "{} state not in states dictionary".format(
|
27
|
-
name)
|
28
|
+
assert name in ms["State"], "{} state not in states dictionary".format(name)
|
28
29
|
data["state"] = ms["State"][name]
|
29
30
|
|
30
31
|
# Build the state object
|
@@ -40,5 +41,7 @@ def load_entities(ms: Dict, json: Dict) -> None:
|
|
40
41
|
"""
|
41
42
|
|
42
43
|
ms["Entities"] = {}
|
43
|
-
|
44
|
-
|
44
|
+
|
45
|
+
for e in json["Entities"]:
|
46
|
+
ms["Entities"][e["name"]] = convert_entity(e, ms)
|
47
|
+
assert "Global" in ms["Entities"], "There must be a global entity"
|