Skip to content

Commit

Permalink
Merge 949f94a into 884ed75
Browse files Browse the repository at this point in the history
  • Loading branch information
enadeau committed Sep 17, 2019
2 parents 884ed75 + 949f94a commit ac2cd67
Show file tree
Hide file tree
Showing 6 changed files with 586 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ sudo: false

language: python
python:
- 'pypy3.5'
- '3.5'
- '3.6'
- '3.7'
- '3.7-dev'
- '3.8-dev'
- 'nightly'
- 'pypy3.5'

install:
- pip install --upgrade pip
Expand Down
303 changes: 303 additions & 0 deletions tests/algorithms/test_obstruction_inferral.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
import abc
from unittest.mock import MagicMock, patch

import pytest

from comb_spec_searcher import Rule
from permuta import Perm
from tilings import Obstruction, Requirement, Tiling
from tilings.algorithms import (AllObstructionInferral, EmptyCellInferral,
SubobstructionInferral)
from tilings.algorithms.obstruction_inferral import ObstructionInferral


class CommonTest(abc.ABC):
@pytest.fixture
def tiling1(self):
"""
A tiling that can be inferred.
"""
t = Tiling(obstructions=[
Obstruction(Perm((0, 1)), ((1, 0), (1, 0))),
Obstruction(Perm((1, 0)), ((0, 0), (0, 0))),
Obstruction(Perm((0, 1, 2)), ((0, 0), (0, 0), (0, 0))),
Obstruction(Perm((0, 1, 2)), ((0, 0), (0, 0), (1, 0))),
Obstruction(Perm((2, 1, 0)), ((0, 0), (1, 0), (1, 0))),
Obstruction(Perm((2, 1, 0)), ((1, 0), (1, 0), (1, 0)))
], requirements=[[
Requirement(Perm((1, 0)), ((1, 0), (1, 0)))
]])
return t

@pytest.fixture
def tiling2(self):
"""
A tiling that can be inferred.
"""
t2 = Tiling(obstructions=[
Obstruction(Perm((0, 2, 1)), ((0, 0), (1, 0), (1, 0))),
Obstruction(Perm((0, 2, 1)), ((0, 0), (1, 0), (2, 0))),
Obstruction(Perm((0, 2, 1)), ((0, 0), (2, 0), (2, 0))),
Obstruction(Perm((0, 2, 1)), ((1, 0), (2, 0), (2, 0))),
Obstruction(Perm((1, 0, 2)), ((0, 0), (0, 0), (1, 0))),
Obstruction(Perm((1, 0, 2)), ((0, 0), (0, 0), (2, 0))),
Obstruction(Perm((1, 0, 2)), ((0, 0), (1, 0), (2, 0))),
Obstruction(Perm((1, 0, 2)), ((1, 0), (1, 0), (2, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((0, 0), (0, 0), (0, 0), (0, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((0, 0), (0, 0), (0, 0), (1, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((0, 0), (0, 0), (0, 0), (2, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((1, 0), (1, 0), (1, 0), (1, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((1, 0), (1, 0), (1, 0), (2, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((2, 0), (2, 0), (2, 0), (2, 0))),
Obstruction(Perm((1, 0, 3, 2)), ((0, 0), (0, 0), (0, 0), (0, 0))),
Obstruction(Perm((1, 0, 3, 2)), ((1, 0), (1, 0), (1, 0), (1, 0))),
Obstruction(Perm((1, 0, 3, 2)), ((2, 0), (2, 0), (2, 0), (2, 0)))
], requirements=[[
Requirement(Perm((1, 0)), ((1, 0), (1, 0)))
]])
return t2

@pytest.fixture
def tiling_not_inf(self):
"""
A tiling that cannot be inferred.
"""
return Tiling.from_string('1234_2341')

@abc.abstractmethod
@pytest.fixture
def obs_inf1(self, tiling1):
pass

@abc.abstractmethod
@pytest.fixture
def obs_not_inf(self, obs_not_inf):
pass

def test_formal_step(self, obs_inf1):
assert (obs_inf1.formal_step() ==
"Added the obstructions {}.".format(obs_inf1.new_obs()))

def test_rule(self, obs_inf1, obs_not_inf):
rule = obs_inf1.rule()
assert isinstance(rule, Rule)
assert rule.comb_classes == [obs_inf1.obstruction_inferral()]
assert rule.ignore_parent
assert rule.workable == [True]
assert rule.constructor == 'equiv'
assert rule.possibly_empty == [False]
assert obs_not_inf.rule() is None


class TestObstructionInferral(CommonTest):

@pytest.fixture
@patch.multiple(ObstructionInferral, __abstractmethods__=set())
def obs_inf1(self, tiling1):
obs_trans = ObstructionInferral(tiling1)
obs_trans.potential_new_obs = MagicMock(return_value=[
Obstruction(Perm((0, 1)), [(0, 0), (0, 0)]),
Obstruction(Perm((1, 0)), [(0, 0), (1, 0)]),
])
return obs_trans

@pytest.fixture
@patch.multiple(ObstructionInferral, __abstractmethods__=set())
def obs_not_inf(self, tiling_not_inf):
"""
An obstruction inferral object where no new obstructions can be
added.
"""
obs_trans = ObstructionInferral(tiling_not_inf)
obs_trans.potential_new_obs = MagicMock(return_value=[])
return obs_trans

def test_init(self, tiling1):
with pytest.raises(TypeError):
ObstructionInferral(tiling1)

def test_new_obs(self, obs_inf1, obs_not_inf):
assert obs_inf1.new_obs() == [
Obstruction(Perm((0, 1)), ((0, 0), (0, 0))),
]
assert obs_not_inf.new_obs() == []

def test_obstruction_inferral(self, obs_inf1, tiling1, obs_not_inf,
tiling_not_inf):
assert obs_not_inf.obstruction_inferral() == tiling_not_inf
inf_tiling = tiling1.add_single_cell_obstruction(Perm((0, 1)), (0, 0))
assert obs_inf1.obstruction_inferral() == inf_tiling

def test_can_add_obstruction(self, obs_inf1, tiling1):
ob1 = Obstruction(Perm((0, 1)), [(0, 0), (0, 0)])
ob2 = Obstruction(Perm((1, 0)), [(0, 0), (1, 0)])
assert obs_inf1.can_add_obstruction(ob1, tiling1)
assert not obs_inf1.can_add_obstruction(ob2, tiling1)


class TestSubobstructionInferral(CommonTest):
@pytest.fixture
def obs_inf1(self, tiling1):
obs_inf = SubobstructionInferral(tiling1)
return obs_inf

@pytest.fixture
def obs_inf2(self, tiling2):
obs_inf = SubobstructionInferral(tiling2)
return obs_inf

@pytest.fixture
def obs_not_inf(self, tiling_not_inf):
"""
An obstruction inferral object where no new obstructions can be
added.
"""
obs_trans = SubobstructionInferral(tiling_not_inf)
return obs_trans

def test_init(self, tiling1):
sub_obs_inf = SubobstructionInferral(tiling1)
assert sub_obs_inf._tiling == tiling1

def test_potential_new_obs(self, obs_inf1):
assert obs_inf1.potential_new_obs() == set([
Obstruction(Perm((0,)), ((0, 0),)),
Obstruction(Perm((0,)), ((1, 0),)),
Obstruction(Perm((0, 1)), ((0, 0), (0, 0))),
Obstruction(Perm((0, 1)), ((0, 0), (1, 0))),
Obstruction(Perm((1, 0)), ((0, 0), (1, 0))),
Obstruction(Perm((1, 0)), ((1, 0), (1, 0))),
])

def test_new_obs(self, obs_not_inf, obs_inf1, obs_inf2):
assert obs_inf1.new_obs() == [
Obstruction(Perm((0, 1)), ((0, 0), (0, 0))),
]
assert obs_not_inf.new_obs() == []
assert obs_inf2.new_obs() == [
Obstruction(Perm((0, 1)), ((0, 0), (2, 0))),
]

def test_obstruction_inferral(self, obs_inf2):
t = Tiling(obstructions=[
Obstruction(Perm((0, 1)), ((0, 0), (2, 0))),
Obstruction(Perm((0, 2, 1)), ((0, 0), (1, 0), (1, 0))),
Obstruction(Perm((0, 2, 1)), ((1, 0), (2, 0), (2, 0))),
Obstruction(Perm((1, 0, 2)), ((0, 0), (0, 0), (1, 0))),
Obstruction(Perm((1, 0, 2)), ((1, 0), (1, 0), (2, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((0, 0), (0, 0), (0, 0), (0, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((0, 0), (0, 0), (0, 0), (1, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((1, 0), (1, 0), (1, 0), (1, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((1, 0), (1, 0), (1, 0), (2, 0))),
Obstruction(Perm((0, 3, 2, 1)), ((2, 0), (2, 0), (2, 0), (2, 0))),
Obstruction(Perm((1, 0, 3, 2)), ((0, 0), (0, 0), (0, 0), (0, 0))),
Obstruction(Perm((1, 0, 3, 2)), ((1, 0), (1, 0), (1, 0), (1, 0))),
Obstruction(Perm((1, 0, 3, 2)), ((2, 0), (2, 0), (2, 0), (2, 0)))
], requirements=[[
Requirement(Perm((1, 0)), ((1, 0), (1, 0)))
]])
assert obs_inf2.obstruction_inferral() == t


class TestEmptyCellInferral(CommonTest):
@pytest.fixture
def tiling1(self):
t = Tiling(obstructions=[
Obstruction(Perm((0, 1)), ((1, 0), (1, 0))),
Obstruction(Perm((0, 1)), ((0, 0), (0, 0))),
Obstruction(Perm((0, 1)), ((0, 0), (1, 0))),
Obstruction(Perm((1, 0)), ((0, 0), (1, 0))),
], requirements=[[
Requirement(Perm((0,)), ((0, 0),)),
]])
return t

@pytest.fixture
def obs_inf1(self, tiling1):
obs_inf = EmptyCellInferral(tiling1)
return obs_inf

@pytest.fixture
def obs_inf2(self, tiling2):
obs_inf = EmptyCellInferral(tiling2)
return obs_inf

@pytest.fixture
def obs_not_inf(self, tiling_not_inf):
obs_trans = SubobstructionInferral(tiling_not_inf)
return obs_trans

def test_init(self, tiling1):
empty_inf = EmptyCellInferral(tiling1)
assert empty_inf._tiling == tiling1

def test_new_obs(self, obs_inf1, obs_inf2):
assert set(obs_inf1.potential_new_obs()) == set([
Obstruction(Perm((0,)), ((1, 0), )),
])
assert set(obs_inf2.potential_new_obs()) == set([
Obstruction(Perm((0,)), ((0, 0), )),
Obstruction(Perm((0,)), ((2, 0), )),
])

def test_formal_step(self, obs_inf1):
assert "The cells (1, 0) are empty."


class TestAllObstructionInferral(CommonTest):

@pytest.fixture
def obs_inf1(self, tiling1):
return AllObstructionInferral(tiling1, 2)

@pytest.fixture
def obs_not_inf(self, tiling_not_inf):
return AllObstructionInferral(tiling_not_inf, 3)

def test_obstruction_length(self, obs_inf1):
assert obs_inf1.obstrucion_length == 2

def test_avoids_obstruction(self, obs_inf1):
assert obs_inf1.avoids_obstructions(Obstruction(Perm((0, 1)),
((0, 0), (1, 0))))
assert not obs_inf1.avoids_obstructions(
Obstruction(Perm((0, 1, 2)), ((0, 0), (0, 0), (1, 0))))

def test_not_required(self, obs_inf1):
assert not obs_inf1.not_required(Requirement(Perm((0,)), ((1, 0),)))
assert not obs_inf1.not_required(Requirement(Perm((1, 0)),
((1, 0), (1, 0))))
assert obs_inf1.not_required(Requirement(Perm((0, 1)),
((1, 0), (1, 0))))
t = Tiling(obstructions=[
Obstruction(Perm((0, 1, 2)), ((0, 0),)*3),
], requirements=[[
Requirement(Perm((0, 1)), ((0, 0),)*2),
Requirement(Perm((1, 0)), ((0, 0),)*2),
]])
obs_inf = AllObstructionInferral(t, 2)
assert obs_inf.not_required(
Obstruction(Perm((0, 1)), ((0, 0),)*2))
assert not obs_inf.not_required(
Obstruction(Perm((0,)), ((0, 0),)))

def test_potential_new_obs(self, obs_inf1, obs_not_inf):
assert set(obs_inf1.potential_new_obs()) == set([
Obstruction(Perm((0, 1)), ((0, 0), (0, 0))),
Obstruction(Perm((0, 1)), ((0, 0), (1, 0))),
Obstruction(Perm((1, 0)), ((0, 0), (1, 0))),
])
assert set(obs_not_inf.potential_new_obs()) == set([
Obstruction(Perm((0, 1, 2)), ((0, 0),)*3),
Obstruction(Perm((0, 2, 1)), ((0, 0),)*3),
Obstruction(Perm((1, 0, 2)), ((0, 0),)*3),
Obstruction(Perm((1, 2, 0)), ((0, 0),)*3),
Obstruction(Perm((2, 0, 1)), ((0, 0),)*3),
Obstruction(Perm((2, 1, 0)), ((0, 0),)*3),
])

def test_new_obs(self, obs_inf1, obs_not_inf):
assert set(obs_inf1.new_obs()) == set([
Obstruction(Perm((0, 1)), ((0, 0), (0, 0))),
])
assert obs_not_inf.new_obs() == []

0 comments on commit ac2cd67

Please sign in to comment.