lsrule.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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 .lrule import LRule
  6. from ..tcore.rewriter import Rewriter
  7. from ..tcore.resolver import Resolver
  8. class LSRule(LRule):
  9. '''
  10. Applies an inner rule for each application of the outer rule as long as matches can be found.
  11. '''
  12. def __init__(self, LHS, RHS, inner_rule, outer_first, sendAndApplyDeltaFunc, max_iterations=INFINITY):
  13. '''
  14. Applies an inner rule for each application of the outer rule as long as matches can be found.
  15. @param LHS: The pre-condition pattern (LHS + NACs).
  16. @param RHS: The post-condition pattern (RHS).
  17. @param inner_rule: The rule to apply in the loop.
  18. @param outer_first: Whether the outer rule should be applied before the inner rule.
  19. @param max_iterations: The maximum number of matches of the LHS.
  20. '''
  21. super(LSRule, self).__init__(LHS, inner_rule, max_iterations)
  22. self.W = Rewriter(condition=RHS,sendAndApplyDeltaFunc=sendAndApplyDeltaFunc)
  23. self.outer_first = outer_first
  24. def packet_in(self, packet):
  25. self.exception = None
  26. self.is_success = False
  27. # Match
  28. packet = self.M.packet_in(packet)
  29. if not self.M.is_success:
  30. self.exception = self.M.exception
  31. return packet
  32. # Choose the first match
  33. packet = self.I.packet_in(packet)
  34. if not self.I.is_success:
  35. self.exception = self.I.exception
  36. return packet
  37. while True:
  38. if self.outer_first:
  39. # Rewrite
  40. packet = self.W.packet_in(packet)
  41. if not self.W.is_success:
  42. self.exception = self.W.exception
  43. return packet
  44. # Apply the inner rule
  45. packet = self.inner_rule.packet_in(packet)
  46. if not self.inner_rule.is_success:
  47. self.exception = self.inner_rule.exception
  48. return packet
  49. if not self.outer_first:
  50. # Rewrite
  51. packet = self.W.packet_in(packet)
  52. if not self.W.is_success:
  53. self.exception = self.W.exception
  54. return packet
  55. # Rule has been applied once, so it's a success anyway
  56. self.is_success = True
  57. if self.I.iterations == self.I.max_iterations:
  58. return packet
  59. # Re-Match
  60. packet = self.M.packet_in(packet)
  61. if not self.M.is_success:
  62. self.exception = self.M.exception
  63. return packet
  64. # Choose another match
  65. packet = self.I.next_in(packet)
  66. # No more iterations are left
  67. if not self.I.is_success:
  68. if self.I.exception:
  69. self.exception = self.I.exception
  70. return packet
  71. class LSRule_r(LSRule):
  72. '''
  73. Applies an inner rule for each application of the outer rule as long as matches can be found.
  74. '''
  75. def __init__(self, LHS, RHS, external_matches_only=False, custom_resolution=lambda packet: False):
  76. '''
  77. Applies an inner rule for each application of the outer rule as long as matches can be found.
  78. @param LHS: The pre-condition pattern (LHS + NACs).
  79. @param RHS: The post-condition pattern (RHS).
  80. @param inner_rule: The rule to apply in the loop.
  81. @param outer_first: Whether the outer rule should be applied before the inner rule.
  82. @param max_iterations: The maximum number of matches of the LHS.
  83. @param external_matches_only: Resolve conflicts ignoring the matches found in this FRule.
  84. @param custom_resolution: Override the default resolution function.
  85. '''
  86. super(LSRule_r, self).__init__()
  87. self.R = Resolver(external_matches_only=external_matches_only,
  88. custom_resolution=custom_resolution)
  89. def packet_in(self, packet):
  90. self.exception = None
  91. self.is_success = False
  92. # Match
  93. packet = self.M.packet_in(packet)
  94. if not self.M.is_success:
  95. self.exception = self.M.exception
  96. return packet
  97. # Choose the first match
  98. packet = self.I.packet_in(packet)
  99. if not self.I.is_success:
  100. self.exception = self.I.exception
  101. return packet
  102. while True:
  103. if self.outer_first:
  104. # Rewrite
  105. packet = self.W.packet_in(packet)
  106. if not self.W.is_success:
  107. self.exception = self.W.exception
  108. return packet
  109. # Resolve any conflicts if necessary
  110. packet = self.R.packet_in(packet)
  111. if not self.R.is_success:
  112. self.exception = self.R.exception
  113. return packet
  114. # Apply the inner rule
  115. packet = self.inner_rule.packet_in(packet)
  116. if not self.inner_rule.is_success:
  117. self.exception = self.inner_rule.exception
  118. return packet
  119. if not self.outer_first:
  120. # Rewrite
  121. packet = self.W.packet_in(packet)
  122. if not self.W.is_success:
  123. self.exception = self.W.exception
  124. return packet
  125. # Resolve any conflicts if necessary
  126. packet = self.R.packet_in(packet)
  127. if not self.R.is_success:
  128. self.exception = self.R.exception
  129. return packet
  130. # Rule has been applied once, so it's a success anyway
  131. self.is_success = True
  132. if self.I.iterations == self.I.max_iterations:
  133. return packet
  134. # Re-Match
  135. packet = self.M.packet_in(packet)
  136. if not self.M.is_success:
  137. self.exception = self.M.exception
  138. return packet
  139. # Choose another match
  140. packet = self.I.next_in(packet)
  141. # No more iterations are left
  142. if not self.I.is_success:
  143. if self.I.exception:
  144. self.exception = self.I.exception
  145. return packet