xrule.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. '''This file is part of AToMPM - A Tool for Multi-Paradigm Modelling
  2. Copyright 2011 by the AToMPM team and licensed under the LGPL
  3. See COPYING.lesser and README.md in the root of this project for full details'''
  4. from ..util.infinity import INFINITY
  5. from .arule import ARule
  6. from ..tcore.rollbacker import Rollbacker
  7. from ..tcore.resolver import Resolver
  8. class XRule(ARule):
  9. '''
  10. Applies the transformation on one match with roll-back capability.
  11. '''
  12. def __init__(self, LHS, RHS, max_iterations=INFINITY):
  13. '''
  14. Applies the transformation on one match with roll-back capability.
  15. @param LHS: The pre-condition pattern (LHS + NACs).
  16. @param RHS: The post-condition pattern (RHS).
  17. @param max_iterations: The maximum number of times to apply the transformation.
  18. @param LHS: The pre-condition pattern (LHS + NACs).
  19. @param RHS: The post-condition pattern (RHS).
  20. '''
  21. # external_matches_only=True because further matches of this rule are only processed after a roll-back
  22. super(XRule, self).__init__(LHS, RHS)
  23. self.M.max = max_iterations
  24. self.I.max_iterations = max_iterations
  25. self.B = Rollbacker(condition=LHS, max_iterations=max_iterations)
  26. def packet_in(self, packet):
  27. self.exception = None
  28. self.is_success = False
  29. # Checkpoint the original packet
  30. self.B.packet_in(packet)
  31. if not self.B.is_success:
  32. self.exception = self.B.exception
  33. return packet
  34. # Match
  35. packet = self.M.packet_in(packet)
  36. if not self.M.is_success:
  37. packet = self.B.restore(packet)
  38. if self.M.exception:
  39. self.exception = self.M.exception
  40. elif self.B.exception:
  41. self.exception = self.B.exception
  42. return packet
  43. # Choose one match
  44. packet = self.I.packet_in(packet)
  45. if not self.I.is_success:
  46. packet = self.B.restore(packet)
  47. if self.I.exception:
  48. self.exception = self.I.exception
  49. elif self.B.exception:
  50. self.exception = self.B.exception
  51. return packet
  52. # Rewrite
  53. packet = self.W.packet_in(packet)
  54. if not self.W.is_success:
  55. packet = self.B.restore(packet)
  56. if self.W.exception:
  57. self.exception = self.W.exception
  58. elif self.B.exception:
  59. self.exception = self.B.exception
  60. return packet
  61. self.is_success = True
  62. return packet
  63. def next_in(self, packet):
  64. self.exception = None
  65. self.is_success = False
  66. packet = self.B.next_in(packet)
  67. if not self.B.is_success:
  68. self.exception = self.B.exception
  69. return packet
  70. # Choose the next match
  71. packet = self.I.packet_in(packet)
  72. if not self.I.is_success:
  73. packet = self.B.next_in(packet)
  74. if self.I.exception:
  75. self.exception = self.I.exception
  76. elif self.B.exception:
  77. self.exception = self.B.exception
  78. return packet
  79. # Rewrite
  80. packet = self.W.packet_in(packet)
  81. if not self.W.is_success:
  82. packet = self.B.next_in(packet)
  83. if self.W.exception:
  84. self.exception = self.W.exception
  85. elif self.B.exception:
  86. self.exception = self.B.exception
  87. return packet
  88. # Output success packet
  89. self.is_success = True
  90. return packet
  91. class XRule_r(XRule):
  92. '''
  93. Applies the transformation on one match with roll-back capability.
  94. '''
  95. def __init__(self, LHS, RHS, max_iterations=INFINITY, external_matches_only=False, custom_resolution=lambda packet: False):
  96. '''
  97. Applies the transformation on one match with roll-back capability.
  98. @param LHS: The pre-condition pattern (LHS + NACs).
  99. @param RHS: The post-condition pattern (RHS).
  100. @param max_iterations: The maximum number of times to apply the transformation.
  101. @param external_matches_only: Resolve conflicts ignoring the matches found in this ARule.
  102. @param custom_resolution: Override the default resolution function.
  103. '''
  104. super(XRule_r, self).__init__(LHS, RHS, max_iterations)
  105. self.R = Resolver(external_matches_only=external_matches_only,
  106. custom_resolution=custom_resolution)
  107. def packet_in(self, packet):
  108. packet = super(XRule_r, self).packet_in(packet)
  109. # is_success is True
  110. if self.exception is None:
  111. # Resolve any conflicts if necessary
  112. packet = self.R.packet_in(packet)
  113. if not self.R.is_success:
  114. self.exception = self.R.exception
  115. return packet
  116. # Output success packet
  117. else:
  118. self.is_success = False
  119. return packet
  120. def next_in(self, packet):
  121. packet = super(XRule_r, self).next_in(packet)
  122. # is_success is True
  123. if self.exception is None:
  124. # Resolve any conflicts if necessary
  125. packet = self.R.packet_in(packet)
  126. if not self.R.is_success:
  127. self.exception = self.R.exception
  128. return packet
  129. # Output success packet
  130. else:
  131. self.is_success = False
  132. return packet