Actually, I'll add a few more things to my reply, which should be helpful ...

At 5:11 PM -0700 5/4/06, Darren Duncan wrote:
At 10:51 AM +1200 5/5/06, Sam Vilain wrote:
 >Moreover, the Relation type has these
operators that the Set type doesn't have: rename(), project(),
restrict(), extend(), join(), divide(), summarize(), group(),
 >ungroup(), wrap(), unwrap(), matching(), etc.

Is there a reference for the meaning of these methods?

There are many written references to these methods; just type "relational algebra" into Google.

I will add that the first hit on such a search, the Wikipedia page on relational algebra ( http://en.wikipedia.org/wiki/Relational_algebra ), is a perfectly good primer on what relational algebra is and what its importance is.

The article's introduction says:

Relational algebra, an offshoot of first-order logic, is a set of relations closed under operators. Operators operate on one or more relations to yield a relation. Relational algebra is a part of computer science.

Relation algebra in pure mathematics is an algebraic structure, relevant to mathematical logic and set theory.

That article also explains many of the most important relational operators.

Note that there is a related set of operators comprising relational calculus, and you can do everything in one that you can in the other, though less or more verbosely as the case may be.

At 10:51 AM +1200 5/5/06, Sam Vilain wrote:
I do think that a Pair should be a sub-type of a more general "Tuple"
type, with the 'where' clause being { .items == 2 } or something like that.

I think that the most flexible arrangement is to define;

- a Collection as a Bag of Tuples
- a Relation as a Collection where the tuples have a shape and no
duplicate tuples are allowed (but Relation does not need to be a core type)

Then, Mappings, Sequences, etc, become sub-types of one of the above two
types. For instance, a sequence is a Collection of (Int, Any) where the
first Int is unique across the collection. Similarly a Mapping is a
Collection of (Any, Any) where Unique(0).

something like

role Tuple { has @.items };
role Collection { has Tuple @.tuples };
subset Pair of Tuple where { .items.items == 2 };
subset Bag of Collection where { ! .tuples.grep:{.items > 1 } }
subset Set of Bag where {
all( .tuples.map:{ .items } ) == one( .tuples.map:{ .items } )
}
subset Mapping of Collection where { ! .tuples.grep:{ .items != 2 } }
subset Array of Mapping where { .tuples.grep:{ .items[0].isa(Int) } }
subset Hash of Mapping where { .tuples.grep:{ .items[0].does(Str) } }

While this may not actually change anything, I should point out that every collection type can also be expressed in terms of a Relation definition and/or they can all be implemented over a Relation (whose members are actually always unique). For example:

1. A Set of Any is a Relation with one Any attribute.
2. A Bag of N Any attributes is a Relation of N+1 attributes, where the extra attribute is an Int (constrained >= 1) that counts occurrances of the distinct other attributes.
3. A Mapping can be a Relation of 2 Any attributes.
4. A Hash is a Relation of 2 attributes, Str (key) and Any (value), where the key has a unique constraint. 5. A Seq is a Relation of 2 attributes, typed Int (>= 0) and Any, where the first shows their ordinal position and the second is the actual value; the first has a unique constraint. 6. An Array is the same, assuming it is a sparse; if it is not sparse, there is an additional constraint that the greatest Int value is the same / one less than the count of Relation members.

Suffice it to say that I'm sure you would implement a bag using some other type, whether a relation or a hash or an array, where the member is stored once with an occurrance count.

-- Darren Duncan

Reply via email to