# Revision history [back]

### Group actions (e.g. on simplicial complexes, sets of tuples etc.)

I'm trying to implement some extended functionality with simplicial complexes and have several questions about group actions in Sage. Any help with any of the following would be greatly appreciated!

1. Group actions on nested lists, sets, tuples etc.

In Magma, I can apply a permutation to an arbitrarily nested object of sets, sequences etc. without having to know what exactly that object is. For example,

>> [{[1,2],[4,5]},{[4,5]}] ^ Sym(5)!(1,2,3,4);

applies the permutation to a list of sets of lists. GAP is slightly less flexible, providing functions such as OnTuples, OnTuplesTuples, OnSetsTuples which deal with specific cases, but you have to know "in advance" what sort of object you are acting on. As far as I can see Sage hasn't got functions like these at all.

The simplicial complexes can take various forms which would each require a different type of action; for example, the vertices could be integers, or tuples (for example in the case of a Chessboard complex the vertices are coordinates on a chessboard), or sets.

I don't mind calling GAP functions, but would rather avoid calling Magma functions so that code I write can be used by those who don't have access to Magma. Am I missing a simple way of acting on such objects in Sage, or do I need to write my own code dealing with each case separately?

2. Registering group actions in Sage

Once I have defined my action with a function I'd like to register it so I can apply permutations to simplices using x * g. I have tried to follow the syntax explained in the docs here: (I cannot post links, search for register_action in the doc entitled Base class for parent objects.) A minimal example follows:

import sage.categories.action
import operator

def chessboard(n, m):

k = min(n, m)
row_tups = [tuple(x) for x in Subsets([1..n], k)]
col_tups = [tuple(x) for x in Permutations([n+1..n+m], k)]
placements = cartesian_product([row_tups, col_tups])
placements_as_sets = [{(p[0][i],p[1][i]) for i in range(k)} \
for p in placements]

G = SymmetricGroup(n+m)
A = G.stabilizer([1..n], "OnSets")

return SimplicialComplex(placements_as_sets), A

class ChessboardAction(sage.categories.action.Action):
def __init__(self, G, C, is_left=True):
sage.categories.action.Action.__init__(self, G, C, is_left,
operator.mul)

def _act_(self, g, c):
new = set(tuple([g(i) for i in x]) for x in c)
out = next(f for f in C.faces()[c.dimension()] if set(f) == new)
return out

C, G = chessboard(3, 4)
act = ChessboardAction(G, C)
g = G.an_element()
c = C.an_element()
act(g, c)


This fails with error:

NotImplementedError                       Traceback (most recent call last)
<ipython-input-69-7155e64e7004> in <module>()

245             if attach:
--> 247             exec(preparse_file(open(fpath).read()) + "\n", globals)
248     elif ext == '.spyx' or ext == '.pyx':
249         if attach:

<string> in <module>()

sage/categories/action.pyx in sage.categories.action.Action.__call__ (build/cythonized/sage/categories/action.c:3602)()

sage/categories/action.pyx in sage.categories.action.Action._call_ (build/cythonized/sage/categories/action.c:3864)()

NotImplementedError: Action not implemented.


I then tried to implement a simple action on another object but received the same error, so perhaps I am misunderstanding the method:

class TestAction(sage.categories.action.Action):
def __init__(self, G, S, is_left=True):
sage.categories.action.Action.__init__(self, G, S, is_left,
operator.mul)

def _act_(self, g, s):
return Set([g(i) for i in s])

G = SymmetricGroup(4)
S = Subsets([1..4], 3)
act = TestAction(G, S)
g = G.an_element()
s = S.an_element()
act(g, s)


This fails with the same error as above.