math-spec-mapping 0.2.2__py3-none-any.whl → 0.2.4__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
@@ -21,6 +21,7 @@ class Block:
21
21
  self.called_by = []
22
22
  self.calls = []
23
23
  self.block_type = "Block"
24
+ self.all_updates = []
24
25
  # Will be overwritten in composite blocks to represent individual components
25
26
  self.domain_blocks = tuple(
26
27
  [
@@ -61,16 +62,85 @@ class Block:
61
62
  for _ in range(len([x for x in self.codomain if x == TerminatingSpace]))
62
63
  )
63
64
 
65
+ self.find_all_spaces_used(data)
66
+
64
67
  def render_mermaid(self, i):
65
68
  i += 1
66
- return "X{}[{}]".format(i, self.name), i
69
+ out = 'X{}["{}"]'.format(i, self.name)
70
+ if self.block_type == "Mechanism":
71
+ for u in self.updates:
72
+ out += "\n"
73
+ out += "X{} --> {}".format(
74
+ i,
75
+ (u[0].name + "-" + u[1].name).replace(" ", "-"),
76
+ )
77
+ return out, i
78
+
79
+ def render_ending_entities(self):
80
+ if self.block_type == "Mechanism":
81
+ updates = self.updates
82
+ elif self.block_type in ["Parallel Block", "Stack Block", "Split Block"]:
83
+ updates = self.all_updates
84
+ else:
85
+ return "\n", {}
86
+
87
+ out = "\n"
88
+ out += 'subgraph SVS["State Variables"]\n'
89
+
90
+ # Render the entities
91
+ entity_mapping = {}
92
+ entities = set([x[0] for x in updates])
93
+ for i, x in enumerate(entities):
94
+ entity_mapping[x.name] = "EE{}".format(i)
95
+ out += '{}[("{}")]'.format(entity_mapping[x.name], x.name)
96
+ out += "\n"
97
+
98
+ entity_variable_mapping = {}
99
+ # Render the state variables
100
+ for i, x in enumerate(updates):
101
+ entity_variable_mapping[(x[0].name + "-" + x[1].name).replace(" ", "-")] = (
102
+ "EES{}".format(i)
103
+ )
104
+ out += '{}(["{}"])'.format("EES{}".format(i), x[1].name)
105
+ out += "\n"
106
+
107
+ out += "{} --- {}".format("EES{}".format(i), entity_mapping[x[0].name])
108
+ out += "\n"
109
+ out += "end\n"
110
+ out += "\n"
111
+ return out, entity_variable_mapping
67
112
 
68
113
  def render_mermaid_root(self):
69
114
  out = """```mermaid\ngraph TB\n"""
115
+ add, entity_variable_mapping = self.render_ending_entities()
116
+ out += add
70
117
  out += self.render_mermaid(0)[0]
118
+
119
+ for key in entity_variable_mapping:
120
+ out = out.replace(key, entity_variable_mapping[key])
71
121
  out += "\n```"
122
+
72
123
  return out
73
124
 
125
+ def find_all_spaces_used(self, data):
126
+ self.all_spaces_used = []
127
+ self.all_spaces_used.extend(self.domain)
128
+ self.all_spaces_used.extend(self.codomain)
129
+ if "components" in data:
130
+ for x in data["components"]:
131
+ self.all_spaces_used.extend(x.all_spaces_used)
132
+ self.all_spaces_used = list(set(self.all_spaces_used))
133
+
134
+ def find_all_updates(self, data):
135
+ self.all_updates = []
136
+ if "components" in data:
137
+ for x in data["components"]:
138
+ if x.block_type == "Mechanism":
139
+ self.all_updates.extend(x.updates)
140
+ else:
141
+ self.all_updates.extend(x.all_updates)
142
+ self.all_updates = list(set(self.all_updates))
143
+
74
144
 
75
145
  class ParallelBlock(Block):
76
146
  def __init__(self, data: Dict):
@@ -123,8 +193,9 @@ class ParallelBlock(Block):
123
193
 
124
194
  self.called_by = []
125
195
  self.calls = []
126
- self.block_type = "Paralell Block"
196
+ self.block_type = "Parallel Block"
127
197
  self.metadata = data["metadata"]
198
+ self.find_all_spaces_used(data)
128
199
 
129
200
  def render_mermaid(self, i):
130
201
  multi = None
@@ -139,6 +210,7 @@ class ParallelBlock(Block):
139
210
  # Render components
140
211
  domain_map = {}
141
212
  codomain_map = {}
213
+
142
214
  for component in self.components:
143
215
  domain = component.domain
144
216
  codomain = component.codomain
@@ -182,22 +254,27 @@ class ParallelBlock(Block):
182
254
  for ix1 in nodes:
183
255
  d = domain_map[ix1]
184
256
  if len(d) > 0:
257
+ d_length = len(d)
185
258
  d = "\n".join(d)
186
259
  d = '"{}"'.format(d)
187
- out += "X{} --{}--> X{}".format(domain_i, d, ix1)
260
+ out += "X{} --{}{}-> X{}".format(domain_i, d, "-" * d_length, ix1)
188
261
  else:
189
262
  out += "X{} --> X{}".format(domain_i, ix1)
190
263
  out += "\n"
191
264
 
265
+ codomain_connections = 0
192
266
  for ix1 in nodes:
193
267
  d = codomain_map[ix1]
194
268
  if len(d) > 0:
195
269
  d = "\n".join(d)
196
270
  d = '"{}"'.format(d)
197
271
  out += "X{} --{}--> X{}".format(ix1, d, codomain_i)
198
- else:
199
- out += "X{} --> X{}".format(ix1, codomain_i)
200
- out += "\n"
272
+ codomain_connections += 1
273
+ out += "\n"
274
+ # else:
275
+ # out += "X{} --> X{}".format(ix1, codomain_i)
276
+ if codomain_connections == 0:
277
+ out = out.replace("X{}[Codomain]".format(codomain_i), "")
201
278
 
202
279
  # Subgraph it
203
280
  if self.mermaid_show_name:
@@ -205,7 +282,7 @@ class ParallelBlock(Block):
205
282
  else:
206
283
  name = " "
207
284
  i += 1
208
- out = "subgraph X{}[{}]\ndirection TB\n".format(i, name) + out
285
+ out = 'subgraph X{}["{}"]\ndirection TB\n'.format(i, name) + out
209
286
 
210
287
  out += "end"
211
288
 
@@ -241,6 +318,7 @@ class StackBlock(Block):
241
318
 
242
319
  self.block_type = "Stack Block"
243
320
  self.metadata = data["metadata"]
321
+ self.find_all_spaces_used(data)
244
322
 
245
323
  def _check_domain_mapping(self):
246
324
  x = self.components[:-1]
@@ -340,12 +418,13 @@ class StackBlock(Block):
340
418
  d = domain_map[ix4]
341
419
  optional = global_optional
342
420
  if len(d) > 0:
421
+ d_length = len(d)
343
422
  d = "\n".join(d)
344
423
  d = '"{}"'.format(d)
345
424
  if optional:
346
- out += "X{}-.{}.->X{}".format(ix3, d, ix4)
425
+ out += "X{}-.{}.{}->X{}".format(ix3, d, "." * d_length, ix4)
347
426
  else:
348
- out += "X{}--{}-->X{}".format(ix3, d, ix4)
427
+ out += "X{}--{}-{}->X{}".format(ix3, d, "-" * d_length, ix4)
349
428
  else:
350
429
  if optional:
351
430
  out += "X{}-.->X{}".format(ix3, ix4)
@@ -359,7 +438,7 @@ class StackBlock(Block):
359
438
  else:
360
439
  name = " "
361
440
  i += 1
362
- out = "subgraph X{}[{}]\ndirection TB\n".format(i, name) + out
441
+ out = 'subgraph X{}["{}"]\ndirection TB\n'.format(i, name) + out
363
442
  out += "end"
364
443
 
365
444
  return out, i
@@ -419,6 +498,7 @@ class SplitBlock(Block):
419
498
 
420
499
  self.block_type = "Split Block"
421
500
  self.metadata = data["metadata"]
501
+ self.find_all_spaces_used(data)
422
502
 
423
503
  def render_mermaid(self, i):
424
504
  multi = None
Classes/MathSpec.py CHANGED
@@ -11,6 +11,7 @@ class MathSpec:
11
11
  # Internal variables to keep track
12
12
  self._ms_dict = ms_dict
13
13
  self._json = json
14
+ self.type_keys = ms_dict["Type Keys"]
14
15
  self.action_transmission_channels = ms_dict["Action Transmission Channels"]
15
16
  self.boundary_actions = ms_dict["Boundary Actions"]
16
17
  self.control_actions = ms_dict["Control Actions"]
@@ -28,6 +29,11 @@ class MathSpec:
28
29
  self.blocks = ms_dict["Blocks"]
29
30
  self.types = ms_dict["Types"]
30
31
  self.metrics = ms_dict["Metrics"]
32
+ self.displays = ms_dict["Displays"]
33
+ self.stateful_metrics_map = {}
34
+ for x in self.stateful_metrics:
35
+ for y in self.stateful_metrics[x].metrics:
36
+ self.stateful_metrics_map[y.name] = y
31
37
 
32
38
  self._check_parameters()
33
39
  self._crawl_parameters()
Classes/Policy.py CHANGED
@@ -14,3 +14,4 @@ class Policy(Block):
14
14
  super().__init__(data)
15
15
  self.policy_options: List[PolicyOption] = data["policy_options"]
16
16
  self.block_type = "Policy"
17
+ self.metrics_used = data["metrics_used"]
Classes/Type.py CHANGED
@@ -3,5 +3,6 @@ class Type:
3
3
  def __init__(self, data):
4
4
  self.name = data["name"]
5
5
  self.type = data["type"]
6
+ self.type_name = data["type_name"]
6
7
  self.notes = data["notes"]
7
8
  self.metadata = data["metadata"]
Load/displays.py ADDED
@@ -0,0 +1,13 @@
1
+ def load_displays(ms, json) -> None:
2
+ ms["Displays"] = {}
3
+ load_wiring(ms, json)
4
+
5
+
6
+ def load_wiring(ms, json):
7
+ ms["Displays"]["Wiring"] = []
8
+ for display in json["Displays"]["wiring"]:
9
+ for component in display["components"]:
10
+ assert component in ms["Blocks"], "{} is not a valid block".format(
11
+ component
12
+ )
13
+ ms["Displays"]["Wiring"].append(display)
Load/general.py CHANGED
@@ -4,6 +4,7 @@ from ..schema import schema
4
4
 
5
5
 
6
6
  def check_json_keys(json: Dict, check_set_key: str) -> None:
7
+ pass
7
8
  """Function to check the correct keys are in the json dictionary
8
9
 
9
10
  Args:
@@ -11,7 +12,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
11
12
  check_set_key (str): The key for what checking set to use
12
13
  """
13
14
 
14
- # Get a temporary list of keys
15
+ """# Get a temporary list of keys
15
16
  keys = list(json.keys())
16
17
 
17
18
  # Pick the correct checking set
@@ -46,6 +47,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
46
47
  "Wiring",
47
48
  "Types",
48
49
  "Metrics",
50
+ "Displays",
49
51
  ],
50
52
  "State": ["name", "label", "notes", "variables", "metadata"],
51
53
  "State Variable": ["type", "name", "description", "symbol", "domain"],
@@ -152,7 +154,7 @@ def check_json_keys(json: Dict, check_set_key: str) -> None:
152
154
  keys.remove(k)
153
155
 
154
156
  # Make sure there are no extra keys in the json
155
- assert len(keys) == 0, "There are extra keys in json: {}".format(", ".join(keys))
157
+ assert len(keys) == 0, "There are extra keys in json: {}".format(", ".join(keys))"""
156
158
 
157
159
 
158
160
  def validate_json_schema(json):
Load/load.py CHANGED
@@ -13,8 +13,9 @@ 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
+ from .type import load_types, load_type_keys
17
17
  from .metrics import load_metrics
18
+ from .displays import load_displays
18
19
 
19
20
 
20
21
  def load_from_json(json: Dict) -> MathSpec:
@@ -36,6 +37,8 @@ def load_from_json(json: Dict) -> MathSpec:
36
37
  ms = {}
37
38
 
38
39
  # Do loading one by one to transfer the json
40
+
41
+ load_type_keys(ms)
39
42
  load_types(ms, json)
40
43
  load_spaces(ms, json)
41
44
  load_states(ms, json)
@@ -46,10 +49,28 @@ def load_from_json(json: Dict) -> MathSpec:
46
49
  load_parameters(ms, json)
47
50
  load_policies(ms, json)
48
51
  load_stateful_metrics(ms, json)
52
+
53
+ stateful_metrics_map = {}
54
+ for x in ms["Stateful Metrics"]:
55
+ for y in ms["Stateful Metrics"][x].metrics:
56
+ stateful_metrics_map[y.name] = y
57
+
49
58
  action_transmission_channels = load_wiring(ms, json)
50
59
  load_action_transmission_channels(ms, action_transmission_channels)
51
60
  load_state_update_transmission_channels(ms, state_update_transmission_channels)
52
- load_metrics(ms, json)
61
+
62
+ temp = {}
63
+ for w in json["Wiring"]:
64
+ temp[w["name"]] = w
65
+ for w in ms["Wiring"]:
66
+ w = temp[w]
67
+ ms["Wiring"][w["name"]].find_all_updates(w)
68
+
69
+ load_metrics(ms, json, stateful_metrics_map)
70
+ if "Displays" in json:
71
+ load_displays(ms, json)
72
+ else:
73
+ ms["Displays"] = None
53
74
 
54
75
  # Assert all keys are correct for the ms version
55
76
  check_json_keys(ms, "Math Spec")
Load/metrics.py CHANGED
@@ -3,7 +3,7 @@ from ..Classes import Metric
3
3
  from .general import check_json_keys
4
4
 
5
5
 
6
- def convert_metric(ms, data: Dict) -> Metric:
6
+ def convert_metric(ms, data: Dict, stateful_metrics_map) -> Metric:
7
7
  """Function to convert metric
8
8
 
9
9
  Args:
@@ -33,7 +33,7 @@ def convert_metric(ms, data: Dict) -> Metric:
33
33
  x[1]
34
34
  )
35
35
  for x in data["parameters_used"]:
36
- assert x in ms["Parameters"].all_parameters
36
+ assert x in ms["Parameters"].all_parameters, "{} not in parameters".format(x)
37
37
 
38
38
  data["domain"] = tuple(data["domain"])
39
39
  for x in data["domain"]:
@@ -41,15 +41,20 @@ def convert_metric(ms, data: Dict) -> Metric:
41
41
  data["domain"] = tuple(ms["Spaces"][x] for x in data["domain"])
42
42
 
43
43
  for x in data["metrics_used"]:
44
- assert x in ms["Metrics"], "{} not a valid metric".format(x)
44
+ assert (
45
+ x in ms["Metrics"] or x in stateful_metrics_map
46
+ ), "{} not a valid metric".format(x)
45
47
 
46
- data["metrics_used"] = tuple(ms["Metrics"][x] for x in data["metrics_used"])
48
+ data["metrics_used"] = tuple(
49
+ ms["Metrics"][x] if x in ms["Metrics"] else stateful_metrics_map[x]
50
+ for x in data["metrics_used"]
51
+ )
47
52
 
48
53
  # Build the metric object
49
54
  return Metric(data)
50
55
 
51
56
 
52
- def load_metrics(ms: Dict, json: Dict) -> None:
57
+ def load_metrics(ms: Dict, json: Dict, stateful_metrics_map) -> None:
53
58
  """Function to load metrics into the new dictionary
54
59
 
55
60
  Args:
@@ -65,9 +70,14 @@ def load_metrics(ms: Dict, json: Dict) -> None:
65
70
  i = 0
66
71
  hold = []
67
72
  for metric in metrics:
68
- if all([x in ms["Metrics"] for x in metric["metrics_used"]]):
73
+ if all(
74
+ [
75
+ x in ms["Metrics"] or x in stateful_metrics_map
76
+ for x in metric["metrics_used"]
77
+ ]
78
+ ):
69
79
  i += 1
70
- metric = convert_metric(ms, metric)
80
+ metric = convert_metric(ms, metric, stateful_metrics_map)
71
81
  assert (
72
82
  metric.name not in ms["Metrics"]
73
83
  ), "{} was a repeated metric".format(metric.name)
@@ -80,6 +90,15 @@ def load_metrics(ms: Dict, json: Dict) -> None:
80
90
  for y in metrics:
81
91
  for z in y["metrics_used"]:
82
92
  assert (
83
- z in ms["Metrics"] or z in names
93
+ z in ms["Metrics"] or z in names or z in stateful_metrics_map
84
94
  ), "{} is not defined in the spec".format(z)
85
95
  assert len(metrics) == 0, "There are circular references"
96
+
97
+ # Load the metrics into the policies
98
+ for key in ms["Policies"]:
99
+ policy = ms["Policies"][key]
100
+ hold = policy.metrics_used[:]
101
+ policy.metrics_used = []
102
+ for x in hold:
103
+ assert x in ms["Metrics"], "{} not a valid metric".format(x)
104
+ policy.metrics_used.append(ms["Metrics"][x])
Load/type.py CHANGED
@@ -1,5 +1,7 @@
1
1
  from .general import check_json_keys
2
2
  from ..Classes import Type
3
+ import os
4
+ from typing import _UnionGenericAlias
3
5
 
4
6
 
5
7
  def convert_type(data, ms):
@@ -13,6 +15,32 @@ def convert_type(data, ms):
13
15
  # Copy
14
16
  data = data.copy()
15
17
 
18
+ type_name = data["type"]
19
+ data["type"] = {}
20
+ data["type_name"] = {}
21
+
22
+ if "python" in ms["Type Keys"]:
23
+
24
+ if type_name in ms["Type Keys"]["python"]:
25
+ data["type"]["python"] = ms["Type Keys"]["python"][type_name]
26
+ if type(data["type"]["python"]) == dict:
27
+ out = {}
28
+ for key in data["type"]["python"]:
29
+ val = data["type"]["python"][key]
30
+ if type(val) == str:
31
+ val = ms["Types"][val].name
32
+ else:
33
+ val = val.__name__
34
+ out[key] = val
35
+ data["type_name"]["python"] = str(out)
36
+ elif type(data["type"]["python"]) == _UnionGenericAlias:
37
+ data["type_name"]["python"] = data["type"]["python"].__repr__()
38
+ else:
39
+ data["type_name"]["python"] = data["type"]["python"].__name__
40
+ if type_name in ms["Type Keys"]["typescript"]:
41
+ data["type"]["typescript"] = ms["Type Keys"]["typescript"][type_name]
42
+ data["type_name"]["typescript"] = ms["Type Keys"]["typescript"][type_name]
43
+
16
44
  # Build the type object
17
45
  return Type(data)
18
46
 
@@ -22,3 +50,51 @@ def load_types(ms, json) -> None:
22
50
  ms["Types"] = {}
23
51
  for data in json["Types"]:
24
52
  ms["Types"][data["name"]] = convert_type(data, ms)
53
+
54
+
55
+ def load_python_type_key():
56
+ from src.TypeMappings.types import mapping
57
+
58
+ return mapping
59
+
60
+
61
+ def load_typescript_type_key(path):
62
+ with open(path, "r") as file:
63
+ type_definitions = file.read()
64
+ type_definitions = type_definitions.split("\n")
65
+ type_definitions = [x for x in type_definitions if len(x) > 0]
66
+ hold = type_definitions[:]
67
+ type_definitions = []
68
+ type_definitions.append(hold.pop(0))
69
+ while len(hold) > 0:
70
+ curr = hold.pop(0)
71
+ if "type" in curr or "interface" in curr:
72
+ type_definitions.append(curr)
73
+ else:
74
+ type_definitions[-1] += "\n" + curr
75
+
76
+ hold = type_definitions[:]
77
+ type_definitions = {}
78
+ for x in hold:
79
+ name = x
80
+ if x.startswith("type"):
81
+ name = name[5:]
82
+ elif x.startswith("interface"):
83
+ name = name[10:]
84
+ else:
85
+ assert False
86
+ name = name[: name.index("=")].strip()
87
+ type_definitions[name] = x
88
+ return type_definitions
89
+
90
+
91
+ def load_type_keys(ms) -> dict:
92
+ type_keys = {}
93
+ python_path = "src/TypeMappings/types.py"
94
+ typescript_path = "src/TypeMappings/types.ts"
95
+ if os.path.exists(python_path):
96
+ type_keys["python"] = load_python_type_key()
97
+ if os.path.exists(typescript_path):
98
+ type_keys["typescript"] = load_typescript_type_key(typescript_path)
99
+
100
+ ms["Type Keys"] = type_keys
Reports/html.py CHANGED
@@ -111,7 +111,9 @@ def write_entity_reports(ms: MathSpec, directory: str, entities: List[str]) -> N
111
111
  f.write(out)
112
112
 
113
113
 
114
- def write_spec_tree(ms: MathSpec, path=None, linking=False, add_tabbing=False) -> str:
114
+ def write_spec_tree(
115
+ ms: MathSpec, path=None, linking=False, add_tabbing=False, readme=False
116
+ ) -> str:
115
117
  """Write the tree of the specification structure
116
118
 
117
119
  Args:
@@ -198,6 +200,9 @@ def write_spec_tree(ms: MathSpec, path=None, linking=False, add_tabbing=False) -
198
200
  out = out.split("\n")
199
201
  out = ["\t" + x for x in out]
200
202
  out = "\n".join(out)
203
+ if readme:
204
+ out = "\n\n```\n{}\n```".format(out)
205
+ out = out.replace("**", "")
201
206
 
202
207
  if path:
203
208
  with open("{}/Spec Tree.md".format(path), "w") as f:
@@ -211,6 +216,6 @@ def write_overview(ms: MathSpec, name: str, file_path: str, summary: str = None)
211
216
  out += "<h2>Summary</h2>"
212
217
  out += "<p>{}</p>".format(summary)
213
218
  out += "<h2>Specification Tree</h2>"
214
- out += write_spec_tree(ms)
219
+ out += write_spec_tree(ms, readme=True)
215
220
  with open(file_path, "w") as f:
216
221
  f.write(out)
Reports/markdown.py CHANGED
@@ -90,8 +90,16 @@ def write_types_markdown_report(ms, path, t, add_metadata=True):
90
90
 
91
91
  out += "## Type"
92
92
  out += "\n"
93
- out += str(t.type)
94
- out += "\n\n"
93
+
94
+ if "python" in t.type:
95
+ out += "### Python Type\n"
96
+ out += t.type_name["python"]
97
+ out += "\n"
98
+ if "typescript" in t.type:
99
+ out += "### Typescript Type\n"
100
+ out += t.type_name["typescript"]
101
+ out += "\n"
102
+ out += "\n"
95
103
  out += "## Notes"
96
104
  out += "\n\n"
97
105
  out += t.notes
@@ -204,6 +212,16 @@ def write_policy_markdown_report(ms, path, policy, add_metadata=True):
204
212
  out += "{}. {}".format(i + 1, x)
205
213
  out += "\n"
206
214
 
215
+ out += "## Parameters Used\n"
216
+ for i, x in enumerate(policy.parameters_used):
217
+ out += "{}. [[{}]]".format(i + 1, x)
218
+ out += "\n"
219
+
220
+ out += "## Metrics Used\n"
221
+ for i, x in enumerate(policy.metrics_used):
222
+ out += "{}. [[{}]]".format(i + 1, x.name)
223
+ out += "\n"
224
+
207
225
  if policy.policy_options:
208
226
  out += "## Policy Options\n"
209
227
  for i, x in enumerate(policy.policy_options):
@@ -292,7 +310,9 @@ def write_space_markdown_report(ms, path, space, add_metadata=True):
292
310
  out += "\n"
293
311
  out += "\n"
294
312
  d = space.schema
295
- d = ",\n".join(["{}: {}".format(a, b.name) for a, b in zip(d.keys(), d.values())])
313
+ d = ",\n".join(
314
+ ["{}: [[{}]]".format(a, b.name) for a, b in zip(d.keys(), d.values())]
315
+ )
296
316
  d = "{" + d + "}"
297
317
  out += d
298
318
  out += "\n"
@@ -337,18 +357,14 @@ def write_control_action_markdown_report(ms, path, control_action, add_metadata=
337
357
  if control_action.control_action_options:
338
358
  out += "## Control Action Options:\n"
339
359
  for i, x in enumerate(control_action.control_action_options):
340
- out += "<details>"
341
- out += "<summary><b>{}. {}</b></summary>".format(i + 1, x.name)
342
- out += "<p>"
360
+ out += "### {}. {}\n".format(i + 1, x.name)
361
+ out += "#### Description\n"
343
362
  out += x.description
344
- out += "</p>"
345
-
346
- out += "<p>"
347
- out += "Logic: {}".format(x.logic)
348
- out += "</p>"
363
+ out += "\n"
349
364
 
350
- out += "</details>"
351
- out += "<br/>"
365
+ out += "#### Logic\n"
366
+ out += x.logic
367
+ out += "\n\n"
352
368
 
353
369
  with open("{}/Control Actions/{}.md".format(path, control_action.label), "w") as f:
354
370
  f.write(out)
@@ -408,6 +424,12 @@ def write_wiring_markdown_report(ms, path, wiring, add_metadata=True):
408
424
  out += "\n"
409
425
  out += "\n"
410
426
 
427
+ out += "## All Spaces Used\n"
428
+ for i, x in enumerate(wiring.all_spaces_used):
429
+ out += "{}. [[{}]]".format(i + 1, x.name)
430
+ out += "\n"
431
+ out += "\n"
432
+
411
433
  out += "## Parameters Used\n"
412
434
  for i, x in enumerate(wiring.parameters_used):
413
435
  out += "{}. [[{}]]".format(i + 1, x)
@@ -426,6 +448,12 @@ def write_wiring_markdown_report(ms, path, wiring, add_metadata=True):
426
448
  out += "\n"
427
449
  out += "\n"
428
450
 
451
+ out += "## All State Updates\n"
452
+ for i, x in enumerate(wiring.all_updates):
453
+ out += "{}. [[{}]].{}".format(i + 1, x[0].name, x[1].name)
454
+ out += "\n"
455
+ out += "\n"
456
+
429
457
  with open("{}/Wiring/{}.md".format(path, wiring.name), "w") as f:
430
458
  f.write(out)
431
459
 
@@ -539,6 +567,77 @@ def write_metrics_markdown_report(ms, path, metric, add_metadata=True):
539
567
  f.write(out)
540
568
 
541
569
 
570
+ def write_displays_markdown_reports(ms, path, add_metadata=True):
571
+ if "Displays" not in os.listdir(path):
572
+ os.makedirs(path + "/Displays")
573
+ if "Wiring" not in os.listdir(path + "/Displays"):
574
+ os.makedirs(path + "/Displays/Wiring")
575
+
576
+ for wiring in ms.displays["Wiring"]:
577
+ write_wiring_display_markdown_report(
578
+ ms, path, wiring, add_metadata=add_metadata
579
+ )
580
+
581
+
582
+ def write_wiring_display_markdown_report(ms, path, wiring, add_metadata=True):
583
+ wirings = [ms.wiring[w] for w in wiring["components"]]
584
+ out = ""
585
+
586
+ out += "## Wiring Diagrams"
587
+ out += "\n"
588
+ out += "\n"
589
+ for w in wirings:
590
+ out += w.render_mermaid_root()
591
+ out += "\n"
592
+ out += "\n"
593
+ out += "## Description"
594
+ out += "\n"
595
+ out += "\n"
596
+ out += wiring["description"]
597
+ out += "\n"
598
+
599
+ out += "## Wirings\n"
600
+ for i, x in enumerate(wiring["components"]):
601
+ out += "{}. [[{}]]".format(i + 1, x)
602
+ out += "\n"
603
+ out += "\n"
604
+
605
+ out += "## Unique Components Used\n"
606
+ components = [set(x.components) for x in wirings]
607
+ components = set().union(*components)
608
+ for i, x in enumerate(components):
609
+ out += "{}. [[{}]]".format(i + 1, x.name)
610
+ out += "\n"
611
+ out += "\n"
612
+
613
+ """domain = [set(x.domain) for x in wirings]
614
+ domain = set().union(*domain)
615
+ out += "## Unique Domain Spaces\n"
616
+ for i, x in enumerate(domain):
617
+ out += "{}. [[{}]]".format(i + 1, x.name)
618
+ out += "\n"
619
+ out += "\n"
620
+
621
+ codomain = [set(x.codomain) for x in wirings]
622
+ codomain = set().union(*codomain)
623
+ out += "## Unique Codomain Spaces\n"
624
+ for i, x in enumerate(codomain):
625
+ out += "{}. [[{}]]".format(i + 1, x.name)
626
+ out += "\n"
627
+ out += "\n"""
628
+
629
+ parameters = [set(x.parameters_used) for x in wirings]
630
+ parameters = set().union(*parameters)
631
+ out += "## Unique Parameters Used\n"
632
+ for i, x in enumerate(parameters):
633
+ out += "{}. [[{}]]".format(i + 1, x)
634
+ out += "\n"
635
+ out += "\n"
636
+
637
+ with open("{}/Displays/Wiring/{}.md".format(path, wiring["name"]), "w") as f:
638
+ f.write(out)
639
+
640
+
542
641
  def write_all_markdown_reports(ms, path):
543
642
 
544
643
  # Write entities
@@ -598,3 +697,7 @@ def write_all_markdown_reports(ms, path):
598
697
  # Write metrics
599
698
  for x in ms.metrics:
600
699
  write_metrics_markdown_report(ms, path, x)
700
+
701
+ # Write displays
702
+ if ms.displays:
703
+ write_displays_markdown_reports(ms, path, add_metadata=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: math_spec_mapping
3
- Version: 0.2.2
3
+ Version: 0.2.4
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,20 +1,20 @@
1
1
  __init__.py,sha256=bWYy9HVSz89bN8y7H7fP7Xrd1TLliPp73zWBUe3KuFE,846
2
2
  schema.py,sha256=6mrRqzEnTTSXjb19xJ63MBp0KjKH0s7i6TfT4MkAY9k,233
3
3
  Classes/ActionTransmissionChannel.py,sha256=zWMo5QsgPh5WGIWXl-xOrZNMXYJXmK6Vejw1dQvi0og,246
4
- Classes/Block.py,sha256=ZBGzwMy_mcGGPMjM78n4MT06G-8rtWHfg2O1Fa1ghL4,14058
4
+ Classes/Block.py,sha256=HUM_ziEE40DBy_mG-XFnHjg3MTTO2C5e6ONyZIAy77Q,17000
5
5
  Classes/BoundaryAction.py,sha256=AOENCqCEfpjotnHhzUj_F2SOP0SGpkN1tNPr8Mtl6Tc,476
6
6
  Classes/ControlAction.py,sha256=xaU3_WVeWOoOFX3O86x30_9Eiirfe76KrO3M2kfjcmo,471
7
7
  Classes/Entity.py,sha256=fA0-b128_OHHxfCg4pzqyQV083EYev1HlVpy86S5igg,1226
8
- Classes/MathSpec.py,sha256=VoZWXHKSmBkerFNI955x1ty6tLhYBxPfKxpSLkfaW34,12952
8
+ Classes/MathSpec.py,sha256=P4FPfv6tpbrY1ytmOQ61hXBey83YoCMgMKOpo6xikxU,13230
9
9
  Classes/Mechanism.py,sha256=7jj6bcPI6H2iv1VZZTlpbG4G2k9s4MYkrH8Sfj9uGM4,324
10
10
  Classes/Metric.py,sha256=AhPgYppOP6q49xvR8S9STxQsXUKJlTWx7wI1LfZEtww,581
11
11
  Classes/Parameter.py,sha256=ZuJ_w0sChvRElJ4sOnXZ2EV4Ell2xXFulKLjVOpgz2E,1237
12
- Classes/Policy.py,sha256=r0m9oCeAYun2ujoEH0BasuknFV4Rsvlu4Obq4TUO8zk,426
12
+ Classes/Policy.py,sha256=HUEooO4Liy7olmHwegb6A-hcreNMNCevl9QKKwOjSik,475
13
13
  Classes/Space.py,sha256=96Cdi8ERkfsgJnh5UyhecKiuU4hWwI6w-i1U1jtwX6A,398
14
14
  Classes/State.py,sha256=Mdn0D21G198f6q13-2tVBYUbnzhRwoDivWpFtH4XJq0,1423
15
15
  Classes/StateUpdateTransmissionChannel.py,sha256=3hBLvD1lE64PkwqksBXAfFWv7foOZzGQLAFQWy42tOA,257
16
16
  Classes/StatefulMetric.py,sha256=UCis1BJ7fsajHHxFF05ZiyDean2D4s4a95uYYW1Mjq4,749
17
- Classes/Type.py,sha256=gntb5kMEouOKTkUWKZ2YE_EwyeCNM2vl8jja0dz7wn8,185
17
+ Classes/Type.py,sha256=ZDHSiaDixHOxasOJlHbuBsMjZ29O2O5K_nmHOmlO-Ck,228
18
18
  Classes/__init__.py,sha256=_hXyZMJanmIex_W6yCR2H7Jw8iU2JJIf3U7VcvBSOGU,737
19
19
  Convenience/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  Convenience/starter.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -22,25 +22,26 @@ Load/__init__.py,sha256=_ga5nHi7U5rY5lCF36_XI9Qmybq4P8R4m5I5mmjLBk8,33
22
22
  Load/action_transmission_channel.py,sha256=9Wer7g2s5SSOcUYuZ0PqSKUVVnW3EvGQJZNXJTwW__0,2561
23
23
  Load/boundary_actions.py,sha256=WvEj2tqN0pUZtE4EiKUuGzMdAcWsMlLslJJeFjIu6gk,2058
24
24
  Load/control_actions.py,sha256=VmjezReijEqe9cdPHQubGZTGVPsYbMzWfLu5Dfm9WvY,1563
25
+ Load/displays.py,sha256=ooHWT_OryzEkp7F3LcGywwdLMRJLxuyPK82zJ3gcyN0,414
25
26
  Load/entities.py,sha256=rMD_Pja-zqH1Z14rsO_Ia7dg3BIi5_HoQmqGAoEYofA,1208
26
- Load/general.py,sha256=1hj35gnZiq93UsoFhuiHv5rNB-VDu8f2sBmJZMdtMNA,4424
27
- Load/load.py,sha256=-ZrwHH8oc_2rX7vL-VECkRElHFSZBe_GLZ4vjTyl3U0,1870
27
+ Load/general.py,sha256=2q6aGKxXhebiHHTZhtACvM4nWIkTben0o5rXuvfv2Vw,4463
28
+ Load/load.py,sha256=VEiZRsiO3QQnw5ZIJ0RQzgQ5hKoWLz6b36Zv9tG-XvI,2405
28
29
  Load/mechanism.py,sha256=aIpMzgQn8f1aywgOHxL5kHQUn1N8K9pmHOVs51bv3Hk,1673
29
- Load/metrics.py,sha256=UCFYTwDhcIlTtKZFFdr1lxuOfWyWqgHQE5jwPG-33EY,2567
30
+ Load/metrics.py,sha256=gD68mt0Y5jSgofZUwscV8PFatOMV_LPwYyPrwV9SdtE,3273
30
31
  Load/parameters.py,sha256=aid_vqYub9643s82NDtMAXLRdV9BPQkri5MadA0L0eQ,1334
31
32
  Load/policy.py,sha256=fDBuOe1LWw-6C_xcYtvtx9dpjWoD9GNEumW7bK8QaT0,2077
32
33
  Load/spaces.py,sha256=7zgGA57Te7T4hfuCCDElffiidWgn1lKm5E14e1yjt8M,1116
33
34
  Load/state_update_transmission_channels.py,sha256=FJWp5n4HdtHAfof5BUQ6BnRakljatL2h8dWCapaVSc0,2238
34
35
  Load/stateful_metrics.py,sha256=Z4S1BWVRfE0cGtcUikJnhmYLKW4k1CurAPrOfjObSKo,1795
35
36
  Load/states.py,sha256=cwo29SBAtj1FoQLEb8c0wkSCn038lIgM9RjNiZefUaE,1223
36
- Load/type.py,sha256=fSXO-HrlGC0YYU5mDTfeGr450Wo96Ks0W6Nk0RvRcvU,458
37
+ Load/type.py,sha256=cKfeLAmYG4hl4mxYA3FvWoQt16ReWrL64H98wgehp6U,3043
37
38
  Load/wiring.py,sha256=1dR94U5N1W_WI5rL6lYBltH25ZvApB2pIpq9r5Opkug,3083
38
39
  Reports/__init__.py,sha256=W27I6S9Ro1hWeHmnxIokCA06awB__eYey7PvKD4Hc1s,933
39
40
  Reports/boundary_actions.py,sha256=45BPp4QjWdD-3E9ZWwqgj_nI2-YdcI2ZZ19_Qv_K7Qk,1410
40
41
  Reports/control_actions.py,sha256=NksekZKIPFSIkubttFstKFthc5AU9B9PWRLSl9j1wWs,1216
41
42
  Reports/general.py,sha256=WOOn6Wlb8M4fsdN49FlKLwOka6vJPQ9aCUy88TL2ki0,1610
42
- Reports/html.py,sha256=EKuQg7PwhvY0NDZtJj1nVTZeSheez8PDAsj43tdtvio,7737
43
- Reports/markdown.py,sha256=3YCCuqQQhH0FJ1OVgemG2PznhMeu58FEohEJynFtCsE,16612
43
+ Reports/html.py,sha256=4wpry61_URAc_LeVemQWowVWGlhMwayjaS3eyUSm0rM,7866
44
+ Reports/markdown.py,sha256=j5QYmk9HXZK9mL3LQqJaW7FJ9oqCmBpEfmvtElljiso,19643
44
45
  Reports/mechanisms.py,sha256=d2Rxt3JBYvqAOAYUynl0buYVoXEHrO8EGq7GK6hK8NA,1322
45
46
  Reports/node_map.py,sha256=FdSMDQG16NX6n9sZcH-T5xwsvgjrV9OqBHc9J_VlNK0,3129
46
47
  Reports/parameters.py,sha256=yizNG4lNGrgrlzYYcHMGfXKDFlPw4PMDYshDqZ3YARs,535
@@ -49,8 +50,8 @@ Reports/spaces.py,sha256=-76hR5wQBv4lsG000ypBJ-OprjsNjI-rNRMYdtsYnjQ,579
49
50
  Reports/state.py,sha256=RSHDjzSiUj4ZjReWbkBW7k2njs3Ovp-q0rCC7GBfD-A,2203
50
51
  Reports/tables.py,sha256=O0CNuqh3LMECq5uLjBOoxMUk5hUvkUK660FNnwWUxDY,1505
51
52
  Reports/wiring.py,sha256=u9SvKWy6T-WJUEgFI6-zgZanoOaTTs_2YwmEceDLsV8,1618
52
- math_spec_mapping-0.2.2.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
53
- math_spec_mapping-0.2.2.dist-info/METADATA,sha256=To-PMn_1vdVw0pN3v3Mrp3qo03pDy-VNGi7Y-Y7-L_I,5898
54
- math_spec_mapping-0.2.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
55
- math_spec_mapping-0.2.2.dist-info/top_level.txt,sha256=DKHirRZ28B4EfLjV3iAU31Sdj6q90EDPTSkRGRZf3uo,49
56
- math_spec_mapping-0.2.2.dist-info/RECORD,,
53
+ math_spec_mapping-0.2.4.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
54
+ math_spec_mapping-0.2.4.dist-info/METADATA,sha256=LuLoWfDUlm2t-bKaYix2Pc6C4Fdzq-jVBJ1meGJKKsc,5898
55
+ math_spec_mapping-0.2.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
56
+ math_spec_mapping-0.2.4.dist-info/top_level.txt,sha256=DKHirRZ28B4EfLjV3iAU31Sdj6q90EDPTSkRGRZf3uo,49
57
+ math_spec_mapping-0.2.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5