Dear David,

I'm glad you asked this because, this was planned to be my next
step. Remember, I not doing combinatoric but algebraic combinatorics. So that
after dealing with basic combinatorics, the next goal is algebra. One
direction toward this goal is Nicolas catorgoy framework, which should be
also discussed here...

So, now that you asked, I can give my answers without asking and answering at
the same time :-)

> Ex. 1: This is a Sage sequence
> class:
> 
> sage: F0 = FreeModule(QQ,
> 3)
> sage: B0 = F0.basis
> ()
> sage: type
> (B0)
> <class
> 'sage.structure.sequence.Sequence'>
> 
> and tuple for the same basis given by gens
> ()
> 
> sage: type(F0.gens
> ())
> <type
> 'tuple'>
> 
> Ex. 2: This is the EnumeratedSet
> class:
> 
> sage: F1 = CombinatorialFreeModule(QQ, list
> ("abc"))
> sage: B1 = F1.basis
> ()
> sage: type
> (B1)
> <class
> 'sage.combinat.family.FiniteFamily'>
> 
> Currently gens() is not
> implemented.

Note that this is a particular kind of family. Depending whether the
generating set is infinite, we switch to a different kind of family, with
different data structure. So that my first answer is, before choosing a data
structure optimize it, I'd rather try to gather all different use case to see
if we can find a common interface.

> As a start, I would suggest that for free objects F, one
> define
> 
> F.basis() : EnumeratedSet X such that F = F
> (X)
> F.gens()  : Python tuple when X is finite, or else an
> error
>             (or should this be an immutable
> Sequence?)

Let me start with the problems I see in this design: 

 1) I dislike gens... A typical example currently studied by several people in
combinat is the algebra K[G] of a Coxeter group G, say the symmetric group. So
as a K-module, it is the free K module whose basis are the element of G. now
as an algebra it is generated by the elementary transpositions (i, i+1). So
that gens is far too ambiguous... So if you have generator, this is for a
particular category...

 2) For technical reason (one object has only one parent) but also for
mathematical reason (see below) , we need to make the difference between the
generator in F an the indexing set X. Let me quote one of my previous e-mail
concerning free modules:

As usual in mathematics, we identify two different things, whereas when
writing code we have to be very precise. The universal property in the
category of R-module state that:

   For any ring R and set E, there exist an unique (upto isomorphism) R-module
   R(E), and a mapping i: E -> R(E) such that if f is an arbitrary mapping
   from E to some R-module M, then there exists a unique module homomorphism
   g: R(E) -> M such that f = g o i. The mapping i is called the canonical
   injection from E to R(E).

Usually when speaking about R(E), we don't make any difference between any e
in E, and the corresponding element i(e) in R(E). The same abuse of language
is usually done in free group. This being clear, in R(E) there is a canonical
basis (i(e))_{e in E}. Please mind the canonical injection i in this formula. 

Mathematically, it is important to distinguish between e and i(e) because
there are a lot of examples of module which are free and which have several
natural bases all indexed by the same set. Incidentally, this is one of our
principal work to find the best basis to understand a computation. So that we
keep playing with different bases.   

Let's go back to the point: It took quite a time to Nicolas and I to realize
that the good notion is the notion of family (f_i)_{i in I}. Please have a
look at
      sage.combinat.family.Family
This code is very new to sage, so it probably needs some polishing and
optimization. But I pretty convinced that this is the good design. We keep
doing this in maths without even thinking about it... Here is a more or less
python tuned of the design we had in MuPAD-combinat for my previous example of
K[G]. Let call it A.

1) as a free module there is a family, that is a particular case of
EnumeratedSet called A.basis().
 - therefore A.basis().list() or equivalently list(A.basis()) return a list of
   element of A.
 - A.basis().keys() return the EnumeratedSet of element of the group G. 
 - if you have an element of G, you can ask A.basis()[G] to get the
   corresponding element in A

2) as an algebra there is another family called A.algebra_generators() which
   is the family (s_i := A((i, i+1)) )_{i=1..n-1} if we are in the algebra of
   the symmetric group S_n.
 - So A.algebra_generators().keys() is the set {1...n-1}. Note that we can
   also index it by the transpositions themselves.

3) If we (and it seems that some people do) want to play in the algebra of
   S_oo. There is nothing to change to the design ! The main difference is
   that the family basis() and algebra_generators() are no more implemented by
   a dictionary but by something more lazy.

I hope I managed to make myself clear... Please comment at will. As usual,
when we agreed, this should end on a wiki and finally in sage's doc.  

Cheers,

Florent


--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-devel@googlegroups.com
To unsubscribe from this group, send email to 
sage-devel-unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to