[Zope-dev] Acquisition Confusion :S

Steve Alexander steve@cat-box.net
Mon, 07 Aug 2000 21:27:54 +0100


Chris Withers wrote:
> 
> Steve Alexander said he was going to have a think, but I haven't heard
> anything since he mentioned it...

I'll have to start running a Kibo-bot soon :-)

I've got as far as defining the difference between the two acquisition
behaviours.

Warning: The following goes into some detail about acquisition algebras.
There are lots of nested parentheses with letters in them.


Let's say we have the following object tree. The upper-case letters
represent names, not identity. The lower-case letters represent
identity.

/
|-A        a
| |-B      b
|
|-X        x
| |-P      p1
| |-Y      y
|
|-P        p0

Let's consider the path X.Y.A.B.P in both types of acquisition.

Containment first:

  Start at the root.
  Look for X. Find X at x.
  Look for Y in x. Find Y at y.
  Look for A in y.
    Not found, so look for A in x.
    Not found, so look for A in /. Found as a.
  Look for B in a. Found as b.
  Look for P in b.
    Not found, so look for P in a.
    Not found, so look for P in /. Found as p0.

Context first

  Start at the root.
  Look for X. Find X at x.
  Look for Y in x. Find Y at y.
  Look for A in y.
    Not found, so look for A in x.
    Not found, so look for A in /. Found as a.
  Look for B in a. Found as b.
  Look for P in b.
    Not found, so look for P in a.
    Not found, so look for P in y.
    Not found, so look for P in x. Found as p1.


The acquisition algebra is based on the "of" operator: (object of
context).

The difference in algebra is that with containment-first, as you build
up the expression, you add to it using the last object you searched as
the context part of the expression.

With conext-first, you need to add the whole expression so far as the
context part of the expression.

Containment first:

           Start at the root.

(X of /)   
           Look for X. Find X at x.

(Y of X) of (X of /)
           Look for Y in x. Find Y at y.

(A of /) of ((Y of X) of (X of /))
           Look for A in y.
             Not found, so look for A in x.
             Not found, so look for A in /. Found as a.

(B of A) of ((A of /) of ((Y of X) of (X of /)))
           Look for B in a. Found as b.

(P of /) of ((B of A) of ((A of /) of ((Y of X) of (X of /))))
           Look for P in b.
             Not found, so look for P in a.
             Not found, so look for P in /. Found as p0.


Context first

  Start at the root.

(X of /)
  Look for X. Find X at x.

(Y of (X of /)) of (X of /)
  Look for Y in x. Find Y at y.

(A of (Y of (X of /))) of ((Y of (X of /)) of (X of /))
  Look for A in y.
    Not found, so look for A in x.
    Not found, so look for A in /. Found as a.

(B of (A of (Y of (X of /))) of ((Y of (X of /)) of (X of /)))
    of ((A of (Y of (X of /))) of ((Y of (X of /)) of (X of /)))
  Look for B in a. Found as b.

(P of (B of (A of (Y of (X of /))) of ((Y of (X of /)) of (X of /)))
    of ((A of (Y of (X of /))) of ((Y of (X of /)) of (X of /))))
        of (B of (A of (Y of (X of /))) of ((Y of (X of /)) of (X of
/)))
            of ((A of (Y of (X of /))) of ((Y of (X of /)) of (X of /)))
  Look for P in b.
    Not found, so look for P in a.
    Not found, so look for P in y.
    Not found, so look for P in x. Found as p1.


I just put that in to give Chris a fright :-)

You can see from this that the algorithm is more complex.

Acrually, it can be rather simplified, because what I've written out in
full above contains many internal repetitions. In C terms, these become
pointers to the same acquisition wrapper.

So the following...

(P of (B of (A of (Y of (X of /))) of ((Y of (X of /)) of (X of /)))
    of ((A of (Y of (X of /))) of ((Y of (X of /)) of (X of /))))
        of (B of (A of (Y of (X of /))) of ((Y of (X of /)) of (X of
/)))
            of ((A of (Y of (X of /))) of ((Y of (X of /)) of (X of /)))

...is really this:

((P of q) of q)
where q is ((B of r) of r)
where r is ((A of s) of s)
where s is ((Y of t) of t)
where t is (X of /)


I also wonder whether we need the second part of all the context-first
expansions above.
That is, whether (P of q) will do, instead of ((P of q) of q).

To see if the simplification works, let's take the example of acquiring
X.Y in the tree:

  /
  |-X
    |-Y

Containment first:

  (X of /)
  (Y of X) of (X of /)

Simplified Context first:

  (X of /)
  (Y of (X of /))


Applying this simplification to my larger example above, we get for the
following:

Simplified Context first

  Start at the root.

(X of /)
  Look for X. Find X at x.

(Y of (X of /))
  Look for Y in x. Find Y at y.

(A of (Y of (X of /)))
  Look for A in y.
    Not found, so look for A in x.
    Not found, so look for A in /. Found as a.

(B of (A of (Y of (X of /)))
  Look for B in a. Found as b.

(P of (B of (A of (Y of (X of /))) 
  Look for P in b.
    Not found, so look for P in a.
    Not found, so look for P in y.
    Not found, so look for P in x. Found as p1.


The search just proceeds as you read from left to right.
There are no repeated searches, unless you specify a repeated search
(such as A.B.A.A.B.C). Therefore, there is little need to simplify
expressions in the simplified context-first algebra.

--
Steve Alexander
Software Engineer
Cat-Box limited
http://www.cat-box.net