#17979: Reimplementation of IntegerListsLex
-------------------------------------+-------------------------------------
       Reporter:  aschilling         |        Owner:
           Type:  defect             |       Status:  needs_work
       Priority:  blocker            |    Milestone:  sage-6.6
      Component:  combinatorics      |   Resolution:
       Keywords:  days64             |    Merged in:
        Authors:  Bryan Gillespie,   |    Reviewers:  Nathann Cohen, Jeroen
  Anne Schilling, Nicolas M. Thiery  |  Demeyer, Travis Scrimshaw
Report Upstream:  N/A                |  Work issues:
         Branch:                     |       Commit:
  public/ticket/17979                |  2380fd4fcf61347f9b86ee09f7488dac7e1d9fe2
   Dependencies:                     |     Stopgaps:
-------------------------------------+-------------------------------------

Comment (by nthiery):

 On Tue, Apr 07, 2015 at 03:06:42PM -0000, sage-trac wrote:
 >  - Lexicographic ordering is broken when `n` is a list.
 >    {{{
 >    sage: print IntegerListsLex([1,2],length=3).list()
 >    [[1, 0, 0], [0, 1, 0], [0, 0, 1], [2, 0, 0], [1, 1, 0], [1, 0, 1],
 [0,
 >  2, 0], [0, 1, 1], [0, 0, 2]]
 >    }}}
 >
 >    In particular, the output differs depending on how `n` is sorted.

 Indeed, and this is in fact a feature. I reworked the documentation to
 better highlight this.

 >  - Cardinality is broken when `n` is a list
 >    {{{
 >    sage: IntegerListsLex(3,length=3).cardinality()
 >    10
 >    sage: IntegerListsLex([3,3],length=3).cardinality()
 >    20
 >    }}}

 I documented this behavior some more. That's part of the
 specifications that this returns a disjoint union. A different
 specification might look desirable, but there would be no efficient
 way to handle it.

 >  - {{{return typecall(cls, n=n, **kwargs)}}} -- for clarity I find
 >    the normal syntax better. This place is not a critical part for
 >    speed, especially when you create `DisjointUnionEnumeratedSets`
 >    with lambda functions just above.

 I am not sure what you mean by "normal syntax". That you prefer using
 DisjointUnionEnumeratedSets directly rather than this syntactic sugar?

 >  - Are `min_sum` and `max_sum` also ignored when `n` is a list? From
 >    the doc it seems to be, though I am not sure that it is the best
 >    design choice in this case.

 Indeed they are ignored. I don't see a simple way to implement it
 otherwise.


 Speaking of which: should there be a warning when a user-specified
 value for `min_sum` or `max_sum` is overridden by `n`? Same for
 `length` versus `min_length` and `max_length`.


 >  - I was surprised by the following output:
 >    {{{
 >    sage: IntegerListsLex(3,max_length=3,floor=[1,1,1]).list()
 >    [[3], [2, 1], [1, 2], [1, 1, 1]]
 >    }}}

 >    I would have expected the length of the lists to be at least 3,
 >    as I requested the first three parts to be `>=1`. The
 >    documentation is consistent, but I still find it surprising.

 I agree it can be surprising at first sight, but the other way round
 would have prevented interesting use cases. Not that some of the
 specialized classes, like partitions or integer vectors, take a
 separate argument inner and outer which does impose length
 restrictions, according to the usual math vocable in those contexts.

 >  - ``check`` seems misnamed
 >  - About the finiteness check: what about a specific
 >  `allow_infinite_iterator`
 >    independent from the current 'check'.

 I also wondered, but see the discussion with Jeroen: let's keep things
 simple until we actually meet a serious use case.


 >  - {{{# constructor is known to be safe and don't claim ownership
      on}}} -- "does not".

 Done.


 >  - Typing `IntegerListsLex.<tab>` in the console is very
 >    entertaining. I would be very glad if we some day decide to
 >    consider this as a bug.

 Agreed: about one half of the items should not be there. But that's a
 different discussion.


 >  - I had not noticed that `IntegerListsLex` objects could have a 'name'
 >    argument.. As all arguments, it must be documented in the INPUT
 section.
 >  - Same for `element_constructor` and `element_class`.

 Done.


 >  - The error message when the set is infinite is misleading:
 >    {{{
 >    sage: L = IntegerListsLex(4)
 >    sage: L._check_finiteness()
 >    ...
 >    ValueError: Could not check that the specified constraints yield a
 >  finite set
 >    }}}
 >    The code was able to perform the check, though it was not "able to
 >  decide that
 >    the set is finite".

 Good point. At the end of the day, I made it into "could not prove
 that the set is finite" which better highlights the lack of symmetry.

 >  - I do not understand this comment:
 >    {{{If a part has no bound on its value, it will be detected at some
 >  point}}}
 >    Do you mean that "at some point in __iter__" it will be detected?
 >  Probably
 >    not, as this function is called only once.

 I rewrote the documentation of `_check_finiteness` to be more specific
 and discuss this point.

 >  - about `check_finiteness` -> what about `guess_finiteness` instead, to
 >    emphasize that the function makes mistakes?

 I see your point; however `guess` improperly suggests that it's going
 to return a boolean, whereas `check` conveys that it's about trying to
 catch and report bad situations.

 Another issue with this name, which is even more apparent with the
 rewrite of the documentation, is that this method is really about
 trying to prove the existence of a bound on the length.

 Oh well, I believe it's good enough for now; it's a private method
 with an extensive documentation giving a precise specification; if
 someone comes up with a perfect name, it's a trivial change.  Besides
 `check` conveys that the verification needs not be comprehensive.


 >  - The function `_check_finiteness` assumes that the alphabet size is
 >  bounded. It
 >    is always true when this function is called, but the following raises
 no
 >    warning:
 >    {{{
 >    sage: for x in IntegerListsLex(NonNegativeIntegers(),max_length=3):
 >    ....:     pass
 >    }}}
 >    For the reason given earlier, the output is not sorted
 >  lexicographically. It
 >    is not detected as infinite either.

 Correct, which is fine: the above example is properly iterable, and
 it's nowhere claimed to be finite:

 {{{
 sage: C = IntegerListsLex(NonNegativeIntegers(),max_length=3)
 sage: C in EnumeratedSets().Finite()
 False
 }}}

 In general, it's documented that `n=iterable` is nothing but a
 convenience, and that it does not return an `IntegerListsLex` object
 but a disjoint union thereof. I would not want to pollute the
 documentation everywhere with straightforward consequences.

 >  - The many `if A: return` from `_check_finiteness` can be replaced by a
 >  `if A or
 >    B or C or ...: return`.

 As Jeroen says, that's a matter of style. Here I like that it
 highlights the fact that each test is independent.  So the reader can
 think about just one at a time.


 >  - in `_check_finiteness`: the documentation of `limit()` says that it
 is
 >  only an
 >    upper bound. Thus you cannot write the following:
 >    {{{
 >    if self._ceiling.limit() < self._floor.limit():
 >        return
 >    }}}
 >  - Same comment here
 >    {{{
 >    if self._floor.limit() > 0 or self._min_slope > 0:
 >       floor_sum_lower_bound = Infinity
 >    }}}
 >

 Jeroen's fault! (Just kidding :-) )

 That's actually correct: for the floor, `limit` in fact returns a
 lower bound. I reinstated the documentation and tests for this as they
 had gotten scrambled in the sign-refactoring of Envelope.

 >  - Also, it seems that `limit_start()` can be `Infinity`, in which case
 one
 >    cannot deduce anything from the value of `limit`. Please add checks.

 Ah yes, the specifications of `limit` / `limit_start` were not
 explicit in this case. Fixed. With those specs, the deduction is
 actually correct.

 >  - I stop reviewing `_check_finiteness`, as it is complicated while the
 >  situation
 >    of `limit()` is not cleared.

 Hopefully it's cleared now!

 >  - {{{Which specific bound is returned is not set in stone}}}. Be more
 >  accurate.

 I tried to make the sentence clearer.

 More tomorrow. Off to bed now!

 Cheers from Montreal,
                                     Nicolas

--
Ticket URL: <http://trac.sagemath.org/ticket/17979#comment:437>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

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

Reply via email to