add renderer for Port + Petri Net + traceability

This commit is contained in:
Joeri Exelmans 2024-12-09 17:09:43 +01:00
parent e4c12b7349
commit 3ddfc96532
5 changed files with 163 additions and 37 deletions

View file

@ -2,12 +2,14 @@ from concrete_syntax.common import indent
from concrete_syntax.graphviz.make_url import make_url
from examples.semantics.operational.port.helpers import design_to_state, state_to_design, get_time, get_num_ships
def render_port_graphviz(od):
def render_port_to_dot(od,
make_id=lambda name,obj: name # by default, we just use the object name for the graphviz node name
):
txt = ""
def render_place(place):
name = od.get_name(place)
return f'"{name}" [ label = "{name}\\n ships = {get_num_ships(od, place)}", style = filled, fillcolor = lightblue ]\n'
return f'"{make_id(name,place)}" [ label = "{name}\\n ships = {get_num_ships(od, place)}", style = filled, fillcolor = lightblue ]\n'
for _, cap in od.get_all_instances("CapacityConstraint", include_subtypes=False):
name = od.get_name(cap)
@ -26,10 +28,10 @@ def render_port_graphviz(od):
for _, berth_state in od.get_all_instances("BerthState", include_subtypes=False):
berth = state_to_design(od, berth_state)
name = od.get_name(berth)
txt += f'"{name}" [ label = "{name}\\n numShips = {get_num_ships(od, berth)}\\n status = {od.get_slot_value(berth_state, "status")}", fillcolor = yellow, style = filled]\n'
txt += f'"{make_id(name,berth)}" [ label = "{name}\\n numShips = {get_num_ships(od, berth)}\\n status = {od.get_slot_value(berth_state, "status")}", fillcolor = yellow, style = filled]\n'
for _, gen in od.get_all_instances("Generator", include_subtypes=False):
txt += f'"{od.get_name(gen)}" [ label = "+", shape = diamond, fillcolor = green, fontsize = 30, style = filled ]\n'
txt += f'"{make_id(od.get_name(gen),gen)}" [ label = "+", shape = diamond, fillcolor = green, fontsize = 30, style = filled ]\n'
for _, conn in od.get_all_instances("connection"):
src = od.get_source(conn)
@ -37,23 +39,26 @@ def render_port_graphviz(od):
moved = od.get_slot_value(design_to_state(od, conn), "moved")
src_name = od.get_name(src)
tgt_name = od.get_name(tgt)
txt += f"{src_name} -> {tgt_name} [color=deepskyblue3, penwidth={1 if moved else 2}];\n"
txt += f"{make_id(src_name,src)} -> {make_id(tgt_name,tgt)} [color=deepskyblue3, penwidth={1 if moved else 2}];\n"
for _, workers in od.get_all_instances("WorkerSet"):
already_have = []
name = od.get_name(workers)
num_workers = od.get_slot_value(workers, "numWorkers")
txt += f'{name} [label="{num_workers} worker(s)", shape=parallelogram, fillcolor=chocolate, style=filled];\n'
txt += f'{make_id(name,workers)} [label="{num_workers} worker(s)", shape=parallelogram, fillcolor=chocolate, style=filled];\n'
for lnk in od.get_outgoing(design_to_state(od, workers), "isOperating"):
berth = od.get_target(lnk)
already_have.append(berth)
txt += f"{name} -> {od.get_name(berth)} [arrowhead=none, color=chocolate];\n"
txt += f"{make_id(name,workers)} -> {make_id(od.get_name(berth),berth)} [arrowhead=none, color=chocolate];\n"
for lnk in od.get_outgoing(workers, "canOperate"):
berth = od.get_target(lnk)
if berth not in already_have:
txt += f"{name} -> {od.get_name(berth)} [style=dotted, arrowhead=none, color=chocolate];\n"
txt += f"{make_id(name,workers)} -> {make_id(od.get_name(berth),berth)} [style=dotted, arrowhead=none, color=chocolate];\n"
return make_url(txt)
return txt
def render_port_graphviz(od):
return make_url(render_port_to_dot(od))
def render_port_textual(od):
txt = ""