Re: [Zope3-dev] Yet Another Relations (aka Reference) Engine...

2005-11-13 Thread Helmut Merz
Am Sonntag, 13. November 2005 12:07 schrieb Jean-Marc Orliaguet:
> Helmut Merz wrote:
> >Anyway, what we are talking about are not "references".
>
> The approach is quite different: references start from the
> objects themselves that they connect to other objects using
> one-way relations (a pointer, an arrow). 

And this can be easily implemented by using assignments to object 
attributes.

> The application has 
> to know how to interpret the references. I don't think that 
> you can build a robust relation engine only with that.
> Relations start from "the top": you first define an ontology
> (a set of general predicates) that you use to relate the
> objects of your application. This is a conceptual schema. Here
> is the cpsskins ontology:
> http://svn.nuxeo.org/trac/pub/file/z3lab/cpsskins/branches/jmo
>-perspectives/ontology.py
>
> The relation engine then manages all the necessary references,
> but the application does not need to know about the references
> at all. The interaction with the relation engine is done only
> via the ontology.

OK, I see. I now also understand why you include monadic 
relations which could just be attributes or annotations... 
(I ignored them up to now but I think I should change this.)

OTOH I'd like to have a relation management API that could as 
well be used for cases where the relations are controlled by the 
application or the objects involved.

This is then just a convenience API that cares about the problems 
of keeping up-to-date references in both directions, deletion 
handling, the complexity arising with connecting more than two 
objects, attributed or annotated relations, etc.

Helmut
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] Extrinsic references

2005-11-13 Thread Helmut Merz
Am Samstag, 12. November 2005 17:15 schrieb Jim Fulton:
> We have a *simple* facility for managing references between
> objects extrinsically.  See:
>
>   
> http://svn.zope.org/Sandbox/zc/extrinsicreference/extrinsicref
>erence.txt?view=markup
>
> If there is sufficient interest, we plan to move this (tiny)
> project to the zope repository.

+1

... though it does not provide a complete solution for what I am 
thinking about concerning the relation management stuff; but it 
is a solution for a lot of use cases and may also provide the 
basis for an implementation of a richer relation management 
framework.

Helmut
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] Yet Another Relations (aka Reference) Engine...

2005-11-13 Thread Helmut Merz
Am Samstag, 12. November 2005 23:13 schrieb Jean-Marc Orliaguet:
> Helmut Merz wrote:
> >Maybe there is a better word for this kind of 'relation'?
> >
> >Helmut
>
> I don't know. I think you have to start from a definition that
> is not dependent on zope in general and understand what the
> concepts mean outside the computer world. This was not
> invented here.
>
> The "relations" used in software are more than just relations
> since they also assert something, and a relation by itself
> asserts nothing, it is just an abstraction that connect
> several things or aspects of things. So "relations" here are
> rather "propositions".
>
> for instance:
> "A blue box" involves a relation between the "box" and the
> quality "blue", but to represent the relation, you would to
> assert a proposition:
>
> "The box is blue"

Thanks for the clarification, and I think I got it - though I 
have to admit that I got the feeling that my brain is not really 
built to work with formal logic in a practical way ;-)

So my suggestion would be to go the pragmatic way an just keep 
the word "relation" for representing the assertion of such 
propositions in software.

I'll be going to write a Zope 3 proposal on on the relation 
management stuff (in the first step only on the interfaces 
trying not to talk about implementation issues) and would gladly 
expect your comments then...

I think we cannot alway avoid words defined in another problem 
domain in a different way, which may be problem especially if 
the problem domains are related (like formal logic and computer 
science); but I'd care not to use a nomenclature that might 
confuse or mislead people knowing more about some stuff than me.

Anyway, what we are talking about are not "references".

> The proposition can be analysed. It has a predicate and a
> subject (or subjects if taken individually), the subject is an
> ordered tuple and the predicate is what is left of the
> proposition when the subjects have been removed (it is what is
> "predicated", or asserted of the subjects of the proposition)
>
> for instance in the proposition:
>
> "The box is blue"
>
> the predicate "__ is blue" predicates "blueness" of the box
>
> but a predicate is not the same thing as a relation

Yup - I'm at the moment using the word "predicate" to signify a 
type of a relation (using it as a homonym to "relationship") 
though I'm again not sure if this might be plainly wrong or at 
least confusing.

Helmut
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] Yet Another Relations (aka Reference) Engine...

2005-11-12 Thread Helmut Merz
Am Samstag, 12. November 2005 20:00 schrieb Jean-Marc Orliaguet:
> Helmut Merz wrote:
> >Am Samstag, 12. November 2005 18:00 schrieb Jean-Marc 
Orliaguet:
> >>My
> >>impression is that you are thinking of a reference engine
> >>rather than a relation engine
> >
> >Maybe I just don't see the difference... (There is one, of
> >course, but I doubt it is really of relevance in a practical
> >context. )
> >
> >Helmut
>
> A relation contains several references:
>
> a relation between A, B and C involves 7 references:
>
> A with itself
> B with itself
> C with itself
> A with B
> B with C
> C with A
> A with B with C
>
> But a set of references don't make explicit relations, unless
> the application know how to interpret the references.

OK - then I'm not talking about references, though we still mean 
different things when talking about 'relation':

Mine goes like this: A relation object R providing 
ITriadicRelation and connecting A, B and C involves three 
references: 

R with A
R with B
R with C

In addition the relation object has a sort of type, the 
'relationship' (corresponding to a 'predicate') that may be 
specified by the relation's class or - a special case - a 
string.

Maybe there is a better word for this kind of 'relation'?

Helmut
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] Yet Another Relations (aka Reference) Engine...

2005-11-12 Thread Helmut Merz
Am Samstag, 12. November 2005 18:00 schrieb Jean-Marc Orliaguet:

> The good thing about IntIds is that it leaves the objects
> untouched, the bad thing is that it creates a hard coupling
> between the integer id that is used to *refer* to the object
> and the key that is used to *represent* the object in the
> relation. These are really two different aspects.
>
> In cpsskins when objects are set in relation, it is the
> application's responsibility to tell the engine how objects
> will be identified in the relation, i.e. with a unique id
> (IntIds), or with a URI or a with a name (that may be share
> between several objects) ... The relation engine then stores
> this key as well as an internal reference to the object.
>
> so for each object put in relation we have:
> - a key (used by the application to query the engine)
> - a reference to the object (used internally by the relation
> engine to get the object)
>
> the application only "sees" the keys until the objects get
> dereferenced.
>
> But no 1:1 mapping between the key and the object is imposed
> by any external IntIds utility. Which make it possible to ask
> the engine: "give me all the portlets associated to the 'left'
> slot" even though the 'left' slot is materialized in more than
> one instance.

Hm, I'm not sure I understand - so it's not the object (more 
precisely: its unique id) that's indexed but some value provided 
by the object - so this is indeed some sort of an attribute 
that's indexed.

This I would prefer to solve using relation objects that 
explicitly handle additional attributes (provided by the objects 
that are connected by the relation) that may be indexed *in 
addition* to the unique ids.

Or let's see this way: The keys (unique ids in the standard 
implementation) are retrieved by an adapter to the relation 
class (providing IIndexableRelation) so this adapter could 
provide something else if necessary.

> In your implementation only objects that are identified
> uniquely can be put in relation, and it doesn't seem to be a
> design choice other than a limitation imposed by the catalog.

Yes, it is a limitation of the default implementation but I'm 
still not sure it is bad, and it can be overcome easily.

> http://svn.nuxeo.org/trac/pub/file/z3lab/cpsskins/branches
> /j mo -perspectives/storage/relations.py
> >>>
> >>>I read this, and it indeed gave me the impression that it
> >>>might be a not so bad idea to use a catalog ;-)
> >>
> >>well, you haven't written the catalog indexes yet :-)
> >
> >I needn't because I just use the FieldIndex from zope.index.
>
> I understand, but the idea is to index relations, not simply 
> the references between in the objects put in relation. 

ACK

> My 
> impression is that you are thinking of a reference engine
> rather than a relation engine 

Maybe I just don't see the difference... (There is one, of 
course, but I doubt it is really of relevance in a practical 
context. )

Helmut
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] Yet Another Relations (aka Reference) Engine...

2005-11-11 Thread Helmut Merz
Am Freitag, 11. November 2005 17:26 schrieb Jean-Marc Orliaguet:

> if the relation is symmetrical, there are 2 relations:
>
> A is like B
>
> means:
>
>A resembles B
>
> and
>
>B resembles A( or A __ is resembled by __ B )
>
> which you can express as a compound predicate:
>
> is_like = CompoundPredicate(Predicate('_ resembles _', '_
> is resembled by _'))
>
> and do a query with:
>
> relations.search(predicate=is_like, first=A)
>
> to get all the B:s in relation with A independently of the
> position.

Interesting, maybe I should learn more about predicate logic...

Nevertheless let me try it "my way":

Let's have an interface ISymmetricalRelation(IDyadicRelation) 
that is implemented by a class 
SymmetricalRelation(PredicateRelation) (PredicateRelation is an 
example from the README.txt 
http://svn.cy55.de/viewcvs/Zope3/src/cybertools/trunk/relation, 
Concept is some imaginary class used for conceptual modelling).

  >>> isSynonym = Predicate('__ is a synonym of __')
  >>> crazy = Concept('crazy')
  >>> mad = Concept('mad')

Then the contract for ISymmetricalRelation would look like this 
(this is not strictly necessary but makes it easier to 
understand):

  >>> SymmetricalRelation(isSynonym, crazy, mad) == 
SymmetricalRelation(isSynonym, mad, crazy)
  True

Now we register such a relation:

  >>> relations.register(SymmetricalRelation(isSynonym, crazy, 
mad))

and query in two ways:

  >>> rels1 = relations.query(relationship=isSynonym, 
  ... first=crazy) 
  >>> rels2 = relations.query(relationship=isSynonym, 
  ... second=crazy) 

then all the found relations must be identical:

  >>> [r1 in rels2 for r1 in rels1]
  [True]

(When I'd query for 'mad' I'd get the same results; I could also 
omit the relationship parameter on the query() call.)

In addition to the standard IDyadicRelation interface, 
ISymmetricalRelation has a method getOther():

  >>> [r.getOther(crazy) for r in rels1]
  []

This is all I need to find all the synonyms of 'mad'.

Don't ask me about the implementation now - I just don't care at 
the moment...

> Then most of the relations do have a direction ( __ has author
> __, __ was modified by __,  ...)

Yes, a symmetrical relationship is a special case, and one could 
even handle it on the application layer. Nevertheless I think 
it's a good idea to consider it.

Helmut


___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Re: [Zope3-dev] Yet Another Relations (aka Reference) Engine...

2005-11-11 Thread Helmut Merz
Am Freitag, 11. November 2005 16:11 schrieb Jean-Marc Orliaguet:

> Hi Helmut!

Hi Jean-Marc,

thanks for your remarks,

just before going into more detail: My primary concern was the 
API - it would really fine if there could be a simple (as simple 
as possible but not simpler) standard set of (low-level) 
interfaces on which to build (defining semantically richer 
interfaces) and for which to provide implementations (depending 
on the needs of the application).

The implementation with the catalog should serve as a (again 
fairly simple but working) example and a proof of concept; I 
think I would be just lucky if it would show up as really 
useful ;-) (but maybe...)

> I can tell you about the design decisions made in the case of
> the relation tool included in CPSSkins. They don't necessarily
> appear in the code itself in an obvious way.
>
> 1) separate storage from storage policy
>
> the relation storage stores what it is told to store, as long
> as the objects are Relatable they can be stored. The storage
> policy (using unique ids or not, etc..) is the responsibility
> of the application itself. To impose a unique id policy when
> storing elements would be a mistake in my opinion (in the case
> of cpsskins it wouln't work either).

The only prerequisite for using the IntIds utility is that the 
objects are persistent (provide IPersistent). If one wants to 
relate objects that are not persistent or have relations that 
for some reason can't be persistent you can't use the catalog 
approach because the catalog depends on IntIds.

So the catalog-based implementation won't be usable for relations 
between in-memory objects (like views, adapters and related 
stuff), that's true.

> 2) keep the relation storage index as small as possible.
>
> Do not index predicates, the same predicates are used in too
> many relations, the size of the index ould just increase
> dramatically. Instead only index the elements that are inside
> the relation, the chances that the same elements are related
> in many different ways are very low.
>
> cf.
> 
http://www.z3lab.org/sections/blogs/jean-marc-orliaguet/2005_08_27_triadic-relations/
>
> http://svn.nuxeo.org/trac/pub/file/z3lab/cpsskins/branches/jmo
>-perspectives/storage/relations.py

I read this, and it indeed gave me the impression that it might 
be a not so bad idea to use a catalog ;-)

> I don't know about using the zc.catalog for indexing
> relations, you could end up in huge indexes and very slow
> queries.

This is one of my concerns, too, but I'm fairly optimistic: the 
catalog indexes store a common string to be indexed only once, 
so having identical ; I'm working with the Archetypes reference 
engine (that uses - at least in this respect - the same kind of 
catalog indexes) in situations with many thousands of objects 
and didn't get problems of this kind.

> 3) don't make the API for querying the storage be too
> intelligent,

The query() method using the catalog's searchResults() / apply() 
methods was the dumbest one I could thing of ;-)

>  to create complex queries, create complex predicates instead,
> i.e.
>
>- predicates that combine several predicates
>- proxy predicates (when the predicate is evaluated at
> runtime and a method is specifed instead)
>
> cf
> 
http://svn.nuxeo.org/trac/pub/file/z3lab/cpsskins/branches/jmo-perspectives/relations/__init__.py
>
> if you need to do really complex queries, do several
> queries and filter out the results afterwards  in you
> application unless you're fine with ending up with a huge
> catalog index.

To be honest, I never thought about complex queries as I just 
want to find e.g. the subtasks of a task and the resources 
allocated to it - maybe my use case is just somewhat simple.

OTOH: An advantage of using a catalog are the - as I think - 
fairly efficient set operations on search results for the 
indexes...

Helmut
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



[Zope3-dev] Yet Another Relations (aka Reference) Engine...

2005-11-11 Thread Helmut Merz
Hi,

there are quite a few solutions out there in the Zope world that 
allow the management of relations or references between objects. 
So I have been working with the reference engine provided by 
Archetypes (as part of Plone) for nearly two years now; and I 
also had a look at some proposals on zope.org and 
implementations that are available in the Zope 3 packages from
SchoolTool and CPSSkins.

I have to confess that I was not really happy with any of these 
proposals or solutions - a feeling that we may discuss in more 
detail, the main point being just that I wanted to have 
something simple that is nevertheless flexible enough to 
accommodate to various needs.

So I came up with the following stuff (mainly combining concepts 
by Jean-Marc Orliaguet and implementation ideas from Archetypes 
1.3) :

A relation is an object providing the IRelation interface. This 
has got two attributes ('first', 'second' - dyadic relation) or 
three ('first', 'second', 'third' - triadic relation). (You may 
ignore triadic relations if you don't think you need them.)

If I now create corresponding classes (DyadicRelation, 
TriadicRelation) I can assign the objects taking part in a 
relation directly to these attributes of the relation. (Note 
that the objects taking part in a relation are not touched at 
all.) In fact I create a class for each kind of relation (each 
relationship or predicate or whatever you like to call it)
I want to use.

So the question arises what to do with the relation objects? The 
point here is not so much where to store them but how to make 
sure that we can find them. So we need a registry for relations 
- interface IRelationsRegistry.

This has three methods:

- register(relation)
- unregister(relation)
- query(**kw)

The keyword arguments to the query() method may be:

- relationship=... - a relation class (we can also work with
 named predicates - see below)
- first=... - an object
- second=... - an object
- third=... - an object

One can combine those arguments at will to search for all 
relations of the relation class specified (if given) with the 
given values for the attributes. The list may be extended if you 
use relation classes with additional attributes you want to 
search for.

(For details have a look at the README.txt and other files on 
http://svn.cy55.de/viewcvs/Zope3/src/cybertools/trunk/relation 
or check it out via 
svn co svn://svn.cy55.de/Zope3/src/cybertools/trunk/relation)

You see that this looks very much like a catalog search - so why 
not implement the relations registry as a subclass of 
zope.app.catalog.catalog.Catalog?

OK, so the RelationsRegistry class is derived from Catalog, and 
of course it is a local utility. The indexes are just FieldIndex 
objects, using an adapter to provide unique ids for the objects 
involved via the IntIds utility; the same is done for providing 
ids for the relation objects themselves. The relationship is 
mapped to the full module path + class name of the relation 
class.

An interesting consequence of this is that the relation objects 
are not explicitly stored somewhere, the only reference to them 
is via the IntIds utility. Thus you are free to store them in 
some container or even make them first class content objects if 
you want - but you needn't.

The whole stuff is flexible enough to be extended as needed, e.g. 
with special registry classes used via named utilities, 
additional attributes on relations (easily indexable in the 
registry); it could be wrapped in a richer and more 
application-oriented API, etc.

It is also possible to use named predicates (with URIs or strings 
like '_ is child of _') instead of different relation classes to 
represent relationships (this is shown by an example at the end 
of the README.txt).


So what do you think? - any feedback and suggestions welcome...

I'd also gladly write a proposal (if I get write access to the 
wiki ;-)) and of course change the license from GPL to ZPL if 
this would be considered useful.

Helmut
___
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com