Closed videlec closed 8 years ago
Sounds great. I will be reviewing this.
Branch: u/vdelecroix/19619
Author: Vincent Delecroix
Description changed:
---
+++
@@ -13,8 +13,16 @@
Infinite Words over {0, 1}
-The proposal of this ticket is to have only three classes: +The proposal of this ticket is to have only four classes:
FiniteWords
Words_n
: words of length n
(as a slice of the one before)InfiniteWords
(or FullShift
)
+- FiniteAndInfiniteWords
The parent FiniteWords
should hence have a method .shift()
that return the associated shift (e.g u ** Infinity
will belong there). Similarly, the parent InfiniteWords
should have a method .factors()
that return the set of factors (and finite slices will belong there).
+
+We also:
+
+- deprecate size_of_alphabet
and has_letter
+- use a bit more of categories in lyndon_word.py
+- use more often Word_char
if possible
+- implement a better iterator for periodic points that avoids computing huge power of the morphism (that is not always doable)
Branch pushed to git repo; I updated commit sha1. New commits:
0917c15 | Trac 19619: fix unpickling |
What a mess this unpickling stuff!!!
Branch pushed to git repo; I updated commit sha1. New commits:
ab9f0e1 | Trac 19619: typo |
Branch pushed to git repo; I updated commit sha1. New commits:
661588f | Trac 19619: bad input block |
All tests pass!
Is it ready for review? I saw a TODO in the diff...
Replying to @seblabbe:
Is it ready for review? I saw a TODO in the diff...
Read for review. The TODO can be removed. It was because of the cmp_letters
method. Now its status is decided on construction as follows
if alphabet.cardinality() == Infinity or \
(alphabet.cardinality() < 36 and
all(alphabet.unrank(i) > alphabet.unrank(j) for
i in range(min(36,alphabet.cardinality())) for j in range(i))):
self.cmp_letters = cmp
else:
self.cmp_letters = self._cmp_letters
where _cmp_letters
is the previous version which compares by ranking in the alphabet. It is of course not ideal, but I think that we should get rid of this cmp_letters
anyway.
Branch pushed to git repo; I updated commit sha1. New commits:
a706f49 | Trac 19619: remove the TODO |
Some methods are missing doctests apparently:
Decreased doctests in combinat/words/morphism.py: from 53 / 53 = 100% to 53 / 56 = 94%
Decreased doctests in combinat/words/paths.py: from 57 / 57 = 100% to 57 / 59 = 96%
Decreased doctests in combinat/words/words.py: from 45 / 45 = 100% to 63 / 66 = 95%
Is that a problem?
In words.py
, I can add some:
TESTS:
sage: print "hello"
hello
but I do not see the point. The missing doctest are in the deprecated class Words_all
I do not see any relevant test...
For morphism.py
and paths.py
I will complete the missing ones.
Branch pushed to git repo; I updated commit sha1. New commits:
bcc2d86 | Trac 19619: more doc (and equality improvements) |
The ones at lines 302 and 1721 are not deprecated. The method _cmp_letters
is tested with cmp_letters
(?). To my opinion, the two methods that are deprecated should also be doctested. It will take three lines, show the user how to use those methods. Maybe with a pickle through an indirect doctest, I don't know. For the one at line 2429, say why this method must exist, it contains only "pass", why?
------------------------------------------------------------------------
SCORE src/sage/combinat/words/words.py: 95.5% (63 of 66)
Missing documentation:
* line 1721: def _element_classes(self)
* line 2424: def __setstate__(self, state)
* line 2429: def _element_constructor_(self)
Possibly wrong (function name doesn't occur in doctests):
* line 302: def _cmp_letters(self, letter1, letter2)
------------------------------------------------------------------------
Branch pushed to git repo; I updated commit sha1. New commits:
29daae2 | Trac 19619: doc for _cmp_letters and _element_classes |
Branch pushed to git repo; I updated commit sha1. New commits:
4494886 | Trac 19619: remove `__setstate__` and few words for _element_constructor_ |
Why Words_n
inherits from Parent
instead of AbstractLanguage
?
Should a parent return an element for which he is the parent?
sage: W = Words('abc')
sage: W
Finite and infinite words over {'a', 'b', 'c'}
sage: W('aabbcc').parent()
Finite words over {'a', 'b', 'c'}
sage: W('aabbcc').parent() == W
False
sage: W = Words(range(4))
sage: W(lambda n:n%4).parent() == W
False
Replying to @seblabbe:
Why
Words_n
inherits forParent
instead ofAbstractLanguage
?
AbstractLanguage
is designed to disappear. For the moment it just holds the _alphabet
attributes and some deprecated methods. I am not sure that all language should keep this _alphabet
attribute. That can be changed. Do we want that languages implement a method alphabet
or simply provides an alphabet to the constructor of a base class?
Words_n
does not care about an attribute _alphabet
since it is initialized with a FiniteWords
as first argument. It is essentially an empty shell.
Replying to @seblabbe:
Should a parent return an element for which he is the parent?
There are other parents doing the same
sage: NN.an_element().parent() == NN
False
sage: Primes().an_element().parent() == Primes()
False
And this is the concept of facade (in the Sage category sense).
With my branch you always have:
FiniteWords
InfiniteWords
FiniteOrInfiniteWords
In particularsage: W = Words('ab')
sage: W('ab').parent() is W.finite_words()
True
sage: W(lambda n: 'a', length='infinite').parent() is W.infinite_words()
True
sage: W(iter("ab"*100)).parent() is W
True
Replying to @videlec:
AbstractLanguage
is designed to disappear.
If so, say it in the docstring __doc__
of AbstractLanguage
. It helps to know what should be the next improvements to the code.
For the moment it just holds the
_alphabet
attributes and some deprecated methods.
But it contains some other nondeprecated methods too.
Replying to @seblabbe:
Replying to @videlec:
AbstractLanguage
is designed to disappear.If so, say it in the docstring
__doc__
ofAbstractLanguage
. It helps to know what should be the next improvements to the code.For the moment it just holds the
_alphabet
attributes and some deprecated methods.But it contains some other nondeprecated methods too.
Right. Let say that it is an experimental abstraction of a potential Language
base class... I will update the doc (not changing anything else).
Replying to @videlec:
With my branch you always have:
- finte words have a parent
FiniteWords
- infinite words have a parent
InfiniteWords
- words with indefinite status have a parent
FiniteOrInfiniteWords
It is interesting that you write FiniteOrInfiniteWords
here instead of FiniteAndInfiniteWords
in the code because I was going to suggest to call that class FiniteOrInfiniteWords
instead.
Replying to @seblabbe:
Replying to @videlec:
With my branch you always have:
- finte words have a parent
FiniteWords
- infinite words have a parent
InfiniteWords
- words with indefinite status have a parent
FiniteOrInfiniteWords
It is interesting that you write
FiniteOrInfiniteWords
here instead ofFiniteAndInfiniteWords
in the code because I was going to suggest to call that classFiniteOrInfiniteWords
instead.
Oh right. It is clearly a union, hence Or
makes more sense... will do it.
Branch pushed to git repo; I updated commit sha1. New commits:
7ee2e3c | Trac 19619: FiniteAndInfinite -> FiniteOrInfinite |
Description changed:
---
+++
@@ -17,7 +17,7 @@
- `FiniteWords`
- `Words_n`: words of length `n` (as a slice of the one before)
- `InfiniteWords` (or `FullShift`)
-- `FiniteAndInfiniteWords`
+- `FiniteOrInfiniteWords`
The parent `FiniteWords` should hence have a method `.shift()` that return the associated shift (e.g `u ** Infinity` will belong there). Similarly, the parent `InfiniteWords` should have a method `.factors()` that return the set of factors (and finite slices will belong there).
We also:
Reviewer: Sébastien Labbé
I am still not done with the review as I need more time to think and look at the code... Will continue this tomorrow.
__call__
to be implemented in one place in AbstractLanguage
? Lot of documentation is a copy paste...
length
in unused in InfiniteWords.__call__
.InfiniteWords.__call__
should not mention list, str, tuple, char and the length argument.FiniteWords._word_from_word
seem useless. Same comment for InfiniteWords._word_from_word
:from sage.combinat.words.finite_word import CallableFromListOfWords
if isinstance(data._func, CallableFromListOfWords):
# The following line is important because, in this case,
# data._func is also a tuple (indeed
# CallableFromListOfWords inherits from tuple)
datatype = "callable"
Words_n.__call__
should include a INPUTS:
blockfrom sage.misc.mrange import xmrange
from sage.structure.parent import Set_PythonType
from sage.combinat.combinat import InfiniteAbstractCombinatorialClass
Branch pushed to git repo; I updated commit sha1. New commits:
f8e4ca5 | Trac 19619: remove length arguments |
Replying to @seblabbe:
- Are sure that we do not prefer the
__call__
to be implemented in one place inAbstractLanguage
? Lot of documentation is a copy paste...
Definitely not. We do not want to impose the class of elements for (future) languages. Moreover:
FiniteWords
or finite ones from InfiniteWords
.To my mind, the documentation is completely useless. Which user will do
sage: W = Words('ab')
sage: W.__call__?
As a very casual user of words: I would expect FiniteOrInfiniteWords
to be Words
...
Currently we have too many parent for words:
Words_all
,Words_over_alphabet
,Words_over_OrderedAlphabet
)FiniteWords_over_OrderedAlphabet
)InfiniteWords_over_OrderedAlphabet
)FiniteWords_length_k_over_OrderedAlphabet
andWords_n
)This lead to subtle bug like
The proposal of this ticket is to have only four classes:
FiniteWords
Words_n
: words of lengthn
(as a slice of the one before)InfiniteWords
(orFullShift
)FiniteOrInfiniteWords
The parentFiniteWords
should hence have a method.shift()
that return the associated shift (e.gu ** Infinity
will belong there). Similarly, the parentInfiniteWords
should have a method.factors()
that return the set of factors (and finite slices will belong there).We also:
size_of_alphabet
andhas_letter
lyndon_word.py
Word_char
if possibleCC: @seblabbe
Component: combinatorics
Author: Vincent Delecroix
Branch/Commit:
4fd6556
Reviewer: Sébastien Labbé
Issue created by migration from https://trac.sagemath.org/ticket/19619