Author: jmorliaguet
Date: Tue Dec  6 22:39:27 2005
New Revision: 1971

Added:
   cpsskins/branches/jmo-perspectives/relations/predicates.py   (contents, 
props changed)
Log:

- added missing file



Added: cpsskins/branches/jmo-perspectives/relations/predicates.py
==============================================================================
--- (empty file)
+++ cpsskins/branches/jmo-perspectives/relations/predicates.py  Tue Dec  6 
22:39:27 2005
@@ -0,0 +1,182 @@
+##############################################################################
+#
+# Copyright (c) 2005 Nuxeo and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import re
+
+from zope.interface import implements
+
+from cpsskins.relations.interfaces import (
+    IProxyPredicate, IPredicate, ICompoundPredicate)
+
+class Predicate:
+    """A predicate is a group of marks.
+
+    >>> p = Predicate('_ is white')
+    >>> p
+    <Predicate: _ is white>
+
+    >>> str(p)
+    '_ is white'
+
+    >>> p()
+    '%s is white'
+
+    >>> p = Predicate('something is missing')
+    Traceback (most recent call last):
+    ...
+    ValueError: A predicate must contain one, two or three '_' blank mark(s)
+
+    >>> p = Predicate('too many _ _ _ _')
+    Traceback (most recent call last):
+    ...
+    ValueError: A predicate must contain one, two or three '_' blank mark(s)
+
+    """
+    implements(IPredicate)
+
+    def __init__(self, predicate=''):
+        if predicate.count('_') in range(1,4):
+            self._predicate = predicate
+        else:
+            raise ValueError, \
+             "A predicate must contain one, two or three '_' blank mark(s)"
+
+    def __str__(self):
+        return self._predicate
+
+    def __call__(self):
+        return re.sub(r'_', '%s', str(self))
+
+    def __repr__(self):
+        return '<Predicate: %s>' % self._predicate
+
+    def __len__(self):
+        return self._predicate.count('_')
+
+    def __iter__(self):
+        return iter([self._predicate])
+
+
+class CompoundPredicate:
+    """A compound predicate is an unordered collection of predicates.
+    They are used for doing queries.
+
+    >>> from cpsskins.relations import Predicate, CompoundPredicate
+    >>> is_black = Predicate('_ is black')
+    >>> is_white = Predicate('_ is white')
+    >>> is_black_or_white = CompoundPredicate((is_black, is_white))
+    >>> is_black_or_white
+    <Compound Predicate: '_ is black OR _ is white'>
+
+    len() return the arity of predicates:
+    >>> len(is_black_or_white)
+    1
+
+    >>> [p for p in is_black_or_white]
+    ['_ is black', '_ is white']
+
+    Compound predicates can be combined to form a new predicate:
+    >>> P1 = Predicate('_ is A')
+    >>> P2 = Predicate('_ is B')
+    >>> P3 = Predicate('_ is C')
+    >>> CP = CompoundPredicate((P1, P2))
+    >>> CP
+    <Compound Predicate: '_ is A OR _ is B'>
+
+    >>> CP2 = CompoundPredicate((CP, P3))
+    >>> CP2
+    <Compound Predicate: '_ is A OR _ is B OR _ is C'>
+
+    The combination order has no effect on the predicate:
+    >>> CP3 = CompoundPredicate((P3, CP))
+    >>> CP3
+    <Compound Predicate: '_ is A OR _ is B OR _ is C'>
+
+    A compound predicate consists of at least 2 predicates:
+    >>> CompoundPredicate((Predicate('_ is A'),))
+    Traceback (most recent call last):
+    ...
+    ValueError: A compound predicate is composed of several predicates.
+
+    The predicates of a compound predicate must of the same arity:
+    >>> CompoundPredicate((Predicate('_ is A'), Predicate('_ has _')))
+    Traceback (most recent call last):
+    ...
+    ValueError: A compound predicate is made of predicates of the same arity.
+
+    """
+    implements(ICompoundPredicate)
+
+    def __init__(self, predicates):
+        if not isinstance(predicates, tuple):
+            raise ValueError, "A compound predicate must be written as a 
tuple."
+
+        if len(predicates) < 2:
+            raise ValueError, \
+                "A compound predicate is composed of several predicates."
+        l0 = len(predicates[0])
+        for p in predicates:
+            if len(p) == l0:
+                continue
+            raise ValueError, \
+                "A compound predicate is made of predicates of the same arity."
+
+        self._predicates = self._normalize(predicates)
+        self._order = l0
+
+    def _normalize(self, seq):
+        return self._sort(self._flatten(seq))
+
+    def _flatten(self, seq):
+        flat = []
+        for s in seq:
+            if isinstance(s, CompoundPredicate):
+                flat.extend(self._flatten(s))
+            else:
+                flat.append(str(s))
+        return tuple(flat)
+
+    def _sort(self, seq):
+        s = list(seq)
+        s.sort()
+        return tuple(s)
+
+    def __len__(self):
+        return self._order
+
+    def __repr__(self):
+        return "<Compound Predicate: '%s'>" % ' OR '.join(self._predicates)
+
+    def __iter__(self):
+        return iter(self._predicates)
+
+    def __str__(self):
+        return str(self._predicates)
+
+class ProxyPredicate:
+    """A proxy predicate refers to another predicate.
+    """
+    implements(IProxyPredicate)
+
+    def __init__(self, proxy):
+        self.proxy = proxy
+
+    def __call__(self):
+        return self.proxy()
+
-- 
http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins

Reply via email to