[pypy-svn] r26791 - in pypy/dist/pypy/lib/pyontology: . test

ale at codespeak.net ale at codespeak.net
Fri May 5 10:05:20 CEST 2006


Author: ale
Date: Fri May  5 10:05:19 2006
New Revision: 26791

Added:
   pypy/dist/pypy/lib/pyontology/constraint_classes.py
Modified:
   pypy/dist/pypy/lib/pyontology/pyontology.py
   pypy/dist/pypy/lib/pyontology/test/test_ontology.py
Log:
Split files into to. some whitespace cleanup

Added: pypy/dist/pypy/lib/pyontology/constraint_classes.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/pyontology/constraint_classes.py	Fri May  5 10:05:19 2006
@@ -0,0 +1,495 @@
+from logilab.constraint.propagation import AbstractDomain, AbstractConstraint, ConsistencyFailure
+
+class OwlConstraint(AbstractConstraint):
+
+    cost = 1
+    
+    def __init__(self, variable):
+        AbstractConstraint.__init__(self, [variable])
+        self.variable = variable
+
+    def __repr__(self):
+        return '<%s  %s>' % (self.__class__.__name__, str(self._variables[0]))
+
+    def estimateCost(self, domains):
+        return self.cost
+
+def get_cardinality(props, cls):
+        if props.get(cls):
+           card = len(props[cls]) 
+        elif props.get(None):
+           card = len(props[None]) 
+        else:
+           card = 0
+        return card 
+
+class MaxCardinality(AbstractConstraint):
+    """Contraint: all values must be distinct"""
+
+    def __init__(self, variable, cardinality):
+        AbstractConstraint.__init__(self, [variable])
+        self.cost = 80
+        self.variable = variable
+        self.cardinality = cardinality
+
+    def __repr__(self):
+        return '<%s  %s %i>' % (self.__class__.__name__, str(self._variables[0]), self.cardinality)
+
+    def estimateCost(self, domains):
+        return self.cost
+    
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        prop = domains[self.variable].property
+        props = Linkeddict(domains[prop].getValues())
+        dom = domains[self.variable].getValues()
+        if not dom:
+            return 0
+        cls = dom[0]
+        card = get_cardinality(props, cls)
+        if card > self.cardinality:
+            raise ConsistencyFailure("Maxcardinality of %i exceeded by the value %i" %(self.cardinality,len(props[cls])))
+        else:
+            return 1
+
+class MinCardinality(MaxCardinality):
+
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        prop = domains[self.variable].property
+        props = Linkeddict(domains[prop].getValues())
+        cls = domains[self.variable].getValues()[0]
+        card = get_cardinality(props, cls)
+        if card < self.cardinality:
+            raise ConsistencyFailure("MinCardinality of %i not achieved by the value %i" %(self.cardinality,len(props[cls])))
+        else:
+            return 1
+        
+class Cardinality(MaxCardinality):
+    
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        prop = domains[self.variable].property
+        props = Linkeddict(domains[prop].getValues())
+        cls = domains[self.variable].getValues()[0]
+        card = get_cardinality(props, cls)
+        if card != self.cardinality:
+            raise ConsistencyFailure("Cardinality of %i exceeded by the value %r for %r" %
+                                     (self.cardinality, props[cls], prop))
+        else:
+            return 1
+
+class SubClassConstraint(AbstractConstraint):
+
+    cost=1
+    
+    def __init__(self, variable, cls_or_restriction):
+        AbstractConstraint.__init__(self, [variable, cls_or_restriction])
+        self.object = cls_or_restriction
+        self.variable = variable
+        
+    def estimateCost(self, domains):
+        return self.cost
+
+    def __repr__(self):
+        return '<%s  %s %s>' % (self.__class__.__name__, str(self._variables[0]), self.object)
+
+    def narrow(self, domains):
+        subdom = domains[self.variable]
+        superdom = domains[self.object]
+        vals = []
+        vals += superdom.getValues()
+        vals += subdom.getValues() +[self.variable]
+        superdom.setValues(vals)
+	        
+        return 0
+
+class DisjointClassConstraint(SubClassConstraint):
+
+    def narrow(self, domains):
+        subdom = domains[self.variable]
+        superdom = domains[self.object]
+        vals1 = superdom.getValues()  
+        vals2 = subdom.getValues()  
+        for i in vals1:
+            if i in vals2:
+                raise ConsistencyFailure()
+
+class ComplementClassConstraint(SubClassConstraint):
+
+    def narrow(self, domains):
+        subdom = domains[self.variable]
+        superdom = domains[self.object]
+
+class RangeConstraint(SubClassConstraint):
+
+    cost = 30
+    
+    def narrow(self, domains):
+        propdom = domains[self.variable]
+        rangedom = domains[self.object]
+        newrange = rangedom.getValues()
+        res = []
+        oldrange = propdom.range
+        if oldrange:
+            for v in oldrange:
+                if v in newrange:
+                    res.append(v)
+        else:
+            res = newrange
+        propdom.range = res
+        propdom.setValues([(None,i) for i in res])
+        #prop = Linkeddict(propdom.getValues())
+        #for pval in sum(prop.values(),[]):
+        #    if pval not in range:
+        #        raise ConsistencyFailure("Value %r not in range %r for Var %s"%(pval,range, self.variable))
+
+class DomainConstraint(SubClassConstraint):
+
+    cost = 200
+
+    def narrow(self, domains):
+        propdom = domains[self.variable]
+        domaindom = domains[self.object]
+        newdomain = domaindom.getValues() +[self.object]
+        domain = []
+        olddomain = propdom.domain
+        if olddomain:
+            for v in olddomain:
+                if v in newdomain:
+                    domain.append(v)
+        else:
+            domain = newdomain
+        propdom.domain = domain
+        prop = Linkeddict(propdom.getValues())
+        for pval in prop.keys():
+            if pval not in domain:
+                raise ConsistencyFailure("Value %r not in range %r"%(pval, domain))
+
+class SubPropertyConstraint(SubClassConstraint):
+
+    def narrow(self, domains):
+        subdom = domains[self.variable]
+        superdom = domains[self.object]
+        vals = superdom.getValues()
+        for val in subdom.getValues():
+            if not val in vals:
+                vals.append(val)
+        superdom.setValues(vals)
+
+class EquivalentPropertyConstraint(SubClassConstraint):
+
+    cost = 100
+    
+    def narrow(self, domains):
+        subdom = domains[self.variable]
+        superdom = domains[self.object]
+        vals = superdom.getValues()  
+        for val in subdom.getValues():
+            if not val in vals:
+                raise ConsistencyFailure("The Property %s is not equivalent to Property %s" %
+                                         (self.variable, self.object))
+
+class TypeConstraint(SubClassConstraint):
+    cost = 1
+    def narrow(self, domains):
+        subdom = domains[self.variable]
+        superdom = domains[self.object]
+        vals = []
+        vals += superdom.getValues()  
+        vals.append(self.variable)
+        superdom.setValues(vals)
+        return 1
+
+class FunctionalCardinality(OwlConstraint):
+    """Contraint: all values must be distinct"""
+
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        domain = domains[self.variable].getValues()
+        domain_dict = Linkeddict(domain)
+        for cls, val in domain_dict.items():
+            if len(val) != 1:
+                raise ConsistencyFailure("FunctionalCardinality error")
+        else:
+            return 0
+
+class InverseFunctionalCardinality(OwlConstraint):
+    """Contraint: all values must be distinct"""
+
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        domain = domains[self.variable].getValues()
+        vals = {}
+        for cls, val in domain:
+            if vals.has_key(val):
+                raise ConsistencyFailure("InverseFunctionalCardinality error")
+            else:
+                vals[val] = 1
+        else:
+            return 0
+
+class Linkeddict(dict):
+    def __init__(self, values=()):
+        for k,v in values:
+            dict.setdefault(self,k,[])
+            if type(v) == list:
+                dict.__setitem__(self, k, v)
+            else:
+                if not v in dict.__getitem__(self,k):
+                    dict.__getitem__(self,k).append(v)
+            
+class TransitiveConstraint(OwlConstraint):
+    """Contraint: all values must be distinct"""
+
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        domain = domains[self.variable].getValues()
+        domain_dict = Linkeddict(domain)
+        for cls, val in domain:
+            if  val in domain_dict:
+                for v in domain_dict[val]:
+                    domain.append((cls,v))
+        domains[self.variable].setValues(domain)
+
+class SymmetricConstraint(OwlConstraint):
+    """Contraint: all values must be distinct"""
+
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        domain = domains[self.variable].getValues()
+        for cls, val in domain:
+            if not (val, cls) in domain:
+                domain.append((val,cls))
+        domains[self.variable].setValues(domain)
+
+class InverseofConstraint(SubClassConstraint):
+    """Contraint: all values must be distinct"""
+    cost = 200
+    
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        obj_domain = domains[self.object].getValues()
+        sub_domain = domains[self.variable].getValues()
+        res = []
+        for cls, val in obj_domain:
+            if not (val,cls) in sub_domain:
+                raise ConsistencyFailure("Inverseof failed for (%r, %r) in %r" % 
+                                         (val, cls, sub_domain) )
+        for cls, val in sub_domain:
+            if not (val,cls) in obj_domain:
+                raise ConsistencyFailure("Inverseof failed for (%r, %r) in %r" % 
+                                         (val, cls, obj_domain)) 
+
+class DifferentfromConstraint(SubClassConstraint):
+
+    def narrow(self, domains):
+        if self.variable == self.object:
+            raise ConsistencyFailure("%s can't be differentFrom itself" % self.variable)
+        else:
+            return 0
+
+class SameasConstraint(SubClassConstraint):
+
+    def narrow(self, domains):
+        if self.variable == self.object:
+            return 1
+        else:
+            for dom in domains.values():
+                vals = dom.getValues()
+                if hasattr(dom, '_dict'):
+                    val = Linkeddict(vals)
+                    if self.variable in val.keys() and not self.object in val.keys():
+                        vals +=[(self.object,v) for v in val[self.variable]]
+                        dom.setValues(vals)
+                    elif not self.variable in val.keys() and self.object in val.keys():
+                        vals +=[(self.variable,v) for v in val[self.object]]
+                        dom.setValues(vals)
+                    elif self.variable in val.keys() and self.object in val.keys():
+                        if not val[self.object] == val[self.variable]:
+                            raise ConsistencyFailure("Sameas failure: The two individuals (%s, %s) \
+                                                has different values for property %r"%(self.variable, self.object, dom))
+                else:
+                    if self.variable in vals and not self.object in vals:
+                        vals.append(self.object)
+                    elif not self.variable in vals and self.object in vals:
+                        vals.append(self.variable)
+                    else:
+                        continue
+                    dom.setValues(vals)
+            return 0
+
+class ListConstraint(OwlConstraint):
+    """Contraint: all values must be distinct"""
+
+    cost = 10
+
+    def narrow(self, domains):
+        """narrowing algorithm for the constraint"""
+        
+        vals =[]
+        vals += domains[self.variable].getValues()
+        if vals == []:
+            return 0
+        while True:
+            if vals[-1] in domains.keys() and isinstance(domains[vals[-1]], List):
+                vals = vals[:-1] + domains[vals[-1]].getValues()
+                if domains[vals[-1]].remove : 
+                    domains.pop(vals[-1])
+            else:
+                break
+        domains[self.variable].setValues(vals)
+        return 1
+
+class RestrictionConstraint(OwlConstraint):
+
+    cost = 70
+
+    def narrow(self, domains):
+        prop = domains[self.variable].property
+        vals = domains[self.variable].getValues()
+        if vals:
+            cls = vals[0]
+            props = domains[prop].getValues()
+            props.append((cls, None))
+            domains[prop].setValues(props)
+            return 1
+        else:
+            return 0
+        
+class OneofPropertyConstraint(AbstractConstraint):
+
+    def __init__(self, variable, list_of_vals):
+        AbstractConstraint.__init__(self, [variable ])
+        self.variable = variable
+        self.List = list_of_vals
+    cost = 100
+
+    def estimateCost(self, domains):
+        return self.cost
+
+    def narrow(self, domains):
+        val = domains[self.List].getValues()
+        if isinstance(domains[self.variable],Restriction):
+            # This should actually never happen ??
+            property = domains[self.variable].property
+            cls = domains[self.variable].getValues()[0]
+            prop = Linkeddict(domains[property].getValues())
+            for v in prop[cls]:
+                if not v in val:
+                    raise ConsistencyFailure(
+                        "The value of the property %s in the class %s is not oneof %r"
+                            %(property, cls, val))
+        else:
+            domains[self.variable].setValues(val)
+            return 1
+
+class UnionofConstraint(OneofPropertyConstraint):
+
+    cost = 200
+
+    def narrow(self, domains):
+        val = domains[self.List].getValues()
+        union = []
+        for v in val:
+            for u in domains[v].getValues():
+                if not u in union:
+                    union.append(u)
+        cls = domains[self.variable].setValues(union)
+        
+class IntersectionofConstraint(OneofPropertyConstraint):
+
+    cost = 200
+
+    def narrow(self, domains):
+        val = domains[self.List].getValues()
+        intersection = domains[val[0]].getValues()
+        for v in val[1:]:
+            vals= domains[v].getValues()
+            remove = []
+            for u in intersection:
+                if not u in vals:
+                    remove.append(u)
+            for u in remove:
+                intersection.remove(u)
+        cls = domains[self.variable].setValues(intersection)
+        term = {}
+        for l in [domains[x] for x in val]:
+            if hasattr(l,'TBox'):
+                TBox = l.TBox
+                prop = l.property
+                for item in TBox.values():
+                    term.setdefault(prop,[])
+                    term[prop].append(item)
+        for prop in term:
+            axioms = term[prop]
+            ranges = [ax[0] for ax in axioms]
+            res = []
+            while axioms:
+                r, comp = axioms.pop(0)
+                if res:
+                    res = [x for x in res if eval('x %s r' % comp)]
+                else:
+                    res = [x for x in r if eval('x %s r' % comp)]
+                if not res:
+                    axioms.append((r,comp))
+        if not res:
+            raise ConsistencyFailure("Inconsistent use of intersectionOf")
+
+class SomeValueConstraint(OneofPropertyConstraint):
+
+    cost = 100
+        
+    def narrow(self, domains):
+        val = domains[self.List].getValues()
+        property = domains[self.variable].property
+        cls = domains[self.variable].getValues()[0]
+        prop = Linkeddict(domains[property].getValues())
+        for v in prop[cls]:
+            if v in val:
+                break
+        else:
+            raise ConsistencyFailure(
+                    "The value of the property %s in the class %s has no values from %r"
+                        %(property, cls, val))
+
+class AllValueConstraint(OneofPropertyConstraint):
+
+    cost = 100
+        
+    def narrow(self, domains):
+        val = domains[self.List].getValues()
+        property = domains[self.variable].property
+        cls = domains[self.variable].getValues()[0]
+        prop = Linkeddict(domains[property].getValues())
+        for v in prop[cls]:
+            if not v in val:
+                raise ConsistencyFailure(
+                    "The value of the property %s in the class %s has a value not from %r"
+                        %(property, cls, val))
+
+class HasvalueConstraint(AbstractConstraint):
+
+    def __init__(self, variable, List):
+        AbstractConstraint.__init__(self, [variable])
+        self.variable = variable
+        self.List = List
+
+    cost = 100
+
+    def estimateCost(self, domains):
+        return self.cost
+
+    def narrow(self, domains):
+        val = self.List
+        property = domains[self.variable].property
+        cls = domains[self.variable].getValues()[0]
+        prop = Linkeddict(domains[property].getValues())
+        for v in prop[cls]:
+            if v == val:
+                break
+        else:
+            raise ConsistencyFailure(
+                    "The value of the property %s in the class %s has a value not from %r"
+                        %(property, cls, val))
+

Modified: pypy/dist/pypy/lib/pyontology/pyontology.py
==============================================================================
--- pypy/dist/pypy/lib/pyontology/pyontology.py	(original)
+++ pypy/dist/pypy/lib/pyontology/pyontology.py	Fri May  5 10:05:19 2006
@@ -2,6 +2,7 @@
 from logilab.constraint import  Repository, Solver
 from logilab.constraint.fd import  FiniteDomain as fd
 from logilab.constraint.propagation import AbstractDomain, AbstractConstraint, ConsistencyFailure
+from constraint_classes import *
 import sys, py
 import time
 
@@ -13,7 +14,7 @@
 }
 
 uris = {}
-for k,v in namespaces.items(): 
+for k,v in namespaces.items():
     uris[v] = k
 
 Class = URIRef(u'http://www.w3.org/2002/07/owl#Class')
@@ -36,16 +37,15 @@
     else:
         format = "n3"
     return format
-
 class ClassDomain(AbstractDomain):
-
+    
     # Class domain is intended as a (abstract/virtual) domain for implementing
     # Class axioms. Working on class descriptions the class domain should allow
     # creation of classes through axioms.
     # The instances of a class can be represented as a FiniteDomain in values (not always see Disjointwith)
     # Properties of a class is in the dictionary "properties"
     # The bases of a class is in the list "bases"
-
+    
     def __init__(self, name='', values=[], bases = []):
         AbstractDomain.__init__(self)
         self.bases = bases+[self]
@@ -54,46 +54,46 @@
         self.name = name
         self.properties = {}
         # The TBox is a dictionary containing terminology constraints
-        # on predicates for this class. Keys are predicates, constraint 
+        # on predicates for this class. Keys are predicates, constraint
         # tupples ie. (p,'Carddinality') and values are list, comparison
         # tupples
         self.TBox = {}
-        # The ABox contains the constraints the individuals of the class 
-        # shall comply to 
+        # The ABox contains the constraints the individuals of the class
+        # shall comply to
         self.ABox = {}
-
+    
     def __repr__(self):
         return "<%s %s %r>" % (self.__class__, str(self.name),self.getValues())
-
+    
     def __getitem__(self, index):
         return None
-
+    
     def __iter__(self):
-        return iter(self.bases) 
-
+        return iter(self.bases)
+    
     def size(self):
         return len(self.bases)
-
+    
     __len__ = size
-
+    
     def copy(self):
         return self
-
+    
     def removeValues(self, values):
         for val in values:
             self.values.pop(self.values.index(val))
-
+    
     def getBases(self):
         return self.bases
-
+    
     def getValues(self):
         return self.values.keys()
-
+    
     def setValues(self, values):
         self.values = dict.fromkeys(values)
 
 class List(ClassDomain):
-
+    
     def __init__(self, name='', values=[], bases = []):
         ClassDomain.__init__(self, name, values, bases)
         self.constraint = ListConstraint(name)
@@ -101,14 +101,14 @@
 class Property(ClassDomain):
     # Property contains the relationship between a class instance and a value
     # - a pair. To accomodate global assertions like 'range' and 'domain' attributes
-    # for range and domain must be filled in by rdfs:range and rdfs:domain 
-
+    # for range and domain must be filled in by rdfs:range and rdfs:domain
+    
     def __init__(self, name='', values=[], bases = []):
         ClassDomain.__init__(self, name, values, bases)
         self._dict = Linkeddict()
         self.range = []
         self.domain = []
-
+    
     def getValues(self):
         items = self._dict.items()
         res = []
@@ -120,20 +120,20 @@
     def addValue(self, key, val):
         self._dict.setdefault(key, [])
         self._dict[key].append(val)
-
+    
     def setValues(self, values):
         self._dict = Linkeddict(values)
-
+    
     def removeValues(self, values):
         for k,v in values:
             vals = self._dict[k]
             if vals == [None]:
                 self._dict.pop(k)
             else:
-                self._dict[k] = [ x for x in vals if x != v] 
-            
-class ObjectProperty(Property):
+                self._dict[k] = [ x for x in vals if x != v]
 
+class ObjectProperty(Property):
+    
     pass
 
 class DatatypeProperty(Property):
@@ -151,7 +151,7 @@
     pass
 
 class Nothing(ClassDomain):
-
+    
     pass
 
 
@@ -160,7 +160,7 @@
     def __init__(self, name='', values=[], bases = []):
         Property.__init__(self, name, values, bases)
         self.constraint = FunctionalCardinality(name)
-        
+
 class InverseFunctionalProperty(Property):
     
     def __init__(self, name='', values=[], bases = []):
@@ -183,9 +183,9 @@
     """ A owl:restriction is an anonymous class that links a class to a restriction on a property
         The restriction is only applied to the property in the conntext of the specific task. In order
         to construct a constraint to check the restriction three things are thus needed :
-            1. The property to which the restriction applies - this comes from the onProperty tripple. 
+            1. The property to which the restriction applies - this comes from the onProperty tripple.
                 the property is saved in the Restriction class' property attribute
-            2. The restriction itself. This comes from one of the property restrictions triples (oneOf, 
+            2. The restriction itself. This comes from one of the property restrictions triples (oneOf,
                 maxCardinality ....). It adds a constraint class
             3. The class in which context the restriction should be applied. This comes from subClassOf, type...
                 The class is saved in the restrictions cls attribute
@@ -194,7 +194,7 @@
         ClassDomain.__init__(self, name, values, bases)
         self.constraint = RestrictionConstraint(name)
         self.property = None
-        
+
 builtin_voc = {
                getUriref('owl', 'Thing') : Thing,
                getUriref('owl', 'Class') : ClassDomain,
@@ -215,9 +215,9 @@
                getUriref('owl', 'TransitiveProperty') : TransitiveProperty,
                getUriref('rdf', 'List') : List
               }
-  
-class Ontology:
 
+class Ontology:
+    
     def __init__(self, store = 'default'):
         self.graph = Graph(store)
         if store != 'default':
@@ -226,47 +226,54 @@
         self.constraints = []
         self.seen = {}
         self.var2ns ={}
-
+    
     def add(self, triple):
         self.graph.add(triple)
-        
+    
     def add_file(self, f, format=None):
         if not format:
             format = check_format(f)
         self.graph.load(f, format=format)
-
+    
     def attach_fd(self):
         for (s, p, o) in (self.graph.triples((None,)*3)):
-            if p.find('#') != -1:
-                ns, func = p.split('#')
-            else:
-                ns =''
-                func = p
-            if ns in namespaces.values():
-                #predicate is one of builtin OWL or rdf predicates
-                pred = getattr(self, func)
-                res = pred(s, o) 
-                if not res :
-                    continue
-                if type(res) != list :
-                    res = [res]
-                avar = self.make_var(ClassDomain, s) 
-            else:
-                avar = self.make_var(Property, p)
-                # Set the values of the property p to o
-                sub = self.make_var(ClassDomain, s) 
-                obj = self.make_var(Thing, o) 
-                propdom = self.variables[avar]
-                res = propdom.addValue(sub, obj) 
+            if (s, p, o) in self.seen:
+                continue
+            self.seen[(s, p, o)] = True
+            self.consider_triple((s, p, o))
+    
+    def consider_triple(self,(s, p, o)):
+        if p.find('#') != -1:
+            ns, func = p.split('#')
+        else:
+            ns =''
+            func = p
+        if ns in namespaces.values():
+            #predicate is one of builtin OWL or rdf predicates
+            pred = getattr(self, func)
+            res = pred(s, o)
+            if not res :
+                return
+            if type(res) != list :
+                res = [res]
+            avar = self.make_var(ClassDomain, s)
+        else:
+            avar = self.make_var(Property, p)
+            # Set the values of the property p to o
+            sub = self.make_var(ClassDomain, s)
+            obj = self.make_var(Thing, o)
+            propdom = self.variables[avar]
+            res = propdom.addValue(sub, obj)
 
+    
     def solve(self,verbose=0):
         rep = Repository(self.variables.keys(), self.variables, self.constraints)
         return Solver().solve(rep, verbose)
-
+    
     def consistency(self, verbose=0):
         self.rep = Repository(self.variables.keys(), self.variables, self.constraints)
         self.rep.consistency(verbose)
-
+    
     def flatten_rdf_list(self, rdf_list):
         res = []
         if not type(rdf_list) == list:
@@ -280,7 +287,7 @@
                 res.append(list(self.graph.objects(lis, rdf_first))[0])
                 lis = list(self.graph.objects(lis, rdf_rest))[0]
         else:
-            # For testing 
+            # For testing
             avar = self.make_var(List, BNode('anon_%r'%rdf_list))
             if type(rdf_list[0]) ==  list:
                 res = [tuple(x) for x in rdf_list]
@@ -288,7 +295,15 @@
                 res = rdf_list
         self.variables[avar].setValues(res)
         return avar
-            
+    
+    def resolve_item(self, item):
+        item_as_subject = self.graph.triples((item, None, None))
+        for triple in item_as_subject:
+            if triple in self.seen:
+               continue
+            self.seen[triple] = True
+            self.consider_triple(triple)
+    
     def make_var(self, cls=fd, a=''):
         if type(a) == URIRef:
             if a.find('#') != -1:
@@ -297,7 +312,7 @@
                 ns,name = a,''
             if ns not in uris.keys():
                 uris[ns] = ns.split('/')[-1]
-            a = uris[ns] + '_' + name    
+            a = uris[ns] + '_' + name
             var = str(a.replace('-','_'))
         else:
             var = a
@@ -309,13 +324,13 @@
             vals = self.variables[var].getValues()
             self.variables[var] = cls(var)
             self.variables[var].setValues(vals)
-        return var 
+        return var
 
 #---------------- Implementation ----------------
-
+    
     def comment(self, s, var):
         pass
-        
+    
     def type(self, s, var):
         if not var in builtin_voc :
             # var is not one of the builtin classes
@@ -330,16 +345,16 @@
                 return
             else:
                 svar = self.make_var(None, s)
-            if not (self.variables.has_key(svar) and 
+            if not (self.variables.has_key(svar) and
                    isinstance(self.variables[svar], cls)):
                 svar = self.make_var(cls, s)
             cls = self.variables[svar]
             if hasattr(cls, 'constraint'):
                 self.constraints.append(cls.constraint)
-
+    
     def first(self, s, var):
         pass
-
+    
     def rest(self, s, var):
         pass
     
@@ -347,49 +362,49 @@
         svar =self.make_var(Restriction, s)
         avar =self.make_var(Property, var)
         self.variables[svar].property = avar
-        
 
-#---Class Axioms---#000000#FFFFFF-----------------------------------------------
 
+#---Class Axioms---#000000#FFFFFF-----------------------------------------------
+    
     def subClassOf(self, s, var):
-        # s is a subclass of var means that the 
+        # s is a subclass of var means that the
         # class extension of s is a subset of the
-        # class extension of var, ie if a indiviual is in 
+        # class extension of var, ie if a indiviual is in
         # the extension of s it must be in the extension of
         # var
         avar = self.make_var(None, var)
         svar = self.make_var(ClassDomain, s)
         cons = SubClassConstraint( svar, avar)
         self.constraints.append(cons)
-
+    
     def equivalentClass(self, s, var):
         self.subClassOf(s, var)
         self.subClassOf(var, s)
-
+    
     def disjointWith(self, s, var):
         avar = self.make_var(None, var)
         svar = self.make_var(None, s)
-        constrain = DisjointClassConstraint(svar, avar) 
+        constrain = DisjointClassConstraint(svar, avar)
         self.constraints.append(constrain)
-
+    
     def complementOf(self, s, var):
         # add constraint of not var
         # TODO: implementthis for OWL DL
 ##        avar = self.make_var(ClassDomain, var)
 ##        svar = self.make_var(ClassDomain, s)
             pass
-
+    
     def oneOf(self, s, var):
         var = self.flatten_rdf_list(var)
         #avar = self.make_var(List, var)
         svar = self.make_var(ClassDomain, s)
         res = self.variables[var].getValues()
         self.variables[svar].setValues(res)
-
+    
     def unionOf(self,s, var):
         var = self.flatten_rdf_list(var)
         vals = self.variables[var].getValues()
-
+        
         res = []
         for val in vals:
              res.extend([x for x in val])
@@ -397,7 +412,7 @@
         vals = self.variables[svar].getValues()
         res.extend(vals)
         self.variables[svar].setValues(res)
-
+    
     def intersectionOf(self, s, var):
         var = self.flatten_rdf_list(var)
         vals = self.variables[var].getValues()
@@ -412,33 +427,33 @@
         self.variables[svar].setValues(res)
 
 #---Property Axioms---#000000#FFFFFF--------------------------------------------
-
+    
     def range(self, s, var):
         avar = self.make_var(ClassDomain, var)
         svar = self.make_var(Property, s)
         cons = RangeConstraint(svar, avar)
         self.constraints.append(cons)
-
+    
     def domain(self, s, var):
         # The classes that has this property (s) must belong to the class extension of var
         avar = self.make_var(ClassDomain, var)
         svar = self.make_var(Property, s)
         cons = DomainConstraint(svar, avar)
         self.constraints.append(cons)
-
+    
     def subPropertyOf(self, s, var):
         # s is a subproperty of var
         avar = self.make_var(Property, var)
         svar = self.make_var(Property, s)
         cons = SubPropertyConstraint( svar, avar)
         self.constraints.append(cons)
-
+    
     def equivalentProperty(self, s, var):
         avar = self.make_var(Property, var)
         svar = self.make_var(Property, s)
         cons = EquivalentPropertyConstraint( svar, avar)
         self.constraints.append(cons)
-
+    
     def inverseOf(self, s, var):
         avar = self.make_var(Property, var)
         svar = self.make_var(Property, s)
@@ -446,39 +461,39 @@
         self.constraints.append(con)
 
 #---Property restrictions------------------------------------------------------
-
+    
     def maxCardinality(self, s, var):
         """ Len of finite domain of the property shall be less than or equal to var"""
         svar =self.make_var(Restriction, s)
         constrain = MaxCardinality(svar, int(var))
-        self.constraints.append(constrain) 
+        self.constraints.append(constrain)
         # Make a new variable that can hold the domain of possible cardinality
         # values
         self.variables[svar].TBox['Cardinality'] = (range( int(var)+1), 'in')
 #        var_name = '%s_Cardinality' % svar
 #        self.variables[var_name] = fd(range(int(var)+1))
-	          
+    
     def minCardinality(self, s, var):
         """ Len of finite domain of the property shall be greater than or equal to var"""
         svar =self.make_var(Restriction, s)
         constrain = MinCardinality(svar, int(var))
-        self.constraints.append(constrain) 
+        self.constraints.append(constrain)
         self.variables[svar].TBox['Cardinality'] = ( range(int(var)), 'not in')
 #        var_name = '%s_Cardinality' % svar
 #        self.variables[var_name] = fd(range(int(var)))
 #        constraint = Expression(var_name,' not in')
 #        self.constraints.append(constraint)
-
+    
     def cardinality(self, s, var):
         """ Len of finite domain of the property shall be equal to var"""
         svar =self.make_var(Restriction, s)
         # Check if var is an int, else find the int buried in the structure
         constrain = Cardinality(svar, int(var))
-        self.constraints.append(constrain) 
+        self.constraints.append(constrain)
         self.variables[svar].TBox['Cardinality'] = ( [int(var)], 'in')
 #        var_name = '%s_Cardinality' % svar
-#        self.variables['var_name'] = fd(int(var))        
-
+#        self.variables['var_name'] = fd(int(var))
+    
     def differentFrom(self, s, var):
         s_var = self.make_var(Thing, s)
         var_var = self.make_var(Thing, var)
@@ -491,532 +506,38 @@
         var_var = self.flatten_rdf_list(var)
         #var_var = self.make_var(List, var)
         for v in var_var:
-           indx = var_var.index(v) 
+           indx = var_var.index(v)
            for other in var_var[indx+1:]:
                self.differentFrom(v, other)
         constrain = AllDifferentConstraint(s_var, var_var)
         self.constraints.append(constrain)
-
+    
     def sameAs(self, s, var):
         s_var = self.make_var(None, s)
         var_var = self.make_var(None, var)
         constrain = SameasConstraint(s_var, var_var)
         self.constraints.append(constrain)
-
+    
     def hasValue(self, s, var):
         svar = self.make_var(Restriction, s)
         avar = self.make_var(None, var)
         constrain = HasvalueConstraint(svar, avar)
         self.constraints.append(constrain)
-        
+    
     def allValuesFrom(self, s, var):
         svar = self.make_var(Restriction, s)
         avar = self.make_var(None, var)
         constrain = AllValueConstraint(svar, avar)
         self.constraints.append(constrain)
-
+    
     def someValuesFrom(self, s, var):
         svar = self.make_var(Restriction, s)
         avar = self.make_var(None, var)
         constrain = SomeValueConstraint(svar, avar)
         self.constraints.append(constrain)
-
+    
     def imports(self, s, var):
-        # PP TODO: implement this 
+        # PP TODO: implement this
         pass
 
 # ----------------- Helper classes ----------------
-
-class OwlConstraint(AbstractConstraint):
-
-    cost = 1
-    
-    def __init__(self, variable):
-        AbstractConstraint.__init__(self, [variable])
-        self.variable = variable
-
-    def __repr__(self):
-        return '<%s  %s>' % (self.__class__.__name__, str(self._variables[0]))
-
-    def estimateCost(self, domains):
-        return self.cost
-
-def get_cardinality(props, cls):
-        if props.get(cls):
-           card = len(props[cls]) 
-        elif props.get(None):
-           card = len(props[None]) 
-        else:
-           card = 0
-        return card 
-
-class MaxCardinality(AbstractConstraint):
-    """Contraint: all values must be distinct"""
-
-    def __init__(self, variable, cardinality):
-        AbstractConstraint.__init__(self, [variable])
-        self.cost = 80
-        self.variable = variable
-        self.cardinality = cardinality
-
-    def __repr__(self):
-        return '<%s  %s %i>' % (self.__class__.__name__, str(self._variables[0]), self.cardinality)
-
-    def estimateCost(self, domains):
-        return self.cost
-    
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        prop = domains[self.variable].property
-        props = Linkeddict(domains[prop].getValues())
-        dom = domains[self.variable].getValues()
-        if not dom:
-            return 0
-        cls = dom[0]
-        card = get_cardinality(props, cls)
-        if card > self.cardinality:
-            raise ConsistencyFailure("Maxcardinality of %i exceeded by the value %i" %(self.cardinality,len(props[cls])))
-        else:
-            return 1
-
-class MinCardinality(MaxCardinality):
-
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        prop = domains[self.variable].property
-        props = Linkeddict(domains[prop].getValues())
-        cls = domains[self.variable].getValues()[0]
-        card = get_cardinality(props, cls)
-        if card < self.cardinality:
-            raise ConsistencyFailure("MinCardinality of %i not achieved by the value %i" %(self.cardinality,len(props[cls])))
-        else:
-            return 1
-        
-class Cardinality(MaxCardinality):
-    
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        prop = domains[self.variable].property
-        props = Linkeddict(domains[prop].getValues())
-        cls = domains[self.variable].getValues()[0]
-        card = get_cardinality(props, cls)
-        if card != self.cardinality:
-            raise ConsistencyFailure("Cardinality of %i exceeded by the value %r for %r" %
-                                     (self.cardinality, props[cls], prop))
-        else:
-            return 1
-
-class SubClassConstraint(AbstractConstraint):
-
-    cost=1
-    
-    def __init__(self, variable, cls_or_restriction):
-        AbstractConstraint.__init__(self, [variable, cls_or_restriction])
-        self.object = cls_or_restriction
-        self.variable = variable
-        
-    def estimateCost(self, domains):
-        return self.cost
-
-    def __repr__(self):
-        return '<%s  %s %s>' % (self.__class__.__name__, str(self._variables[0]), self.object)
-
-    def narrow(self, domains):
-        subdom = domains[self.variable]
-        superdom = domains[self.object]
-        vals = []
-        vals += superdom.getValues()
-        vals += subdom.getValues() +[self.variable]
-        superdom.setValues(vals)
-	        
-        return 0
-
-class DisjointClassConstraint(SubClassConstraint):
-
-    def narrow(self, domains):
-        subdom = domains[self.variable]
-        superdom = domains[self.object]
-        vals1 = superdom.getValues()  
-        vals2 = subdom.getValues()  
-        for i in vals1:
-            if i in vals2:
-                raise ConsistencyFailure()
-
-class ComplementClassConstraint(SubClassConstraint):
-
-    def narrow(self, domains):
-        subdom = domains[self.variable]
-        superdom = domains[self.object]
-
-class RangeConstraint(SubClassConstraint):
-
-    cost = 30
-    
-    def narrow(self, domains):
-        propdom = domains[self.variable]
-        rangedom = domains[self.object]
-        newrange = rangedom.getValues()
-        res = []
-        oldrange = propdom.range
-        if oldrange:
-            for v in oldrange:
-                if v in newrange:
-                    res.append(v)
-        else:
-            res = newrange
-        propdom.range = res
-        propdom.setValues([(None,i) for i in res])
-        #prop = Linkeddict(propdom.getValues())
-        #for pval in sum(prop.values(),[]):
-        #    if pval not in range:
-        #        raise ConsistencyFailure("Value %r not in range %r for Var %s"%(pval,range, self.variable))
-
-class DomainConstraint(SubClassConstraint):
-
-    cost = 200
-
-    def narrow(self, domains):
-        propdom = domains[self.variable]
-        domaindom = domains[self.object]
-        newdomain = domaindom.getValues() +[self.object]
-        domain = []
-        olddomain = propdom.domain
-        if olddomain:
-            for v in olddomain:
-                if v in newdomain:
-                    domain.append(v)
-        else:
-            domain = newdomain
-        propdom.domain = domain
-        prop = Linkeddict(propdom.getValues())
-        for pval in prop.keys():
-            if pval not in domain:
-                raise ConsistencyFailure("Value %r not in range %r"%(pval, domain))
-
-class SubPropertyConstraint(SubClassConstraint):
-
-    def narrow(self, domains):
-        subdom = domains[self.variable]
-        superdom = domains[self.object]
-        vals = superdom.getValues()
-        for val in subdom.getValues():
-            if not val in vals:
-                vals.append(val)
-        superdom.setValues(vals)
-
-class EquivalentPropertyConstraint(SubClassConstraint):
-
-    cost = 100
-    
-    def narrow(self, domains):
-        subdom = domains[self.variable]
-        superdom = domains[self.object]
-        vals = superdom.getValues()  
-        for val in subdom.getValues():
-            if not val in vals:
-                raise ConsistencyFailure("The Property %s is not equivalent to Property %s" %
-                                         (self.variable, self.object))
-
-class TypeConstraint(SubClassConstraint):
-    cost = 1
-    def narrow(self, domains):
-        subdom = domains[self.variable]
-        superdom = domains[self.object]
-        vals = []
-        vals += superdom.getValues()  
-        vals.append(self.variable)
-        superdom.setValues(vals)
-        return 1
-
-class FunctionalCardinality(OwlConstraint):
-    """Contraint: all values must be distinct"""
-
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        domain = domains[self.variable].getValues()
-        domain_dict = Linkeddict(domain)
-        for cls, val in domain_dict.items():
-            if len(val) != 1:
-                raise ConsistencyFailure("FunctionalCardinality error")
-        else:
-            return 0
-
-class InverseFunctionalCardinality(OwlConstraint):
-    """Contraint: all values must be distinct"""
-
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        domain = domains[self.variable].getValues()
-        vals = {}
-        for cls, val in domain:
-            if vals.has_key(val):
-                raise ConsistencyFailure("InverseFunctionalCardinality error")
-            else:
-                vals[val] = 1
-        else:
-            return 0
-
-class Linkeddict(dict):
-    def __init__(self, values=()):
-        for k,v in values:
-            dict.setdefault(self,k,[])
-            if type(v) == list:
-                dict.__setitem__(self, k, v)
-            else:
-                if not v in dict.__getitem__(self,k):
-                    dict.__getitem__(self,k).append(v)
-            
-class TransitiveConstraint(OwlConstraint):
-    """Contraint: all values must be distinct"""
-
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        domain = domains[self.variable].getValues()
-        domain_dict = Linkeddict(domain)
-        for cls, val in domain:
-            if  val in domain_dict:
-                for v in domain_dict[val]:
-                    domain.append((cls,v))
-        domains[self.variable].setValues(domain)
-
-class SymmetricConstraint(OwlConstraint):
-    """Contraint: all values must be distinct"""
-
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        domain = domains[self.variable].getValues()
-        for cls, val in domain:
-            if not (val, cls) in domain:
-                domain.append((val,cls))
-        domains[self.variable].setValues(domain)
-
-class InverseofConstraint(SubClassConstraint):
-    """Contraint: all values must be distinct"""
-    cost = 200
-    
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        obj_domain = domains[self.object].getValues()
-        sub_domain = domains[self.variable].getValues()
-        res = []
-        for cls, val in obj_domain:
-            if not (val,cls) in sub_domain:
-                raise ConsistencyFailure("Inverseof failed for (%r, %r) in %r" % 
-                                         (val, cls, sub_domain) )
-        for cls, val in sub_domain:
-            if not (val,cls) in obj_domain:
-                raise ConsistencyFailure("Inverseof failed for (%r, %r) in %r" % 
-                                         (val, cls, obj_domain)) 
-
-class DifferentfromConstraint(SubClassConstraint):
-
-    def narrow(self, domains):
-        if self.variable == self.object:
-            raise ConsistencyFailure("%s can't be differentFrom itself" % self.variable)
-        else:
-            return 0
-
-class SameasConstraint(SubClassConstraint):
-
-    def narrow(self, domains):
-        if self.variable == self.object:
-            return 1
-        else:
-            for dom in domains.values():
-                vals = dom.getValues()
-                if isinstance(dom, Property):
-                    val = Linkeddict(vals)
-                    if self.variable in val.keys() and not self.object in val.keys():
-                        vals +=[(self.object,v) for v in val[self.variable]]
-                        dom.setValues(vals)
-                    elif not self.variable in val.keys() and self.object in val.keys():
-                        vals +=[(self.variable,v) for v in val[self.object]]
-                        dom.setValues(vals)
-                    elif self.variable in val.keys() and self.object in val.keys():
-                        if not val[self.object] == val[self.variable]:
-                            raise ConsistencyFailure("Sameas failure: The two individuals (%s, %s) \
-                                                has different values for property %r"%(self.variable, self.object, dom))
-                else:
-                    if self.variable in vals and not self.object in vals:
-                        vals.append(self.object)
-                    elif not self.variable in vals and self.object in vals:
-                        vals.append(self.variable)
-                    else:
-                        continue
-                    dom.setValues(vals)
-            return 0
-
-class ListConstraint(OwlConstraint):
-    """Contraint: all values must be distinct"""
-
-    cost = 10
-
-    def narrow(self, domains):
-        """narrowing algorithm for the constraint"""
-        
-        vals =[]
-        vals += domains[self.variable].getValues()
-        if vals == []:
-            return 0
-        while True:
-            if vals[-1] in domains.keys() and isinstance(domains[vals[-1]], List):
-                vals = vals[:-1] + domains[vals[-1]].getValues()
-                if domains[vals[-1]].remove : 
-                    domains.pop(vals[-1])
-            else:
-                break
-        domains[self.variable].setValues(vals)
-        return 1
-
-class RestrictionConstraint(OwlConstraint):
-
-    cost = 70
-
-    def narrow(self, domains):
-        prop = domains[self.variable].property
-        vals = domains[self.variable].getValues()
-        if vals:
-            cls = vals[0]
-            props = domains[prop].getValues()
-            props.append((cls, None))
-            domains[prop].setValues(props)
-            return 1
-        else:
-            return 0
-        
-class OneofPropertyConstraint(AbstractConstraint):
-
-    def __init__(self, variable, list_of_vals):
-        AbstractConstraint.__init__(self, [variable ])
-        self.variable = variable
-        self.List = list_of_vals
-    cost = 100
-
-    def estimateCost(self, domains):
-        return self.cost
-
-    def narrow(self, domains):
-        val = domains[self.List].getValues()
-        if isinstance(domains[self.variable],Restriction):
-            # This should actually never happen ??
-            property = domains[self.variable].property
-            cls = domains[self.variable].getValues()[0]
-            prop = Linkeddict(domains[property].getValues())
-            for v in prop[cls]:
-                if not v in val:
-                    raise ConsistencyFailure(
-                        "The value of the property %s in the class %s is not oneof %r"
-                            %(property, cls, val))
-        else:
-            domains[self.variable].setValues(val)
-            return 1
-
-class UnionofConstraint(OneofPropertyConstraint):
-
-    cost = 200
-
-    def narrow(self, domains):
-        val = domains[self.List].getValues()
-        union = []
-        for v in val:
-            for u in domains[v].getValues():
-                if not u in union:
-                    union.append(u)
-        cls = domains[self.variable].setValues(union)
-        
-class IntersectionofConstraint(OneofPropertyConstraint):
-
-    cost = 200
-
-    def narrow(self, domains):
-        val = domains[self.List].getValues()
-        intersection = domains[val[0]].getValues()
-        for v in val[1:]:
-            vals= domains[v].getValues()
-            remove = []
-            for u in intersection:
-                if not u in vals:
-                    remove.append(u)
-            for u in remove:
-                intersection.remove(u)
-        cls = domains[self.variable].setValues(intersection)
-        term = {}
-        for l in [domains[x] for x in val]:
-            if hasattr(l,'TBox'):
-                TBox = l.TBox
-                prop = l.property
-                for item in TBox.values():
-                    term.setdefault(prop,[])
-                    term[prop].append(item)
-        for prop in term:
-            axioms = term[prop]
-            ranges = [ax[0] for ax in axioms]
-            res = []
-            while axioms:
-                r, comp = axioms.pop(0)
-                if res:
-                    res = [x for x in res if eval('x %s r' % comp)]
-                else:
-                    res = [x for x in r if eval('x %s r' % comp)]
-                if not res:
-                    axioms.append((r,comp))
-        if not res:
-            raise ConsistencyFailure("Inconsistent use of intersectionOf")
-
-class SomeValueConstraint(OneofPropertyConstraint):
-
-    cost = 100
-        
-    def narrow(self, domains):
-        val = domains[self.List].getValues()
-        property = domains[self.variable].property
-        cls = domains[self.variable].getValues()[0]
-        prop = Linkeddict(domains[property].getValues())
-        for v in prop[cls]:
-            if v in val:
-                break
-        else:
-            raise ConsistencyFailure(
-                    "The value of the property %s in the class %s has no values from %r"
-                        %(property, cls, val))
-
-class AllValueConstraint(OneofPropertyConstraint):
-
-    cost = 100
-        
-    def narrow(self, domains):
-        val = domains[self.List].getValues()
-        property = domains[self.variable].property
-        cls = domains[self.variable].getValues()[0]
-        prop = Linkeddict(domains[property].getValues())
-        for v in prop[cls]:
-            if not v in val:
-                raise ConsistencyFailure(
-                    "The value of the property %s in the class %s has a value not from %r"
-                        %(property, cls, val))
-
-class HasvalueConstraint(AbstractConstraint):
-
-    def __init__(self, variable, List):
-        AbstractConstraint.__init__(self, [variable])
-        self.variable = variable
-        self.List = List
-
-    cost = 100
-
-    def estimateCost(self, domains):
-        return self.cost
-
-    def narrow(self, domains):
-        val = self.List
-        property = domains[self.variable].property
-        cls = domains[self.variable].getValues()[0]
-        prop = Linkeddict(domains[property].getValues())
-        for v in prop[cls]:
-            if v == val:
-                break
-        else:
-            raise ConsistencyFailure(
-                    "The value of the property %s in the class %s has a value not from %r"
-                        %(property, cls, val))
-

Modified: pypy/dist/pypy/lib/pyontology/test/test_ontology.py
==============================================================================
--- pypy/dist/pypy/lib/pyontology/test/test_ontology.py	(original)
+++ pypy/dist/pypy/lib/pyontology/test/test_ontology.py	Fri May  5 10:05:19 2006
@@ -500,7 +500,7 @@
 
 
 def test_cardinality_terminology():
-    py.test.skip("In progress")
+    #py.test.skip("In progress")
     # Modeled after one of the standard tests (approved/maxCardinality)
     # 'cls' by subclassing two maxCardinality restrictions becomes the set of
     # individuals satisfying both restriction, ie having exactly 2 values of
@@ -526,7 +526,7 @@
     O.minCardinality(restr2, 3)
     constraints = len(O.constraints)
     py.test.raises(ConsistencyFailure, O.consistency, 3)
-    assert len(O.constraints) < constraints
-    py.test.raises(ConsistencyFailure, O.consistency, 3)
+    
+    assert 0
 
     



More information about the Pypy-commit mailing list