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

Sign up to get free protection for your applications and to get access to all the features.
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,,