math-spec-mapping 0.1.7__tar.gz → 0.2.1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. {math_spec_mapping-0.1.7/src/math_spec_mapping.egg-info → math_spec_mapping-0.2.1}/PKG-INFO +1 -1
  2. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/pyproject.toml +1 -1
  3. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/Block.py +8 -1
  4. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/Entity.py +2 -2
  5. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/MathSpec.py +15 -0
  6. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/Parameter.py +2 -0
  7. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/Space.py +3 -2
  8. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/State.py +5 -6
  9. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/StatefulMetric.py +2 -0
  10. math_spec_mapping-0.2.1/src/Classes/Type.py +7 -0
  11. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/__init__.py +1 -0
  12. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/boundary_actions.py +7 -4
  13. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/control_actions.py +7 -4
  14. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/entities.py +7 -4
  15. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/general.py +22 -6
  16. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/load.py +8 -3
  17. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/mechanism.py +23 -3
  18. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/parameters.py +9 -3
  19. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/policy.py +8 -2
  20. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/spaces.py +10 -2
  21. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/state_update_transmission_channels.py +4 -2
  22. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/stateful_metrics.py +19 -4
  23. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/states.py +10 -4
  24. math_spec_mapping-0.2.1/src/Load/type.py +24 -0
  25. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/wiring.py +2 -0
  26. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/__init__.py +14 -0
  27. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/html.py +58 -23
  28. math_spec_mapping-0.2.1/src/Reports/markdown.py +547 -0
  29. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/spaces.py +1 -1
  30. math_spec_mapping-0.2.1/src/Reports/state.py +88 -0
  31. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/wiring.py +1 -1
  32. math_spec_mapping-0.2.1/src/__init__.py +28 -0
  33. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1/src/math_spec_mapping.egg-info}/PKG-INFO +1 -1
  34. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/math_spec_mapping.egg-info/SOURCES.txt +4 -0
  35. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/math_spec_mapping.egg-info/top_level.txt +1 -0
  36. math_spec_mapping-0.2.1/src/schema.py +8 -0
  37. math_spec_mapping-0.1.7/src/Reports/state.py +0 -45
  38. math_spec_mapping-0.1.7/src/__init__.py +0 -15
  39. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/LICENSE +0 -0
  40. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/README.md +0 -0
  41. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/setup.cfg +0 -0
  42. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/ActionTransmissionChannel.py +0 -0
  43. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/BoundaryAction.py +0 -0
  44. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/ControlAction.py +0 -0
  45. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/Mechanism.py +0 -0
  46. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/Policy.py +0 -0
  47. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Classes/StateUpdateTransmissionChannel.py +0 -0
  48. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Convenience/__init__.py +0 -0
  49. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Convenience/starter.py +0 -0
  50. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/__init__.py +0 -0
  51. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Load/action_transmission_channel.py +0 -0
  52. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/boundary_actions.py +0 -0
  53. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/control_actions.py +0 -0
  54. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/general.py +0 -0
  55. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/mechanisms.py +0 -0
  56. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/node_map.py +0 -0
  57. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/parameters.py +0 -0
  58. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/policies.py +0 -0
  59. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/Reports/tables.py +0 -0
  60. {math_spec_mapping-0.1.7 → math_spec_mapping-0.2.1}/src/math_spec_mapping.egg-info/dependency_links.txt +0 -0
  61. {math_spec_mapping-0.1.7 → 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.7
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
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
  [project]
5
5
  name = "math_spec_mapping"
6
- version = "0.1.7"
6
+ version = "0.2.1"
7
7
  authors = [
8
8
  { name="Sean McOwen", email="Sean@Block.Science" },
9
9
  ]
@@ -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
- self.called_by = []
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
@@ -120,6 +124,7 @@ class ParallelBlock(Block):
120
124
  self.called_by = []
121
125
  self.calls = []
122
126
  self.block_type = "Paralell Block"
127
+ self.metadata = data["metadata"]
123
128
 
124
129
  def render_mermaid(self, i):
125
130
  multi = None
@@ -235,6 +240,7 @@ class StackBlock(Block):
235
240
  self.calls = []
236
241
 
237
242
  self.block_type = "Stack Block"
243
+ self.metadata = data["metadata"]
238
244
 
239
245
  def _check_domain_mapping(self):
240
246
  x = self.components[:-1]
@@ -412,6 +418,7 @@ class SplitBlock(Block):
412
418
  self.calls = []
413
419
 
414
420
  self.block_type = "Split Block"
421
+ self.metadata = data["metadata"]
415
422
 
416
423
  def render_mermaid(self, i):
417
424
  multi = None
@@ -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()
@@ -327,3 +328,17 @@ class MathSpec:
327
328
  out["State"] = [x.state for x in out["Entities"]]
328
329
  out["State"] = list(set(out["State"]))
329
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
@@ -28,6 +28,7 @@ class ParameterSet:
28
28
  self.name = data["name"]
29
29
  self.notes = data["notes"]
30
30
  self.parameters = data["parameters"]
31
+ self.metadata = data["metadata"]
31
32
 
32
33
 
33
34
  # Individual Parameter
@@ -43,3 +44,4 @@ class Parameter:
43
44
  self.parameter_class = data[
44
45
  "parameter_class"
45
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 var.name not in self.variable_map, "Variable name {} is already present in variables!".format(
31
- key)
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"]
@@ -0,0 +1,7 @@
1
+ class Type:
2
+
3
+ def __init__(self, data):
4
+ self.name = data["name"]
5
+ self.type = data["type"]
6
+ self.notes = data["notes"]
7
+ 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")
@@ -56,9 +60,8 @@ def load_boundary_actions(ms: Dict, json: Dict) -> None:
56
60
  """
57
61
 
58
62
  ms["Boundary Actions"] = {}
59
- for key in json["Boundary Actions"]:
60
- ms["Boundary Actions"][key] = convert_boundary_action(
61
- json["Boundary Actions"][key], ms
62
- )
63
+ for ba in json["Boundary Actions"]:
64
+ key = ba["name"]
65
+ ms["Boundary Actions"][key] = convert_boundary_action(ba, ms)
63
66
  for entity in ms["Boundary Actions"][key].called_by:
64
67
  entity.add_boundary_action(ms["Boundary Actions"][key])
@@ -14,6 +14,11 @@ 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")
19
24
  assert type(data["codomain"]) == tuple, "{} codomain is not a tuple".format(
@@ -48,7 +53,5 @@ def load_control_actions(ms: Dict, json: Dict) -> None:
48
53
  """
49
54
 
50
55
  ms["Control Actions"] = {}
51
- for key in json["Control Actions"]:
52
- ms["Control Actions"][key] = convert_control_action(
53
- json["Control Actions"][key], ms
54
- )
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
- for key in json["Entities"]:
44
- ms["Entities"][key] = convert_entity(json["Entities"][key], ms)
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"
@@ -1,4 +1,6 @@
1
1
  from typing import Dict
2
+ from jsonschema import validate
3
+ from ..schema import schema
2
4
 
3
5
 
4
6
  def check_json_keys(json: Dict, check_set_key: str) -> None:
@@ -28,6 +30,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
28
30
  "Control Actions",
29
31
  "Wiring",
30
32
  "Blocks",
33
+ "Types",
31
34
  ],
32
35
  "JSON": [
33
36
  "Boundary Actions",
@@ -37,14 +40,14 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
37
40
  "Policies",
38
41
  "Spaces",
39
42
  "State",
40
- "State Update Transmission Channels",
41
43
  "Stateful Metrics",
42
44
  "Control Actions",
43
45
  "Wiring",
46
+ "Types",
44
47
  ],
45
- "State": ["name", "label", "notes", "variables"],
48
+ "State": ["name", "label", "notes", "variables", "metadata"],
46
49
  "State Variable": ["type", "name", "description", "symbol", "domain"],
47
- "Entity": ["name", "notes", "state"],
50
+ "Entity": ["name", "notes", "state", "metadata"],
48
51
  "Boundary Action": [
49
52
  "name",
50
53
  "label",
@@ -54,6 +57,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
54
57
  "called_by",
55
58
  "codomain",
56
59
  "parameters_used",
60
+ "metadata",
57
61
  ],
58
62
  "Action Transmission Channel": ["origin", "target", "space", "optional"],
59
63
  "Mechanism": [
@@ -64,6 +68,8 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
64
68
  "logic",
65
69
  "domain",
66
70
  "parameters_used",
71
+ "metadata",
72
+ "updates",
67
73
  ],
68
74
  "State Update Transmission Channel": [
69
75
  "origin",
@@ -80,9 +86,10 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
80
86
  "domain",
81
87
  "codomain",
82
88
  "parameters_used",
89
+ "metadata",
83
90
  ],
84
91
  "Policy Option": ["name", "description", "logic"],
85
- "Stateful Metric Set": ["name", "label", "notes", "metrics"],
92
+ "Stateful Metric Set": ["name", "label", "notes", "metrics", "metadata"],
86
93
  "Stateful Metric": [
87
94
  "type",
88
95
  "name",
@@ -92,6 +99,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
92
99
  "parameters_used",
93
100
  "symbol",
94
101
  "domain",
102
+ "metadata",
95
103
  ],
96
104
  "Control Action": [
97
105
  "name",
@@ -101,10 +109,11 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
101
109
  "control_action_options",
102
110
  "codomain",
103
111
  "parameters_used",
112
+ "metadata",
104
113
  ],
105
114
  "Control Action Option": ["name", "description", "logic"],
106
115
  "Boundary Action Option": ["name", "description", "logic"],
107
- "Parameter Set": ["name", "notes", "parameters"],
116
+ "Parameter Set": ["name", "notes", "parameters", "metadata"],
108
117
  "Parameter": [
109
118
  "variable_type",
110
119
  "name",
@@ -112,8 +121,9 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
112
121
  "symbol",
113
122
  "domain",
114
123
  "parameter_class",
124
+ "metadata",
115
125
  ],
116
- "Space": ["name", "schema"],
126
+ "Space": ["name", "schema", "metadata"],
117
127
  "Block": [
118
128
  "name",
119
129
  "components",
@@ -122,7 +132,9 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
122
132
  "mermaid_show_name",
123
133
  "loop",
124
134
  "optional_indices",
135
+ "metadata",
125
136
  ],
137
+ "Type": ["name", "notes", "metadata", "type"],
126
138
  }
127
139
 
128
140
  check_set = check_sets[check_set_key]
@@ -139,3 +151,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
139
151
 
140
152
  # Make sure there are no extra keys in the json
141
153
  assert len(keys) == 0, "There are extra keys in json: {}".format(", ".join(keys))
154
+
155
+
156
+ def validate_json_schema(json):
157
+ validate(json, schema)
@@ -1,6 +1,6 @@
1
1
  from typing import Dict
2
2
  from ..Classes import MathSpec
3
- from .general import check_json_keys
3
+ from .general import check_json_keys, validate_json_schema
4
4
  from .states import load_states
5
5
  from .entities import load_entities
6
6
  from .boundary_actions import load_boundary_actions
@@ -13,6 +13,7 @@ from .policy import load_policies
13
13
  from .spaces import load_spaces
14
14
  from .stateful_metrics import load_stateful_metrics
15
15
  from .wiring import load_wiring
16
+ from .type import load_types
16
17
 
17
18
 
18
19
  def load_from_json(json: Dict) -> MathSpec:
@@ -28,21 +29,25 @@ def load_from_json(json: Dict) -> MathSpec:
28
29
  # Assert the keys are correct in the json
29
30
  check_json_keys(json, "JSON")
30
31
 
32
+ # Validate against the JSON schema
33
+ validate_json_schema(json)
34
+
31
35
  ms = {}
32
36
 
33
37
  # Do loading one by one to transfer the json
38
+ load_types(ms, json)
34
39
  load_spaces(ms, json)
35
40
  load_states(ms, json)
36
41
  load_entities(ms, json)
37
42
  load_boundary_actions(ms, json)
38
43
  load_control_actions(ms, json)
39
- load_mechanisms(ms, json)
44
+ state_update_transmission_channels = load_mechanisms(ms, json)
40
45
  load_parameters(ms, json)
41
46
  load_policies(ms, json)
42
47
  load_stateful_metrics(ms, json)
43
48
  action_transmission_channels = load_wiring(ms, json)
44
49
  load_action_transmission_channels(ms, action_transmission_channels)
45
- load_state_update_transmission_channels(ms, json)
50
+ load_state_update_transmission_channels(ms, state_update_transmission_channels)
46
51
 
47
52
  # Assert all keys are correct for the ms version
48
53
  check_json_keys(ms, "Math Spec")
@@ -13,6 +13,11 @@ def convert_mechanism(data: Dict, ms: Dict) -> Mechanism:
13
13
  Mechanism: Mechanism object
14
14
  """
15
15
 
16
+ if "metadata" not in data:
17
+ data["metadata"] = {}
18
+
19
+ data["domain"] = tuple(data["domain"])
20
+
16
21
  # Check the keys are correct
17
22
  check_json_keys(data, "Mechanism")
18
23
  assert type(data["domain"]) == tuple, "{} domain is not a tuple".format(
@@ -24,10 +29,22 @@ def convert_mechanism(data: Dict, ms: Dict) -> Mechanism:
24
29
  # Copy
25
30
  data = data.copy()
26
31
 
32
+ new_channels = []
33
+ updates = data.pop("updates")
34
+ for x in updates:
35
+ new_channels.append(
36
+ {
37
+ "origin": data["name"],
38
+ "entity": x[0],
39
+ "variable": x[1],
40
+ "optional": x[2],
41
+ }
42
+ )
43
+
27
44
  data["domain"] = tuple(ms["Spaces"][x] for x in data["domain"])
28
45
 
29
46
  # Build the action transmission channel object
30
- return Mechanism(data)
47
+ return Mechanism(data), new_channels
31
48
 
32
49
 
33
50
  def load_mechanisms(ms: Dict, json: Dict) -> None:
@@ -39,5 +56,8 @@ def load_mechanisms(ms: Dict, json: Dict) -> None:
39
56
  """
40
57
 
41
58
  ms["Mechanisms"] = {}
42
- for key in json["Mechanisms"]:
43
- ms["Mechanisms"][key] = convert_mechanism(json["Mechanisms"][key], ms)
59
+ state_update_transmission_channels = []
60
+ for m in json["Mechanisms"]:
61
+ ms["Mechanisms"][m["name"]], new_channels = convert_mechanism(m, ms)
62
+ state_update_transmission_channels.extend(new_channels)
63
+ return state_update_transmission_channels
@@ -3,7 +3,9 @@ from ..Classes import ParameterContainer, ParameterSet, Parameter
3
3
  from .general import check_json_keys
4
4
 
5
5
 
6
- def convert_parameter_set(data: Dict) -> ParameterSet:
6
+ def convert_parameter_set(ms, data: Dict) -> ParameterSet:
7
+ if "metadata" not in data:
8
+ data["metadata"] = {}
7
9
  # Check the keys are correct
8
10
  check_json_keys(data, "Parameter Set")
9
11
 
@@ -13,7 +15,11 @@ def convert_parameter_set(data: Dict) -> ParameterSet:
13
15
  # Convert the parameters
14
16
  new_parameters = []
15
17
  for param in data["parameters"]:
18
+ if "metadata" not in param:
19
+ param["metadata"] = {}
16
20
  check_json_keys(param, "Parameter")
21
+ assert param["variable_type"] in ms["Types"], "Type not in ms"
22
+ param["variable_type"] = ms["Types"][param["variable_type"]]
17
23
  new_parameters.append(Parameter(param))
18
24
  data["parameters"] = new_parameters
19
25
 
@@ -32,8 +38,8 @@ def load_parameters(ms: Dict, json: Dict) -> None:
32
38
  ms["Parameters"] = {}
33
39
 
34
40
  # Convert parameter sets
35
- for key in json["Parameters"]:
36
- ms["Parameters"][key] = convert_parameter_set(json["Parameters"][key])
41
+ for param in json["Parameters"]:
42
+ ms["Parameters"][param["name"]] = convert_parameter_set(ms, param)
37
43
 
38
44
  # Placeholder for now
39
45
  ms["Parameters"] = ParameterContainer(ms["Parameters"])
@@ -35,8 +35,14 @@ def convert_policy(data: Dict, ms: Dict) -> Policy:
35
35
  Policy: Policy object
36
36
  """
37
37
 
38
+ if "metadata" not in data:
39
+ data["metadata"] = {}
38
40
  # Check the keys are correct
39
41
  check_json_keys(data, "Policy")
42
+
43
+ data["codomain"] = tuple(data["codomain"])
44
+ data["domain"] = tuple(data["domain"])
45
+
40
46
  assert type(data["codomain"]) == tuple, "{} codomain is not a tuple".format(
41
47
  data["name"]
42
48
  )
@@ -75,5 +81,5 @@ def load_policies(ms: Dict, json: Dict) -> None:
75
81
  """
76
82
 
77
83
  ms["Policies"] = {}
78
- for key in json["Policies"]:
79
- ms["Policies"][key] = convert_policy(json["Policies"][key], ms)
84
+ for policy in json["Policies"]:
85
+ ms["Policies"][policy["name"]] = convert_policy(policy, ms)
@@ -3,13 +3,21 @@ from ..Classes import Space, TerminatingSpace, EmptySpace
3
3
  from .general import check_json_keys
4
4
 
5
5
 
6
- def convert_space(data: Dict) -> Space:
6
+ def convert_space(ms, data: Dict) -> Space:
7
+ if "metadata" not in data:
8
+ data["metadata"] = {}
7
9
  # Check the keys are correct
8
10
  check_json_keys(data, "Space")
9
11
 
10
12
  # Copy
11
13
  data = data.copy()
12
14
 
15
+ for x in data["schema"]:
16
+ assert data["schema"][x] in ms["Types"], "Type {} not in ms".format(
17
+ data["schema"][x]
18
+ )
19
+ data["schema"][x] = ms["Types"][data["schema"][x]]
20
+
13
21
  # Build the space object
14
22
  return Space(data)
15
23
 
@@ -29,4 +37,4 @@ def load_spaces(ms: Dict, json: Dict) -> None:
29
37
 
30
38
  for space in json["Spaces"]:
31
39
  assert space["name"] not in ms["Spaces"], "{} repeated"
32
- ms["Spaces"][space["name"]] = convert_space(space)
40
+ ms["Spaces"][space["name"]] = convert_space(ms, space)
@@ -51,7 +51,9 @@ def convert_state_update_transmission_channel(
51
51
  return StateUpdateTransmissionChannel(data)
52
52
 
53
53
 
54
- def load_state_update_transmission_channels(ms: Dict, json: Dict) -> None:
54
+ def load_state_update_transmission_channels(
55
+ ms: Dict, state_update_transmission_channels
56
+ ) -> None:
55
57
  """Function to load state update transmission channels into the new dictionary
56
58
 
57
59
  Args:
@@ -60,7 +62,7 @@ def load_state_update_transmission_channels(ms: Dict, json: Dict) -> None:
60
62
  """
61
63
 
62
64
  ms["State Update Transmission Channels"] = []
63
- for sutc in json["State Update Transmission Channels"]:
65
+ for sutc in state_update_transmission_channels:
64
66
  ms["State Update Transmission Channels"].append(
65
67
  convert_state_update_transmission_channel(sutc, ms)
66
68
  )
@@ -3,7 +3,7 @@ from ..Classes import StatefulMetric, StatefulMetricSet
3
3
  from .general import check_json_keys
4
4
 
5
5
 
6
- def convert_stateful_metric(data: Dict) -> StatefulMetricSet:
6
+ def convert_stateful_metric(ms, data: Dict) -> StatefulMetricSet:
7
7
  """Function to convert stateful metric
8
8
 
9
9
  Args:
@@ -12,6 +12,8 @@ def convert_stateful_metric(data: Dict) -> StatefulMetricSet:
12
12
  Returns:
13
13
  StatefulMetricSet: A stateful metric set
14
14
  """
15
+ if "metadata" not in data:
16
+ data["metadata"] = {}
15
17
 
16
18
  # Check the keys are correct
17
19
  check_json_keys(data, "Stateful Metric Set")
@@ -22,7 +24,21 @@ def convert_stateful_metric(data: Dict) -> StatefulMetricSet:
22
24
  # Convert the variables
23
25
  new_variables = []
24
26
  for var in data["metrics"]:
27
+ if "metadata" not in var:
28
+ var["metadata"] = {}
25
29
  check_json_keys(var, "Stateful Metric")
30
+ for x in var["variables_used"]:
31
+ assert type(x) == tuple, "Variables used is not tuple"
32
+ assert len(x) == 2, "Length of variables used is not 2"
33
+ assert (
34
+ x[0] in ms["State"]
35
+ ), "State '{}' from variables used not in states".format(x[0])
36
+ vm = ms["State"][x[0]].variable_map
37
+ assert (
38
+ x[1] in vm
39
+ ), "Variable '{}' not in variable map for stateful metrics variables used".format(
40
+ x[1]
41
+ )
26
42
  new_variables.append(StatefulMetric(var))
27
43
  data["metrics"] = new_variables
28
44
 
@@ -39,6 +55,5 @@ def load_stateful_metrics(ms: Dict, json: Dict) -> None:
39
55
  """
40
56
 
41
57
  ms["Stateful Metrics"] = {}
42
- for key in json["Stateful Metrics"]:
43
- ms["Stateful Metrics"][key] = convert_stateful_metric(
44
- json["Stateful Metrics"][key])
58
+ for sm in json["Stateful Metrics"]:
59
+ ms["Stateful Metrics"][sm["name"]] = convert_stateful_metric(ms, sm)