Ignore changes in the amount of whitespace
Differences between version dated 2010-08-10 18:36:20 and 2011-08-31 21:11:59
Deletions are marked like this.
Additions are marked like this.
important.
(Note also that expression objects aren't required to have a ``branch_table()``
method; that's just an implementation detail of the demos in this document.
method; that's just an implementation detail of the demos in this document.)
Computing Selectivity and Building Nodes
subclass to handle reseeds differently.
expanded_sets()
Return a list of ``(seed, (inc, exc)`` tuples, where ``inc`` and ``exc``
Return a list of ``(seed, (inc, exc))`` tuples, where ``inc`` and ``exc``
are integer case lists. This method is for debugging and testing only.
all_seeds
All of the criterion objects provided by ``peak.rules.criteria`` have
``BitmapIndex`` subclasses suitable for indexing them::
>>> from peak.rules.criteria import Value, Range, IsObject, Class, Classes
>>> from peak.rules.criteria import Value, Range, IsObject, Class, Conjunction
To demonstrate them, we'll use a dummy engine object::
>>> ind.add_case(1, ppne)
>>> dict(ind.expanded_sets())
{...: [[0], [1]], None: [[1], [0]]}
>>> dict(ind.expanded_sets()) == {id(p): [[0], [1]], None: [[1], [0]]}
True
>>> ind.selectivity([1])
(2, 1)
>>> ind.selectivity([0,1])
(2, 2)
>>> ind.add_case(2, IsObject(object()))
>>> q = object()
>>> ind.add_case(2, IsObject(q))
>>> ind.selectivity([1]) # now it's (3,2) instead of (2,1) or (3,1)
(3, 2)
>>> ind.selectivity([0]) # 'is' pointers are always 1
(3, 1)
>>> dict(ind.expanded_sets()) == {
... None: [[1], [0, 2]], id(p): [[0], [1]], id(q): [[1, 2], []],
... }
True
>>> from peak.rules.core import intersect
>>> ind.add_case(3, intersect(ppne, IsObject(q,False)))
>>> dict(ind.expanded_sets()) == {
... None: [[1, 3], [0, 2]], id(p): [[0], [1, 3]], id(q): [[1, 2], [3]],
... }
True
>>> r = object()
>>> ind.add_case(4, IsObject(r))
>>> dict(ind.expanded_sets()) == {
... None: [[1, 3], [0, 2, 4]], id(p): [[0], [1, 3]],
... id(q): [[1, 2], [3]], id(r): [[1, 3, 4], []]
... }
True
>>> ind.selectivity([2])
(3, 1)
>>> dict(ind.expanded_sets()) == {
... int: [[0], [2]], object: [[2], []], myint: [[0, 1], [2]]
... int: [[0], []], object: [[2], []], myint: [[0, 1], []]
... }
True
(4, 2)
>>> dict(ind.expanded_sets()) == {
... int: [[0], [2]], object: [[2], []], other: [[3], []],
... myint: [[0, 1], [2]]
... int: [[0], []], object: [[2], []], other: [[2, 3], []],
... myint: [[0, 1], []]
... }
True
# the default cases should include all of the "not isinstance" criteria
>>> list(from_bits(ind.seed_bits(to_bits(range(4)))[0]))
[2]
Multiple Classes
================
``Classes`` objects hold sets of 2 or more ``Class`` criteria, and represent
the "and" of those criteria. This is the most complex type of criteria to
index, because there's no easy way to incrementally update a set intersection::
``Conjunction`` objects can hold sets of 2 or more ``Class`` criteria, and
represent the "and" of those criteria. This is the most complex type of
criteria to index, because there's no easy way to incrementally update a set
intersection::
>>> class a(object): pass
>>> class b(object): pass
>>> ind = TypeIndex(eng, 'classes')
>>> ind.add_case(0, Classes([Class(a), Class(b)]))
>>> ind.add_case(0, Conjunction([Class(a), Class(b)]))
>>> ind.selectivity([0])
(3, 0)
>>> dict(ind.expanded_sets()) == {
True
>>> ind.add_case(2, Classes([Class(a), Class(b), Class(c, False)]))
>>> ind.add_case(2, Conjunction([Class(a), Class(b), Class(c, False)]))
>>> ind.selectivity([2])
(4, 0)
>>> ind.selectivity([0]) # c, e
(6, 2)
(5, 2)
>>> ind.selectivity([2])
(6, 1)
(5, 1)
>>> ind.selectivity([3])
(6, 1)
(5, 1)
>>> dict(ind.expanded_sets()) == {
... a: [[], []], b: [[], []], c: [[0, 1], []], object: [[], []],
... d: [[], []], e: [[0, 2, 3], []]
... e: [[0, 2, 3], []]
... }
True
>>> ind.add_case(4, Class(f))
>>> ind.selectivity([0]) # c, e, f
(7, 3)
(6, 3)
>>> ind.selectivity([2])
(7, 1)
(6, 1)
>>> dict(ind.expanded_sets()) == {
... a: [[], []], b: [[], []], c: [[0, 1], []], object: [[], []],
... d: [[], []], e: [[0, 2, 3], []], f: [[0, 1, 3, 4], []]
... e: [[0, 2, 3], []], f: [[0, 1, 3, 4], []]
... }
True
>>> ind.add_case(5, Class(g))
>>> ind.selectivity([0]) # c, e, f, g
(8, 4)
(7, 4)
>>> ind.selectivity([2]) # still just 'e'
(8, 1)
(7, 1)
>>> Classes([Class(d, False), Class(e, False)])
>>> Conjunction([Class(d, False), Class(e, False)])
Class(<class 'd'>, False)
>>> ind.add_case(6, Classes([Class(d, False), Class(e, False)]))
>>> ind.add_case(6, Conjunction([Class(d, False), Class(e, False)]))
>>> ind.selectivity([6]) # all but d, e, f
(8, 5)
>>> dict(ind.expanded_sets()) == {
... a: [[], []], b: [[], []], c: [[0, 1], []], object: [[6], []],
... d: [[], [6]], e: [[0, 2, 3], [6]], f: [[0, 1, 3, 4], [6]], g: [[0, 1, 5], []]
... a: [[6], []], b: [[6], []], c: [[0, 1, 6], []], object: [[6], []],
... d: [[], []], e: [[0, 2, 3], []], f: [[0, 1, 3, 4], []],
... g: [[0, 1, 5, 6], []],
... }
True
# the default cases should include all of the "not isinstance" criteria
>>> list(from_bits(ind.seed_bits(to_bits(range(7)))[0]))
[6]
Reseeding
=========
information for the new ``x`` class::
>>> dict(ind.expanded_sets()) == {
... a: [[], []], b: [[], []], c: [[0, 1], []], object: [[6], []],
... d: [[], [6]], e: [[0, 2, 3], [6]], f: [[0, 1, 3, 4], [6]], g: [[0, 1, 5], []],
... x: [[0, 2], []]
... a: [[6], []], b: [[6], []], c: [[0, 1, 6], []], object: [[6], []],
... d: [[], []], e: [[0, 2, 3], []], f: [[0, 1, 3, 4], []],
... g: [[0, 1, 5, 6], []], x: [[0, 2, 6], []]
... }
True
(3, 4)
>>> dict(ind.expanded_sets()) == {
... a:[[0, 2], []],
... b:[[], [1]],
... a:[[0, 1, 2], []],
... b:[[], []],
... object:[[1], []]
... }
True
(3, 6)
>>> dict(ind.expanded_sets()) == {
... a:[[0, 2], [3]],
... b:[[], [1]],
... a:[[0, 1, 2], []],
... b:[[3], []],
... object:[[1, 3], []]
... }
True
>>> ind.add_case(4, Classes([Class(a), istype(c, False)]))
>>> ind.add_case(4, Conjunction([Class(a), istype(c, False)]))
>>> ind.selectivity([4])
(4, 1)
>>> dict(ind.expanded_sets()) == {
... a:[[0, 2, 4], [3]],
... b:[[], [1]],
... c:[[2], [3]],
... a:[[0, 1, 2, 4], []],
... b:[[3], []],
... c:[[1, 2], []],
... object:[[1, 3], []]
... }
True
>>> ind.reseed(Class(e))
>>> dict(ind.expanded_sets()) == {
... a:[[0, 2, 4], [3]],
... b:[[], [1]],
... c:[[2], [3]],
... d:[[], []],
... e:[[2, 4], [3]],
... a:[[0, 1, 2, 4], []],
... b:[[3], []],
... c:[[1, 2], []],
... e:[[1, 2, 4], []],
... object:[[1, 3], []]
... }
True
>>> ind.add_case(5, istype(object))
# the default cases should include all of the "not isinst/type" criteria
>>> list(from_bits(ind.seed_bits(to_bits(range(6)))[0]))
[1, 3]