#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                |  e151d78ea32b9cac2047e2faff3247bdcce1f5d5
   Dependencies:                     |     Stopgaps:
-------------------------------------+-------------------------------------
Changes (by ncohen):

 * status:  needs_review => needs_work


Comment:

 Hello,

 This is what I did during the last 3~4 hours. I stopped before the end and
 did
 not review `m_interval`, `_lookahead` nor the code of `Envelope`, as I
 really
 should be working on mathematics instead of Sage `T_T`

 Some are easy, some are harder. Also, let me write somewhere that I am
 against
 keeping `integer_list_old` in Sage, as I am afraid that it will still be
 here
 several years from now. Here are my comments:

 - Module documentation -- in the 'itemize' section listing
 `IntegerListsLex` and
   `Envelope`, could you add a short description of what they are meant
 for?

 - Why a 'history' section?

 - Documentation of `IntegerListsLex`: instead of stating the *purpose* of
 the
   class (which is more something one would explain on a trac ticket), what
 about
   a SEEALSO section? I have the following paragraph in mind:
   {{{
   The main purpose is to provide a generic iteration engine for all
   the enumerated sets like :class:`Partitions`,
   class:`Compositions`, :class:`IntegerVectors`. It can also be
   used to generate many other combinatorial objects like Dyck paths,
   Motzkin paths, etc.
   }}}
   I thought that it would make more sense as a SEEALSO section pointing
 toward
   the mentionned objects.

 - About this paragraph:
   {{{
   The set of allowable constraints has been specifically designed to
 enable
   iteration with a good time and memory complexity in most practical use
 cases,
   and in inverse lexicographic order (see below)
   }}}

   I do not believe that it is true, i.e. that the set of allowable
 contraints
   has been specifically designed to enable iteration with a good time and
 memory
   complexity.

   In particular, it is possible to get great speed improvements by writing
 a
   Constant Amortized Algorithm to list only partitions satisfying a
 smaller set
   of constraints like (sum,length,min/max part).

   This statement sounds wrong to me, and so I believe that it should be
 removed.

 - Documentation of the parameter `n` -- you say that a list of integers
 can be
   provided but do not explain what the output will be.

 - 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.

 - 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 woud 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.

 - ``check`` seems misnamed. It is not about checking the input or output,
 only
   about displaying warnings. What about `disable_warnings` instead?

 - In the following text which says that one can force the enumeration when
 it is
   formally impossible, can you explicitly say what will happen? "All
 possible
   lists are enumerated, but the ordering is incorrect" or something?
   {{{If one wants to proceed anyway, one can sign a waiver by setting
 check=False:}}}

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

 - Building the doc of `integer_list.py` with `--warn-links` fails.

 - {{{sage: list(IntegerListsLex(3, max_length=2, ))}}}

 - 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.

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

 - {{{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 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`.

 - {{{self._max_length = ZZ(max_length) if max_length != Infinity else
 max_length}}}
   Just my two cents: I would return 'Infinity' instead of max_length. You
   defined your `Infinity` in order to be fast, and you don't know what
   `max_length` may be. This occurs several times.

 - You can save space and turn the two following tests into one (using the
 same
   'all'). Occurs twice.
   {{{
   if not all(i in ZZ for i in floor):
       raise TypeError("the parts of floor={} should be nonnegative
 integers".format(floor))
   if not all(i >= 0 for i in floor):
       raise NotImplementedError("negative parts in
 floor={}".format(floor))
   }}}
   This would also solve the following, which tests `ceiling` but mentions
   `floor`
   {{{
   if not all(i >= 0 for i in ceiling):
       raise NotImplementedError("negative parts in
 floor={}".format(ceiling))
   }}}

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

 - 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.

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

 - 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".

 - 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.

 - 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.

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

 - 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
   }}}

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

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

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

 Nathann

--
Ticket URL: <http://trac.sagemath.org/ticket/17979#comment:412>
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