renderer.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. from concrete_syntax.common import indent
  2. from concrete_syntax.graphviz.make_url import make_url
  3. from examples.semantics.operational.port.helpers import design_to_state, state_to_design, get_time, get_num_ships
  4. def render_port_graphviz(od):
  5. txt = ""
  6. def render_place(place):
  7. name = od.get_name(place)
  8. return f'"{name}" [ label = "{name}\\n ships = {get_num_ships(od, place)}", style = filled, fillcolor = lightblue ]\n'
  9. for _, cap in od.get_all_instances("CapacityConstraint", include_subtypes=False):
  10. name = od.get_name(cap)
  11. capacity = od.get_slot_value(cap, "shipCapacity")
  12. txt += f'subgraph cluster_{name} {{\n label = "{name}\\n capacity = {capacity}";\n'
  13. for lnk in od.get_outgoing(cap, "capacityOf"):
  14. place = od.get_target(lnk)
  15. txt += f' {render_place(place)}'
  16. txt += f'}}\n'
  17. for _, place_state in od.get_all_instances("PlaceState", include_subtypes=False):
  18. place = state_to_design(od, place_state)
  19. if len(od.get_incoming(place, "capacityOf")) == 0:
  20. txt += render_place(place)
  21. for _, berth_state in od.get_all_instances("BerthState", include_subtypes=False):
  22. berth = state_to_design(od, berth_state)
  23. name = od.get_name(berth)
  24. 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'
  25. for _, gen in od.get_all_instances("Generator", include_subtypes=False):
  26. txt += f'"{od.get_name(gen)}" [ label = "+", shape = diamond, fillcolor = green, fontsize = 30, style = filled ]\n'
  27. for _, conn in od.get_all_instances("connection"):
  28. src = od.get_source(conn)
  29. tgt = od.get_target(conn)
  30. moved = od.get_slot_value(design_to_state(od, conn), "moved")
  31. src_name = od.get_name(src)
  32. tgt_name = od.get_name(tgt)
  33. txt += f"{src_name} -> {tgt_name} [color=deepskyblue3, penwidth={1 if moved else 2}];\n"
  34. for _, workers in od.get_all_instances("WorkerSet"):
  35. already_have = []
  36. name = od.get_name(workers)
  37. num_workers = od.get_slot_value(workers, "numWorkers")
  38. txt += f'{name} [label="{num_workers} worker(s)", shape=parallelogram, fillcolor=chocolate, style=filled];\n'
  39. for lnk in od.get_outgoing(design_to_state(od, workers), "isOperating"):
  40. berth = od.get_target(lnk)
  41. already_have.append(berth)
  42. txt += f"{name} -> {od.get_name(berth)} [arrowhead=none, color=chocolate];\n"
  43. for lnk in od.get_outgoing(workers, "canOperate"):
  44. berth = od.get_target(lnk)
  45. if berth not in already_have:
  46. txt += f"{name} -> {od.get_name(berth)} [style=dotted, arrowhead=none, color=chocolate];\n"
  47. return make_url(txt)
  48. def render_port_textual(od):
  49. txt = ""
  50. for _, place_state in od.get_all_instances("PlaceState", include_subtypes=False):
  51. place = state_to_design(od, place_state)
  52. name = od.get_name(place)
  53. txt += f'place "{name}" {"🚢"*get_num_ships(od, place)}\n'
  54. for _, berth_state in od.get_all_instances("BerthState", include_subtypes=False):
  55. berth = state_to_design(od, berth_state)
  56. name = od.get_name(berth)
  57. operated_descr = ""
  58. if len(od.get_incoming(berth, "isOperating")):
  59. operated_descr = " and being operated"
  60. txt += f'berth "{name}" {"🚢"*get_num_ships(od, berth)} {od.get_slot_value(berth_state, "status")}{operated_descr}\n'
  61. return txt