Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_valid_error_in_construction():
with pytest.raises(ValueError):
Av(Basis())
with pytest.raises(ValueError):
Av(Basis(Perm()))
Av.from_string("132").enumeration(8)
== Av(Basis(Perm((0, 2, 1)))).enumeration(8)
== [1, 1, 2, 5, 14, 42, 132, 429, 1430]
)
assert (
Av.from_string("Av(123,231)").enumeration(8)
== Av(Basis(Perm((0, 1, 2)), Perm((1, 2, 0)))).enumeration(8)
== [1, 1, 2, 4, 7, 11, 16, 22, 29]
)
assert Av(
(Perm((0, 1, 2)), MeshPatt(Perm((2, 0, 1)), [(0, 1), (1, 1), (2, 1), (3, 1)]))
).enumeration(7) == [1, 1, 2, 4, 8, 16, 32, 64]
assert (
Av.from_string("0123_2013_1023").enumeration(8)
== Av(
Basis(Perm((0, 1, 2, 3)), Perm((2, 0, 1, 3)), Perm((1, 0, 2, 3)))
).enumeration(8)
== [1, 1, 2, 6, 21, 79, 309, 1237, 5026]
)
assert (
Av.from_string("1243 1342 3241 3241").enumeration(8)
== Av(
Basis(
Perm((0, 1, 3, 2)),
Perm((0, 2, 3, 1)),
Perm((2, 1, 3, 0)),
Perm((2, 1, 3, 0)),
)
).enumeration(8)
== [1, 1, 2, 6, 21, 75, 262, 891, 2964]
)
assert (
def test_avoiding_enumeration(patts, enum):
patts = [Perm(patt) for patt in patts]
basis = Basis(*patts)
for (n, cnt) in enumerate(enum):
# print(n, cnt)
inst = Av(basis).of_length(n)
gen = list(inst)
# assert len(gen) == cnt
assert len(gen) == len(set(gen))
for perm in gen:
assert perm.avoids(*patts)
mx = len(enum) - 1
cnt = [0 for _ in range(mx + 1)]
for perm in Av(basis).up_to_length(mx):
assert perm.avoids(*patts)
cnt[len(perm)] += 1
assert enum == cnt
def test_enumeration():
assert (
Av.from_string("132").enumeration(8)
== Av(Basis(Perm((0, 2, 1)))).enumeration(8)
== [1, 1, 2, 5, 14, 42, 132, 429, 1430]
)
assert (
Av.from_string("Av(123,231)").enumeration(8)
== Av(Basis(Perm((0, 1, 2)), Perm((1, 2, 0)))).enumeration(8)
== [1, 1, 2, 4, 7, 11, 16, 22, 29]
)
assert Av(
(Perm((0, 1, 2)), MeshPatt(Perm((2, 0, 1)), [(0, 1), (1, 1), (2, 1), (3, 1)]))
).enumeration(7) == [1, 1, 2, 4, 8, 16, 32, 64]
assert (
Av.from_string("0123_2013_1023").enumeration(8)
== Av(
Basis(Perm((0, 1, 2, 3)), Perm((2, 0, 1, 3)), Perm((1, 0, 2, 3)))
).enumeration(8)
== [1, 1, 2, 6, 21, 79, 309, 1237, 5026]
)
assert (
Av.from_string("1243 1342 3241 3241").enumeration(8)
== Av(
Basis(
av = Av(basis)
assert basis in Av._CLASS_CACHE
list(av.of_length(5))
assert len(av.cache) == 6
assert len(Av(Basis(Perm((0, 1)))).cache) == 6
av2 = Av(Basis(Perm((0, 1))))
assert len(av2.cache) == 6
list(av2.of_length(10))
assert len(av.cache) == 11
assert len(av2.cache) == 11
assert len(Av.from_string("12").cache) == 11
assert len(Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)))).cache) == 1
list(Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)))).of_length(5))
assert len(Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)))).cache) == 6
assert (
len(Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)), Perm((1, 2, 0, 3)))).cache) == 6
)
assert len(Av(Basis(Perm((1, 2, 0)), Perm((2, 0, 1)))).cache) == 6
for p in Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)), Perm((1, 2, 0, 3)))).of_length(
10
):
pass
assert len(Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)))).cache) == 11
Av.clear_cache()
def test_class_variable_cache():
Av.clear_cache()
assert len(Av._CLASS_CACHE) == 0
assert Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)))) is Av(
Basis(Perm((2, 0, 1)), Perm((1, 2, 0)))
)
av = Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0))))
assert av is Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0))))
assert av is Av(Basis(Perm((2, 0, 1)), Perm((1, 2, 0)), Perm((1, 2, 0, 3))))
assert len(Av._CLASS_CACHE) == 1
av2 = Av(Basis(Perm((0, 1, 3, 2)), Perm((0, 2, 1))))
assert len(Av._CLASS_CACHE) == 2
assert av is not av2
assert av2 is Av(Basis(Perm((0, 2, 1))))
assert Av.from_string("132") is av2
assert Basis(Perm((0, 2, 1))) in Av._CLASS_CACHE
assert (
Av._CLASS_CACHE[Basis(Perm((0, 2, 1)))]
is Av._CLASS_CACHE[Basis(Perm((0, 1, 3, 2)), Perm((0, 2, 1)))]
)
assert Av((Perm((2, 0, 1)),)) is Av(Basis(Perm((2, 0, 1))))
def from_string(cls, basis) -> "Av":
"""Create a permutation class from a string. Basis can be either zero or one
based and seperated by anything. MeshBasis is not supported.
"""
return cls(Basis.from_string(basis))
def from_iterable(
cls, basis: Union[Iterable[Perm], Iterable[Union[Perm, MeshPatt]]]
) -> "Av":
"""Create a permutation class from a basis defined by an iterable of patterns.
"""
if MeshBasis.is_mesh_basis(basis):
return cls(MeshBasis(*basis))
return cls(Basis(*basis))
from .basis import Basis, MeshBasis
class AvBase(NamedTuple):
"""A base class for Av to define instance variables without having to use
__init__ in Av.
"""
basis: Union[Basis, MeshBasis]
cache: List[Dict[Perm, Optional[List[int]]]]
class Av(AvBase):
"""A permutation class defined by its minimal basis."""
_FORBIDDEN_BASIS = Basis(Perm())
_VALUE_ERROR_MSG = "Basis should be non-empty without the empty perm!"
_BASIS_ONLY_MSG = "Only supported for Basis!"
_CLASS_CACHE: ClassVar[Dict[Union[Basis, MeshBasis], "Av"]] = {}
_CACHE_LOCK = multiprocessing.Lock()
def __new__(
cls,
basis: Union[
Basis, MeshBasis, Iterable[Perm], Iterable[Union[Perm, MeshPatt]],
],
) -> "Av":
if not isinstance(basis, (Basis, MeshBasis)):
return Av.from_iterable(basis)
if len(basis) == 0 or basis == Av._FORBIDDEN_BASIS:
raise ValueError(Av._VALUE_ERROR_MSG)
instance = Av._CLASS_CACHE.get(basis)