#  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.
#-------------------------------------------------------------------------------

declare object Representation {

# the underlying permutation group 
property GROUP : Group;

# the dimension of the representation
property DEGREE : Int;

# the decomposition into irreducible representations, in the same order as the rows of the GROUP.CHARACTER_TABLE
property IRREDUCIBLE_DECOMPOSITION : Array<Int>;

}


declare object PermutationRepresentationOnSets : Representation {

# the list of sets on which the group acts
property DOMAIN : Array<Set<Int>>;

# the list of sets on which the group acts, ordered by orbits and conjugacy classes
property DOMAIN_IN_ORBIT_ORDER : Array<Set<Int>>;

# the union of all sets in DOMAIN
property UNDERLYING_SET : Set<Int>;

# the function that indexes these sets
property INDEX_OF : Map<Set<Int>, Int>;

# the function that indexes these sets
property INDEX_IN_ORBIT_ORDER_OF : Map<Set<Int>, Int>;

# the character of the representation
property CHARACTER : Array<Int>;

# the lex-min representatives for each orbit
property ORBIT_REPRESENTATIVES : Array<Set<Int>>;

# the size of each orbit
property ORBIT_SIZES : Array<Int>;

rule DEGREE : DOMAIN {
    $this->DEGREE = $this->DOMAIN->size;
}

rule UNDERLYING_SET : DOMAIN {
    my $s = new Set<Int>;
    foreach (@{$this->DOMAIN}) {
        $s += $_;
    }
    $this->UNDERLYING_SET = $s;
}

rule INDEX_OF : DOMAIN {
    $this->INDEX_OF(temporary) = index_of($this->DOMAIN);
}

rule INDEX_IN_ORBIT_ORDER_OF : DOMAIN_IN_ORBIT_ORDER {
    $this->INDEX_IN_ORBIT_ORDER_OF(temporary) = index_of($this->DOMAIN_IN_ORBIT_ORDER);
}

rule CHARACTER : GROUP.CONJUGACY_CLASS_REPRESENTATIVES, DOMAIN {
    my @character = ();
    foreach my $ccr (@{$this->GROUP->CONJUGACY_CLASS_REPRESENTATIVES}) {
        my $n_fix = 0;
        foreach my $set (@{$this->DOMAIN}) {
            my @image = ();
            foreach (@{$set}) {
                push @image, $ccr->[$_];
            } 
            my $image = new Set<Int>(\@image);
            if ($image == $set) {
                ++$n_fix;
            }
        }
        push @character, $n_fix;
    }
    $this->CHARACTER = new Array<Int>(\@character);
}

rule IRREDUCIBLE_DECOMPOSITION : CHARACTER, GROUP {
    $this->IRREDUCIBLE_DECOMPOSITION = irreducible_decomposition($this->CHARACTER, $this->GROUP);
}

rule DOMAIN_IN_ORBIT_ORDER : ORBIT_REPRESENTATIVES, GROUP.CONJUGACY_CLASSES {
    my @doo = ();
    foreach my $rep (@{$this->ORBIT_REPRESENTATIVES}) {
        my $orbit_bag = new Set<Set<Int>>;
        foreach my $cc (@{$this->GROUP->CONJUGACY_CLASSES}) {
            foreach my $g (@{$cc}) {
                my $img = new Set<Int>;
                foreach (@{$rep}) {
                    $img += $g->[$_];
                }
                $orbit_bag += $img;
            }
        }
        foreach (@{$orbit_bag}) {
            push @doo, new Set<Int>($_);
        }
    }
    $this->DOMAIN_IN_ORBIT_ORDER = new Array<Set<Int>>(\@doo);
}

} # end object PermutationRepresentationOnSets


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