Opened 23 months ago

# Abelian complexity when alphabet is not specified

Reported by: Owned by: evandomme major sage-8.4 combinatorics days95, words, abelian, complexity slabbe, mlapointe, mstipulanti N/A

### Description

There is an error when one computes the abelian complexity of a word without specifying its alphabet. The code

```u = Word('110101')
u.abelian_complexity(2)
```

raises the error:

```---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-33a7ed281f2e> in <module>()
----> 1 u.abelian_complexity(Integer(2))

/Applications/sagemath/sage/local/lib/python2.7/site-packages/sage/combinat/words/finite_word.pyc in abelian_complexity(self, n)
5837
5838         """
-> 5839         return len(self.abelian_vectors(n))
5840
5841     def sturmian_desubstitute_as_possible(self):

/Applications/sagemath/sage/local/lib/python2.7/site-packages/sage/combinat/words/finite_word.pyc in abelian_vectors(self, n)
5802         size = alphabet.cardinality()
5803         if size == float('inf'):
-> 5804             raise TypeError("The alphabet of the parent is infinite; define"
5805                    " the word with a parent on a finite alphabet")
5806         S = set()

TypeError: The alphabet of the parent is infinite; define the word with a parent on a finite alphabet

```

But if we specify the parent of the word, everything works.

```W = Words('01'')
u = W('110101')
u.abelian_complexity(2)
```

Note the error comes from the abelian_vectors method where it is required that "the word must be defined with a parent on a finite alphabet". But I would expect the alphabet to be equal to the set of letters occurring in the word, if it is not specified.

NB: This question is linked to the ticket 17058 where the argument "alphabet" was deprecated in the abelian_vector method.

### comment:1 Changed 23 months ago by slabbe

It was decided long time ago (this can of course be discussed) that the alphabet is `Set of Python objects of class 'object'` when not specified. The reason is that you want `Word(input)` to be fast no matter how big is the input and thus, you do not want to check all of its letters to compute the alphabet of the word each time you create a word:

```sage: w = Word('asdfas'*100000)
sage: w.parent()
Finite words over Set of Python objects of class 'object'
```

As the error message says, one must provide the alphabet:

```sage: w = Word('asdfas'*100000, alphabet='asdf')
sage: w.parent()
Finite words over {'a', 's', 'd', 'f'}
```

or first create the parent:

```sage: W = Words('asdf')
sage: W
Finite and infinite words over {'a', 's', 'd', 'f'}
sage: w = W('asdfas'*100000)
sage: w.parent()
Finite words over {'a', 's', 'd', 'f'}
```

Note that you can get the letters appearing in a word by doing:

```sage: w.letters()
['a', 's', 'd', 'f']
```
Note: See TracTickets for help on using tickets.