math-spec-mapping 0.2.2__py3-none-any.whl → 0.2.4__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
@@ -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