The PEAK Developers' Center   Diff for "PEAK-Rules/Criteria" UserPreferences
 
HelpContents Search Diffs Info Edit Subscribe XML Print View Up
Ignore changes in the amount of whitespace

Differences between version dated 2010-08-10 20:09:26 and 2011-08-31 21:11:41 (spanning 2 versions)

Deletions are marked like this.
Additions are marked like this.

 
    Test(IsInstance(Local('x')), Class(Y))
 
``Conjunction`` subclasses, on the other hand, are used to "and" together
``Conjunction`` instances, on the other hand, are used to "and" together
criteria that apply to the same dispatch expression. For example, this
expression::
 

 
would be represented internally like this::
 
    Test(IsInstance(Local('x')), Classes([Class(Y), Class(Z)]))
 
(That is, ``Classes`` is a ``Conjunction`` subclass representing the "and" of
multiple ``Class`` criteria.)
 
    Test(IsInstance(Local('x')), Conjunction([Class(Y), Class(Z)]))
 
The rest of this document describes how predicates, signatures, tests, dispatch
expressions, and criteria work together to create expressions in disjunctive

``False`` from the resulting predicate, and conditions that can never be true
are not used for indexing or dispatching.
 
Another special case is tuples containing nested tuples::
 
    >>> disjuncts( (float, (int, str)) )
    [(<type 'float'>, <type 'int'>),
     (<type 'float'>, <type 'str'>)]
 
    >>> disjuncts( ((int, str), object) )
    [(<type 'int'>, <type 'object'>),
     (<type 'str'>, <type 'object'>)]
 
    >>> disjuncts( (object, (int, str), float) )
    [(<type 'object'>, <type 'int'>, <type 'float'>),
     (<type 'object'>, <type 'str'>, <type 'float'>)]
 
    >>> disjuncts( ((int, str), (int, str)) )
    [(<type 'int'>, <type 'int'>),
     (<type 'str'>, <type 'int'>),
     (<type 'int'>, <type 'str'>),
     (<type 'str'>, <type 'str'>)]
 
This lets you avoid writing lots of decorators for the cases where you want
more than one type (or ``istype()`` instance) to match in a given argument
position. (As you can see, it's equivalent to specifying all the individual
combinations of specified types.)
 
Finally, the ``negate()`` function inverts the truth of a condition, e.g.::
 
    >>> negate(True)

``y is x`` condition would be true. Conversely, ``IsObject(x, False)``
represents the set of objects ``y`` for whom ``y is not x``::
 
    >>> from peak.rules.criteria import IsObject, NotObjects
    >>> from peak.rules.criteria import IsObject, Conjunction
 
    >>> o = object()
    >>> is_o = IsObject(o)

    False
 
And the intersection of multiple ``is not`` conditions produces a
``NotObjects`` set::
``Conjunction``::
 
    >>> not_foo = IsObject("foo", False)
    >>> not_bar = IsObject("bar", False)
    >>> not_foobar = intersect(not_foo, not_bar)
    >>> not_foobar
    NotObjects([IsObject('foo', False), IsObject('bar', False)])
    Conjunction([IsObject('foo', False), IsObject('bar', False)])
 
Which of course then implies each of the individual "not" conditions::
 

    >>> implies(not_foobar, IsObject("bar"))
    False
 
Oh, and an ``is`` condition implies any ``NotObjects`` that don't contain its
Oh, and an ``is`` condition implies any ``Conjunction`` that don't contain its
opposite::
 
    >>> implies(is_o, not_foobar)

    >>> implies(not_foobar, is_o)
    False
 
Finally, negating a ``NotObjects`` returns a disjunction of true ``IsObject``
tests, and vice versa::
Finally, negating a ``Conjunction`` of is-nots returns a disjunction of true
``IsObject`` tests, and vice versa::
 
    >>> negate(not_foobar)
    DisjunctionSet([IsObject('foo', True), IsObject('bar', True)])
 
    >>> negate(DisjunctionSet([IsObject('foo'), IsObject('bar')]))
    NotObjects([IsObject('foo', False), IsObject('bar', False)])
    Conjunction([IsObject('foo', False), IsObject('bar', False)])
 
 
Values and Ranges

    >>> intersect(Class(object), Class(int))
    Class(<type 'int'>, True)
 
The intersection of two or more unrelated ``Class`` criteria is a ``Classes``
set::
The intersection of two or more unrelated ``Class`` criteria is represented by
a ``Conjunction``::
 
    >>> from peak.rules.criteria import Classes
    >>> from peak.rules.criteria import Conjunction
 
    >>> intersect(Class(int, False), Class(str, False)) == Classes(
    >>> intersect(Class(int, False), Class(str, False)) == Conjunction(
    ... [Class(int, False), Class(str, False)]
    ... )
    True
 
``Classes`` is a subclass of ``Conjunction``, so all the standard
rules of intersection and implication apply.
 
 
Exact-Type and Type-Exclusion Tests
===================================

    False
 
Unless both are exclusion tests on different types, in which case their
intersection is a ``Classes()`` conjunction::
intersection is a ``Conjunction`` of the two::
 
    >>> intersect(istype(str, False), istype(int, False)) == Classes([
    >>> intersect(istype(str, False), istype(int, False)) == Conjunction([
    ... istype(int, False), istype(str, False)
    ... ])
    True

    istype(<type 'object'>, True)
 
But when it's intersected with a type exclusion test, the result is a
``Classes`` conjunction::
``Conjunction``::
 
    >>> intersect(istype(int, False), Class(str)) == Classes([
    >>> intersect(istype(int, False), Class(str)) == Conjunction([
    ... istype(int, False), Class(str, True)
    ... ])
    True
 
    >>> s = intersect(Class(str), istype(int, False))
    >>> s == Classes([istype(int, False), Class(str, True)])
    >>> s == Conjunction([istype(int, False), Class(str, True)])
    True
 
    >>> intersect(s, istype(int))

 
    >>> negate(
    ... Test('x',
    ... NotObjects([IsObject('foo',False), IsObject('bar',False)])
    ... Conjunction([IsObject('foo',False), IsObject('bar',False)])
    ... )
    ... ) == DisjunctionSet(
    ... [Test('x', IsObject('foo', True)),

criterion is the intersection of the original tests' criteria::
 
    >>> intersect(x_isa_int, Test("x", Class(str))) == Test(
    ... 'x', Classes([Class(int), Class(str)])
    ... 'x', Conjunction([Class(int), Class(str)])
    ... )
    True
 

 
    >>> intersect(x_int_y_str, Test("y", Class(float))) == Signature([
    ... Test('x', Class(int)),
    ... Test('y', Classes([Class(str), Class(float)]))
    ... Test('y', Conjunction([Class(str), Class(float)]))
    ... ])
    True
 
    >>> intersect(x_int_y_str, Test("x", Class(float))) == Signature([
    ... Test('x', Classes([Class(int), Class(float)])),
    ... Test('x', Conjunction([Class(int), Class(float)])),
    ... Test('y', Class(str))
    ... ])
    True
 
    >>> intersect(Test("x", Class(float)), x_int_y_str) == Signature([
    ... Test('x', Classes([Class(int), Class(float)])),
    ... Test('x', Conjunction([Class(int), Class(float)])),
    ... Test('y', Class(str))
    ... ])
    True

 
    >>> DisjunctionSet([OrElse([Class(a), Class(b)])]) == DisjunctionSet([
    ... Class(a, True),
    ... Classes([Class(a, False), Class(b, True)])
    ... Conjunction([Class(a, False), Class(b, True)])
    ... ])
    True
    

 
    >>> set(disjuncts(OrElse([istype(int), a_or_b]))) == set([
    ... istype(int),
    ... Classes([istype(int, False), Class(b)]),
    ... Classes([istype(int, False), Class(a)])
    ... Conjunction([istype(int, False), Class(b)]),
    ... Conjunction([istype(int, False), Class(a)])
    ... ])
    True
 

We'll do one more test, to show that the disjuncts of the negated portions of
the ``OrElse`` are also expanded::
 
    >>> a_and_b = Classes([Class(a), Class(b)])
    >>> a_and_b = Conjunction([Class(a), Class(b)])
    >>> not_a = Class(a, False)
    >>> not_b = Class(b, False)
    >>> int_or_str = DisjunctionSet([Class(int), Class(str)])
 
    >>> set(disjuncts(OrElse([a_and_b, int_or_str]))) == set([
    ... a_and_b, Classes([not_a, Class(int)]), Classes([not_a, Class(str)]),
    ... Classes([not_b, Class(int)]), Classes([not_b, Class(str)])
    ... a_and_b, Conjunction([not_a, Class(int)]), Conjunction([not_a, Class(str)]),
    ... Conjunction([not_b, Class(int)]), Conjunction([not_b, Class(str)])
    ... ])
    True
 

PythonPowered
ShowText of this page
EditText of this page
FindPage by browsing, title search , text search or an index
Or try one of these actions: AttachFile, DeletePage, LikePages, LocalSiteMap, SpellCheck