math-spec-mapping 0.1.4__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Classes/Block.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from typing import Dict
2
+ from .Space import TerminatingSpace, EmptySpace
2
3
 
3
4
 
4
5
  class Block:
@@ -16,6 +17,45 @@ class Block:
16
17
  self.called_by = []
17
18
  self.calls = []
18
19
  self.block_type = "Block"
20
+ # Will be overwritten in composite blocks to represent individual components
21
+ self.domain_blocks = tuple(
22
+ [
23
+ self
24
+ for _ in range(
25
+ len(
26
+ [
27
+ x
28
+ for x in self.domain
29
+ if x not in [TerminatingSpace, EmptySpace]
30
+ ]
31
+ )
32
+ )
33
+ ]
34
+ )
35
+ self.codomain_blocks = tuple(
36
+ [
37
+ self
38
+ for _ in range(
39
+ len(
40
+ [
41
+ x
42
+ for x in self.codomain
43
+ if x not in [TerminatingSpace, EmptySpace]
44
+ ]
45
+ )
46
+ )
47
+ ]
48
+ )
49
+ self.domain_blocks_empty = tuple(
50
+ self for _ in range(len([x for x in self.domain if x == EmptySpace]))
51
+ )
52
+ self.codomain_blocks_empty = tuple(
53
+ self for _ in range(len([x for x in self.codomain if x == EmptySpace]))
54
+ )
55
+ self.codomain_blocks_terminating = tuple(
56
+ self
57
+ for _ in range(len([x for x in self.codomain if x == TerminatingSpace]))
58
+ )
19
59
 
20
60
  def render_mermaid(self, i):
21
61
  i += 1
@@ -34,13 +74,48 @@ class ParallelBlock(Block):
34
74
  self.components = data["components"]
35
75
  self.description = data["description"]
36
76
  self.constraints = data["constraints"]
37
- self.domain = tuple([i for x in self.components for i in x.domain])
38
-
39
- self.codomain = tuple([i for x in self.components for i in x.codomain])
77
+ self.domain = tuple(
78
+ [
79
+ i
80
+ for x in self.components
81
+ for i in x.domain
82
+ if i not in [TerminatingSpace, EmptySpace]
83
+ ]
84
+ )
85
+ if len(self.domain) == 0:
86
+ self.domain = (EmptySpace,)
87
+
88
+ self.codomain = tuple(
89
+ [
90
+ i
91
+ for x in self.components
92
+ for i in x.codomain
93
+ if i not in [TerminatingSpace, EmptySpace]
94
+ ]
95
+ )
96
+ if len(self.codomain) == 0:
97
+ self.codomain = (EmptySpace,)
40
98
  self.parameters_used = list(
41
99
  set([i for x in self.components for i in x.parameters_used])
42
100
  )
43
101
 
102
+ self.domain_blocks = tuple(
103
+ [i for x in self.components for i in x.domain_blocks]
104
+ )
105
+ self.codomain_blocks = tuple(
106
+ [i for x in self.components for i in x.codomain_blocks]
107
+ )
108
+
109
+ self.domain_blocks_empty = tuple(
110
+ [i for x in self.components for i in x.domain_blocks_empty]
111
+ )
112
+ self.codomain_blocks_empty = tuple(
113
+ [i for x in self.components for i in x.codomain_blocks_empty]
114
+ )
115
+ self.codomain_blocks_terminating = tuple(
116
+ [i for x in self.components for i in x.codomain_blocks_terminating]
117
+ )
118
+
44
119
  self.called_by = []
45
120
  self.calls = []
46
121
  self.block_type = "Paralell Block"
@@ -90,6 +165,14 @@ class StackBlock(Block):
90
165
  set([i for x in self.components for i in x.parameters_used])
91
166
  )
92
167
 
168
+ self.domain_blocks = self.components[0].domain_blocks
169
+ self.codomain_blocks = self.components[-1].codomain_blocks
170
+ self.domain_blocks_empty = self.components[0].domain_blocks_empty
171
+ self.codomain_blocks_empty = self.components[-1].codomain_blocks_empty
172
+ self.codomain_blocks_terminating = self.components[
173
+ -1
174
+ ].codomain_blocks_terminating
175
+
93
176
  self.called_by = []
94
177
  self.calls = []
95
178
 
@@ -97,9 +180,44 @@ class StackBlock(Block):
97
180
 
98
181
  def _check_domain_mapping(self):
99
182
  for a, b in zip(self.components[:-1], self.components[1:]):
100
- assert (
101
- a.codomain == b.domain
102
- ), "{} codomain does not match {} domain".format(a.name, b.name)
183
+ assert [
184
+ x for x in a.codomain if x not in [EmptySpace, TerminatingSpace]
185
+ ] == [
186
+ x for x in b.domain if x not in [EmptySpace, TerminatingSpace]
187
+ ], "{} codomain does not match {} domain, {} != {}".format(
188
+ a.name, b.name, a.codomain, b.domain
189
+ )
190
+
191
+ def build_action_transmission_channels(self):
192
+ channels = []
193
+ for a, b in zip(self.components[:-1], self.components[1:]):
194
+ assert len(a.codomain_blocks) == len(b.domain_blocks) and len(
195
+ b.domain_blocks
196
+ ) == len([x for x in b.domain if x not in [EmptySpace, TerminatingSpace]])
197
+ for x, y, z in zip(
198
+ a.codomain_blocks,
199
+ b.domain_blocks,
200
+ [x for x in b.domain if x not in [EmptySpace, TerminatingSpace]],
201
+ ):
202
+ channels.append(
203
+ {
204
+ "origin": x.name,
205
+ "target": y.name,
206
+ "space": z.name,
207
+ "optional": False,
208
+ }
209
+ )
210
+ for x in a.codomain_blocks_empty:
211
+ for y in b.domain_blocks_empty:
212
+ channels.append(
213
+ {
214
+ "origin": x.name,
215
+ "target": y.name,
216
+ "space": "Empty Space",
217
+ "optional": False,
218
+ }
219
+ )
220
+ return channels
103
221
 
104
222
  def render_mermaid(self, i):
105
223
  multi = None
@@ -146,12 +264,48 @@ class SplitBlock(Block):
146
264
  self.components = data["components"]
147
265
  self.description = data["description"]
148
266
  self.constraints = data["constraints"]
149
- self.domain = tuple([i for x in self.components for i in x.domain])
150
- self.codomain = tuple([i for x in self.components for i in x.codomain])
267
+ self.domain = tuple(
268
+ [
269
+ i
270
+ for x in self.components
271
+ for i in x.domain
272
+ if i not in [TerminatingSpace, EmptySpace]
273
+ ]
274
+ )
275
+ if len(self.domain) == 0:
276
+ self.domain = (EmptySpace,)
277
+
278
+ self.codomain = tuple(
279
+ [
280
+ i
281
+ for x in self.components
282
+ for i in x.codomain
283
+ if i not in [TerminatingSpace, EmptySpace]
284
+ ]
285
+ )
286
+ if len(self.codomain) == 0:
287
+ self.codomain = (EmptySpace,)
151
288
  self.parameters_used = list(
152
289
  set([i for x in self.components for i in x.parameters_used])
153
290
  )
154
291
 
292
+ self.domain_blocks = tuple(
293
+ [i for x in self.components for i in x.domain_blocks]
294
+ )
295
+ self.codomain_blocks = tuple(
296
+ [i for x in self.components for i in x.codomain_blocks]
297
+ )
298
+
299
+ self.domain_blocks_empty = tuple(
300
+ [i for x in self.components for i in x.domain_blocks_empty]
301
+ )
302
+ self.codomain_blocks_empty = tuple(
303
+ [i for x in self.components for i in x.codomain_blocks_empty]
304
+ )
305
+ self.codomain_blocks_terminating = tuple(
306
+ [i for x in self.components for i in x.codomain_blocks_terminating]
307
+ )
308
+
155
309
  self.called_by = []
156
310
  self.calls = []
157
311
 
Classes/MathSpec.py CHANGED
@@ -25,6 +25,7 @@ class MathSpec:
25
25
  ]
26
26
  self.stateful_metrics = ms_dict["Stateful Metrics"]
27
27
  self.wiring = ms_dict["Wiring"]
28
+ self.blocks = ms_dict["Blocks"]
28
29
 
29
30
  self._check_parameters()
30
31
  self._crawl_parameters()
Classes/Mechanism.py CHANGED
@@ -1,10 +1,11 @@
1
1
  from typing import Dict
2
2
  from .Block import Block
3
+ from .Space import TerminatingSpace
3
4
 
4
5
 
5
6
  class Mechanism(Block):
6
7
  def __init__(self, data: Dict):
7
- data["codomain"] = tuple()
8
+ data["codomain"] = (TerminatingSpace,)
8
9
  super().__init__(data)
9
10
  self.logic = data["logic"]
10
11
  self.updates = []
Classes/Space.py CHANGED
@@ -5,3 +5,10 @@ class Space:
5
5
  def __init__(self, data: Dict):
6
6
  self.name = data["name"]
7
7
  self.schema = data["schema"]
8
+
9
+ def __repr__(self):
10
+ return self.name
11
+
12
+
13
+ TerminatingSpace = Space({"name": "Terminating Space", "schema": {}})
14
+ EmptySpace = Space({"name": "Empty Space", "schema": {}})
Classes/__init__.py CHANGED
@@ -9,5 +9,5 @@ from .Policy import Policy, PolicyOption
9
9
  from .StateUpdateTransmissionChannel import StateUpdateTransmissionChannel
10
10
  from .StatefulMetric import StatefulMetric, StatefulMetricSet
11
11
  from .ControlAction import ControlAction, ControlActionOption
12
- from .Space import Space
12
+ from .Space import Space, TerminatingSpace, EmptySpace
13
13
  from .Block import ParallelBlock, Block, StackBlock, SplitBlock
@@ -57,15 +57,17 @@ def convert_action_transmission_channel(
57
57
  return ActionTransmissionChannel(data)
58
58
 
59
59
 
60
- def load_action_transmission_channels(ms: Dict, json: Dict) -> None:
60
+ def load_action_transmission_channels(
61
+ ms: Dict, action_transmission_channels: list
62
+ ) -> None:
61
63
  """Function to load states into the new dictionary
62
64
 
63
65
  Args:
64
66
  ms (Dict): MathSpec dictionary
65
- json (Dict): JSON version of MathSpec to load
67
+ action_transmission_channels (list): List of action transmission channels
66
68
  """
67
69
 
68
70
  ms["Action Transmission Channels"] = []
69
- for atc in json["Action Transmission Channels"]:
71
+ for atc in action_transmission_channels:
70
72
  atc = convert_action_transmission_channel(atc, ms)
71
73
  ms["Action Transmission Channels"].append(atc)
Load/general.py CHANGED
@@ -30,7 +30,6 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
30
30
  "Blocks",
31
31
  ],
32
32
  "JSON": [
33
- "Action Transmission Channels",
34
33
  "Boundary Actions",
35
34
  "Entities",
36
35
  "Mechanisms",
Load/load.py CHANGED
@@ -40,8 +40,8 @@ def load_from_json(json: Dict) -> MathSpec:
40
40
  load_parameters(ms, json)
41
41
  load_policies(ms, json)
42
42
  load_stateful_metrics(ms, json)
43
- load_wiring(ms, json)
44
- load_action_transmission_channels(ms, json)
43
+ action_transmission_channels = load_wiring(ms, json)
44
+ load_action_transmission_channels(ms, action_transmission_channels)
45
45
  load_state_update_transmission_channels(ms, json)
46
46
 
47
47
  # Assert all keys are correct for the ms version
Load/spaces.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from typing import Dict
2
- from ..Classes import Space
2
+ from ..Classes import Space, TerminatingSpace, EmptySpace
3
3
  from .general import check_json_keys
4
4
 
5
5
 
@@ -24,6 +24,9 @@ def load_spaces(ms: Dict, json: Dict) -> None:
24
24
 
25
25
  # Placeholder for now
26
26
  ms["Spaces"] = {}
27
+ ms["Spaces"]["Terminating Space"] = TerminatingSpace
28
+ ms["Spaces"]["Empty Space"] = EmptySpace
27
29
 
28
30
  for space in json["Spaces"]:
31
+ assert space["name"] not in ms["Spaces"], "{} repeated"
29
32
  ms["Spaces"][space["name"]] = convert_space(space)
Load/wiring.py CHANGED
@@ -29,15 +29,42 @@ def load_single_wiring(data, ms):
29
29
  return block
30
30
 
31
31
 
32
+ def check_repeat(d, blocks):
33
+ for x in blocks:
34
+ assert x not in d, "{} was a repeated block".format(x)
35
+
36
+
37
+ def filter_atc(action_transmission_channels):
38
+ seen = []
39
+ out = []
40
+ for x in action_transmission_channels:
41
+ key = frozenset(x.items())
42
+ if key not in seen:
43
+ seen.append(key)
44
+ out.append(x)
45
+ return out
46
+
47
+
32
48
  def load_wiring(ms, json):
33
49
  ms["Blocks"] = {}
50
+ check_repeat(ms["Blocks"], ms["Boundary Actions"])
34
51
  ms["Blocks"].update(ms["Boundary Actions"])
52
+ check_repeat(ms["Blocks"], ms["Control Actions"])
35
53
  ms["Blocks"].update(ms["Control Actions"])
54
+ check_repeat(ms["Blocks"], ms["Policies"])
36
55
  ms["Blocks"].update(ms["Policies"])
56
+ check_repeat(ms["Blocks"], ms["Mechanisms"])
37
57
  ms["Blocks"].update(ms["Mechanisms"])
38
58
 
39
59
  ms["Wiring"] = {}
60
+ action_transmission_channels = []
40
61
  for w in json["Wiring"]:
41
62
  w = load_single_wiring(w, ms)
63
+ assert w.name not in ms["Blocks"], "{} was a repeated block".format(w.name)
42
64
  ms["Wiring"][w.name] = w
43
65
  ms["Blocks"][w.name] = w
66
+ if w.block_type == "Stack Block":
67
+ action_transmission_channels.extend(w.build_action_transmission_channels())
68
+ action_transmission_channels = filter_atc(action_transmission_channels)
69
+
70
+ return action_transmission_channels
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: math_spec_mapping
3
- Version: 0.1.4
3
+ Version: 0.1.5
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
@@ -1,35 +1,35 @@
1
1
  __init__.py,sha256=lsyvmC37lNTZbIK_b0O4WQpYt129kB0-fhj14UXje80,339
2
2
  Classes/ActionTransmissionChannel.py,sha256=zWMo5QsgPh5WGIWXl-xOrZNMXYJXmK6Vejw1dQvi0og,246
3
- Classes/Block.py,sha256=1ZXdOGqHlnBozOZgPhgIyV-yE4bKRIpBUOag5axDcas,5181
3
+ Classes/Block.py,sha256=kCvXCSPA7vWbzTQrnMN9HR4O5Dpn9D7FF101JrIg-X8,10474
4
4
  Classes/BoundaryAction.py,sha256=AOENCqCEfpjotnHhzUj_F2SOP0SGpkN1tNPr8Mtl6Tc,476
5
5
  Classes/ControlAction.py,sha256=xaU3_WVeWOoOFX3O86x30_9Eiirfe76KrO3M2kfjcmo,471
6
6
  Classes/Entity.py,sha256=wCckyg7880oenwj503Wi4_HbVRZab9zl13Q51Dc2OtA,1197
7
- Classes/MathSpec.py,sha256=n03srEYhuZWd9ZYqqMKxC-iQLPhHfj-jz_VdgnKE73U,9953
8
- Classes/Mechanism.py,sha256=BWFg5O9_li0Qy3IL4w2avPBjxsD_FLttDK5cJBJoyxI,276
7
+ Classes/MathSpec.py,sha256=haU6iR4ILfqOucWHEyYHCUK1XD_nFSRfpMUd5I9JCVI,9993
8
+ Classes/Mechanism.py,sha256=7jj6bcPI6H2iv1VZZTlpbG4G2k9s4MYkrH8Sfj9uGM4,324
9
9
  Classes/Parameter.py,sha256=ZWHgXP1MyxjFH943ZU3tWkhw6YGqcBY4xTmnQDJ1cJo,1052
10
10
  Classes/Policy.py,sha256=r0m9oCeAYun2ujoEH0BasuknFV4Rsvlu4Obq4TUO8zk,426
11
- Classes/Space.py,sha256=-8e__ZkCvksoUD3QDEysJQnQSdl6cv8jGIUmO096A0s,145
11
+ Classes/Space.py,sha256=jlPIGgRR1GmJScJMc-jpK1kLBV3lxW3GyqY4JVWdlLo,325
12
12
  Classes/State.py,sha256=2JsI63lG_4K-f6QXMqFFoiu_0oFF0rbNQp-0ivb3uGE,1369
13
13
  Classes/StateUpdateTransmissionChannel.py,sha256=3hBLvD1lE64PkwqksBXAfFWv7foOZzGQLAFQWy42tOA,257
14
14
  Classes/StatefulMetric.py,sha256=r0d7mEE4yPJNQ-aQybLAiywcXo-K9AiwPvq2ILgmT-Y,667
15
- Classes/__init__.py,sha256=ih6YYC4QdJGYa6CF0sapbitu-dILJYNqqM5xPsKxe5E,657
15
+ Classes/__init__.py,sha256=_BdQRhSAtm2Ks3cTdu36P4dtBdcFHfg7JuP3UvfUojA,687
16
16
  Convenience/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  Convenience/starter.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  Load/__init__.py,sha256=_ga5nHi7U5rY5lCF36_XI9Qmybq4P8R4m5I5mmjLBk8,33
19
- Load/action_transmission_channel.py,sha256=E_EPWJ44H5GKNDl0fwJhC9LksI7z6AAaV9dttjQcQD4,2511
19
+ Load/action_transmission_channel.py,sha256=9Wer7g2s5SSOcUYuZ0PqSKUVVnW3EvGQJZNXJTwW__0,2561
20
20
  Load/boundary_actions.py,sha256=SBc5wTA1dv1Hb6hipuPpUdMRjQdmwZAmZnPZKTcllto,1894
21
21
  Load/control_actions.py,sha256=0Jrfhxz7aP3sEI71JmS0FU4CzgFnJqcXW5HOntb3zK0,1307
22
22
  Load/entities.py,sha256=mz1zx1KQZjGPI6KvDnA0HbMRT3ijmeYGpvF8MH6R118,1104
23
- Load/general.py,sha256=hISy9IEbb6wnYsqmoDUlN07f2ZVT-D0-TPl9a1Xwmi0,3859
24
- Load/load.py,sha256=vRh7g7JZDCudUh28C8UK_54Qw4zU6aof1V45ewsoxCU,1540
23
+ Load/general.py,sha256=Q8JHNhVS0S2VHkO_pAA40hrv27Cq1s1tel4fxUw0g78,3815
24
+ Load/load.py,sha256=2Br4ISFOlzEs4PvOjWe9dM73zbF1W9Q4QLHWujMEadk,1595
25
25
  Load/mechanism.py,sha256=MLcT5siLsDsriougm7cQKNXioaFnmH6oJBFYZF6MX5A,1042
26
26
  Load/parameters.py,sha256=7QvNXvI2e5dEnW2KvwqtX_Pr-cnvz51WFa3aEbnqMLg,1060
27
27
  Load/policy.py,sha256=Wu4YYZ59QmkZuDatbim3N9pvsAiYeK4r79zqsWtCTPM,1769
28
- Load/spaces.py,sha256=H93XwDjaXHjQQXnJLQ49sZMo2GgONdOSKJ5TtA3u1MA,645
28
+ Load/spaces.py,sha256=HKjHQoqK7XHacWyVdn7_3fb84RPUYzD-m9jnbtiCt08,841
29
29
  Load/state_update_transmission_channels.py,sha256=l6KnF_4eQwmhvpcuBjEIveNqeZVBQK861SUiOBAWHqA,2216
30
30
  Load/stateful_metrics.py,sha256=85zRqK2AuOmxgH9b7Lgha2v44ei3RVClnZ0I17WZ_hg,1160
31
31
  Load/states.py,sha256=A_4rBPFAnkuXzzMlv5wnGB5wsFVA-0RghqNp7XCgK8E,966
32
- Load/wiring.py,sha256=-Vls7mazBQ7hhxw3xJ4ll15_Y3skE8QWElxT8h8SzIk,1158
32
+ Load/wiring.py,sha256=kz6wpxsZBOv_TMKGozK6OgXAYpb6HpaG0E8TKL3bwsY,2098
33
33
  Reports/__init__.py,sha256=we5Qb7FIG4iSdkejnTw1H5vj_EdiCx7zMD9K3Xti888,389
34
34
  Reports/boundary_actions.py,sha256=45BPp4QjWdD-3E9ZWwqgj_nI2-YdcI2ZZ19_Qv_K7Qk,1410
35
35
  Reports/control_actions.py,sha256=NksekZKIPFSIkubttFstKFthc5AU9B9PWRLSl9j1wWs,1216
@@ -42,8 +42,8 @@ Reports/policies.py,sha256=EuBzBsTM6QSS_GHFcAyhGgWvDDZwRuKe7Eos9nX13ho,1814
42
42
  Reports/spaces.py,sha256=hyy0TAM8vz986nexGtDKUrEksd9jPTZx47NQWiTfriY,583
43
43
  Reports/state.py,sha256=5jPrulJ2MIBto6qIWlapYG4c7YnOlYovV0_pYe2hCKg,932
44
44
  Reports/tables.py,sha256=O0CNuqh3LMECq5uLjBOoxMUk5hUvkUK660FNnwWUxDY,1505
45
- math_spec_mapping-0.1.4.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
46
- math_spec_mapping-0.1.4.dist-info/METADATA,sha256=6NYztrnSMy_CAJGwgInwpewMt6KwNbzYWoiVXNomQq8,2484
47
- math_spec_mapping-0.1.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
48
- math_spec_mapping-0.1.4.dist-info/top_level.txt,sha256=VPXI_45FlWgal53yjpbpWhksTVaFU3h8Soro9cmmcxc,42
49
- math_spec_mapping-0.1.4.dist-info/RECORD,,
45
+ math_spec_mapping-0.1.5.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
46
+ math_spec_mapping-0.1.5.dist-info/METADATA,sha256=A9Ktbppjt2hCZspo-OBXQmBWcFmQCvLupZhGLHOI_Z4,2484
47
+ math_spec_mapping-0.1.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
48
+ math_spec_mapping-0.1.5.dist-info/top_level.txt,sha256=VPXI_45FlWgal53yjpbpWhksTVaFU3h8Soro9cmmcxc,42
49
+ math_spec_mapping-0.1.5.dist-info/RECORD,,