add renderer for Port + Petri Net + traceability
This commit is contained in:
parent
e4c12b7349
commit
3ddfc96532
5 changed files with 163 additions and 37 deletions
|
|
@ -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 = ""
|
||||
|
|
|
|||
68
examples/semantics/translational/renderer.py
Normal file
68
examples/semantics/translational/renderer.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
from api.od import ODAPI
|
||||
from concrete_syntax.graphviz.renderer import render_object_diagram, make_graphviz_id
|
||||
from concrete_syntax.graphviz.make_url import show_graphviz
|
||||
from examples.petrinet.renderer import render_petri_net_to_dot
|
||||
from examples.semantics.operational.port.renderer import render_port_to_dot
|
||||
|
||||
# COLORS
|
||||
PLACE_BG = "#DAE8FC" # fill color
|
||||
PLACE_FG = "#6C8EBF" # font, line, arrow
|
||||
BERTH_BG = "#FFF2CC"
|
||||
BERTH_FG = "#D6B656"
|
||||
CAPACITY_BG = "#F5F5F5"
|
||||
CAPACITY_FG = "#666666"
|
||||
WORKER_BG = "#D5E8D4"
|
||||
WORKER_FG = "#82B366"
|
||||
GENERATOR_BG = "#FFE6CC"
|
||||
GENERATOR_FG = "#D79B00"
|
||||
CLOCK_BG = "black"
|
||||
CLOCK_FG = "white"
|
||||
|
||||
def graphviz_style_fg_bg(fg, bg):
|
||||
return f"style=filled,fillcolor=\"{bg}\",color=\"{fg}\",fontcolor=\"{fg}\""
|
||||
|
||||
def render_port(state, m, mm):
|
||||
dot = render_object_diagram(state, m, mm,
|
||||
reify=True,
|
||||
only_render=[
|
||||
# Only render these types
|
||||
"Place", "Berth", "CapacityConstraint", "WorkerSet", "Generator", "Clock",
|
||||
"connection", "capacityOf", "canOperate", "generic_link",
|
||||
# Petri Net types not included (they are already rendered by other function)
|
||||
# Port-State-types not included to avoid cluttering the diagram, but if you need them, feel free to add them.
|
||||
],
|
||||
type_to_style={
|
||||
"Place": graphviz_style_fg_bg(PLACE_FG, PLACE_BG),
|
||||
"Berth": graphviz_style_fg_bg(BERTH_FG, BERTH_BG),
|
||||
"CapacityConstraint": graphviz_style_fg_bg(CAPACITY_FG, CAPACITY_BG),
|
||||
"WorkerSet": "shape=oval,"+graphviz_style_fg_bg(WORKER_FG, WORKER_BG),
|
||||
"Generator": "shape=parallelogram,"+graphviz_style_fg_bg(GENERATOR_FG, GENERATOR_BG),
|
||||
"Clock": graphviz_style_fg_bg(CLOCK_FG, CLOCK_BG),
|
||||
|
||||
# same blue as Place, thick line:
|
||||
"connection": f"color=\"{PLACE_FG}\",fontcolor=\"{PLACE_FG}\",penwidth=2.0",
|
||||
|
||||
# same grey as CapacityConstraint
|
||||
"capacityOf": f"color=\"{CAPACITY_FG}\",fontcolor=\"{CAPACITY_FG}\"",
|
||||
|
||||
# same green as WorkerSet
|
||||
"canOperate": f"color=\"{WORKER_FG}\",fontcolor=\"{WORKER_FG}\"",
|
||||
|
||||
# purple line
|
||||
"generic_link": "color=purple,fontcolor=purple,arrowhead=onormal",
|
||||
}
|
||||
)
|
||||
return dot
|
||||
|
||||
def render_port_and_petri_net(state, m, mm):
|
||||
od = ODAPI(state, m, mm)
|
||||
dot = ""
|
||||
dot += "// petri net:\n"
|
||||
dot += render_petri_net_to_dot(od)
|
||||
dot += "\n// the rest:\n"
|
||||
dot += render_port(state, m, mm)
|
||||
return dot
|
||||
|
||||
|
||||
def show_port_and_petri_net(state, m, mm, engine="dot"):
|
||||
show_graphviz(render_port_and_petri_net(state, m, mm), engine=engine)
|
||||
Loading…
Add table
Add a link
Reference in a new issue