aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndré Erdmann <dywi@mailerd.de>2014-07-17 21:11:38 +0200
committerAndré Erdmann <dywi@mailerd.de>2014-07-17 21:11:38 +0200
commit9b83f08aa38fb713ff4c9fc8c20e9ff4a3fa896d (patch)
treed491b24afbcd179bb86ada7de925c98ce5ad483e
parentremove SillyAdditionControlPackageRuleGenerator (diff)
downloadR_overlay-9b83f08aa38fb713ff4c9fc8c20e9ff4a3fa896d.tar.gz
R_overlay-9b83f08aa38fb713ff4c9fc8c20e9ff4a3fa896d.tar.bz2
R_overlay-9b83f08aa38fb713ff4c9fc8c20e9ff4a3fa896d.zip
package rules: optionally merge acceptor compounds
... of the same type, only AND and OR OR(a,OR(b,AND(AND,c))) -> OR(a,b,AND(c))
-rw-r--r--roverlay/packagerules/abstract/acceptors.py60
1 files changed, 54 insertions, 6 deletions
diff --git a/roverlay/packagerules/abstract/acceptors.py b/roverlay/packagerules/abstract/acceptors.py
index 7618f43..aafc0e7 100644
--- a/roverlay/packagerules/abstract/acceptors.py
+++ b/roverlay/packagerules/abstract/acceptors.py
@@ -8,12 +8,15 @@
Classes provided by this module:
* Acceptor -- base class for all acceptors
* ValueMatchAcceptor -- base class for acceptors that compare a value
-* _AcceptorCompound -- base class combines one more more acceptors
+* _AcceptorCompound -- base class combines one or more acceptors
and represents a boolean term
IOW, they realize a function "[Acceptor] -> Bool"
+* _SelfConsumingAcceptorCompound
+ -- extended _AcceptorCompound that is able to consume
+ sub-acceptors of the same type (class)
* Acceptor_<type> -- specific _AcceptorCompound classes
--> Acceptor_AND
--> Acceptor_OR
+-> Acceptor_AND (self-consuming)
+-> Acceptor_OR (self-consuming)
-> Acceptor_XOR1
-> Acceptor_NOR
@@ -55,6 +58,15 @@ class Acceptor ( object ):
self.logger = logger.getChild ( self.__class__.__name__ )
# --- end of logger (...) ---
+ def merge_sub_compounds ( self ):
+ """Recursively consumes sub compounds of the same type (class),
+ without preserving their priority.
+
+ Must be called manually before prepare().
+ """
+ pass
+ # --- end of merge_sub_compounds (...) ---
+
def prepare ( self ):
"""Prepare the Acceptor for usage (typically used after loading
it from a file).
@@ -121,7 +133,7 @@ class _AcceptorCompound ( Acceptor ):
Raises: EmptyAcceptorError
"""
- if len ( self._acceptors ) > 0:
+ if self._acceptors:
for acceptor in self._acceptors:
acceptor.prepare()
self._acceptors = roverlay.util.priosort ( self._acceptors )
@@ -165,7 +177,43 @@ class _AcceptorCompound ( Acceptor ):
# --- end of _AcceptorCompound ---
-class Acceptor_OR ( _AcceptorCompound ):
+class _SelfConsumingAcceptorCompound ( _AcceptorCompound ):
+
+ def merge_sub_compounds ( self ):
+ """Recursively consumes sub compounds of the same type (class),
+ without preserving their priority.
+
+ Must be called manually before prepare().
+ """
+ if not self._acceptors:
+ return
+
+ acceptors = []
+ append_acceptor = acceptors.append
+ my_cls = self.__class__
+ anything_to_merge = False
+
+ for acceptor in self._acceptors:
+ acceptor.merge_sub_compounds()
+
+ if acceptor.__class__ == my_cls:
+ # ^ must exactly match, no hasattr() etc
+ for acceptor_to_merge in acceptor._acceptors:
+ anything_to_merge = True
+ append_acceptor ( acceptor_to_merge )
+ # --
+ else:
+ append_acceptor ( acceptor )
+ # --
+
+ if anything_to_merge:
+ self._acceptors = acceptors
+ # --- end of merge_sub_compounds (...) ---
+
+# --- end of _SelfConsumingAcceptorCompound ---
+
+
+class Acceptor_OR ( _SelfConsumingAcceptorCompound ):
"""OR( <Acceptors> )"""
def accepts ( self, p_info ):
@@ -183,7 +231,7 @@ class Acceptor_OR ( _AcceptorCompound ):
# --- end of Acceptor_OR ---
-class Acceptor_AND ( _AcceptorCompound ):
+class Acceptor_AND ( _SelfConsumingAcceptorCompound ):
"""AND( <Acceptors> )"""
def accepts ( self, p_info ):