#  Copyright (c) 1997-2015
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
#  http://www.polymake.org
#
#  This program 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 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  This program 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.
#-------------------------------------------------------------------------------

REQUIRE graph::compare.rules

CREDIT graph_compare


# @category Symmetry
# Compute the combinatorial symmetries (i.e., automorphisms of the face lattice) of
# a given polytope //poly//. If //on_vertices// is set to 1, the function
# returns a [[group::GroupOfPolytope|GroupOfPolytope]] which acts on the vertices. If //on_vertices// is set
# to any other number, the function returns a [[group::GroupOfPolytope|GroupOfPolytope]] 
# which acts on the facets of the polytope. If //on_vertices// is unspecified, both 
# groups are returned.
# @param Polytope poly
# @param Int on_vertices specifies whether the returned group should act on vertices (1) or on facets (2)
# @return group::GroupOfPolytope the combinatorial symmetry group acting on the vertices or the facets
#     or (group::GroupOfPolytope, group::GroupOfPolytope) = (group on vertices, group on facets) if //on_vertices// is undefined
# @example To get the vertex and facet symmetry groups of the square and print their generators, type the following:
# > ($gv,$gf) = combinatorial_symmetries(cube(2));
# > print $gv->GENERATORS;
# | 2 3 0 1
# | 1 0 2 3
# > print $gf->GENERATORS;
# | 0 2 1 3
# | 1 0 3 2

user_function combinatorial_symmetries(polytope::Polytope;$) {
    my $poly = $_[0];
    my $pairs_of_gens = automorphisms($poly->VERTICES_IN_FACETS);
    my @ray_gens = map {$_->first} @$pairs_of_gens;
    my @facet_gens = map {$_->second} @$pairs_of_gens;
    if (scalar(@_)==1) {
        my $OnRays_Group = new group::GroupOfPolytope( GENERATORS=>(new Array< Array<Int> >(\@ray_gens)), DOMAIN=>$polytope::domain_OnRays );
        my $OnFacets_Group = new group::GroupOfPolytope( GENERATORS=>(new Array< Array<Int> >(\@facet_gens)), DOMAIN=>$polytope::domain_OnFacets );
        return ($OnRays_Group, $OnFacets_Group);
    } else {
        my $on_vertices = $_[1];
        my @gens = ();
        my $dom;
        if ($on_vertices == 1) {
            @gens = map {$_->first} @$pairs_of_gens;
            $dom = $polytope::domain_OnRays;
        } else {
            @gens = map {$_->second} @$pairs_of_gens;
            $dom = $polytope::domain_OnFacets; 
        }
        return new group::GroupOfPolytope( GENERATORS=>(new Array< Array<Int> >(\@gens)), DOMAIN=>$dom );
    }
}

# Local Variables:
# mode: perl
# cperl-indent-level: 3
# indent-tabs-mode:nil
# End:
