>
> > Then I can think of the set of Tableaux as the parent and lists of 
> objects 
> > as elements. 
>
> You say that you "think of the *set* of Tableaux" as the parent? That 
> doesn't 
> sound promising at all. Although I don't know which notion you are using, 
> it seems likely to me that rather the *set* of all tableaux forms a 
> category, 
> which means that each individual tableau is an object in that category. 
> And "parent" is just another word for "object of a sub-cateogory of the 
> category of sets". So, if there is a category of tableaux and if each 
> tableau has elements, then a tableau is a parent and its elements are, 
> well, its elements. 
>
> This is the wrong viewpoint. The set of Tableaux should be the parent in 
the category of (enumerated?) sets since the elements are a Tableau. Most 
combinatorial objects should not be categories because the morphisms that 
people are typically interested in are bijections. A good smallish example 
to look at is the implementation of Gelfand-Tsetlin patterns (see 
src/sage/combinat/gelfand_tsetlin_patterns.py).

Do *NOT* use Posets as an example. Those are special because of the extra 
structure with the < and are naturally sets (hence parents). Posets are 
naturally a category because the morphisms have to preserve the structure.

> I have struggled to find complete examples in the 
> > combinat source code. As I understand it the key 
> > components are Parent.__init__  Element.__init__ _element_constructor_ 
> but 
> > I don't understand what these do or how they 
> > work together. 
>
> In a nutshell: 
>
> - If you implement a parent FOO, then FOO will be a subclass of 
>   sage.structure.parent.Parent, and at some point during FOO.__init__ the 
>   .__init__ methods of the base classes of FOO should of course be called. 
>   Hence, at some point, Parent.__init__(self, ...) will be called (maybe 
>   indirectly), and this is where the category of your new instance of FOO 
>   has to be declared. 
> - Similarly, if you are implementing the elements of FOO instance in a 
>   class BAR, then of course BAR will be a subclass of 
>   sage.structure.element.Element, and at some point during BAR.__init__ 
>   also Element.__init__(self, P) has to be called (maybe indirectly), 
>   where P is the instance of FOO which `self` will be element of. 
>   Nothing more specific needs to be done in BAR.__init__ regarding the 
>   category framework. 
> - You did not mention another key component: Your class FOO has to have 
>   BAR assigned to a class attribute called "Element". 
> - FOO._element_constructor_ is a method that takes some arguments and 
>   returns an element of FOO. If P is an instance of FOO, then it ought 
>   to return an instance of P.element_class. Here, P.element_class is 
>   automatically created by Sage's category framework: It is a sub-class 
>   of both P.Element (i.e., BAR) and of P.category().parent_class (which 
>   is why FOO.__init__ needs to declare which category is to be used). 
>   It is in fact not always needed to implement FOO._element_constructor_ 
>   explicitly: There is a default implementation, and having 
> `FOO.Element=BAR` 
>   may be sufficient to make it work. But if there is particular input that 
>   BAR.__init__ won't handle then FOO._element_constructor_ is where you 
>   would implement a conversion. 
>   In that sense, _element_constructor_ is less of a key component than 
>   the `Element` attribute. 
> - Also, if your element class BAR implements arithmetic operations 
>   then you should be aware that some of Python's magic arithmetic 
>   methods such as __add__ or __mul__ have default implementations in 
>   Sage's base classe (sage.rings.ring.Ring etc), and these should *not* 
>   be overridden! Instead, you may implement the corresponding single 
>   underscore method (_add_, _mul_, _lmul_). The same holds for __repr__ 
>   versus _repr_. Moreover, _add_ and _mul_ shouldn't just return instances 
>   of BAR, but of P.element_class (if P is the parent of the result of the 
>   arithmetic operation). 
> - Another key component: If there are canonical morphisms from other 
>   algebraic structures to your tableaux, then you may want to use them 
>   for automatic conversions (also known as "coercion map"). If a canonical 
>   morphism from `S` to `P` exists, then `P._coerce_map_from_(S)` should 
>   return True (it is also possible that it return the morphism to be used 
>   for automatic conversion). But be aware that this is only possible if 
>   the system of canonical morphisms is consistent: The identity map from 
>   P to P is a coercion map; there is at most one coercion map from S to 
>   P; and the composition of two coercion maps is a coercion map. 
>
> You can find a more detailed account on the category and coercion 
> framework including parents and elements in 
>
> http://doc.sagemath.org/html/en/thematic_tutorials/coercion_and_categories.html
>  
>
> For most combinatorial objects, the main things you want to implement are:

- An __init__ for the parent that calls Parent.__init__(self, 
category=cat), with cat either Sets(), EnumeratedSets(), 
EnumeratedSets().Finite(), EnumeratedSets().Infinite(), etc.
- An __init__ for the element that takes the parent as the first argument 
that calls Element.__init__(self, parent) or whatever the reasonable base 
class is.
- Set the parent "Element" class level *attribute* to the corresponding 
element class.
- All elements with data D of a parent P you construct should be though 
either P(D) or the more direct P.element_class(P, D).
- An __iter__ for the parent if you know how to iterate over objects.

The default _element_constructor_ is sufficient to handle the rest unless 
you need some extra preprocessing that cannot be done in the element 
class's __init__. However, see Simon's very good response for more specific 
details.

Best,
Travis

-- 
You received this message because you are subscribed to the Google Groups 
"sage-combinat-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-combinat-devel+unsubscr...@googlegroups.com.
To post to this group, send email to sage-combinat-devel@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-combinat-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to