def test_guided_searcher(): tilescope = TileScope( "123", TileScopePack.point_placements().make_fusion(tracked=False)) spec = tilescope.auto_search() searcher = GuidedSearcher.from_spec( spec, TileScopePack.point_placements().make_fusion(tracked=True)) tracked_spec = searcher.auto_search() tracked_spec = tracked_spec.expand_verified() assert [tracked_spec.count_objects_of_size(i) for i in range(13)] == [ 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, ]
def test_123_positive_fusions(): pack = TileScopePack.insertion_row_and_col_placements( row_only=True).make_fusion(tracked=True, apply_first=True) css = TileScope("123", pack) spec = css.auto_search(status_update=30) spec = spec.expand_verified() print(spec) assert isinstance(spec, CombinatorialSpecification) assert [spec.count_objects_of_size(i) for i in range(20)] == [ 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, ] av = Av([Perm((0, 1, 2))]) for i in range(10): assert set(av.of_length(i)) == set( gp.patt for gp in spec.generate_objects_of_size(i)) assert spec.random_sample_object_of_size(i).patt in av
def test_123_interleaving(): pack = TileScopePack.point_placements().make_interleaving() css = TileScope("123", pack) spec = css.auto_search(status_update=30) spec = spec.expand_verified() assert isinstance(spec, CombinatorialSpecification) assert [spec.count_objects_of_size(i) for i in range(20)] == [ 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, ]
def test_123_positive_fusions(): pack = TileScopePack.insertion_row_and_col_placements(row_only=True).make_fusion( tracked=True, apply_first=True ) css = TileScope("123", pack) spec = css.auto_search(status_update=30) assert isinstance(spec, CombinatorialSpecification) assert [spec.count_objects_of_size(i) for i in range(20)] == [ 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, ]
def forest_expansion(): """ A forest spec that at some point became not productive once expanded. """ basis = "0213_1032_1302" pack = TileScopePack.point_placements() css = TileScope(basis, pack, ruledb=RuleDBForest()) spec = css.auto_search(status_update=30) for rule in spec.rules_dict.values(): rule.label = spec.get_label(rule.comb_class) spec.expand_verified() assert [spec.count_objects_of_size(i) for i in range(13)] == [ 1, 1, 2, 6, 21, 77, 287, 1079, 4082, 15522, 59280, 227240, 873886, ]
def test_domino(): domino = Tiling(obstructions=[ GriddedPerm((0, 2, 1), [(0, 0), (0, 0), (0, 0)]), GriddedPerm((1, 0, 2), [(0, 1), (0, 1), (0, 1)]), GriddedPerm((0, 2, 1, 3), [(0, 0), (0, 1), (0, 0), (0, 1)]), ]) tilescope = TileScope( domino, TileScopePack.row_and_col_placements().make_fusion(tracked=True, component=True), ) spec = tilescope.auto_search() assert isinstance(spec, CombinatorialSpecification) assert [spec.count_objects_of_size(i) for i in range(15)] == [ 1, 2, 6, 22, 91, 408, 1938, 9614, 49335, 260130, 1402440, 7702632, 42975796, 243035536, 1390594458, ]
def test_expansion(): """ This cannot be expanded automatically since it requires the positive root that is not in the specification. """ pack = TileScopePack.only_root_placements(3, 1) css = TileScope("132", pack) spec = css.auto_search(smallest=True) spec = spec.expand_verified() assert sum(1 for rule in spec if isinstance(rule, ReverseRule)) == 1 assert [spec.count_objects_of_size(i) for i in range(13)] == [ 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, ]
def test_inject_basis(): pack = TileScopePack.point_placements() assert not pack.ver_strats[2].basis fixed_pack = pack.add_basis([Perm((0, 1, 2, 3))]) assert isinstance(pack.ver_strats[2], strat.OneByOneVerificationStrategy) assert not pack.ver_strats[2].basis assert isinstance(fixed_pack, TileScopePack) assert isinstance(fixed_pack.ver_strats[2], strat.OneByOneVerificationStrategy) assert fixed_pack.ver_strats[2].basis == (Perm((0, 1, 2, 3)), )
def test_from_tiling(): t = Tiling(obstructions=[ GriddedPerm(Perm((0, 1)), ((0, 0), (0, 0))), GriddedPerm(Perm((0, 1)), ((0, 0), (1, 1))), GriddedPerm(Perm((0, 1)), ((1, 1), (1, 1))), ]) searcher = TileScope(t, TileScopePack.point_placements()) spec = searcher.auto_search() print(spec) assert sympy.simplify(spec.get_genf() - sympy.sympify("(1+x)/(1-x)")) == 0
def test_parallel_forest(): expected_count = [1, 1, 2, 6, 22, 90, 394, 1806, 8558, 41586] pack = TileScopePack.only_root_placements(2, 1) bases = ["0231_2031", "0132_1032", "0231_0321"] searchers = [TileScope(b, pack, ruledb=RuleDBForest()) for b in bases] specs = [css.auto_search() for css in searchers] for spec in specs: spec = spec.expand_verified() count = [spec.count_objects_of_size(n) for n in range(10)] assert count == expected_count
def __init__( self, start_class: Union[str, Iterable[Perm], Tiling], strategy_pack: TileScopePack, ruledb: Optional[RuleDBAbstract] = None, expand_verified: bool = False, debug: bool = False, ) -> None: """Initialise TileScope.""" if isinstance(start_class, str): basis = Basis.from_string(start_class) elif isinstance(start_class, Tiling): if start_class.dimensions == (1, 1): basis = Basis(*[o.patt for o in start_class.obstructions]) start_tiling = start_class else: try: basis = Basis(*start_class) except TypeError as e: raise ValueError( "start class must be a string, an iterable of Perm or a tiling" ) from e if not isinstance(start_class, Tiling): start_tiling = Tiling(obstructions=[ GriddedPerm.single_cell(patt, (0, 0)) for patt in basis ]) if start_tiling.dimensions == (1, 1): logger.debug( "Fixing basis in basis aware verification strategies.") strategy_pack = strategy_pack.add_basis(basis) strategy_pack = strategy_pack.setup_subclass_verification(start_tiling) super().__init__( start_class=start_tiling, strategy_pack=strategy_pack, ruledb=ruledb, expand_verified=expand_verified, debug=debug, )
def test_reverse_equiv(): """A specification that should use reverse equivalence.""" pack = TileScopePack( initial_strats=[ strat.FactorFactory(), strat.RequirementCorroborationFactory(), strat.RequirementPlacementFactory(partial=False), ], inferral_strats=[strat.RowColumnSeparationStrategy()], expansion_strats=[[strat.CellInsertionFactory()]], ver_strats=[strat.BasicVerificationStrategy()], iterative=False, name="test pack", ) basis = (Perm((0, 1, 3, 2)), Perm((0, 2, 3, 1)), Perm((1, 0, 3, 2))) # From https://oeis.org/A033321 expected_enum = [ 1, 1, 2, 6, 21, 79, 311, 1265, 5275, 22431, 96900, 424068, 1876143 ] x, f = sympy.symbols("x f") expected_min_poly = sympy.sympify("-4*f^2*x^2 + 8*f^2*x - 4*f*x - 4*f + 4") searcher = TileScope(basis, pack) spec = searcher.auto_search(smallest=True) assert [spec.count_objects_of_size(i) for i in range(13)] == expected_enum genf = spec.get_genf() assert sympy.simplify(expected_min_poly.subs(f, genf)) == 0 assert taylor_expand(genf, 12) == expected_enum # In order to avoid ReccursionError we go incrementally for i in range(0, 100): spec.count_objects_of_size(i) assert spec.count_objects_of_size(50) == 86055297645519796258217673160170 assert ( spec.count_objects_of_size(100) == 2733073112795720153237297124938915907723365837935699807314396095313) len4_perms = tuple(spec.generate_objects_of_size(4)) assert len(len4_perms) == 21 assert all(p not in len4_perms for p in basis) len8_perms = tuple(spec.generate_objects_of_size(8)) assert len(len8_perms) == 5275 assert len(set(len8_perms)) == 5275 for _ in range(10): gp = spec.random_sample_object_of_size(10) print(gp) assert gp.patt.avoids(*basis) av = Av(basis) for i in range(10): assert set(av.of_length(i)) == set( gp.patt for gp in spec.generate_objects_of_size(i)) assert spec.random_sample_object_of_size(i).patt in av
def json_encode_decode(sp): """Take a strategy, encode it as json and build it back as a strategy.""" __tracebackhide__ = True d = sp.to_jsonable() if not isinstance(d, dict): pytest.fail("to_jsonable does not return a dict. \n" "Returned: {}".format(d)) try: json_str = json.dumps(d) except TypeError as e: pytest.fail("The to_jsonable method returns a dictionnary that can " "not be encoded as json string\n" "Got error: {}".format(e)) sp_new = TileScopePack.from_dict(json.loads(json_str)) return sp_new
def test_expansion(): """ For this pack only some basic verification are needed. """ pack = TileScopePack.only_root_placements(3, 1) css = TileScope("132", pack) spec = css.auto_search(smallest=True) for comb_class, rule in spec.rules_dict.items(): if isinstance(rule, VerificationRule): assert isinstance( rule.strategy, ( strat.OneByOneVerificationStrategy, strat.MonotoneTreeVerificationStrategy, strat.BasicVerificationStrategy, EmptyStrategy, ), )
def __init__(self, start_class: Union[str, Iterable[Perm], Tiling], strategy_pack: TileScopePack, logger_kwargs: Optional[dict] = None, **kwargs) -> None: """Initialise TileScope.""" if isinstance(start_class, str): basis = Basis([ Perm.to_standard([int(c) for c in p]) for p in start_class.split("_") ]) elif isinstance(start_class, Tiling): start_tiling = start_class if start_class.dimensions == (1, 1): basis = Basis([o.patt for o in start_class.obstructions]) elif isinstance(start_class, collections.abc.Iterable): basis = Basis(start_class) assert all(isinstance(p, Perm) for p in basis), "Basis must contains Perm only" else: raise ValueError( "start class must be a string, an iterable of Perm or a tiling" ) if not isinstance(start_class, Tiling): start_tiling = Tiling(obstructions=[ GriddedPerm.single_cell(patt, (0, 0)) for patt in basis ]) if start_tiling.dimensions == (1, 1): procname = kwargs.get("logger_kwargs", {"processname": "runner"}) logger.debug("Fixing basis in OneByOneVerificationStrategy", extra=procname) strategy_pack = strategy_pack.fix_one_by_one(basis) super().__init__( start_tiling, strategy_pack, logger_kwargs=logger_kwargs, **kwargs, )
def from_uri(cls, URI: str) -> "GuidedSearcher": response = requests.get(URI) spec = CombinatorialSpecification.from_dict( response.json()["specification"]) pack = TileScopePack.from_dict(response.json()["pack"]).make_tracked() return cls.from_spec(spec, pack)
return [ pack(row_only=row_only, col_only=col_only, partial=partial) for row_only, col_only, partial in product((True, False), (True, False), (True, False)) if not row_only or not col_only ] packs = (length(TileScopePack.all_the_strategies) + partial(TileScopePack.insertion_point_placements) + row_col_partial(TileScopePack.insertion_row_and_col_placements) + row_col_partial(TileScopePack.insertion_point_row_and_col_placements) + length_maxnumreq_partial(TileScopePack.only_root_placements) + [ TileScopePack.only_root_placements( length=3, max_num_req=2, max_placement_rules_per_req=100) ] + length_partial(TileScopePack.pattern_placements) + length_partial(TileScopePack.point_placements) + directions(TileScopePack.regular_insertion_encoding) + length_partial(TileScopePack.requirement_placements) + row_col_partial(TileScopePack.row_and_col_placements) + length(TileScopePack.cell_insertions)) packs.extend( [pack.make_database() for pack in packs] + [pack.make_elementary() for pack in packs] + [pack.make_fusion() for pack in packs] + [pack.add_all_symmetry() for pack in packs] + [pack.make_interleaving() for pack in packs] + [pack.make_database().add_all_symmetry() for pack in packs] + [pack.make_fusion().add_all_symmetry()
import pytest import sympy from comb_spec_searcher import CombinatorialSpecification from comb_spec_searcher.rule_db import LimitedStrategyRuleDB from comb_spec_searcher.strategies import EmptyStrategy from comb_spec_searcher.strategies.rule import VerificationRule from comb_spec_searcher.utils import taylor_expand from permuta import Perm from tilings import GriddedPerm, Tiling from tilings import strategies as strat from tilings.strategies.fusion import ComponentFusionStrategy, FusionStrategy from tilings.strategy_pack import TileScopePack from tilings.tilescope import TileScope point_placements = TileScopePack.point_placements() all_the_strategies_verify_database = TileScopePack.all_the_strategies( ).make_database() all_the_strategies_fusion = TileScopePack.all_the_strategies().make_fusion( tracked=False) point_placements_fusion = point_placements.make_fusion(tracked=False) point_placements_component_fusion = point_placements.make_fusion( component=True, tracked=False) row_placements_fusion = TileScopePack.row_and_col_placements( row_only=True).make_fusion(tracked=True) row_and_col_placements_component_fusion_fusion = ( TileScopePack.row_and_col_placements().make_fusion( component=True, tracked=False).make_fusion(tracked=False)) reginsenc = TileScopePack.regular_insertion_encoding(3)