Open subsets of the Cantor set

class thompson.cantorsubset.CantorSubset(signature, generators=None)[source]

A subclass of Generators specifically designed to represent an open subset of the Cantor set \(\mathcal C\). We store this as a (typically sorted) list of Generators \(u_1, \dots, u_n\). This stands for the set of all points \(u_i\Gamma\) where \(\Gamma \in \{0,1\}^{\mathbb N}\).

is_entire_Cantor_set()[source]
is_empty()[source]
status()[source]
contract()[source]

Contracts the current generating set as much as possible (without using words involving a \(\lambda\)). The set should be sorted before using this method.

>>> basis = random_basis(cls=CantorSubset)
>>> basis.contract()
>>> basis == CantorSubset.standard_basis(basis.signature)
True
>>> basis = CantorSubset((2,1), '01011 01010'.split())
>>> basis.contract()
>>> print(basis)
[0101]
simplify()[source]

Simplifies the current Cantor subset to a normal form. We do this in three steps. Firstly we expand any nonsimple Words. Second, we contract() as much as possible (without using words involving a \(\lambda\)). Last, we check to see if the set contains any pairs \(u, u\Gamma\) and remove the latter.

>>> X = CantorSubset((2,1), "0 11 10 00 111 1101 11110".split())
>>> X.simplify(); print(X)
[<entire Cantor set>]
>>> X = CantorSubset((2,1), ["1"])
>>> X.simplify(); print(X)
[1]
__str__()[source]

We use a notation introduced to us by Bleak: square brackets around a word stand for “the Cantor set underneath” its argument. We use the format_cantor() function to display the elements of the generating set.

>>> print(CantorSubset((2, 1)))
[]
>>> print(CantorSubset((2, 1), ["x"]))
[<entire Cantor set>]
>>> print(CantorSubset((2, 1), ["x a1"]))
[0]
>>> S = CantorSubset((2, 1), ["x a1", "x a1 a1", "x a2 a1 a1", "x a2 a1 a2"])
>>> print(S)
[0, 00, 100, 101]
>>> S.simplify(); print(S)
[0, 10]
__and__(other)[source]

Computes the intersection of Cantor subsets. We assume the list of words is sorted before calling this function.

>>> A = CantorSubset((2, 1), ["00"])
>>> B = CantorSubset((2, 1), "01 111".split())
>>> C = A & B
>>> print(A, B, C)
[00] [01, 111] []
>>> D = CantorSubset((2, 1), ["11"])
>>> print(D, B, D & B)
[11] [01, 111] [111]
__invert__()[source]

The complement. again it only works on a sorted list of leaves.

>>> X = CantorSubset((2, 1), "01 1010 11".split())
>>> print(~X)
[00, 100, 1011]
>>> print(~CantorSubset((2, 1), []))
[<entire Cantor set>]
>>> print(~CantorSubset((2, 1), ["x1"]))
[]
>>> X = random_generators(cls=CantorSubset, signature=(2,1))
>>> X.sort();
>>> comp = ~X
>>> print(X & comp)
[]
>>> X.extend(comp); X.simplify()
>>> print(X)
[<entire Cantor set>]
thompson.cantorsubset.detailed_comparison(self, other)[source]

Returns a tuple (subword, comparison) of two Booleans. Either one word is a subword of the other or not. In the former case subword is True, otherwise subword is False.

In both cases we can decide if self is lexicographically smaller than other. If so, comparison is -1. If they are equal, comparison is 0; if self is larger than other then comparison is 1.

>>> for thing in ["0 00", "001 00", "101 101", "0 1", "11 00"]:
...     thing = thing.split()
...     s = Word(thing[0], (2, 1))
...     o = Word(thing[1], (2, 1))
...     print(*detailed_comparison(s, o))
... 
True -1
True 1
True 0
False -1
False 1