text:
#############################################################################
##
##  Magic.gi                                         AutoDoc package
##
##  Copyright 2013, Max Horn, JLU Giessen
##                  Sebastian Gutsche, University of Kaiserslautern
##
#############################################################################

# Check if a string has the given suffix or not. Another
# name for this would "StringEndsWithOtherString".
# For example, AUTODOC_HasSuffix("file.gi", ".gi") returns
# true while AUTODOC_HasSuffix("file.txt", ".gi") returns false.
BindGlobal( "AUTODOC_HasSuffix",
function(str, suffix)
    local n, m;
    n := Length(str);
    m := Length(suffix);
    return n >= m and str{[n-m+1..n]} = suffix;
end );

# Given a string containing a ".", , return its suffix,
# i.e. the bit after the last ".". For example, given "test.txt",
# it returns "txt".
BindGlobal( "AUTODOC_GetSuffix",
function(str)
    local i;
    i := Length(str);
    while i > 0 and str[i] <> '.' do i := i - 1; od;
    if i < 0 then return ""; fi;
    return str{[i+1..Length(str)]};
end );

# Check whether the given directory exists, and if not, attempt
# to create it.
BindGlobal( "AUTODOC_CreateDirIfMissing",
function(d)
    local tmp;
    if not IsDirectoryPath(d) then
        tmp := CreateDir(d); # Note: CreateDir is currently undocumented
        if tmp = fail then
            Error("Cannot create directory ", d, "\n",
                  "Error message: ", LastSystemError().message, "\n");
            return false;
        fi;
    fi;
    return true;
end );

# Scan the given (by name) subdirs of a package dir for
# files with one of the given extensions, and return the corresponding
# filenames, as relative paths (relative to the package dir).
#
# For example, the invocation
#   AUTODOC_FindMatchingFiles("AutoDoc", [ "gap/" ], [ "gi", "gd" ]);
# might return a list looking like
#  [ "gap/AutoDocMainFunction.gd", "gap/AutoDocMainFunction.gi", ... ]
BindGlobal( "AUTODOC_FindMatchingFiles",
function (pkg, subdirs, extensions)
    local d_rel, d, tmp, files, result;

    result := [];

    for d_rel in subdirs do
        # Get the absolute path to the directory in side the package...
        d := DirectoriesPackageLibrary( pkg, d_rel );
        if IsEmpty( d ) then
            continue;
        fi;
        d := d[1];
        # ... but also keep the relative path (such as "gap")
        d_rel := Directory( d_rel );

        files := DirectoryContents( d );
        Sort( files );
        for tmp in files do
            if not AUTODOC_GetSuffix( tmp ) in [ "g", "gi", "gd", "autodoc" ] then
                continue;
            fi;
            if not IsReadableFile( Filename( d, tmp ) ) then
                continue;
            fi;
            Add( result, Filename( d_rel, tmp ) );
        od;
    od;
    return result;
end );

# AutoDoc(pkg[, opt])
#
## Make this function callable with the package_name AutoDocWorksheet.
## Which will then create a worksheet!
InstallGlobalFunction( AutoDoc,
function( arg )
    local pkg, package_info, opt, scaffold, gapdoc, maketest,
          autodoc, pkg_dir, doc_dir, doc_dir_rel, d, tmp,
          title_page, tree, is_worksheet, position_document_class, i, gapdoc_latex_option_record;

    pkg := arg[1];

    if LowercaseString( pkg ) = "autodocworksheet" then
        is_worksheet := true;
        package_info := rec( );
        pkg_dir := DirectoryCurrent( );
    else
        is_worksheet := false;
        package_info := PackageInfo( pkg )[ 1 ];
        pkg_dir := DirectoriesPackageLibrary( pkg, "" )[1];
    fi;

    if Length(arg) >= 2 then
        opt := arg[2];
    else
        opt := rec();
    fi;

    # Check for certain user supplied options, and if present, add them
    # to the opt record.
    tmp := function( key )
        local val;
        val := ValueOption( key );
        if val <> fail then
            opt.(key) := val;
        fi;
    end;

    tmp( "dir" );
    tmp( "scaffold" );
    tmp( "autodoc" );
    tmp( "gapdoc" );
    tmp( "maketest" );

    #
    # Setup the output directory
    #
    if not IsBound( opt.dir ) then
        doc_dir := "doc";
    elif IsString( opt.dir ) or IsDirectory( opt.dir ) then
        doc_dir := opt.dir;
    else
        Error( "opt.dir must be a string containing a path, or a directory object" );
    fi;

    if IsString( doc_dir ) then
        # Record the relative version of the path
        doc_dir_rel := Directory( doc_dir );

        # We intentionally do not use
        #   DirectoriesPackageLibrary( pkg, "doc" )
        # because it returns an empty list if the subdirectory is missing.
        # But we want to handle that case by creating the directory.
        doc_dir := Filename(pkg_dir, doc_dir);
        doc_dir := Directory(doc_dir);

    else
        # TODO: doc_dir_rel = ... ?
    fi;

    # Ensure the output directory exists, create it if necessary
    AUTODOC_CreateDirIfMissing(Filename(doc_dir, ""));

    # Let the developer know where we are generating the documentation.
    # This helps diagnose problems where multiple instances of a package
    # are visible to GAP and the wrong one is used for generating the
    # documentation.
    # TODO: Using Info() instead of Print?
    Print( "Generating documentation in ", doc_dir, "\n" );

    #
    # Extract scaffolding settings, which can be controlled via
    # opt.scaffold or package_info.AutoDoc. The former has precedence.
    #
    if not IsBound(opt.scaffold) then
        # Default: enable scaffolding if and only if package_info.AutoDoc is present
        if IsBound( package_info.AutoDoc ) then
            scaffold := rec( );
        fi;
    elif IsRecord(opt.scaffold) then
        scaffold := opt.scaffold;
    elif IsBool(opt.scaffold) then
        if opt.scaffold = true then
            scaffold := rec();
        fi;
    else
        Error("opt.scaffold must be a bool or a record");
    fi;

    # Merge package_info.AutoDoc into scaffold
    if IsBound(scaffold) and IsBound( package_info.AutoDoc ) then
        AUTODOC_APPEND_RECORD_WRITEONCE( scaffold, package_info.AutoDoc );
    fi;

    if IsBound( scaffold ) then
        AUTODOC_WriteOnce( scaffold, "TitlePage", true );
        AUTODOC_WriteOnce( scaffold, "MainPage", true );
    fi;

    #
    # Extract AutoDoc settings
    #
    if not IsBound(opt.autodoc) and not is_worksheet then
        # Enable AutoDoc support if the package depends on AutoDoc.
        tmp := Concatenation( package_info.Dependencies.NeededOtherPackages,
                              package_info.Dependencies.SuggestedOtherPackages );
        if ForAny( tmp, x -> LowercaseString(x[1]) = "autodoc" ) then
            autodoc := rec();
        fi;
    elif IsRecord(opt.autodoc) then
        autodoc := opt.autodoc;
    elif IsBool(opt.autodoc) and opt.autodoc = true then
        autodoc := rec();
    fi;

    if IsBound(autodoc) then
        if not IsBound( autodoc.files ) then
            autodoc.files := [ ];
        fi;

        if not IsBound( autodoc.scan_dirs ) and not is_worksheet then
            autodoc.scan_dirs := [ "gap", "lib", "examples", "examples/doc" ];
        elif not IsBound( autodoc.scan_dirs ) and is_worksheet then
            autodoc.scan_dirs := [ ];
        fi;

        if not IsBound( autodoc.level ) then
            autodoc.level := 0;
        fi;

        PushOptions( rec( level_value := autodoc.level ) );

        if not is_worksheet then
            Append( autodoc.files, AUTODOC_FindMatchingFiles(pkg, autodoc.scan_dirs, [ "g", "gi", "gd" ]) );
        fi;
    fi;

    #
    # Extract GAPDoc settings
    #
    if not IsBound( opt.gapdoc ) then
        # Enable GAPDoc support by default
        gapdoc := rec();
    elif IsRecord( opt.gapdoc ) then
        gapdoc := opt.gapdoc;
    elif IsBool( opt.gapdoc ) and opt.gapdoc = true then
        gapdoc := rec();
    fi;

    #
    # Extract test settings
    #

    if IsBound( opt.maketest ) then
        if IsRecord( opt.maketest ) then
            maketest := opt.maketest;
        elif opt.maketest = true then
            maketest := rec( );
        fi;
    fi;

    if IsBound( gapdoc ) then

        if not IsBound( gapdoc.main ) then
            gapdoc.main := pkg;
        fi;

        # FIXME: the following may break if a package uses more than one book
        if IsBound( package_info.PackageDoc ) and IsBound( package_info.PackageDoc[1].BookName ) then
            gapdoc.bookname := package_info.PackageDoc[1].BookName;
        elif not is_worksheet then
            # Default: book name = package name
            gapdoc.bookname := pkg;

            Print("\n");
            Print("WARNING: PackageInfo.g is missing a PackageDoc entry!\n");
            Print("Without this, your package manual will not be recognized by the GAP help system.\n");
            Print("You can correct this by adding the following to your PackageInfo.g:\n");
            Print("PackageDoc := rec(\n");
            Print("  BookName  := ~.PackageName,\n");
            #Print("  BookName  := \"", pkg, "\",\n");
            Print("  ArchiveURLSubset := [\"doc\"],\n");
            Print("  HTMLStart := \"doc/chap0.html\",\n");
            Print("  PDFFile   := \"doc/manual.pdf\",\n");
            Print("  SixFile   := \"doc/manual.six\",\n");
            Print("  LongTitle := ~.Subtitle,\n");
            Print("),\n");
            Print("\n");
        fi;

        if not IsBound( gapdoc.files ) then
            gapdoc.files := [];
        fi;

        if not IsBound( gapdoc.scan_dirs ) and not is_worksheet then
            gapdoc.scan_dirs := [ "gap", "lib", "examples", "examples/doc" ];
        fi;

        if not is_worksheet then
            Append( gapdoc.files, AUTODOC_FindMatchingFiles(pkg, gapdoc.scan_dirs, [ "g", "gi", "gd" ]) );
        fi;

        # Attempt to weed out duplicates as they may confuse GAPDoc (this
        # won't work if there are any non-normalized paths in the list).
        gapdoc.files := Set( gapdoc.files );

        # Convert the file paths in gapdoc.files, which are relative to
        # the package directory, to paths which are relative to the doc directory.
        # For this, we assume that doc_dir_rel is normalized (e.g.
        # it does not contains '//') and relative.
        d := Number( Filename( doc_dir_rel, "" ), x -> x = '/' );
        d := Concatenation( ListWithIdenticalEntries(d, "../") );
        gapdoc.files := List( gapdoc.files, f -> Concatenation( d, f ) );
    fi;

    # read tree
    # FIXME: shouldn't tree be declared inside of an 'if IsBound(autodoc)' section?
    tree := DocumentationTree( );

    if IsBound( autodoc ) then
        if IsBound( autodoc.section_intros ) then
            AUTODOC_PROCESS_INTRO_STRINGS( autodoc.section_intros : Tree := tree );
        fi;

        AutoDocScanFiles( autodoc.files : PackageName := pkg, Tree := tree );
    fi;

    if is_worksheet then
        # FIXME: We use scaffold and autodoc here without checking whether
        # they are bound. Does that mean worksheets always use them?
        if IsRecord( scaffold.TitlePage ) and IsBound( scaffold.TitlePage.Title ) then
            pkg := scaffold.TitlePage.Title;

        elif IsBound( tree!.TitlePage.Title ) then
            pkg := tree!.TitlePage.Title;

        elif IsBound( autodoc.files ) and Length( autodoc.files ) > 0  then
            pkg := autodoc.files[ 1 ];

            while Position( pkg, '/' ) <> fail do
                Remove( pkg, 1 );
            od;

            while Position( pkg, '.' ) <> fail do
                Remove( pkg, Length( pkg ) );
            od;

        else
            Error( "could not figure out a title." );
        fi;

        if not IsString( pkg ) then
            pkg := JoinStringsWithSeparator( pkg, " " );
        fi;

        gapdoc.main := ReplacedString( pkg, " ", "_" );
        gapdoc.bookname := ReplacedString( pkg, " ", "_" );
    fi;

    #
    # Generate scaffold
    #
    gapdoc_latex_option_record := rec( );

    if IsBound( scaffold ) then
        ## Syntax is [ "class", [ "options" ] ]
        if IsBound( scaffold.document_class ) then
            position_document_class := PositionSublist( GAPDoc2LaTeXProcs.Head, "documentclass" );

            if IsString( scaffold.document_class ) then
                scaffold.document_class := [ scaffold.document_class ];
            fi;

            if position_document_class = fail then
                Error( "something is wrong with the LaTeX header" );
            fi;

            GAPDoc2LaTeXProcs.Head := Concatenation(
                  GAPDoc2LaTeXProcs.Head{[ 1 .. PositionSublist( GAPDoc2LaTeXProcs.Head, "{", position_document_class ) ]},
                  scaffold.document_class[ 1 ],
                  GAPDoc2LaTeXProcs.Head{[ PositionSublist( GAPDoc2LaTeXProcs.Head, "}", position_document_class ) .. Length( GAPDoc2LaTeXProcs.Head ) ]} );

            if Length( scaffold.document_class ) = 2 then

                GAPDoc2LaTeXProcs.Head := Concatenation(
                      GAPDoc2LaTeXProcs.Head{[ 1 .. PositionSublist( GAPDoc2LaTeXProcs.Head, "[", position_document_class ) ]},
                      scaffold.document_class[ 2 ],
                      GAPDoc2LaTeXProcs.Head{[ PositionSublist( GAPDoc2LaTeXProcs.Head, "]", position_document_class ) .. Length( GAPDoc2LaTeXProcs.Head ) ]} );
            fi;
        fi;

        if IsBound( scaffold.latex_header_file ) then
            GAPDoc2LaTeXProcs.Head := StringFile( scaffold.latex_header_file );
        fi;

        if IsBound( scaffold.gapdoc_latex_options ) then
            if IsRecord( scaffold.gapdoc_latex_options ) then
                for i in RecNames( scaffold.gapdoc_latex_options ) do
                    if not IsString( scaffold.gapdoc_latex_options.( i ) )
                       and IsList( scaffold.gapdoc_latex_options.( i ) )
                       and LowercaseString( scaffold.gapdoc_latex_options.( i )[ 1 ] ) = "file" then
                        scaffold.gapdoc_latex_options.( i ) := StringFile( scaffold.gapdoc_latex_options.( i )[ 2 ] );
                    fi;
                od;

                gapdoc_latex_option_record := scaffold.gapdoc_latex_options;
            fi;
        fi;

        if not IsBound( scaffold.includes ) then
            scaffold.includes := [ ];
        fi;

        if IsBound( autodoc ) then
            # If scaffold.includes is already set, then we add
            # AutoDocMainFile.xml to it, but *only* if it not already
            # there. This way, package authors can control where
            # it is put in their includes list.
            if not "AutoDocMainFile.xml" in scaffold.includes then
                Add( scaffold.includes, "AutoDocMainFile.xml" );
            fi;
        fi;

        if IsBound( scaffold.bib ) and IsBool( scaffold.bib ) then
            if scaffold.bib = true then
                scaffold.bib := Concatenation( pkg, ".bib" );
            else
                Unbind( scaffold.bib );
            fi;
        elif not IsBound( scaffold.bib ) then
            # If there is a doc/PKG.bib file, assume that we want to reference it in the scaffold.
            if IsReadableFile( Filename( doc_dir, Concatenation( pkg, ".bib" ) ) ) then
                scaffold.bib := Concatenation( pkg, ".bib" );
            fi;
        fi;

        AUTODOC_WriteOnce( scaffold, "index", true );

        if IsBound( gapdoc ) then
            if AUTODOC_GetSuffix( gapdoc.main ) = "xml" then
                scaffold.main_xml_file := gapdoc.main;
            else
                scaffold.main_xml_file := Concatenation( gapdoc.main, ".xml" );
            fi;
        fi;

        # TODO: It should be possible to only rebuild the title page. (Perhaps also only the main page? but this is less important)
        if IsBound( scaffold.TitlePage ) then
            if IsRecord( scaffold.TitlePage ) then
                title_page := scaffold.TitlePage;
            else
                title_page := rec( );
            fi;

            AUTODOC_WriteOnce( title_page, "dir", doc_dir );
            AUTODOC_APPEND_RECORD_WRITEONCE( title_page, tree!.TitlePage );

            if not is_worksheet then
                AUTODOC_APPEND_RECORD_WRITEONCE( title_page, ExtractTitleInfoFromPackageInfo( pkg ) );
            fi;

            CreateTitlePage( title_page );
        fi;

        if IsBound( scaffold.MainPage ) and scaffold.MainPage <> false then
            scaffold.dir := doc_dir;
            scaffold.book_name := pkg;
            CreateMainPage( scaffold );
        fi;
    fi;

    #
    # Run AutoDoc
    #
    if IsBound( autodoc ) then
        WriteDocumentation( tree, doc_dir );
    fi;

    #
    # Run GAPDoc
    #
    if IsBound( gapdoc ) then

        # Ask GAPDoc to use UTF-8 as input encoding for LaTeX, as the XML files
        # of the documentation are also in UTF-8 encoding, and may contain characters
        # not contained in the default Latin 1 encoding.
        SetGapDocLaTeXOptions( "utf8", gapdoc_latex_option_record );

        MakeGAPDocDoc( doc_dir, gapdoc.main, gapdoc.files, gapdoc.bookname, "MathJax" );

        CopyHTMLStyleFiles( Filename( doc_dir, "" ) );

        # The following (undocumented) API is there for compatibility
        # with old-style gapmacro.tex based package manuals. It
        # produces a manual.lab file which those packages can use if
        # they wish to link to things in the manual we are currently
        # generating. This can probably be removed eventually, but for
        # now, doing it does not hurt.

        # FIXME: It seems that this command does not work if pdflatex
        #        is not present. Maybe we should remove it.

        if not is_worksheet then
            GAPDocManualLab( pkg );
        fi;

    fi;

    if IsBound( maketest ) then

        AUTODOC_WriteOnce( maketest, "filename", "maketest.g" );
        AUTODOC_WriteOnce( maketest, "folder", pkg_dir );
        AUTODOC_WriteOnce( maketest, "scan_dir", doc_dir );
        AUTODOC_WriteOnce( maketest, "files_to_scan", gapdoc.files );

        if IsString( maketest.folder ) then
            maketest.folder := Directory( maketest.folder );
        fi;

        if IsString( maketest.scan_dir ) then
            maketest.scan_dir := Directory( maketest.scan_dir );
        fi;

        AUTODOC_WriteOnce( maketest, "commands", [ ] );
        AUTODOC_WriteOnce( maketest, "book_name", gapdoc.main );

        CreateMakeTest( maketest );
    fi;

    return true;
end );

max_stars_repo_name: JavascriptID/sourcerer-app

max_issues_repo_name: JavascriptID/sourcerer-app

max_forks_repo_name: JavascriptID/sourcerer-app


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

#######################################################################################
# Pointers
#
vvref := (loc, idx, vlen) -> nth(tcast(TPtr(TVect(loc.t.t, vlen)), loc), idx);
vtref := (vtype, loc, idx) -> nth(tcast(TPtr(vtype), loc), idx);

#######################################################################################
#   Shuffle instructions and instruction sets

Class(assign_sv, assign, rec(
   __call__ := (self, loc, exp, p) >> WithBases(self,
       rec(operations := CmdOps,
       loc := toAssignTarget(loc),
       exp := toExpArg(exp),
       p := p)),
    print := (self,i,is) >> Chain(Print(Blanks(i), self.name, "("), self.loc.print(), Print(", "), self.exp.print(), Print(", "), Print(self.p), Print(");\n")),
    getNoScalar := self >> [self.loc.loc]
));

_vcprintcs := function ( lst )
    local  i;
    if Length(lst) = 0  then
        return;
    fi;
    lst[1].vcprint();
    for i  in [ 2 .. Length(lst) ]  do
        Print(", ", lst[i].vcprint());
    od;
end;

# vec_shr(<a>, <n>)
#   shift vector <a> elements "right" ("left" in spiral - toward first vector element)
#   by <n> items, shifting in zeros.

Class(vec_shr, AutoFoldExp, rec(
    ev := self >> Error("make ev method"),
    computeType := self >> self.args[1].t
));

# vec_shl(<a>, <n>)
#   shift vector <a> elements "left" ("right" in spiral - toward last vector element)
#   by <n> items, shifting in zeros.

Class(vec_shl,  Exp, rec(
    ev := self >> Error("make ev method"),
    computeType := self >> self.args[1].t
));

# alignr(<x0>, <x1>, <shift>)
#   takes two vectors <x0> and <x1>, concatenates their values, and pulls out a
#   vector-length section from an offset given by <shift>.

Class(alignr,  Exp, rec(
    ev := self >> let(
        x := self.args[1].ev() :: self.args[2].ev(),
        s := self.args[3].ev(),
        x{[s..s+self.t.size-1]}
    ),
    computeType := self >> UnifyPair(self.args[1].t, self.args[2].t),
));

ext: gi


text:
local reps,tori,labels,I,II,ords,blocks;

reps:=[[[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1]],            # E_7
       [[1,1],[3,1],[10,1],[9,1],[5,1],[6,1],[7,1]],           # E_7(a_1)
       [[1,1],[2,1],[3,1],[9,1],[11,1],[12,1],[13,1]],         # E_7(a_2)
       [[15,1],[1,1],[17,1],[6,1],[7,1],[16,1],[4,1]],         # E_7(a_3) asta functioneaza in caracteristica 3
#       [[1,1],[4,1],[7,1],[11,1],[12,1],[15,1],[17,1]],        # E_7(a_3)
       [[1,1],[2,1],[3,1],[4,1],[5,1],[6,1]],                  # E_6
#       [[3,1],[5,1],[1,1],[6,1],[10,1],[11,1],[2,1]],          # E_6(a_1)
       [[1,1],[2,1],[10,1],[11,1],[5,1],[6,1]],                # E_6(a_1)
       [[7,1],[6,1],[5,1],[4,1],[2,1],[3,1]],                  # D_6
       [[1,1],[4,1],[7,1],[13,1],[15,1],[16,1],[17,1],[23,1]], # E_7(a_4) acelas ca cel mai de jos dar ordonat
#       [[15,1],[1,1],[17,1],[13,1],[23,1],[7,1],[16,1],[4,1]], # E_7(a_4) asta functioneaza in caracteristica 3
#       [[1,1],[4,1],[7,1],[10,1],[22,1],[23,1],[24,1]],        # E_7(a_4)
#       [[7,1],[6,1],[5,1],[9,1],[10,-1],[2,1],[3,1]],          # D_6(a_1)
       [[2,1],[3,1],[9,1],[11,1],[6,1],[7,1]],                # D_6(a_1)
       [[1,1],[3,1],[4,1],[2,1],[5,1],[7,1]],                  # D_5A_1
       [[1,1],[3,1],[4,1],[5,1],[6,1],[7,1]],                  # A_6
#       [[21,1],[23,1],[7,1],[24,1],[20,1],[4,1],[22,1]],       # E_7(a_5)
       [[4,1],[10,1],[13,1],[14,1],[21,1],[22,1],[23,1]],      # E_7(a_5)
       [[1,1],[3,1],[4,1],[2,1],[5,1]],                        # D_5
       [[15,1],[1,1],[17,1],[6,1],[16,1],[4,1]],               # E_6(a_3) this works in characteristic 3
#       [[4,1],[6,1],[8,1],[10,1],[16,1],[17,1]],               # E_6(a_3)
#       [[7,1],[12,1],[9,1],[10,-1],[11,1],[2,1],[3,1]],        # D_6(a_2)
       [[2,1],[3,1],[9,1],[11,1],[12,1],[13,1]],              # D_6(a_2)
#       [[1,1],[3,1],[9,1],[11,1],[2,1],[5,1],[7,1]],           # D_5(a_1)A_1
       [[1,1],[9,1],[10,1],[2,1],[5,1],[7,1]],                # D_5(a_1)A_1

       [[2,1],[4,1],[5,1],[6,1],[7,1],[1,1]],       # A_5A_1
       [[1,1],[3,1],[4,1],[5,1],[6,1]],             # (A_5)'
       [[1,1],[3,1],[4,1],[2,1],[6,1],[7,1]],       # A_4A_2
#       [[1,1],[3,1],[9,1],[11,1],[2,1],[5,1]],      # D_5(a_1)
#       [[1,1],[10,1],[11,1],[2,1],[5,1]],           # D_5(a_1) ALSO WORKS?
       [[1,1],[9,1],[10,1],[2,1],[5,1]],           # D_5(a_1)
       [[1,1],[2,1],[3,1],[4,1],[6,1]],             # A_4A_1
       [[3,1],[4,1],[2,1],[5,1],[7,1]],             # D_4A_1
       [[2,1],[4,1],[5,1],[6,1],[7,1]],             # (A_5)''
       [[1,1],[3,1],[2,1],[5,1],[6,1],[7,1]],       # A_3A_2A_1
       [[1,1],[2,1],[3,1],[4,1]],                   # A_4
#       [[3,1],[4,1],[2,1],[6,1],[7,1]],             # A_3A_2
       [[3,1],[4,1],[2,1],[6,1],[7,1]],             # A_3A_2
#       [[3,1],[9,1],[11,1],[2,1],[5,1],[7,1]],      # D_4(a_1)A_1
#       [[2,1],[3,1],[9,1],[11,1],[7,1]],           # D_4(a_1)A_1
       [[2,1],[5,1],[9,1],[10,1],[7,1]],           # D_4(a_1)A_1  cel de deasupra simetric fata de D4
       [[3,1],[4,1],[2,1],[5,1]],                   # D_4
       [[5,1],[6,1],[7,1],[2,1],[3,1]],             # A_3A_1^2
#       [[3,1],[9,1],[11,1],[2,1],[5,1]],            # D_4(a_1)
       [[2,1],[3,1],[9,1],[11,1]],                 # D_4(a_1)
       [[1,1],[3,1],[4,1],[6,1]],                   # (A_3A_1)'
       [[1,1],[3,1],[5,1],[6,1],[2,1]],             # A_2^2A_1
       [[5,1],[6,1],[7,1],[2,1]],                   # (A_3A_1)''
       [[1,1],[3,1],[2,1],[5,1],[7,1]],             # A_2A_1^3
       [[1,1],[3,1],[5,1],[6,1]],                   # A_2^2
       [[1,1],[3,1],[4,1]],                         # A_3
       [[2,1],[4,1],[1,1],[6,1]],                   # A_2A_1^2
       [[1,1],[3,1],[2,1]],                         # A_2A_1
       [[2,1],[3,1],[5,1],[7,1]],                   # A_1^4
       [[1,1],[3,1]],                               # A_2
       [[1,1],[4,1],[6,1]],                         # (A_1^3)'
       [[2,1],[5,1],[7,1]],                         # (A_1^3)''
       [[1,1],[6,1]],                               # A_1^2
       [[1,1]]                                      # A_1
       ];

I:=[[],          # E_7
    [4],         # E_7(a_1)
    [4,6],       # E_7(a_2)
#    [2,3,5],     # E_7(a_3)
    [],          # E_7(a_3)
    [],          # E_6
#    [4],         # E_6(a_1)
    [],          # E_6(a_1)
    [],          # D_6
#    [2,3,5,6],   # E_7(a_4)
    [],          # E_7(a_4)
#    [4],         # D_6(a_1)
    [],          # D_6(a_1)
    [],          # D_5A_1
    [],          # A_6
#    [1,2,3,5,6], # E_7(a_5)
    [],          # E_7(a_5)
    [],          # D_5
#    [2,3,5],     # E_6(a_3)
    [],          # E_6(a_3)
#    [4,5],       # D_6(a_2)    ???
    [],          # D_6(a_2)    ???
#    [4],         # D_5(a_1)A_1 ???
    [],          # D_5(a_1)A_1 ???

    [],          # A_5A_1
    [],          # (A_5)'
    [],          # A_4A_2
#    [4],         # D_5(a_1)    ???
    [],          # D_5(a_1)    ???
    [],          # A_4A_1
    [],          # D_4A_1
    [],          # (A_5)''
    [],          # A_3A_2A_1
    [],          # A_4
    [],          # A_3A_2
#    [4],         # D_4(a_1)A_1
    [],          # D_4(a_1)A_1
    [],          # D_4
    [],          # A_3A_1^2
#    [4],         # D_4(a_1)
    [],          # D_4(a_1)
    [],          # (A_3A_1)'
    [],          # A_2^2A_1
    [],          # (A_3A_1)''
    [],          # A_2A_1^3
    [],          # A_2^2
    [],          # A_3
    [],          # A_2A_1^2
    [],          # A_2A_1
    [],          # A_1^4
    [],          # A_2
    [],          # (A_1^3)'
    [],          # (A_1^3)''
    [],          # A_1^2
    []           # A_1
    ];

#
# The parabolic where the representative is distinguished
#
II:=[[1,2,3,4,5,6,7],  # E_7
     [1,2,3,4,5,6,7],  # E_7(a_1)
     [1,2,3,4,5,6,7],  # E_7(a_2)
     [1,2,3,4,5,6,7],  # E_7(a_3)
#     [],  # E_7(a_3)
     [1,2,3,4,5,6],    # E_6
     [1,2,3,4,5,6],    # E_6(a_1)
#     [],    # E_6(a_1)
     [2,3,4,5,6,7],    # D_6
     [1,2,3,4,5,6,7],  # E_7(a_4)
#     [],  # E_7(a_4)
     [2,3,4,5,6,7],    # D_6(a_1)
#     [],    # D_6(a_1)
     [1,2,3,4,5,7],    # D_5A_1
     [1,3,4,5,6,7],    # A_6
     [1,2,3,4,5,6,7],  # E_7(a_5)
#     [],  # E_7(a_5)
     [1,2,3,4,5],      # D_5
     [1,2,3,4,5,6],    # E_6(a_3)
#     [],    # E_6(a_3)
     [2,3,4,5,6,7],    # D_6(a_2)
#     [],    # D_6(a_2)
     [1,2,3,4,5,7],    # D_5(a_1)A_1
#     [],    # D_5(a_1)A_1

     [1,2,4,5,6,7],    # A_5A_1
     [1,3,4,5,6],      # (A_5)'
     [1,2,3,4,6,7],    # A_4A_2
     [1,2,3,4,5],      # D_5(a_1)
#     [],      # D_5(a_1)
     [1,2,3,4,6],      # A_4A_1
     [2,3,4,5,7],      # D_4A_1
     [2,4,5,6,7],      # (A_5)''
     [1,2,3,5,6,7],    # A_3A_2A_1
     [1,2,3,4],        # A_4
     [2,3,4,6,7],      # A_3A_2
     [2,3,4,5,7],      # D_4(a_1)A_1
#     [],      # D_4(a_1)A_1
     [2,3,4,5],        # D_4
     [2,3,5,6,7],      # A_3A_1^2
     [2,3,4,5],        # D_4(a_1)
#     [],        # D_4(a_1)
     [1,3,4,6],        # (A_3A_1)'
     [1,2,3,5,6],      # A_2^2A_1
     [2,5,6,7],        # (A_3A_1)''
     [1,2,3,5,7],      # A_2A_1^3
     [1,3,5,6],        # A_2^2
     [1,3,4],          # A_3
     [1,2,4,6],        # A_2A_1^2
     [1,2,3],          # A_2A_1
     [2,3,5,7],        # A_1^4
     [1,3],            # A_2
     [1,4,6],          # (A_1^3)'
     [2,5,7],          # (A_1^3)''
     [1,6],            # A_1^2
     [1]               # A_1
     ];

labels:=["E_7",
         "E_7(a_1)",
         "E_7(a_2)",
         "E_7(a_3)",
         "E_6",
         "E_6(a_1)",
         "D_6",
         "E_7(a_4)",
         "D_6(a_1)",
         "D_5A_1",
         "A_6",
         "E_7(a_5)",
         "D_5",
         "E_6(a_3)",
         "D_6(a_2)",
         "D_5(a_1)A_1",

         "A_5A_1",
         "(A_5)1",
         "A_4A_2",
         "D_5(a_1)",
         "A_4A_1",
         "D_4A_1",
         "(A_5)2",
         "A_3A_2A_1",
         "A_4",
         "A_3A_2",
         "D_4(a_1)A_1",
         "D_4",
         "A_3A_1^2",
         "D_4(a_1)",
         "(A_3A_1)1",
         "A_2^2A_1",
         "(A_3A_1)2",
         "A_2A_1^3",
         "A_2^2",
         "A_3",
         "A_2A_1^2",
         "A_2A_1",
         "A_1^4",
         "A_2",
         "(A_1^3)1",
         "(A_1^3)2",
         "A_1^2",
         "A_1"
         ];

tori:=[
       [2,2,2,2,2,2,2],   # E_7
       [2,2,2,0,2,2,2],   # E_7(a_1)
       [2,2,2,0,2,0,2],   # E_7(a_2)
       [2,0,0,2,0,2,2],   # E_7(a_3)
#    [],   # E_7(a_3)
       [2,2,2,2,2,2,-16], # E_6
       [2,2,2,0,2,2,-12], # E_6(a_1)
#    [], # E_6(a_1)
       [-15,2,2,2,2,2,2], # D_6
       [2,0,0,2,0,0,2],   # E_7(a_4)
#    [],   # E_7(a_4)
       [-11,2,2,0,2,2,2], # D_6(a_1)
#    [], # D_6(a_1)
       [2,2,2,2,2,-11,2], # D_5A_1
       [2,-12,2,2,2,2,2], # A_6
       [0,0,0,2,0,0,2],   # E_7(a_5)
#    [],   # E_7(a_5)
       [2,2,2,2,2,-10,0], # D_5
       [2,0,0,2,0,2,-8],  # E_6(a_3)
#    [],  # E_6(a_3)
       [-9,2,2,0,2,0,2],  # D_6(a_2)
#    [],  # D_6(a_2)
       [2,2,2,0,2,-8,2],  # D_5(a_1)A_1
#    [],  # D_5(a_1)A_1

       [2,2,-9,2,2,2,2],   # A_5A_1
       [2,-9,2,2,2,2,-5],  # (A_1)'
       [2,2,2,2,-8,2,2],   # A_4A_2
       [2,2,2,0,2,-7,0],   # D_5(a_1)
#    [],   # D_5(a_1)
       [2,2,2,2,-7,2,-1],  # A_4A_1
       [-6,2,2,2,2,-7,2],  # D_4A_1
       [0,2,-8,2,2,2,2],   # (A_5)''
       [2,2,2,-6,2,2,2],   # A_3A_2A_1
       [2,2,2,2,-6,0,0],   # A_4
       [-3,2,2,2,-6,2,2],  # A_3A_2
       [-4,2,2,0,2,-5,2],  # D_4(a_1)A_1
#    [],  # D_4(a_1)A_1
       [-6,2,2,2,2,-6,0],  # D_4
       [-1,2,2,-5,2,2,2],  # A_3A_1^2
       [-4,2,2,0,2,-4,0],  # D_4(a_1)
#    [],  # D_4(a_1)
       [2,-3,2,2,-4,2,-1], # (A_3A_1)'
       [2,2,2,-5,2,2,-2],  # A_2^2A_1
       [0,2,0,-4,2,2,2],   # (A_3A_1)''
       [2,2,2,-4,2,-2,2],  # A_2A_1^3
       [2,0,2,-4,2,2,-2],  # A_2^2
       [2,-3,2,2,-3,0,0],  # A_3
       [2,2,-3,2,-3,2,-1], # A_2A_1^2
       [2,2,2,-3,0,0,0],   # A_2A_1
       [-1,2,2,-3,2,-2,2], # A_1^4
       [2,0,2,-2,0,0,0],   # A_2
       [2,-1,-2,2,-2,2,-1],# (A_1^3)'
       [0,2,0,-2,2,-2,2],  # (A_1^3)''
       [2,0,-1,0,-1,2,-1], # A_1^2
       [2,0,-1,0,0,0,0],   # A_1
    ];

#blocks:=[];
blocks:=
[[[27, 3], [19, 1], [15, 1], [9, 2]], [[27, 1], [19, 1], [18, 2], [15, 1], [9, 4]], [[19, 1], [18, 2], [15, 1], [9, 7]], [[19, 1], [17, 1], [15, 2], [11, 2], [9, 3], [6, 2], [3, 2]], [[19, 1], [15, 4], [9, 5], [3, 3]], [[9, 14], [7, 1]], [[19, 1], [16, 2], [15, 1], [11, 1], [10, 2], [9, 2], [6, 2], [3, 1], [1, 3]], [[9, 12], [7, 1], [6, 2], [3, 2]], [[9, 11], [8, 2], [6, 2], [3, 1], [1, 3]], [[9, 11], [8, 2], [6, 2], [3, 1], [1, 3]], [[9, 11], [7, 4], [3, 1], [1, 3]], [[9, 9], [7, 1], [6, 2], [5, 3], [3, 6]], [[9, 11], [7, 4], [1, 6]], [[9, 6], [7, 1], [6, 8], [3, 8]], [[9, 9], [7, 1], [6, 2], [5, 1], [4, 4], [3, 3], [1, 3]], [[9, 5], [7, 4], [6, 6], [3, 7], [1, 3]], [[9, 9], [3, 16], [2, 2]], [[9, 5], [8, 2], [6, 8], [3, 7], [1, 3]], [[9, 3], [7, 1], [6, 8], [5, 3], [3, 12]], [[9, 3], [8, 4], [7, 2], [6, 6], [3, 4], [2, 4], [1, 4]], [[9, 1], [8, 2], [7, 3], [6, 4], [5, 5], [4, 2], [3, 8], [2, 2], [1, 2]], [[9, 2], [8, 4], [7, 5], [6, 4], [3, 2], [2, 4], [1, 10]], [[9, 9], [3, 15], [1, 7]], [[7, 1], [6, 8], [5, 3], [3, 21]], [[9, 1], [7, 7], [5, 9], [3, 7], [1, 9]], [[7, 1], [6, 8], [5, 1], [4, 4], [3, 18], [1, 3]], [[7, 1], [6, 6], [5, 4], [4, 4], [3, 16], [1, 6]], [[9, 2], [7, 13], [3, 1], [1, 21]], [[7, 1], [6, 4], [5, 7], [4, 4], [3, 11], [2, 6], [1, 6]], [[7, 1], [6, 2], [5, 12], [3, 15], [1, 9]], [[7, 1], [6, 2], [5, 7], [4, 10], [3, 6], [2, 6], [1, 9]], [[3, 43], [2, 2]], [[7, 1], [5, 15], [3, 10], [1, 21]], [[3, 42], [1, 7]], [[3, 42], [1, 7]], [[7, 1], [5, 7], [4, 16], [3, 1], [1, 24]], [[3, 37], [2, 8], [1, 6]], [[3, 34], [2, 8], [1, 15]], [[3, 28], [2, 14], [1, 21]], [[3, 33], [1, 34]], [[3, 19], [2, 26], [1, 24]], [[3, 27], [1, 52]], [[3, 10], [2, 32], [1, 39]], [[3, 1], [2, 32], [1, 66]]];

ords:=[];
#ords:=[ 27, 27, 27, 27, 27, 9, 27, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 9, 3, 3, 9, 3, 3, 3, 3, 3, 3, 3, 3 ];

return [reps,tori,labels,I,II,ords,blocks];


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

# NOTE: MISSING (YV)
Class(VScat_red);

Class(BaseVScat, BaseMat, SumsBase, rec(
    isVScat := true,
    sums := self >> self,
    dims := self >> self.dimensions,
    isReal := self >> true,
    needInterleavedLeft := False,
    needInterleavedRight := False,
    area := self >> self.transpose().area(),
    toAMat := self >> TransposedAMat(self.transpose().toAMat()),
    conjTranspose := self >> self.transpose(),
));

Class(BaseSVScat, BaseMat, SumsBase, rec(
    isVScat := true,
    isSVScat := true,
    #-----------------------------------------------------------------------
    abbrevs        := BaseSVGath.abbrevs,
    new            := BaseSVGath.new,
    print          := BaseSVGath.print,
    getConstantRem := BaseSVGath.getConstantRem,
    #-----------------------------------------------------------------------
    dims := self >> Error(ObjId(self), ".dims() is undefined"),
    #-----------------------------------------------------------------------
    sums := self >> self,
    isReal := self >> true,
    needInterleavedLeft := True,
    needInterleavedRight := False,
    #-----------------------------------------------------------------------
    conjTranspose := self >> self.transpose(),
    area := self >> self.transpose().area(),
    toAMat := self >> TransposedAMat(self.transpose().toAMat())
));

IsVScat := x -> IsRec(x) and IsBound(x.isVScat) and x.isVScat;
IsSVScat := x -> IsRec(x) and IsBound(x.isSVScat) and x.isSVScat;

# ==========================================================================
# VScat(<func>, <v>) - vector scatter (write) matrix, assumes aligned output
# ==========================================================================
Class(VScat, BaseVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func],
    rSetChild := rSetChildFields("func"),
    from_rChildren := (self, rch) >> ObjId(self)(rch[1], self.v),
    #-----------------------------------------------------------------------
    new := (self, func, v) >> SPL(WithBases(self,
        rec(func := func, v := v))).setDims(),
    #-----------------------------------------------------------------------
    dims := self >> [self.v * self.func.range(), self.v * self.func.domain()],
    #-----------------------------------------------------------------------
    transpose := self >> VGath(self.func, self.v),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.func, ", ", self.v, ")", self.printA()),
 ));

# ==========================================================================
# VScat_u(<func>, <v>) -- same as VScat but assumes that output is unaligned
# ==========================================================================
Class(VScat_u, VScat, rec(
    dims := self >> [ self.func.range(), self.v * self.func.domain()],
    transpose := self >> VGath_u(self.func, self.v)
));

# ==========================================================================
# VScat_zero(N, n, <v>) - vector scatter (write) matrix
# ==========================================================================
Class(VScat_zero, BaseVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [],
    rSetChild := rSetChildFields(),
    from_rChildren := (self, rch) >> ObjId(self)(self.N, self.n, self.v),
    #-----------------------------------------------------------------------
    new := (self, N, n, v) >> SPL(WithBases(self,
        rec(n := n, N := N, v := v))).setDims(),
    #-----------------------------------------------------------------------
    dims := self >> [self.v * self.N, self.v * self.n],
    #-----------------------------------------------------------------------
    transpose := self >> VGath_zero(self.N, self.n, self.v),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.N, ", ",
        self.n, ", ", self.v,")", self.printA()),
 ));

# ==========================================================================
# VScat_sv(<func>, <v>, <sv>) - vector scatter (write) matrix on subvectors
# ==========================================================================
Class(VScat_sv, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func],     # self >> [self.func, self.v, self.sv],
    rSetChild := rSetChildFields("func"), # rSetChildFields("func", "v", "sv"),
    from_rChildren := (self, rch) >> ObjId(self)(rch[1], self.v, self.sv, self.rem),
    #-----------------------------------------------------------------------
    dims := self >> [self.sv * self.func.range(),
                     _roundup(self.sv * self.func.domain(), self.v)],
    #-----------------------------------------------------------------------
    transpose := self >> VGath_sv(self.func, self.v, self.sv, self.rem),
));

# ==========================================================================
# RCVScat_sv(<func>, <v>, <sv>) - vector scatter (write) matrix on subvectors
# ==========================================================================
Class(RCVScat_sv, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func],     # self >> [self.func, self.v, self.sv],
    rSetChild := rSetChildFields("func"), # rSetChildFields("func", "v", "sv"),
    from_rChildren := (self, rch) >> ObjId(self)(rch[1], self.v, self.sv, self.rem),
    #-----------------------------------------------------------------------
    dims := self >> let(
	n := self.func.domain() * self.sv,  nv := _roundup(n, self.v),
	N := self.func.range() * self.sv,
	[2*N, 2*nv]),
    #-----------------------------------------------------------------------
    transpose := self >> RCVGath_sv(self.func, self.v, self.sv, self.rem),
));

# ==========================================================================
# VStretchScat(<func>, part, <v>) - vector scatter (write) matrix on subvectors
# ==========================================================================
Class(VStretchScat, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func],
    rSetChild := rSetChildFields("func"),
    from_rChildren := (self, rch) >> ObjId(self)(rch[1], self.part, self.v),
    #-----------------------------------------------------------------------
    dims := self >> let(
	n  := self.func.domain(), N := self.func.range(),
	nv := self.part * _roundup(n / self.part, self.v),
        [N, nv]),
    #-----------------------------------------------------------------------
    abbrevs := [],
    new := (self, func, part, v) >> SPL(WithBases(self,
	rec(func := func, part := part, v := v))).setDims(),
    #-----------------------------------------------------------------------
    transpose := self >> VStretchGath(self.func, self.part, self.v),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.func, ", ",
        self.part, ", ", self.v, ")", self.printA()),
));

# ==========================================================================
# vRCStretchScat(<func>, part, <v>) - vector scatter (write) matrix on subvectors
# ==========================================================================
Class(vRCStretchScat, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func],
    rSetChild := rSetChildFields("func"),
    from_rChildren := (self, rch) >> ObjId(self)(rch[1], self.part, self.v),
    #-----------------------------------------------------------------------
    dims := self >> let(
	n  := self.func.domain(), N := self.func.range(),
	nv := self.part * _roundup(n / self.part, self.v/2),
        2*[N, nv]),
    #-----------------------------------------------------------------------
    abbrevs := [],
    new := (self, func, part, v) >> SPL(WithBases(self,
        rec(func := func, part := part, v := v))).setDims(),
    #-----------------------------------------------------------------------
    transpose := self >> vRCStretchGath(self.func, self.part, self.v),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.func, ", ",
        self.part, ", ", self.v, ")", self.printA()),
));

# ==========================================================================
# RCVStretchScat(<func>, part, <v>) - vector scatter (write) matrix on subvectors
# ==========================================================================
Class(RCVStretchScat, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func],
    rSetChild := rSetChildFields("func"),
    from_rChildren := (self, rch) >> ObjId(self)(rch[1], self.part, self.v),
    #-----------------------------------------------------------------------
    dims := self >> let(
	n  := self.func.domain(), N := self.func.range(),
	nv := self.part * _roundup(n / self.part, self.v),
        2*[N, nv]),
    #-----------------------------------------------------------------------
    abbrevs := [],
    new := (self, func, part, v) >> SPL(WithBases(self, rec(
        func := func, part := part, v := v))).setDims(),
    #-----------------------------------------------------------------------
    transpose := self >> RCVStretchGath(self.func, self.part, self.v),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.func, ", ",
        self.part, ", ", self.v, ")", self.printA()),
 ));

# ==========================================================================
# VScat_pc(N, n, ofs, v) - vector scatter (write) matrix writing unaligned
#                         partial contiguous vectors
# ==========================================================================
Class(VScat_pc, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.N, self.n, self.ofs, self.v],
    rSetChild := rSetChildFields("N", "n", "ofs", "v"),
    #-----------------------------------------------------------------------
    dims := self >> let(nv := _roundup(self.n, self.v), [self.N, nv]),
    #-----------------------------------------------------------------------
    abbrevs := [],
    new := (self, N, n, ofs, v) >> SPL(WithBases(self, rec(
        N := N, n:= n, ofs := ofs, v := v))).setDims(),
    #-----------------------------------------------------------------------
    transpose := self >> VGath_pc(self.N, self.n, self.ofs, self.v),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.N, ", ", self.n, ", ",
        self.ofs, ", ", self.v,")", self.printA()),
));

# ==========================================================================
# IxVScat_pc(k, N, n, ofs, v) - vector gather (read)
#   matrix reading unaligned
#   partial REAL contiguous vectors
# ==========================================================================
Class(IxVScat_pc, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [self.k, self.N, self.n, self.ofs, self.v],
    rSetChild := rSetChildFields("k", "N", "n", "ofs", "v"),

    from_rChildren := (self, rch) >> ObjId(self)(self.k, self.N, self.n, self.ofs, self.v),
    #-----------------------------------------------------------------------
    dims := self >> let(nv := _roundup(self.n, self.v), [self.k*self.N, self.k*nv]),
    #-----------------------------------------------------------------------
    abbrevs := [],
    new := (self, k, N, n, ofs, v) >> SPL(WithBases(self, rec(
        k := k, N := N, n:= n, ofs := ofs, v := v))).setDims(),
    #-----------------------------------------------------------------------
    transpose := self >> IxVGath_pc(self.k, self.N, self.n, self.ofs, self.v),
    #-----------------------------------------------------------------------
    toloop := (self, bksize) >> self.transpose().toloop(bksize).transpose(),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.k, ", ", self.N, ", ",
        self.n, ", ", self.ofs, ", ", self.v,")", self.printA()),
));

# ==========================================================================
# IxRCVScat_pc(k, N, n, ofs, v) - vector gather (read)
#   matrix reading unaligned
#   partial REAL contiguous vectors
# ==========================================================================
Class(IxRCVScat_pc, BaseSVScat, rec(
    #-----------------------------------------------------------------------
    rChildren := self >> [],         # self >> [self.ofs],  # SEEMS NOT TO WORK?!
    rSetChild := rSetChildFields(),  #  rSetChildFields("ofs"),
    from_rChildren := (self, rch) >> ObjId(self)(self.k, self.N, self.n, self.ofs, self.v),
    #-----------------------------------------------------------------------
    dims := self >> let(nv := _roundup(self.n, self.v), 2 * [self.k*self.N, self.k*nv]),
    #-----------------------------------------------------------------------
    abbrevs := [],
    new := (self, k, N, n, ofs, v) >> SPL(WithBases(self, rec(
        k := k, N := N, n := n, ofs := ofs, v := v))).setDims(),
    #-----------------------------------------------------------------------
    transpose := self >> IxRCVGath_pc(self.k, self.N, self.n, self.ofs, self.v),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.__name__, "(", self.k, ", ", self.N, ", ",
        self.n, ", ", self.ofs, ", ", self.v,")", self.printA()),
));

# ==========================================================================
# Accumulative scatter versions
# NOTE: to be replaced by a Sigma-SPL lowering step, CodeSumsAcc, and
#        a specialized CodegenAcc
#
# NOTE(!!!): .transpose().transpose() on below classes will lead to non-accumulative
#             versions, and thus invalid code!
Class(VScatAcc,    VScat,    rec());
Class(VScatAcc_u,  VScat_u,  rec());
Class(VScat_svAcc, VScat_sv, rec());
Class(VScat_pcAcc, VScat_pc, rec());

# ==========================================================================
# Methods for vectorization  of ScatGath constructs
# NOTE: This is a hack

# BB needed, as basic block size is not known due to varying function domain
ScatGath.toloopRCVec := (self, _bksize, v) >> let(
    bksize := When(_bksize = 1, v, _bksize),
    dom    := RulesMergedStrengthReduce(_divideFunc(self.gfunc.domain(), bksize)),
    i      := Ind(dom), #ok := Error("caught"),
    sfunc  := RulesFuncSimp(self.sfunc),
    ISum(i, dom,
        BB(
            Compose(When(ObjId(sfunc)=fId, [], [RCVScat_sv(sfunc, v, 1)]) ::
		    [VScat(fTensor(fBase(i), fId(2*bksize/v)), v)]) *
            RCVGath_sv(fCompose(self.gfunc, fTensor(fBase(i), fId(bksize))).setDomain(bksize), v, 1)
        )
    )
);

ScatGath.toloopVec := (self, _bksize, v) >> let(
    bksize := When(_bksize = 1, v, _bksize),
    dom    := RulesMergedStrengthReduce(_divideFunc(self.gfunc.domain(), bksize)),
    i      := Ind(dom),
    sfunc  := RulesFuncSimp(self.sfunc),
    ISum(i, dom,
        BB(
            Compose(When(ObjId(sfunc)=fId, [], [VScat_sv(sfunc, v, 1)]) ::
		    [ VScat(fTensor(fBase(i), fId(bksize/v)), v)]) *
            VGath_sv(fCompose(self.gfunc, fTensor(fBase(i), fId(bksize))).setDomain(bksize), v, 1)
        )
    )
);


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

Class(Ext, Sym, rec(
    abbrevs := [
	(n, ext) -> [n, ext, ext, 1, 1],
	(n, l, r) -> [n, l, r, 1, 1] ],

    def := function(n, l, r, lscale, rscale)
         local stack;
         Checked(IsPosInt(n), true);
         stack := [];

         if (IsInt(l) and l>0) then
           Add(stack,O(l,n));
         elif (IsRec(l) and not l.n=0 ) then
           l := When(IsSPL(l), l, l.left(n));
           Add(stack, When(lscale<>1, lscale*Gath(l), Gath(l)));
         fi;

         Add(stack, I(n));

         if (IsInt(r) and r>0) then
           Add(stack,O(r,n));
         elif (IsRec(r) and not r.n=0 ) then
           r := When(IsSPL(r), r, r.right(n));
           Add(stack, When(rscale<>1, rscale*Gath(r), Gath(r)));
         fi;

	    return VStack(stack);
    end
));

Class(DownSample, Sym, rec(
    abbrevs := [ (n, fact, offset) ->
        Checked(IsPosInt(n), IsPosInt(fact), IsPosInt0(offset), [n, fact, offset]) ],

    def := (n, fact, offset) -> let(m := Int((n-offset-1) / fact + 1),
         Gath(H(n, m, offset, fact)))
));

Class(UpSample, Sym, rec(
    abbrevs := [ (n, fact, offset) ->
        Checked(IsPosInt(n), IsPosInt(fact), IsPosInt0(offset), [n, fact, offset]) ],

    def := (n, fact, offset) -> let(m := Int((n-offset-1) / fact + 1),
         Scat(H(n, m, offset, fact)))
));


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

h := HashTableDP();
opts := CopyFields(PRDFTDefaults, rec(
	globalUnrolling := 64,
	compileStrategy := SimpleCS,
	compflags := "-O3 -fomit-frame-pointer"
));

opts.breakdownRules := rec(
    PRDFT := [PRDFT1_Base1, PRDFT1_Base2, PRDFT1_CT],
    PRDFT3 := [PRDFT3_Base1, PRDFT3_Base2, PRDFT3_CT],
    DFT := [DFT_Base, DFT_CT_Mincost],
    DFT3 := [DFT3_Base, DFT3_CT],

    BRDFT1 := [ BRDFT1_Base2, BRDFT1_Decomp ],
    BRDFT3 := [ BRDFT3_Base2, BRDFT3_Base4, BRDFT3_Decomp ],
    BSkewPRDFT := [ BSkewPRDFT_Base2, BSkewPRDFT_Base4, BSkewPRDFT_Decomp ],

    InfoNt := [Info_Base]
);

bopts := CopyFields(opts, rec(breakdownRules := CopyFields(opts.breakdownRules, rec(
    DFT := [DFT_Base, DFT_Bruun_Decomp],
    BSkewDFT3 := [BSkewDFT3_Base2, BSkewDFT3_Base4, BSkewDFT3_Decomp],
    PkRDFT1 := [PkRDFT1_Base2, PkRDFT1_Bruun_Decomp],
    PRDFT3 := [PRDFT3_Base1, PRDFT3_Base2, PRDFT3_CT]
))));

DP(BRDFT1(64), rec(hashTable:=h), opts);
DP(PRDFT1(64), rec(hashTable:=h), opts);

brdft := List([2..6], i->HashLookup(h, BRDFT1(2^i))[1].ruletree);
prdft := List([2..6], i->HashLookup(h, PRDFT1(2^i))[1].ruletree);

codes_brdft := List(brdft, r -> CodeRuleTree(r, opts));
codes_prdft := List(prdft, r -> CodeRuleTree(r, opts));

acost_brdft := List(codes_brdft, ArithCostCode);
acost_prdft := List(codes_prdft, ArithCostCode);

# ---------------------
a := AllRuleTrees(BRDFT1(32), opts);;
p := x -> Chain(PrintLine(x), x);

codes := [];
DoForAll([1..Length(a)], i -> Add(codes, CodeRuleTree(a[p(i)], opts)));
times := List(codes, x->CMeasure(x, opts));
best := Minimum(times);
besti := Position(times, best);
bestcode := codes[besti];

a := AllRuleTrees(BRDFT1(64), opts);;


text:
cube := Group([(1, 2, 3, 4)(5, 6, 7, 8), (1, 4, 8, 5)(2, 3, 7, 6)]);

Print("Order(cube) = ", Order(cube), "\n");

degree := 8;
colorings := Filtered(
  Combinations(Cartesian([1..degree], ["b", "w"]), degree)
, \c -> Size(Set(List(c, \a -> a[1]))) = degree
);

Print("Size(colorings) = ", Size(colorings), "\n");

OnFunctions := function(omega, g)
  local result;
  result := List(omega, t -> [t[1]^g, t[2]]);
  SortBy(result, t -> t[1]);
  return result;
end;

orbits := Orbits(cube, colorings, OnFunctions);
Print("Size(orbits) = ", Size(orbits), "\n");

IsFixed := function(omega, g)
  return OnFunctions(omega, g) = omega;
end;

orbitCount := 1/Order(cube) * Sum(List(Elements(cube), \g -> Size(Filtered(colorings, \c -> IsFixed(c, g)))));

Print("orbitCount: ", orbitCount, ", #orbits: ", Size(orbits));

ext: gap

max_stars_repo_name: fifth-postulate/group-theory-with-gap

max_issues_repo_name: fifth-postulate/group-theory-with-gap

max_forks_repo_name: fifth-postulate/group-theory-with-gap


text:
#
# Read("~/Workspace/Chevalley.gap/init.gi"); Read(Filename(home_dir,"load.gi")); Read(Filename(test_dir,"rsys.test.gi"));
#
# Read("~/Workspace/Chevalley.gap/init.gi"); Read(Filename(test_dir,"rsys.test.init.gi")); Read(Filename(test_dir,"rsys.test.gi"));
#
# Read(Filename(test_dir,"rsys.test.gi"));
#

sys:=RootSystem("F",4);
Print("Created RootSystem ",sys,"\n");
Print("\t[",IsRootSystem(sys)=true,"] IsRootSystem(sys)=true\n");

positiveRootTest:=[ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 1, 0 ], [ 0, 1, 0, 1 ],
  [ 0, 0, 1, 1 ], [ 1, 0, 1, 1 ], [ 0, 1, 1, 1 ], [ 0, 0, 2, 1 ], [ 1, 1, 1, 1 ], [ 1, 0, 2, 1 ],
  [ 0, 1, 2, 1 ], [ 1, 1, 2, 1 ], [ 2, 0, 2, 1 ], [ 0, 1, 2, 2 ], [ 1, 1, 2, 2 ], [ 2, 1, 2, 1 ],
  [ 1, 1, 3, 2 ], [ 2, 1, 2, 2 ], [ 2, 1, 3, 2 ], [ 2, 1, 4, 2 ], [ 2, 1, 4, 3 ], [ 2, 2, 4, 3 ] ]=positiveRoots(sys);
Print("\t[",positiveRootTest,"] testing positiveRoots(sys)\n");

tmp:=StringPrint(Cocharacters(UnderlyingLieAlgebra(sys)));
tmp:=SubstitutionSublist(tmp,"\n  ","");
cocharacterTest:="[ v.49, v.50, v.51, v.52, v.49+v.51, v.50+v.52, v.51+(2)*v.52, v.49+v.51+(2)*v.52, (2)*v.50+v.51+\
(2)*v.52, v.51+v.52, v.49+(2)*v.50+v.51+(2)*v.52, v.49+(2)*v.51+(2)*v.52, v.50+v.51+v.52, v.49+(2)\
*v.50+(2)*v.51+(2)*v.52, v.49+v.51+v.52, v.50+v.51+(2)*v.52, v.49+(2)*v.50+(2)*v.51+(4)*v.52, v.49\
+v.50+v.51+v.52, v.49+(2)*v.50+(3)*v.51+(4)*v.52, v.49+v.50+v.51+(2)*v.52, (2)*v.49+(2)*v.50+(3)*v\
.51+(4)*v.52, v.49+v.50+(2)*v.51+(2)*v.52, v.49+v.50+(2)*v.51+(3)*v.52, v.49+(2)*v.50+(2)*v.51+(3)\
*v.52 ]"=tmp;
Print("\t[",positiveRootTest,"] testing Cocharacters(UnderlyingLieAlgebra(sys))\n");

Print("\t[TODO] testing TorusWeightOnRoot\n");
Print("\t[TODO] testing RootReflections\n");
Print("\t[TODO] testing PositiveTorusPermutation\n");
Print("\t[TODO] testing PermutationMatrix\n");
Print("\t[TODO] testing RootGraph\n");
Print("\t[TODO] testing LatexRootGraph\n");