xrule.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. '''*****************************************************************************
  2. AToMPM - A Tool for Multi-Paradigm Modelling
  3. Copyright (c) 2011 Eugene Syriani
  4. This file is part of AToMPM.
  5. AToMPM is free software: you can redistribute it and/or modify it under the
  6. terms of the GNU Lesser General Public License as published by the Free Software
  7. Foundation, either version 3 of the License, or (at your option) any later
  8. version.
  9. AToMPM is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  11. PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with AToMPM. If not, see <http://www.gnu.org/licenses/>.
  14. *****************************************************************************'''
  15. from ..util.infinity import INFINITY
  16. from arule import ARule
  17. from ..tcore.rollbacker import Rollbacker
  18. from ..tcore.resolver import Resolver
  19. class XRule(ARule):
  20. '''
  21. Applies the transformation on one match with roll-back capability.
  22. '''
  23. def __init__(self, LHS, RHS, max_iterations=INFINITY):
  24. '''
  25. Applies the transformation on one match with roll-back capability.
  26. @param LHS: The pre-condition pattern (LHS + NACs).
  27. @param RHS: The post-condition pattern (RHS).
  28. @param max_iterations: The maximum number of times to apply the transformation.
  29. @param LHS: The pre-condition pattern (LHS + NACs).
  30. @param RHS: The post-condition pattern (RHS).
  31. '''
  32. # external_matches_only=True because further matches of this rule are only processed after a roll-back
  33. super(XRule, self).__init__(LHS, RHS)
  34. self.M.max = max_iterations
  35. self.I.max_iterations = max_iterations
  36. self.B = Rollbacker(condition=LHS, max_iterations=max_iterations)
  37. def packet_in(self, packet):
  38. self.exception = None
  39. self.is_success = False
  40. # Checkpoint the original packet
  41. self.B.packet_in(packet)
  42. if not self.B.is_success:
  43. self.exception = self.B.exception
  44. return packet
  45. # Match
  46. packet = self.M.packet_in(packet)
  47. if not self.M.is_success:
  48. packet = self.B.restore(packet)
  49. if self.M.exception:
  50. self.exception = self.M.exception
  51. elif self.B.exception:
  52. self.exception = self.B.exception
  53. return packet
  54. # Choose one match
  55. packet = self.I.packet_in(packet)
  56. if not self.I.is_success:
  57. packet = self.B.restore(packet)
  58. if self.I.exception:
  59. self.exception = self.I.exception
  60. elif self.B.exception:
  61. self.exception = self.B.exception
  62. return packet
  63. # Rewrite
  64. packet = self.W.packet_in(packet)
  65. if not self.W.is_success:
  66. packet = self.B.restore(packet)
  67. if self.W.exception:
  68. self.exception = self.W.exception
  69. elif self.B.exception:
  70. self.exception = self.B.exception
  71. return packet
  72. self.is_success = True
  73. return packet
  74. def next_in(self, packet):
  75. self.exception = None
  76. self.is_success = False
  77. packet = self.B.next_in(packet)
  78. if not self.B.is_success:
  79. self.exception = self.B.exception
  80. return packet
  81. # Choose the next match
  82. packet = self.I.packet_in(packet)
  83. if not self.I.is_success:
  84. packet = self.B.next_in(packet)
  85. if self.I.exception:
  86. self.exception = self.I.exception
  87. elif self.B.exception:
  88. self.exception = self.B.exception
  89. return packet
  90. # Rewrite
  91. packet = self.W.packet_in(packet)
  92. if not self.W.is_success:
  93. packet = self.B.next_in(packet)
  94. if self.W.exception:
  95. self.exception = self.W.exception
  96. elif self.B.exception:
  97. self.exception = self.B.exception
  98. return packet
  99. # Output success packet
  100. self.is_success = True
  101. return packet
  102. class XRule_r(XRule):
  103. '''
  104. Applies the transformation on one match with roll-back capability.
  105. '''
  106. def __init__(self, LHS, RHS, max_iterations=INFINITY, external_matches_only=False, custom_resolution=lambda packet: False):
  107. '''
  108. Applies the transformation on one match with roll-back capability.
  109. @param LHS: The pre-condition pattern (LHS + NACs).
  110. @param RHS: The post-condition pattern (RHS).
  111. @param max_iterations: The maximum number of times to apply the transformation.
  112. @param external_matches_only: Resolve conflicts ignoring the matches found in this ARule.
  113. @param custom_resolution: Override the default resolution function.
  114. '''
  115. super(XRule_r, self).__init__(LHS, RHS, max_iterations)
  116. self.R = Resolver(external_matches_only=external_matches_only,
  117. custom_resolution=custom_resolution)
  118. def packet_in(self, packet):
  119. packet = super(XRule_r, self).packet_in(packet)
  120. # is_success is True
  121. if self.exception is None:
  122. # Resolve any conflicts if necessary
  123. packet = self.R.packet_in(packet)
  124. if not self.R.is_success:
  125. self.exception = self.R.exception
  126. return packet
  127. # Output success packet
  128. else:
  129. self.is_success = False
  130. return packet
  131. def next_in(self, packet):
  132. packet = super(XRule_r, self).next_in(packet)
  133. # is_success is True
  134. if self.exception is None:
  135. # Resolve any conflicts if necessary
  136. packet = self.R.packet_in(packet)
  137. if not self.R.is_success:
  138. self.exception = self.R.exception
  139. return packet
  140. # Output success packet
  141. else:
  142. self.is_success = False
  143. return packet