[cells-devel] Meta-level oof relations ... How?
Kenny Tilton
ktilton at nyc.rr.com
Tue May 24 14:56:58 UTC 2005
Kenny Tilton wrote:
>> If a new part is added or a part is deleted from the BOM or the
>> price attribute is changed.
>
>
> You just need slots Part-BOMs and BOM-Parts. Any rule such as:
>
> (defclass BOM ()
> ()
> (:default-initargs :price (c? (apply '+ (mapcar 'price (^parts))))))
>
> Will establish dependencies on (a) the parts slot and (b) the price of
> each part.
Nah, that will not work. We could have a parts slot on the BOM class
mediated by c-input, but then how does each part get its BOMs slot
updated? In the past I would kludge up an output method (via
def-c-output) on the parts slot of BOM to maintain the BOMs slot of
Part, but with Cells II we have a Prime Directive which says -- well, it
gets complicated, but logically those two updates are one, and output
methods do not run until propagation is complete, so the model is
inconsistent during propagation of any change to the parts list of a BOM
-- any rule that fires will see a BOMs value on any new part which does
not show the BOM to which the part has been added.
We can go the RDBMS route and create or destroy instances of Relations,
or we can do what AllegroStore does with its persistent CLOS database:
define a so-called inverse function on a slot, via a new defmodel slot
option. It would work like this:
(defclass BOM ()
((parts :cell t :inverse-cell part-BOMs :initform (c-in nil)
:initarg :parts :accessor parts)))
(defclass part ()())
After which:
(let ((p (make-be 'part))
(BOM (make-be 'bom :parts (c-in (list p)))))
(part-BOMs p))
=> A list containing the BOM instance
...and part-BOMS is a cell like any other cell, accept that there is no
BOMs slot on part. Now Cells II's new propagation scheme naturally takes
care of consistency, since it arranges for just-in-time consistency
during propagation.
AllegroStore went one more step and supported a "unique" option for the
case where a one-to-many relationship is to be modeled. We could then
apply this to the Family class, where kids have only one fm-parent. What
do we achieve by this? For one, the inverse Cell fm-parent will now
return just one parent instance instead of a list of one. For another,
an error can be generated if a kid gets pushed onto the kids slot of
more than one instance at the same time.
This is interesting. Although I have gotten by nicely with the one
Family class for a long time, I have started to notice occasions where
the special handling given the kids slot might be useful more generally.
I have even considered a new cell slot option which would let any slot
work like the kids slot. We are talking about a different issue now, but
it is interesting that they point back to the same kind of relational slot.
Thoughts?
kt
More information about the cells-devel
mailing list