simulator.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import abc
  2. import random
  3. import math
  4. import functools
  5. import sys
  6. from framework.conformance import Conformance, render_conformance_check_result
  7. from concrete_syntax.common import indent
  8. from concrete_syntax.textual_od.renderer import render_od
  9. from transformation.cloner import clone_od
  10. from api.od import ODAPI
  11. from util.simulator import MinimalSimulator, DecisionMaker, RandomDecisionMaker, InteractiveDecisionMaker
  12. class Simulator(MinimalSimulator):
  13. def __init__(self,
  14. action_generator,
  15. decision_maker: DecisionMaker,
  16. termination_condition=lambda od: None,
  17. check_conformance=True,
  18. verbose=True,
  19. renderer=lambda od: render_od(od.state, od.m, od.mm),
  20. ):
  21. super().__init__(
  22. action_generator=action_generator,
  23. decision_maker=decision_maker,
  24. termination_condition=lambda od: self.check_render_termination_condition(od),
  25. verbose=verbose,
  26. )
  27. self.check_conformance = check_conformance
  28. self.actual_termination_condition = termination_condition
  29. self.renderer = renderer
  30. def check_render_termination_condition(self, od):
  31. # A termination condition checker that also renders the model, and performs conformance check
  32. self._print("--------------")
  33. self._print(indent(self.renderer(od), 2))
  34. self._print("--------------")
  35. if self.check_conformance:
  36. conf = Conformance(od.state, od.m, od.mm)
  37. self._print(render_conformance_check_result(conf.check_nominal()))
  38. self._print()
  39. return self.actual_termination_condition(od)
  40. def make_actions_pure(actions, od):
  41. # Copy model before modifying it
  42. def exec_pure(action, od):
  43. cloned_rt_m = clone_od(od.state, od.m, od.mm)
  44. new_od = ODAPI(od.state, cloned_rt_m, od.mm)
  45. msgs = action(new_od)
  46. return (new_od, msgs)
  47. for descr, action in actions:
  48. yield (descr, functools.partial(exec_pure, action, od))
  49. def filter_valid_actions(pure_actions):
  50. result = {}
  51. def make_tuple(new_od, msgs):
  52. return (new_od, msgs)
  53. for name, callback in pure_actions:
  54. # print(f"attempt '{name}' ...", end='\r')
  55. (new_od, msgs) = callback()
  56. conf = Conformance(new_od.state, new_od.m, new_od.mm)
  57. errors = conf.check_nominal()
  58. # erase current line:
  59. # print(" ", end='\r')
  60. if len(errors) == 0:
  61. # updated RT-M is conform, we have a valid action:
  62. yield (name, functools.partial(make_tuple, new_od, msgs))