On Mon, Nov 12, 2012 at 05:03:58AM +0000, Dima Pasechnik wrote:
> On 2012-11-11, Nathann Cohen <nathann.co...@gmail.com> wrote:
> > I spent many hours fighting with Posets under Sage. I enjoyed it a lot, but
> > I can already tell that it gets on Florent's and Nicolas' nerves, and so I
> > was thinking of whether I should put an end to it. For their sake.
> > Here's the problem. With comments.
> > -------------------------------
> > Building the poset from a DiGraph defined on integers :
> > sage: g = DiGraph([(1,2),(1,3),(2,4),(3,4)])
> > sage: p = Poset(g)
> > WELL. I personally consider that this behaviour is totally crazy, and I
> > often say so (very loud, and very frequently. Just come eat with us anyday
> > at lunch and I will probably complain about that, or about LaTeX). This
> > being said, I also heard that it may possibly make sense in a very sick
> > logic, and that the correction of some code may actually depend on that.
> > I personally think that having this as the default behaviour of Poset is
> > *madness*. I personally *ONLY* use Posets with he flag "facade = True" when
> > I do not forget it, and lose half an hour when I do forget it. What would
> > you think of making it the default behaviour of Poset ? This way, normal
> > people could use a Poset without having to know what a facade is. Without
> > having to hear about parents, elements, the .value() method and all.
> > I mean. Why the hell should this stay the default behaviour ?
> I agree that this looks very odd. A poset is a pair (set, binary
> relation), and one would fully expect that list() will produce
> the list of the elements in the set ordered in a way preserving
> the partial order...
First thing: for those who want to know more on what a facade is:
sage: S = Sets()
sage: S.Facade?
Now, just to put this in perspective. I think many people would find
the following madness if the end result was 3 and not 0:
In the above use case, you want the element of G, as returned by G, to
be aware that they live in G, so that arithmetic get done
accordingly. Similarly, for posets, there are use cases where one
wants a<b to compare a and b in the poset.
All of this to say that both facade and non facade posets are useful.
Now there is the question of the default value for this option. I
think we all agree (including the original poset authors; facades did
not exist back then), that facade=True is the natural default as this
is the most common use case.
The single remaining question is whether the issue is important enough
to break backward compatibility (with an appropriate transition period
of course).
> Actually, I tried googling poset+facade, and all the maths hits are
> Sage, with an exception of a dissertation on posets, where the only
> place the word "facade" is used is the following quote:
> It turns out that an eerie type of chaos
> can lurk just behind a facade of order
> and yet, deep inside the chaos
> lurks an even eerier type of order.
> D. Hofstadter
> Thus indeed, we should not show "an eerie type of chaos",
> unless a user expicitly asks for it...
> On Mon, Nov 12, 2012 at 05:03:58AM +0000, Dima Pasechnik wrote:
>> On 2012-11-11, Nathann Cohen <nathann.co...@gmail.com> wrote:
>> > I spent many hours fighting with Posets under Sage. I enjoyed it a lot, but
>> > I can already tell that it gets on Florent's and Nicolas' nerves, and so I
>> > was thinking of whether I should put an end to it. For their sake.
>> > Here's the problem. With comments.
>> > -------------------------------
>> > Building the poset from a DiGraph defined on integers :
>> > sage: g = DiGraph([(1,2),(1,3),(2,4),(3,4)])
>> > sage: p = Poset(g)
>> > WELL. I personally consider that this behaviour is totally crazy, and I
>> > often say so (very loud, and very frequently. Just come eat with us anyday
>> > at lunch and I will probably complain about that, or about LaTeX). This
>> > being said, I also heard that it may possibly make sense in a very sick
>> > logic, and that the correction of some code may actually depend on that.
>> > I personally think that having this as the default behaviour of Poset is
>> > *madness*. I personally *ONLY* use Posets with he flag "facade = True" when
>> > I do not forget it, and lose half an hour when I do forget it. What would
>> > you think of making it the default behaviour of Poset ? This way, normal
>> > people could use a Poset without having to know what a facade is. Without
>> > having to hear about parents, elements, the .value() method and all.
>> > I mean. Why the hell should this stay the default behaviour ?
>> I agree that this looks very odd. A poset is a pair (set, binary
>> relation), and one would fully expect that list() will produce
>> the list of the elements in the set ordered in a way preserving
>> the partial order...
> First thing: for those who want to know more on what a facade is:
> sage: S = Sets()
> sage: S.Facade?
> Now, just to put this in perspective. I think many people would find
> the following madness if the end result was 3 and not 0:
> In the above use case, you want the element of G, as returned by G, to
> be aware that they live in G, so that arithmetic get done
> accordingly. Similarly, for posets, there are use cases where one
> wants a<b to compare a and b in the poset.
Absolutely! But if one builds a poset from a set with '<' already
defined (e.g. a subset of integers, or vertices of a directed acyclic graph), and keeps in mind this order, one should not have to jump any hoops.
One way or another, I don't see a (mathematical) reason for the elements of the poset to be replaced by some strange creatures...
> All of this to say that both facade and non facade posets are useful.
> Now there is the question of the default value for this option. I
> think we all agree (including the original poset authors; facades did
> not exist back then), that facade=True is the natural default as this
> is the most common use case.
> The single remaining question is whether the issue is important enough
> to break backward compatibility (with an appropriate transition period
> of course).
the naturalness of interface should overwrite backwards compatibility.
Thanks goodness, Sage is not M$oft Office :-)
>> Actually, I tried googling poset+facade, and all the maths hits are
>> Sage, with an exception of a dissertation on posets, where the only
>> place the word "facade" is used is the following quote:
>> It turns out that an eerie type of chaos
>> can lurk just behind a facade of order
>> and yet, deep inside the chaos
>> lurks an even eerier type of order.
>> D. Hofstadter
>> Thus indeed, we should not show "an eerie type of chaos",
>> unless a user expicitly asks for it...
Hey everyone, I just had an idea, and maybe this is more wishful thinking, but I feel like we should be able to pass a poset/lambda function(s)/class which contains comparison methods into a parent and have that be able to override the default ordering (similar to what C++ does in the STL). Something like this:
sage: g = DiGraph([(0,1),(0,2)]) sage: p = Poset(g) sage: G = IntegerRingMod(3, ordering=p) sage: G(0) < G(1) True sage: G(0) < G(2) True sage: G(1) < G(2) False
Or for partitions under dominance order (instead of how we currently are doing them in 13605):
sage: P = Partitions(3, cmp_lt=Partition_class.dominates) # after 13605 this would just be Partition.dominates sage: P([2,2,1]) < P([3,1,1]) True
On Fri, Nov 23, 2012 at 06:53:56PM -0800, Travis Scrimshaw wrote:
> Hey everyone,
> I just had an idea, and maybe this is more wishful thinking, but I feel
> like we should be able to pass a poset/lambda function(s)/class which
> contains comparison methods into a parent and have that be able to
> override the default ordering (similar to what C++ does in the STL).
> Something like this:
> sage: g = DiGraph([(0,1),(0,2)]) > sage: p = Poset(g)
> sage: G = IntegerRingMod(3, ordering=p)
> sage: G(0) < G(1)
> True
> sage: G(0) < G(2)
> True
> sage: G(1) < G(2)
> False
Well, maybe not that much of a wishful thinking actually!
Define this category:
class Blahs(Category):
def super_categories(self): return [Rings()]
class ParentMethods:
def blah(self): print "blah"
class ElementMethods:
def blih(self): print "blih"
def __lt__(self, other):
print "comparing!"
And create the ring in this category:
sage: G = IntegerModRing(3, category=Blahs())
sage: g = G.an_element()
Now you can do:
sage: G.blah()
blah
sage: g.blih()
blih
So in principle one could use that to provide comparison methods. Alas
this does not work completely, because there already is a comparison
method implemented in G which override that of the category:
sage: g < g
False
This also fails for partitions because they do not yet accept a
category parameter.
Hey Nicolas,
I don't think it is feasible to make this as a change to a parent or category as we would have to change all classes in sage to support this framework. I almost feel as if poset should be a general construct for changing the default order on any set of objects, and we should strive to make it as lightweight and hidden as possible. Here's my current thoughts on how to do this:
- We have elements of a poset P be the elements of the set S, but on creation, we override their comparison operations. I foresee (small) problem with doing this. In an ideal world, I would rather the elements' parent be P, rather than S, but there are many classes that rely on calls to methods in S via the parent() method. Thus it becomes unclear that these elements came from P. Do you see anyway around this?
- Have elements always be wrappers, but make it less obvious that it is a wrapper by having it perform the _latex_, _repr_, arithmetic (maybe return wrapped elements? perhaps throw an error/warning if result is not in the poset?), and any other common methods of the wrapped element. Also equality testing should be much more robust by testing against the wrapped element if the RHS is not a poset element (and not checking that they have the same parent, but just checking the wrapped elements).
The more I think about it, the more I grow uncomfortable with the idea of facades. For example:
sage: g = DiGraph([(0,1),(0,2)])
sage: P = Poset(g, facade=True)
sage: P(1) < P(2)
True
so to do comparisons in the poset, you have to do
sage: P.lt(1, 2)
False
and this seems even more troubling to me if facade is True by default, since I would expect P(1) and P(2) to be elements of the poset and be incomparable. Although I feel like the underlying problem is not facades, but instead the equality comparison method is not robust enough.
On Thursday, November 29, 2012 2:36:05 PM UTC-8, Nicolas M. Thiery wrote:
> On Fri, Nov 23, 2012 at 06:53:56PM -0800, Travis Scrimshaw wrote: > > Hey everyone, > > I just had an idea, and maybe this is more wishful thinking, but I > feel > > like we should be able to pass a poset/lambda function(s)/class which > > contains comparison methods into a parent and have that be able to > > override the default ordering (similar to what C++ does in the STL). > > Something like this: > > sage: g = DiGraph([(0,1),(0,2)]) > > sage: p = Poset(g) > > sage: G = IntegerRingMod(3, ordering=p) > > sage: G(0) < G(1) > > True > > sage: G(0) < G(2) > > True > > sage: G(1) < G(2) > > False
> Well, maybe not that much of a wishful thinking actually!
> sage: G = IntegerModRing(3, category=Blahs()) > sage: g = G.an_element()
> Now you can do:
> sage: G.blah() > blah > sage: g.blih() > blih
> So in principle one could use that to provide comparison methods. Alas > this does not work completely, because there already is a comparison > method implemented in G which override that of the category:
> sage: g < g > False
> This also fails for partitions because they do not yet accept a > category parameter.