Skip to content

Commit

Permalink
implement geometric automaton
Browse files Browse the repository at this point in the history
  • Loading branch information
videlec committed Jul 18, 2023
1 parent 960a18f commit 6dc842d
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 5 deletions.
50 changes: 50 additions & 0 deletions tests/test_automaton.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
######################################################################
# This file is part of veerer.
#
# Copyright (C) 2023 Vincent Delecroix
#
# veerer is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# veerer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with veerer. If not, see <https://www.gnu.org/licenses/>.
######################################################################

import pytest

from veerer import VeeringTriangulation, CoreAutomaton, ReducedCoreAutomaton, GeometricAutomaton

@pytest.mark.parametrize("fp, cols",
[("(0,2,~1)(1,~0,~2)", "RBB"),
("(0,6,~5)(1,8,~7)(2,7,~6)(3,~1,~8)(4,~2,~3)(5,~0,~4)", "RRRBBBBBB"),
("(0,8,~7)(1,11,~10)(2,10,~9)(3,9,~8)(4,~1,~11)(5,~2,~4)(6,~3,~5)(7,~0,~6)", "RRRRBBBBBBBB"),
("(0,2,4)(1,~3,~2)(3,~5,~4)(5,~1,~0)", "RBBRBB"),
("(0,~8,7)(1,6,~2)(2,~6,~3)(3,5,~4)(4,8,~5)(~7,~1,~0)", "RBBBBRRBB"),
("(0,~9,8)(1,10,~2)(2,~6,~3)(3,5,~4)(4,9,~5)(6,11,~7)(7,~10,~8)(~11,~1,~0)", "RBBBBRRBBBRB"),
("(0,~11,10)(1,~9,~2)(2,8,~3)(3,9,~4)(4,~8,~5)(5,7,~6)(6,11,~7)(~10,~1,~0)", "RBBBBBBRRRBB"),
("(0,8,11)(1,10,~2)(2,~10,~3)(3,~7,~4)(4,6,~5)(5,9,~6)(7,~9,~8)(~11,~1,~0)", "RBBBBBRRBBRB"),
("(0,6,8)(1,~11,~2)(2,10,~3)(3,11,~4)(4,~10,~5)(5,~7,~6)(7,~9,~8)(9,~1,~0)", "RBBBBBRBBRRR"),
("(0,6,10)(1,9,~2)(2,~9,~3)(3,8,~4)(4,11,~5)(5,~7,~6)(7,~11,~8)(~10,~1,~0)", "RBBBBBRBRRBR")])
def test_automata(fp, cols):
V = VeeringTriangulation(fp, cols)
assert V.is_geometric()
C = CoreAutomaton(V)

R = ReducedCoreAutomaton(V)
assert len(R) <= len(C)
reduced = set()
for x in C:
x.forgot_forward_flippable_colour()
reduced.add(x.iso_sig())
assert set(x.iso_sig() for x in R) == reduced

G = GeometricAutomaton(V)
assert len(G) <= len(C)
assert set(x.to_string() for x in G) == set(x.to_string() for x in C if x.is_geometric())
57 changes: 52 additions & 5 deletions veerer/automaton.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ def set_seed(self, state):
self._serialized_branch = [iso_sig]

self._graph[iso_sig] = []
self._branch.append(self._forward_flippable_edges(self._state))
self._branch.append(self._forward_flips(self._state))

@classmethod
def from_triangulation(self, T, reduced=False, max_size=None, verbosity=0):
Expand Down Expand Up @@ -535,7 +535,7 @@ def from_stratum(self, stratum, reduced=False, **kwds):
"""
return self.from_triangulation(VeeringTriangulation.from_stratum(stratum), reduced=reduced, **kwds)

def _forward_flippable_edges(self, state):
def _forward_flips(self, state):
r"""
Return the list of forward flip_data from ``state``.
Expand Down Expand Up @@ -676,7 +676,7 @@ def run(self, max_size=None):

# TODO: one can optimize the computation of forward flippable edges knowing
# how the current state was built
branch.append(self._forward_flippable_edges(T))
branch.append(self._forward_flips(T))
count += 1
continue

Expand Down Expand Up @@ -733,7 +733,7 @@ def _serialize(self, state):
def _unserialize(self):
return VeeringTriangulation.from_string(string)

def _forward_flippable_edges(self, state):
def _forward_flips(self, state):
r"""
Return the list of forward flippable edges from ``state``
"""
Expand Down Expand Up @@ -764,7 +764,7 @@ def _seed_setup(self, state):

state.forgot_forward_flippable_colour()

def _forward_flippable_edges(self, state):
def _forward_flips(self, state):
r"""
Return the list of forward flippable edges from ``state``
"""
Expand Down Expand Up @@ -836,3 +836,50 @@ def _flip_back(self, flip_back_data):
self._state._colouring[ee] = ccol
self._state._colouring[self._state._ep[ee]] = ccol
self._state.flip_back(e, old_col)


class GeometricAutomaton(Automaton):
r"""
Automaton of core veering triangulations.
EXAMPLES::
sage: from veerer import *
sage: fp = "(0,~7,6)(1,~8,~2)(2,~6,~3)(3,5,~4)(4,8,~5)(7,~1,~0)"
sage: cols = "RBRBRBBBB"
sage: vt = VeeringTriangulation(fp, cols)
sage: GeometricAutomaton(vt)
Geometric veering automaton with 54 vertices
One can check that the cardinality is indeed correct::
sage: sum(x.is_geometric() for x in CoreAutomaton(vt))
54
"""
_name = 'geometric'

def _seed_setup(self, state):
if not isinstance(state, VeeringTriangulation) or not state.is_geometric():
raise ValueError('invalid seed')

def _serialize(self, state):
return state.iso_sig()

def _unserialize(self):
return VeeringTriangulation.from_string(string)

def _forward_flips(self, state):
r"""
Return the list of forward flippable edges from ``state``
"""
return state.geometric_flips()

def _flip(self, flip_data):
flip_back_data = tuple((e, self._state.colour(e)) for e, _ in flip_data)
for e, col in flip_data:
self._state.flip(e, col)
return True, flip_back_data

def _flip_back(self, flip_back_data):
for e, old_col in flip_back_data:
self._state.flip_back(e, old_col)

0 comments on commit 6dc842d

Please sign in to comment.