Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Apache/docs/manual/programs/   (Apache Software Stiftung Version 2.4.65©)  Datei vom 7.0.2025 mit Größe 18 kB image not shown  

Quelle  itc.gi   Sprache: unbekannt

 
#############################################################################
##
#W  itc.gi                   XGAP library                   Volkmar Felsch
#W                                                               Ludger Hippe
#W                                                          Joachim Neubueser
##
#Y  Copyright 1999,          Volkmar Felsch,            Aachen,       Germany
##
##  This file contains  the implementations for the  Interactive Todd-Coxeter
##  coset enumeration routines.
##
##  *Note* that the comments may be partially outdated!
##
##  This is Version 1.1 of March 2001
##


#############################################################################
##
##  Declarations of representations:
##


#############################################################################
##
#R  IsItcClassSheet . . . . . . . .  representation for a list of gap classes
##
DeclareRepresentation( "IsItcClassSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "boxes",
    "class",
    "ctSheet" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcCoincSheet  . . . . . . .  representation for a list of coincidences
##
DeclareRepresentation( "IsItcCoincSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "boxes",
    "ctSheet",
    "repSheets" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcCosetTableSheet  . . . . . .  representation for graphic coset table
##
DeclareRepresentation( "IsItcCosetTableSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "alives",
    "app",
    "app1",
    "backto",
    "clear",
    "coincSwitch",
    "coincs",
    "coiSheet",
    "deducs",
    "defaultLimit",
    "defs",
    "defSheet",
    "digits",
    "digitString1",
    "digitString2",
    "echo",
    "felsch",
    "fgens",
    "fillgaps",
    "fillrows",
    "first",
    "firstCol",
    "firstDef",
    "firstFree",
    "fsgens",
    "gaps",
    "gapsStrategy",
    "genNames",
    "graphicTable",
    "hlt",
    "hltRow",
    "infoLine",
    "invcol",
    "involutory",
    "isActual",
    "lastDef",
    "lastFree",
    "limit",
    "line",
    "mark",
    "markDefs",
    "marked",
    "message",
    "messageText",
    "ncols",
    "ndefs",
    "newtab",
    "next",
    "nlines",
    "normal",
    "nrdel",
    "oldtab",
    "prev",
    "quitt",
    "relColumnNums",
    "rels",
    "relsGen",
    "relSheet",
    "relText",
    "renumbered",
    "repLists",
    "reset",
    "rtSheets",
    "scroll",
    "scrollby",
    "scrollto",
    "settingsSheet",
    "shortCut",
    "shortcut",
    "showcoincs",
    "showdefs",
    "showgaps",
    "showrels",
    "showsubgrp",
    "small",
    "sortdefs",
    "sorted",
    "stSheets",
    "subColumnNums",
    "subgrp",
    "subSheet",
    "subText",
    "table" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcDefinitionsSheet . . . . .  representation for a list of definitions
##
DeclareRepresentation( "IsItcDefinitionsSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "boxes",
    "ctSheet" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcGapSheet  . . . . . . .  representation for a list of gap class reps
##
DeclareRepresentation( "IsItcGapSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "boxes",
    "ctSheet" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcRelationTableSheet . . . . . . .  representation for a relator table
##
DeclareRepresentation( "IsItcRelationTableSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "ctSheet",
    "graphicTable",
    "newtab",
    "number",
    "oldtab",
    "vertical" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcRelatorsSheet . . . . . . . . .  representation for a relators sheet
##
DeclareRepresentation( "IsItcRelatorsSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "boxes",
    "ctSheet" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcSubgroupGeneratorsSheet . . representation for a subgroup gens sheet
##
DeclareRepresentation( "IsItcSubgroupGeneratorsSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "boxes",
    "ctSheet" ],
  IsGraphicSheet );


#############################################################################
##
#R  IsItcSubgroupTableSheet . . representation for a subgroup generator table
##
DeclareRepresentation( "IsItcSubgroupTableSheet",
  IsComponentObjectRep and IsAttributeStoringRep and IsGraphicSheet and
  IsGraphicSheetRep,
  # we inherit those components from the sheet:
  [ "name", "width", "height", "WindowId", "callbackName", "callbackFunc",
    "menus", "gapMenu", "objects", "free", "DefaultsForGraphicObject",
    "filenamePS",
  # now our own components:
    "ctSheet",
    "graphicTable",
    "newtab",
    "number",
    "oldtab",
    "vertical" ],
  IsGraphicSheet );


#############################################################################
#
# ItcClassSheetLeftPBDown( <classSheet>, <x>, <y> )
#
# installs the methods for the left pointer button in table of gaps of length
# one.
#
InstallGlobalFunction( ItcClassSheetLeftPBDown, function( classSheet, x, y )

  local class, classSheets, coset, gaps, gen, i, ctSheet, ndefs;

  # get some local variables
  ctSheet := classSheet!.ctSheet;
  gaps := ctSheet!.gaps;
  classSheets := gaps[4];

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. Length( classSheet!.boxes ) ] do
    if [x,y] in classSheet!.boxes[i] then

      coset := classSheet!.class[i][1];
      gen := classSheet!.class[i][2];

      # echo the command
      if ctSheet!.echo then
        class := Position( classSheets, classSheet );
        Print( ">> CLICK class ", class, " gap [ ", coset, ", ",
          ctSheet!.genNames[gen], " ]\n" );
      fi;

      # get some local variables
      ndefs := ctSheet!.ndefs;

      # define a new coset
      ItcFillCosetTableEntry( ctSheet, coset, gen );

      # check for a fail because of insufficient table size
      if ctSheet!.ndefs > ndefs then

        # save the current state.
        ItcExtractTable( ctSheet );

        # display the coset tables and set all variables
        ItcDisplayCosetTable( ctSheet );

        # update all active relator tables and subgroup generator tables
        ItcUpdateDisplayedLists( ctSheet );
        ItcEnableMenu( ctSheet );

      fi;
      return;

    fi;
  od;
end );


#############################################################################
#
# ItcCoincSheetLeftPBDown( <coiSheet>, <x>, <y> )
#
# installs  the methods  for the  left pointer button  in the list of pending
# coincidences.
#
InstallGlobalFunction( ItcCoincSheetLeftPBDown, function( coiSheet, x, y )

  local boxes, coincs, cos1, cos2, ctSheet, i, length, newtab, oldtab;

  # get some local variables
  ctSheet := coiSheet!.ctSheet;
  boxes := coiSheet!.boxes;
  length := Length( boxes );

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. length ] do
    if [x,y] in boxes[i] then

      # echo the command
      if ctSheet!.echo then
        coincs := ctSheet!.coincs;
        cos1 := coincs[i][1];
        cos2 := coincs[i][2];
        Print( ">> CLICK coincidence ", cos1, " = ", cos2, "\n" );
      fi;

      # work off the i-th pending coincidence
      ItcHandlePendingCoincidence( ctSheet, i );

      # save the old state as new state
      newtab := ctSheet!.oldtab;
      oldtab := ctSheet!.newtab;
      ctSheet!.newtab := newtab;
      ctSheet!.oldtab := oldtab;

      # make the current state the new state
      ItcExtractTable( ctSheet );

      # display the coset tables and set all variables
      ItcDisplayCosetTable( ctSheet );

      # update all active relator tables and subgroup generator tables
      ItcUpdateDisplayedLists( ctSheet );
      ItcEnableMenu( ctSheet );

      return;
    fi;
  od;

end );


#############################################################################
#
# ItcCoincSheetRightPBDown( <coiSheet>, <x>, <y> )
#
# installs  the methods  for the right pointer button  in the list of pending
# coincidences.
#
InstallGlobalFunction( ItcCoincSheetRightPBDown, function( coiSheet, x, y )

  local boxes, charWidth, coincs, cos1, cos2, ctSheet, distance, height, i,
        length, lineHeight, name, sheet, string, width;

  # get some local variables
  ctSheet := coiSheet!.ctSheet;
  distance := ctSheet!.normal.distance;
  lineHeight := ctSheet!.normal.lineHeight;
  charWidth := ctSheet!.normal.charWidth;
  boxes := coiSheet!.boxes;
  length := Length( boxes );

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. length ] do
    if [x,y] in boxes[i] then

      # get some local variables
      coincs := ctSheet!.coincs;
      cos1 := coincs[i][1];
      cos2 := coincs[i][2];

      # echo the command
      if ctSheet!.echo then
        Print( ">> RIGHT CLICK coincidence ", cos1, " = ", cos2, "\n" );
      fi;

      # check if there is already a window for the rep of this coincidence
      if IsBound( coiSheet!.repSheets[i] ) and
      IsAlive( coiSheet!.repSheets[i] ) then

        Close( coiSheet!.repSheets[i] );

      else

        # get the word string to be displayed
        string := String( ItcRepresentativeCoset( ctSheet, cos1 ) *
          ItcRepresentativeCoset( ctSheet, cos2 )^-1 );

        # open a new graphic sheet
        name := Concatenation( "Coinidence ", String( cos1 ), " = ",
          String( cos2 ) );
        width := Maximum( ( Length( string ) + 2 ) * charWidth,
          WidthOfSheetName( name ) );
        height := 3 * distance + lineHeight;
        sheet := GraphicSheet( name, width, height );

        # get the representative of cos1 * cos2^-1 and display it
        sheet!.word := Text( sheet, FONTS.normal, charWidth, lineHeight,
          string );
        sheet!.ctSheet := ctSheet;
        coiSheet!.repSheets[i] := sheet;

      fi;
      return;

    fi;
  od;

end );


#############################################################################
#
# ItcCosetTableSheetLeftPBDown( <ctSheet>, <x>, <y> )
#
# installs the callback for the left pointer button in the window
# 'Interactive Todd-Coxeter'.
#
InstallGlobalFunction( ItcCosetTableSheetLeftPBDown,
  function( ctSheet, x, y )

  local alives, coset, done, firstCol, graphicTable, i, j, line0, ncols,
        newtab, ndefs, ndefs2, nlines, renumbered;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  if [x,y] in ctSheet!.felsch then
    ItcFelsch( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.fillgaps then
    ItcFillGaps( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.fillrows then
    ItcFillRows( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.hlt  then
    ItcHLT( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.showdefs then
    ItcShowDefs( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.showgaps then
    ItcShowGaps( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.showrels then
    ItcShowRels( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.showsubgrp then
    ItcShowSubgrp( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.backto then
    ItcBackTo( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.clear then
    ItcClear( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.reset then
    ItcReset( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.shortcut then
    ItcShortCut( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.sortdefs then
    ItcSortDefinitions( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.scrollto then
    ItcScrollTo( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.scrollby then
    ItcScrollBy( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.showcoincs then
    ItcShowCoincs( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.mark then
    ItcMarkCosets( ctSheet, 0, 0 );

  elif [x,y] in ctSheet!.quitt then
    ItcQuit( ctSheet, 0, 0 );

  else

    # get some local variables
    firstCol := ctSheet!.firstCol;
    graphicTable := ctSheet!.graphicTable;
    newtab := ctSheet!.newtab;
    ndefs := ctSheet!.ndefs;
    ncols := ctSheet!.ncols;
    nlines := ctSheet!.nlines;
    renumbered := ctSheet!.renumbered;
    alives := ctSheet!.alives;
    line0 := renumbered[ctSheet!.first] - 1;
    done := false;

    for i in [ 1 .. nlines ] do
      coset := alives[line0 + i];

      for j in [ 1 .. ncols ] do
        if [x,y] in graphicTable[i][j] and newtab[coset][j] <= 0 then

          # echo the command
          if ctSheet!.echo then
            Print( ">> CLICK coset table entry [ ", coset, ", ",
              ctSheet!.genNames[j], " ]\n" );
          fi;
          done := true;

          # define a new coset in the specified coset table entry
          ItcFillCosetTableEntry( ctSheet, coset, j );

          # check for a fail because of insufficient table size
          if ctSheet!.ndefs > ndefs then

            # save the current state.
            ItcExtractTable( ctSheet );

            # display the coset tables and set all variables
            ItcDisplayCosetTable( ctSheet );

            # update all active relator and subgroup generator tables
            ItcUpdateDisplayedLists( ctSheet );
            ItcEnableMenu( ctSheet );

          fi;
          return;

        fi;
      od;
    od;

    if not done then
      i := 0;
      while i < nlines do
        i := i + 1;
        if [x,y] in firstCol[i] then

          # echo the command
          coset := alives[line0 + i];
          if ctSheet!.echo then
            Print( ">> CLICK coset table row ", coset, "\n" );
          fi;

          # loop over the entries of the row
          j := 0;
          while j < ncols do

            j := j + 1;
            if ctSheet!.table[j][coset] <= 0 then

              # define a new coset
              ndefs2 := ctSheet!.ndefs;
              ItcFillCosetTableEntry( ctSheet, coset, j );

              # check for a fail because of insufficient table size
              if ctSheet!.ndefs = ndefs2 then
                j := ncols;

              else

                # save the current state.
                ItcExtractTable( ctSheet );
                newtab := ctSheet!.newtab;
                renumbered := ctSheet!.renumbered;

                if ctSheet!.renumbered[coset] = 0 then
                  j := ncols;
                fi;

              fi;
            fi;

          od;

          # check for a fail because of insufficient table size
          if ctSheet!.ndefs > ndefs then

            # display the coset tables and set all variables
            ItcDisplayCosetTable( ctSheet );

            # update all active relator and subgroup generator tables
            ItcUpdateDisplayedLists( ctSheet );
            ItcEnableMenu( ctSheet );
          fi;

          i := nlines;
        fi;
      od;
    fi;

  fi;
end );


#############################################################################
#
# ItcCosetTableSheetRightPBDown( <ctSheet>, <x>, <y> )
#
# installs the callback for the right pointer button in the window
# 'Interactive Todd-Coxeter'.
#
InstallGlobalFunction( ItcCosetTableSheetRightPBDown,
  function( ctSheet, x, y )

  local alives, classSheets, coset, firstCol, gaps, graphicTable, i, j, k,
        line0, newtab, nlines, renumbered;

  # get some local variables
  renumbered := ctSheet!.renumbered;
  line0 := renumbered[ctSheet!.first] - 1;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  if [x,y] in ctSheet!.showdefs then
    ctSheet!.markDefs := not ctSheet!.markDefs;
    if ctSheet!.markDefs then
      # mark the definitions in the coset table
      ItcRecolorDefs( ctSheet );
    else
      # recolor all table entries to unmark the definitons
      ItcRecolorTableEntries( ctSheet );
    fi;
    return;
  fi;

  # get some local variables
  firstCol := ctSheet!.firstCol;
  graphicTable := ctSheet!.graphicTable;
  newtab := ctSheet!.newtab;
  nlines := ctSheet!.nlines;
  alives := ctSheet!.alives;

  # run througth the lines in the coset table sheet
  for i in [ 1 .. nlines ] do
    coset := alives[line0 + i];

    # check if the line number has been clicked
    if [x,y] in firstCol[i] then

      # echo the command
      if ctSheet!.echo then
        Print( ">> RIGHT CLICK coset table row ", coset, "\n" );
      fi;

      # display the representative of thecorrespondingcoset and return
      ItcDisplayDefinition( ctSheet, coset );
      return;
    fi;

    # check if a proper entry in the line has been clicked
    for j in [ 1 .. Length( graphicTable[i] ) ] do
      if [x,y] in graphicTable[i][j] then

        # echo the command
        if ctSheet!.echo then
          Print( ">> RIGHT CLICK coset table entry [ ", alives[line0 + i],
            ", ", ctSheet!.genNames[j], " ]\n" );
        fi;

        # check if the entry is a coset number
        if newtab[coset][j] > 0 then

          # display the representative of the corresponding coset
          ItcDisplayDefinition( ctSheet, newtab[coset][j] );

        # check if the entry represents a gap of length 1
        elif newtab[coset][j] < 0 then

          # get the class number of the gap of length 1
          k := ItcNumberClassOfGaps( ctSheet, coset, j );

          # update the correponding class sheet
          gaps := ctSheet!.gaps;
          classSheets := gaps[4];
          if classSheets[k] <> 0 and IsAlive( classSheets[k] ) then
            Close( classSheets[k] );
          fi;
          ItcOpenClassSheet( ctSheet, k );
        fi;

        return;
      fi;
    od;
  od;
end );


#############################################################################
#
# ItcDefinitionsSheetPBDown( <defSheet>, <x>, <y> )
#
# installs the methods  for the left or right pointer button  in the Table of
# Definitions.
#
InstallGlobalFunction( ItcDefinitionsSheetPBDown, function( defSheet, x, y )

  local alives, boxes, coset, ctSheet, def, defs, gen, i, inv, j, length,
        line0, names, newtab, string;

  # get some local variables
  ctSheet := defSheet!.ctSheet;
  boxes := defSheet!.boxes;
  length := Length( boxes );

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. length ] do
    if [x,y] in boxes[i] then

      # get some local variables
      names := ctSheet!.genNames;
      defs := ctSheet!.defs;
      alives := ctSheet!.alives;
      newtab := ctSheet!.newtab;
      line0 := ctSheet!.renumbered[ctSheet!.first] - 1;
      coset := alives[line0 + i];

      if coset = 1 then
        string := "1 = 1";
      else
        def := defs[coset - 1];
        gen := def[2];
        inv := gen + 1 - 2 * ( ( gen + 1 ) mod 2 );
        j := newtab[coset][inv];
        string := Concatenation( String( coset ), "  =  ", String( j ),
          " * ", names[gen] );
      fi;

      # echo the command
      if ctSheet!.echo then
        Print( ">> RIGHT CLICK definition ", string, "\n" );
      fi;

      # open (or close) a definition sheet and return
      ItcDisplayDefinition( ctSheet, coset );
      return;

    fi;
  od;

end );


#############################################################################
#
# ItcGapSheetLeftPBDown( <gapSheet>, <x>, <y> )
#
# installs the methods for the left pointer button in table of gaps of length
# one.
#
InstallGlobalFunction( ItcGapSheetLeftPBDown, function( gapSheet, x, y )

  local coset, ctSheet, gen, i, ndefs, rep, reps;

  # get some local variables
  ctSheet := gapSheet!.ctSheet;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. Length( gapSheet!.boxes ) ] do
    if [x,y] in gapSheet!.boxes[i] then

      # echo the command
      if ctSheet!.echo then
        Print( ">> CLICK gaps class ", i, "\n" );
      fi;

      # get some local variables
      reps := ctSheet!.gaps[1];
      rep := reps[i];
      coset := rep[2];
      gen := rep[3];
      ndefs := ctSheet!.ndefs;

      # define a new coset
      ItcFillCosetTableEntry( ctSheet, coset, gen );

      # check for a fail because of insufficient table size
      if ctSheet!.ndefs > ndefs then

        # save the current state.
        ItcExtractTable( ctSheet );

        # display the coset tables and set all variables
        ItcDisplayCosetTable( ctSheet );

        # update all active relator tables and subgroup generator tables
        ItcUpdateDisplayedLists( ctSheet );
        ItcEnableMenu( ctSheet );

      fi;
      return;

    fi;
  od;
end );


#############################################################################
#
# ItcGapSheetRightPBDown( <gapSheet>, <x>, <y> )
#
# installs the methods for the left pointer button in table of gaps of length
# one.
#
InstallGlobalFunction( ItcGapSheetRightPBDown, function( gapSheet, x, y )

  local classSheets, ctSheet, gaps, i;

  # get some local variables
  ctSheet := gapSheet!.ctSheet;
  gaps := ctSheet!.gaps;
  classSheets := gaps[4];

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. Length( gapSheet!.boxes ) ] do
    if [x,y] in gapSheet!.boxes[i] then

      # echo the command
      if ctSheet!.echo then
        Print( ">> RIGHT CLICK gaps class ", i, "\n" );
      fi;

      if classSheets[i] <> 0 and IsAlive( classSheets[i] ) then
        Close( classSheets[i] );
      else
        ItcOpenClassSheet( ctSheet, i );
      fi;
    fi;
  od;
end );


#############################################################################
#
# ItcRelationTableSheetLeftPBDown( <rtSheet>, <x>, <y> )
#
# installs the methods for the left pointer button in a relation table.
#
InstallGlobalFunction( ItcRelationTableSheetLeftPBDown, function(
  rtSheet, x, y )

  local alives, columns, coset, ctSheet, gen, graphicTable, i, invcol, j,
        length, line0, ndefs, number, table;

  # get some local variables
  ctSheet := rtSheet!.ctSheet;
  table := rtSheet!.newtab;
  number := rtSheet!.number;
  graphicTable := rtSheet!.graphicTable;
  invcol := ctSheet!.invcol;
  alives := ctSheet!.alives;
  line0 := ctSheet!.renumbered[ctSheet!.first] - 1;
  columns := ctSheet!.relColumnNums[number];

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. Length( graphicTable ) ] do
    if IsBound( graphicTable[i] ) then
      length := Length( graphicTable[i] );
      for j in [ 1 .. length ] do
        if [x,y] in graphicTable[i][j] then
          if j = 1 or j = length then
            # echo the command
            coset := alives[line0 + i];
            if ctSheet!.echo then
              Print( ">> CLICK relation table ", number, " row ", coset,
               "\n" );
            fi;
            # new definitions are not allowed if there are pending
            # coincidences
            if not ctSheet!.coincs = [] then
              Relabel( ctSheet!.messageText,
                "There are pending coincidences" );
              ctSheet!.message := true;
              return;
            fi;
            # fill the row
            ItcFillTrace( ctSheet, coset, columns );
            ItcDisplayCosetTable( ctSheet );
            ItcUpdateDisplayedLists( ctSheet );
            ItcEnableMenu( ctSheet );
            return;

          elif table[i][j] > 0 then
            return;
          elif table[i][j-1] > 0 then
            coset := table[i][j-1];
            gen := columns[j-1];
          elif table[i][j+1] <= 0 then
            Relabel( ctSheet!.messageText, "This command has no effect" );
            ctSheet!.message := true;
            return;
          else
            coset := table[i][j+1];
            gen := invcol[columns[j]];
          fi;

          # echo the command
          if ctSheet!.echo then
            Print( ">> CLICK relation table ", number, " row ",
             alives[line0 + i], " entry [ ", coset, ", ",
             ctSheet!.genNames[gen], " ]\n" );
          fi;

          ndefs := ctSheet!.ndefs;
          ItcFillCosetTableEntry( ctSheet, coset, gen );

          # check for a fail because of insufficient table size
          if ctSheet!.ndefs > ndefs then

            # save the current state.
            ItcExtractTable( ctSheet );

            # display the coset tables and set all variables
            ItcDisplayCosetTable( ctSheet );

            # update all active relator tables and subgroup generator tables
            ItcUpdateDisplayedLists( ctSheet );
            ItcEnableMenu( ctSheet );

          fi;
          return;

        fi;
      od;
    fi;
  od;
end );


#############################################################################
#
# ItcRelatorsSheetLeftPBDown( <relSheet>, <x>, <y> )
#
# installs the methods for the left pointer button in the window 'Relators'.
#
InstallGlobalFunction( ItcRelatorsSheetLeftPBDown, function( relSheet, x, y )

  local boxes, ctSheet, i, rtSheets;

  # get some local variables
  boxes := relSheet!.boxes;
  ctSheet := relSheet!.ctSheet;
  rtSheets := ctSheet!.rtSheets;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. Length( boxes ) ] do
    if [x,y] in boxes[i] then

      # echo the command
      if ctSheet!.echo then
        Print( ">> CLICK relator ", i, "\n" );
      fi;

      if IsBound( rtSheets[i] ) and IsAlive( rtSheets[i] ) then
        Close( rtSheets[i] );
      else
        ItcDisplayRelationTable( ctSheet, i );
      fi;
    fi;
  od;
end );


#############################################################################
#
# ItcSubgroupGeneratorsSheetLeftPBDown( <subSheet>, <x>, <y> )
#
# installs the methods for the left pointer button in the window 'Subgroup
# gens'.
#
InstallGlobalFunction( ItcSubgroupGeneratorsSheetLeftPBDown,
  function( subSheet, x, y )

  local boxes, ctSheet, i, stSheets;

  # get some local variables
  boxes := subSheet!.boxes;
  ctSheet := subSheet!.ctSheet;
  stSheets := ctSheet!.stSheets;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. Length( boxes ) ] do
    if [x,y] in boxes[i] then

      # echo the command
      if ctSheet!.echo then
        Print( ">> CLICK subgroup generator ", i, "\n" );
      fi;

      if IsBound( stSheets[i] ) and IsAlive( stSheets[i] ) then
        Close( stSheets[i] );
      else
        ItcDisplaySubgroupTable( ctSheet, i );
      fi;
    fi;
  od;
end );


#############################################################################
#
# ItcSubgroupTableSheetLeftPBDown( <stSheet>, <x>, <y> )
#
# installs the methods for the left pointer button in a subgroup table.
#
InstallGlobalFunction( ItcSubgroupTableSheetLeftPBDown,
  function( stSheet, x, y )

  local alives, columns, coset, ctSheet, gen, graphicTable, i,invcol, j,
        length, ndefs, number, table;

  # get some local variables
  ctSheet := stSheet!.ctSheet;
  table := stSheet!.newtab;
  number := stSheet!.number;
  graphicTable := stSheet!.graphicTable;
  invcol := ctSheet!.invcol;
  alives := ctSheet!.alives;
  columns := ctSheet!.subColumnNums[number];

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  for i in [ 1 .. Length( graphicTable ) ] do
    if IsBound( graphicTable[i] ) then
      length := Length( graphicTable[i] );
      for j in [ 1 .. length ] do
        if [x,y] in graphicTable[i][j] then
          if j = 1 or j = length then
            coset := alives[i];
            if ctSheet!.echo then
              Print( ">> CLICK subgroup table ", number, " row ", coset,
               "\n" );
            fi;
            # new definitions are not allowed if there are pending
            # coincidences
            if not ctSheet!.coincs = [] then
              Relabel( ctSheet!.messageText,
                "There are pending coincidences" );
              ctSheet!.message := true;
              return;
            fi;
            # fill the row
            ItcFillTrace( ctSheet, coset, columns );
            ItcDisplayCosetTable( ctSheet );
            ItcUpdateDisplayedLists( ctSheet );
            ItcEnableMenu( ctSheet );
            return;
          elif table[i][j] > 0 then
            Relabel( ctSheet!.messageText, "This command has no effect" );
            ctSheet!.message := true;
            return;
          elif table[i][j-1] > 0 then
            coset := table[i][j-1];
            gen := columns[j-1];
          elif table[i][j+1] <= 0 then
            return;
          else
            coset := table[i][j+1];
            gen := invcol[columns[j]];
          fi;

          # echo the command
          if ctSheet!.echo then
            Print( ">> CLICK subgroup table ", number, " row ", alives[i],
             " entry [ ", coset, ", ", ctSheet!.genNames[gen], " ]\n" );
          fi;

          ndefs := ctSheet!.ndefs;
          ItcFillCosetTableEntry( ctSheet, coset, gen );

          # check for a fail because of insufficient table size
          if ctSheet!.ndefs > ndefs then

            # save the current state.
            ItcExtractTable( ctSheet );

            # display the coset tables and set all variables
            ItcDisplayCosetTable( ctSheet );

            # update all active relator tables and subgroup generator tables
            ItcUpdateDisplayedLists( ctSheet );
            ItcEnableMenu( ctSheet );

          fi;
          return;

        fi;
      od;
    fi;
  od;
end );


#############################################################################
#
# ItcBackTo( <ctSheet>, <menu>, <entry> )
#
# is called by selecting the menu entry 'back to definition' or by clicking
# on the button 'back to'.
#
InstallGlobalFunction( ItcBackTo, function( ctSheet, menu, entry )

  local coincSwitch, coset, defs, defSheet, echo, first, i, nargs, ndefs,
        query, repLists, showDefs, steps, table;

  # get some local variables
  ndefs := ctSheet!.ndefs;
  if ndefs = 1 then
    return;
  fi;

  # select the number of steps to be canceled and select the definitions to
  # be made
  query := Query( Dialog( "OKcancel", "back to ..." ), String( ndefs - 1 ) );

  # echo the command
  if ctSheet!.echo then
    Print( ">> BACK TO ", query, "\n" );
  fi;

  # return if the query has been canceled
  if query = false then
    return;
  fi;

  # evaluate the query string and check the arguments
  query := ItcQuery( query );
  nargs := Length( query );
  if nargs = 0 or query = [ ndefs ] then
    Relabel( ctSheet!.messageText, "This command has no effect" );
    ctSheet!.message := true;
    return;
  fi;
  steps := query[1];
  if not IsInt( steps ) or steps > ndefs or steps <= -ndefs or nargs > 1
    then
    Relabel( ctSheet!.messageText, "Illegal argument" );
    ctSheet!.message := true;
    return;
  fi;
  if steps < 0 then
    steps := ndefs + steps;
  fi;

  if steps = 1 then

    # clear the coset table
    ItcClearTable( ctSheet );
    ctSheet!.hltRow := 1;
    ctSheet!.marked := [];
    ctSheet!.scroll := 20;

    # display the coset table
    ItcDisplayCosetTable( ctSheet );
    ItcUpdateDisplayedLists( ctSheet );
    ItcEnableMenu( ctSheet );

    return;
  fi;

  # save the current scroll position
  first := ctSheet!.first;

  # save the definitions and clear the table
  defs := ctSheet!.defs{ [ 1 .. steps - 1 ] };
  ndefs := Length( defs );

  # save the coset representative sheets and the definitions table
  repLists := ctSheet!.repLists;
  ctSheet!.repLists := [ [], [] ];
  showDefs := IsBound( ctSheet!.defSheet ) and IsAlive( ctSheet!.defSheet );
  if showDefs then
    defSheet := ctSheet!.defSheet;
    Unbind( ctSheet!.defSheet );
  fi;

  # clear the coset table
  ItcClearTable( ctSheet );
  ctSheet!.hltRow := 1;

  # switch on the automatic handling of coinicidences, if necessary
  coincSwitch := ctSheet!.coincSwitch;
  ctSheet!.coincSwitch := true;

  # reconstruct and extract the table preceding the requested one
  for i in [ 1 .. ndefs - 1 ] do
    ItcFastCosetStepFill( ctSheet, defs[i][1], defs[i][2] );
  od;
  ItcExtractTable( ctSheet );

  # reconstruct the requested table
  i := ndefs;
  ItcCosetStepFill( ctSheet, defs[i][1], defs[i][2] );

  # reset the coincidences switch
  ctSheet!.coincSwitch := coincSwitch;

  # save the current state
  ItcExtractTable( ctSheet );
  ctSheet!.first := first;

  # display the coset tables and set all variables
  ItcDisplayCosetTable( ctSheet );

  # reset the coset representative sheets and the definitions table
  ctSheet!.repLists := repLists;
  if showDefs then
    ctSheet!.defSheet := defSheet;
    ItcDisplayDefinitionsTable( ctSheet );
  fi;

  # update all active relator and subgroup generator tables
  ItcUpdateDisplayedLists( ctSheet );
  ItcEnableMenu( ctSheet );

end );


#############################################################################
#
# ItcChangeDefaultTableSize( <ctSheet>, <menu>, <entry> )
#
InstallGlobalFunction( ItcChangeDefaultTableSize,
  function( ctSheet, menu, entry )

  local defaultLimit, limit, nargs, ndefs, query, settingsSheet, string,
        suggest;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  # find a suitable default value for the query
  defaultLimit := ctSheet!.defaultLimit;
  if defaultLimit = 1000 then
    suggest := 2000;
  else
    suggest := 1000;
  fi;

  # initialize the default coset table size
  query := Query( Dialog( "OKcancel", Concatenation(
    "change default table size from ", String( defaultLimit ), " to" ) ),
    String( suggest ) );

  # echo the command
  if ctSheet!.echo then
    Print( ">> CHANGE DEFAULT TABLE SIZE TO ", query, "\n" );
  fi;

  # return if the query has been canceled
  if query = false then
    return;
  fi;

  # evaluate the query string and check the arguments
  query := ItcQuery( query );
  nargs := Length( query );
  if nargs = 0 then
    defaultLimit := 0;
  else
    defaultLimit := query[1];
    if not IsInt( defaultLimit ) or defaultLimit <= 0 or nargs > 1 then
      Relabel( ctSheet!.messageText, "Illegal argument" );
      ctSheet!.message := true;
      return;
    fi;
  fi;

  # reset the default table size
  ctSheet!.defaultLimit := defaultLimit;

  # get some local variables
  ndefs := ctSheet!.ndefs;

  # if no enumeration has been started yet reinitialize the coset table
  if ndefs = 1 then
    limit := defaultLimit;
    ctSheet!.limit := limit;
    ctSheet!.defs := [];
    ctSheet!.ndefs := 1;
    ctSheet!.renumbered := [1];
    ctSheet!.alives := [ [1], [1], [1] ];
    ItcMakeDigitStrings( ctSheet );
    ctSheet!.oldtab := ListWithIdenticalEntries( limit, 0 );
    ctSheet!.newtab := ListWithIdenticalEntries( limit, 0 );
    ItcInitializeParameters( ctSheet );
    ItcEnableMenu( ctSheet );
  fi;

  # update the sheet of current settings
  if IsBound( ctSheet!.settingsSheet ) and IsAlive( ctSheet!.settingsSheet )
    then
    settingsSheet := ctSheet!.settingsSheet;
    FastUpdate( ctSheet, true );
    string := Concatenation( "default table size ", String( defaultLimit ) );
    Relabel( settingsSheet!.boxes[1], string );
    string := Concatenation( "table size ", String( ctSheet!.limit ) );
    Relabel( settingsSheet!.boxes[2], string );
    FastUpdate( ctSheet, false );
  fi;
end );


#############################################################################
#
# ItcChangeSettings( <ctSheet>, <menu>, <entry> )
#
# changes the settings.
#
InstallGlobalFunction( ItcChangeSettings, function( ctSheet, menu, entry )

  local i, num, settingsSheet, showSettings, strategy, string;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  # get the entry
  num := Position( menu!.entries, entry );
  if num < 3 or num > 10 then
    Error( "illegal arguments" );
  fi;

  showSettings := IsBound( ctSheet!.settingsSheet ) and
    IsAlive( ctSheet!.settingsSheet );

  if num = 3 then

    # entry "coincidence handling off"
    # --------------------------------

    # echo the command
    if ctSheet!.echo then
      Print( ">> COINCIDENCE HANDLING OFF\n" );
    fi;

    # switch off the automatic handling of coincidences
    ctSheet!.coincSwitch := false;

    if showSettings then
      i := 3;
      string := "coincidence handling OFF";
    fi;
    ItcRelabelInfoLine( ctSheet );

  elif num = 4 then

    # entry "coincidence handling on"
    # -------------------------------

    # echo the command
    if ctSheet!.echo then
      Print( ">> COINCIDENCE HANDLING ON\n" );
    fi;

    # if there is a window 'pending coincidenes' close it
    if IsBound( ctSheet!.coiSheet ) and IsAlive( ctSheet!.coiSheet ) then
      ItcCloseSheets( ctSheet!.coiSheet!.repSheets );
      Close( ctSheet!.coiSheet );
    fi;

    # switch on the automatic handling of coincidences
    ctSheet!.coincSwitch := true;

    if showSettings then
      i := 3;
      string := "coincidence handling ON";
    fi;
    ItcRelabelInfoLine( ctSheet );

    # if there are pending coincidences reconstruct the table
    if ctSheet!.coincs <> [] then

      # reconstruct the preceding state
      ItcExtractPrecedingTable( ctSheet );

      # make the current state the new state
      ItcExtractTable( ctSheet );

      # display the coset tables and set all variables
      ItcDisplayCosetTable( ctSheet );

      # update all active relator tables and subgroup generator tables
      ItcUpdateDisplayedLists( ctSheet );
      ItcEnableMenu( ctSheet );
    fi;

  elif num = 5 then

    # entry "echo on"
    # ---------------

    # switch on the echo
    ctSheet!.echo := true;

    # echo the command
    Print( ">> ECHO ON\n" );

    if showSettings then
      i := 4;
      string := "echo ON";
    fi;

  elif num = 6 then

    # entry "echo off"
    # ----------------

    # echo the command
    if ctSheet!.echo then
      Print( ">> ECHO OFF\n" );
    fi;

    # switch off the echo
    ctSheet!.echo := false;

    if showSettings then
      i := 4;
      string := "echo OFF";
    fi;

  else

    # echo the command
    strategy := num - 6;
    if ctSheet!.echo then
      Print( ">> GAPS STRATEGY ", strategy, "\n" );
    fi;

    # set the gaps strategy
    ctSheet!.gapsStrategy := strategy;

    if showSettings then
      i := 5;
      if strategy = 1 then
        string := "gaps strategy 1 (first gap)";
      elif strategy = 2 then
        string := "gaps strategy 2 (first rep of max weight)";
      elif strategy = 3 then
        string := "gaps strategy 3 (last rep of max weight)";
      fi;
    fi;

  fi;

  # update the sheet of current settings
  if showSettings then
    settingsSheet := ctSheet!.settingsSheet;
    FastUpdate( ctSheet, true );
    Relabel( settingsSheet!.boxes[i], string );
    FastUpdate( ctSheet, false );
  fi;

  ItcEnableMenu( ctSheet );
end );


#############################################################################
#
# ItcClassOfGaps( <ctSheet>, <n> )
#
# compute the n-th class of gaps of length 1.
#
InstallGlobalFunction( ItcClassOfGaps, function( ctSheet, n )

  local class, classes, c, cos, entry, gaps, gen, i, involutory, j, length,
        ncols, next, null, rep, reps, table;

  # get the list of all classes of gaps of length 1
  gaps := ItcGaps( ctSheet );
  classes := gaps[2];

  # check if the class is already available
  if classes[n] <> 0 then

    class := classes[n];

  else

    # get some local variables
    involutory := ctSheet!.involutory;
    next := ctSheet!.next;
    table := ctSheet!.table;
    ncols := ctSheet!.ncols;
    null := ncols * Length( table[1] );
    reps := gaps[1];
    rep := reps[n];
    length := rep[1];
    cos := rep[2];
    gen := rep[3];

    # initialize the class
    class := ListWithIdenticalEntries( length, 0 );
    i := 1;
    class[1] := [ cos, gen ];
    if involutory[gen] = 2 then
      gen := gen + 1;
      i := 2;
      class[2] := [ cos, gen ];
    fi;
    rep := ( cos -1 ) * ncols + gen;

    # loop over the coset table and find all gaps of the class
    while cos <> 0 do
      while gen < ncols do
      gen := gen + 1;
        entry := - table[gen][cos];
        if entry > 0 then
          while entry < null and entry <> rep do
            if entry <= 0 then
              Error( "THIS IS A BUG (ITC 01), YOU SHOULD NEVER GET HERE" );
            fi;
            j := ( entry - 1 ) mod ncols + 1;
            c := ( entry - j ) / ncols + 1;
            entry := - table[j][c];
          od;
          if entry = rep then
            # add the gap to the class
            i := i + 1;
            class[i] := [ cos, gen ];
          fi;
        fi;
      od;
      gen := 0;
      cos := next[cos];
    od;
    if i <> length then
       Error( "THIS IS A BUG (ITC 02), YOU SHOULD NEVER GET HERE" );
    fi;

  fi;
  return class;

end );


#############################################################################
#
# ItcClear( <ctSheet>, <menu>, <entry> )
#
#
InstallGlobalFunction( ItcClear, function( ctSheet, menu, entry )

  local i, limit, nsgens, nrels;

  # get some local variables
  nrels := Length( ctSheet!.rels );
  nsgens := Length( ctSheet!.fsgens );

  # echo the command
  if ctSheet!.echo then
    Print( ">> CLEAR\n" );
  fi;

  # reset the table size
  limit := ctSheet!.defaultLimit;
  ctSheet!.limit := limit;

  # reinitialize some auxiliary lists
  ItcMakeDigitStrings( ctSheet );
  ctSheet!.newtab := ListWithIdenticalEntries( limit, 0 );
  ctSheet!.oldtab := ListWithIdenticalEntries( limit, 0 );

  # clear the coset table
  ItcClearTable( ctSheet );

  # close the definitions table
  if IsBound( ctSheet!.defSheet ) and IsAlive( ctSheet!.defSheet ) then
    ItcCloseSheets( ctSheet!.repLists[2] );
    Close( ctSheet!.defSheet );
  fi;

  # close the relator tables
  if IsBound( ctSheet!.rtSheets ) then
    for i in [ 1 .. nrels ] do
      if IsBound( ctSheet!.rtSheets[i] ) and
        IsAlive( ctSheet!.rtSheets[i] ) then
        Close( ctSheet!.rtSheets[i] );
      fi;
    od;
  fi;

  # close the subgroup generator tables
  if IsBound( ctSheet!.stSheets ) then
    if IsBound( ctSheet!.subSheet ) then
      for i in [ 1 .. nsgens ] do
        if IsBound( ctSheet!.stSheets[i] ) and
          IsAlive( ctSheet!.stSheets[i] ) then
          Close( ctSheet!.stSheets[i] );
        fi;
      od;
    fi;
  fi;

  # reinitialize some parameters
  ctSheet!.hltRow := 1;
  ctSheet!.marked := [];
  ctSheet!.scroll := 20;
  ctSheet!.repLists := [ [], [] ];

  # display the coset table
  ItcDisplayCosetTable( ctSheet );
  ItcEnableMenu( ctSheet );

end );


#############################################################################
#
# ItcClearTable( <ctSheet> )
#
InstallGlobalFunction( ItcClearTable, function( ctSheet )

  local def, definitions, fsgens, nsgens, steps;

  # get some local variables
  fsgens := ctSheet!.fsgens;
  nsgens := Length( fsgens );

  # close the gaps of length 1 sheets if there are any
  ItcCloseGapSheets( ctSheet );

  # close the window 'pending coincidenes'
  if IsBound( ctSheet!.coiSheet ) and IsAlive( ctSheet!.coiSheet ) then
    ItcCloseSheets( ctSheet!.coiSheet!.repSheets );
    Close( ctSheet!.coiSheet );
  fi;

  # set back the variables for the coset enumerations
  ctSheet!.sorted := false;
  ctSheet!.markDefs := false;
  ctSheet!.coincs := [];
  ctSheet!.deducs := [];
  ctSheet!.defs := [];
  ctSheet!.ndefs := 1;
  ctSheet!.renumbered := [1];
  ctSheet!.alives := [ [1], [1], [1] ];

  ItcInitializeParameters( ctSheet );
end );


#############################################################################
#
# ItcCloseGapSheets( <ctSheet> )
#
# close the gaps of length 1 sheets if there are any
#
InstallGlobalFunction( ItcCloseGapSheets, function( ctSheet )

  local i, classSheets, gaps, gapSheet, sheet;

  gaps := ctSheet!.gaps;
  if gaps <> 0 then

    classSheets := gaps[4];
    for sheet in classSheets do
      if sheet <> 0 and IsAlive( sheet ) then
         Close( sheet );
      fi;
    od;

    gapSheet := gaps[3];
    if gapSheet <> 0 and IsAlive( gapSheet ) then
      Close( gapSheet );
    fi;

  fi;
end );


#############################################################################
#
# ItcCloseSheets( <list> )
#
# close all sheets in the given list.
#
InstallGlobalFunction( ItcCloseSheets, function( list )

  local sheet;
  for sheet in list do
    if IsAlive( sheet ) then
      Close( sheet );
    fi;
  od;
end );


#############################################################################
#
# ItcCloseTableFelsch( <ctSheet>, <menu>, <entry> )
#
# is called by selecting the menu entry 'close table By Felsch'.
#
InstallGlobalFunction( ItcCloseTableFelsch, function( ctSheet, menu, entry )

  local count, limit, ndefs;

  # if the coset table is already closed return
  if ctSheet!.firstDef = 0 then
    Relabel( ctSheet!.messageText, "The tables are closed" );
    ctSheet!.message := true;
    return;
  fi;

  # new definitions are not allowed if there are pending coincidences
  if not ctSheet!.coincs = [] then
    Relabel( ctSheet!.messageText, "There are pending coincidences" );
    ctSheet!.message := true;
    return;
  fi;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  # echo the command
  if ctSheet!.echo then
    Print( ">> CLOSE Felsch\n" );
  fi;

  # initialize some local variables
  limit := ctSheet!.limit;
  count := 0;

  # do the enumeration.
  while ctSheet!.firstDef <> 0 and ctSheet!.coincs = [] do

    # extend the table is necessary
    ndefs := ctSheet!.ndefs;
    if ndefs = limit then
      ItcExtendTableSize( ctSheet, 0, 0 );
      limit := ctSheet!.limit;
      if ndefs = limit then
        # insufficient table size: display a message and return
        Relabel( ctSheet!.messageText, "Insufficient table size" );
        ctSheet!.message := true;
        return;
      fi;
      count := 0;
    fi;

    count := count + 1;
    ItcFastCosetStepFelsch( ctSheet );
    ItcRelabelInfoLine( ctSheet );

    # check for a fail because of insufficient table size
    if ctSheet!.ndefs = ndefs then
      Error( "THIS IS A BUG (ITC 03), YOU SHOULD NEVER GET HERE" );
    fi;

    # if table has closed reconstruct the last preceding state.
    if ctSheet!.firstDef = 0 and count > 1 or not ctSheet!.coincs = [] then
      ItcExtractPrecedingTable( ctSheet );
    fi;
  od;

  # save the current state.
  ItcExtractTable( ctSheet );

  # display the coset tables and set all variables
  ItcDisplayCosetTable( ctSheet );

  # update all active relator tables and subgroup generator tables
  ItcUpdateDisplayedLists(ctSheet);

  # if there are pending coincidences display them
  if not ctSheet!.coincs = [] then
    ItcDisplayPendingCoincidences( ctSheet );
  fi;

  ItcEnableMenu( ctSheet );

end );


#############################################################################
#
# ItcCloseTableGaps( <ctSheet>, <menu>, <entry> )
#
# is called by selecting the menu entry 'close table using gaps'.
#
InstallGlobalFunction( ItcCloseTableGaps, function( ctSheet, menu, entry )

  local count, first, limit, ndefs, pos, strategy;

  # if the coset table is already closed return
  if ctSheet!.firstDef = 0 then
    Relabel( ctSheet!.messageText, "The tables are closed" );
    ctSheet!.message := true;
    return;
  fi;

  # new definitions are not allowed if there are pending coincidences
  if not ctSheet!.coincs = [] then
    Relabel( ctSheet!.messageText, "There are pending coincidences" );
    ctSheet!.message := true;
    return;
  fi;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  # get the strategy
  pos := Position( menu!.entries, entry );
  if pos < 2 or pos > 5 then
    Error( "illegal arguments" );
  fi;
  strategy := pos - 1;

  # echo the command
  if ctSheet!.echo then
    Print( ">> CLOSE gaps ", strategy, "\n" );
  fi;

  # save the current scroll position
  first := ctSheet!.first;

  # initialize some local variables
  limit := ctSheet!.limit;
  count := 0;

  # do the enumeration.
  while ctSheet!.firstDef <> 0 and ctSheet!.coincs = [] do

    # extend the table is necessary
    ndefs := ctSheet!.ndefs;
    if ndefs = limit then
      ItcExtendTableSize( ctSheet, 0, 0 );
      limit := ctSheet!.limit;
      if ndefs = limit then
        # insufficient table size: display a message and return
        Relabel( ctSheet!.messageText, "Insufficient table size" );
        ctSheet!.message := true;
        return;
      fi;
      count := 0;
    fi;

    # define the next coset
    count := count + 1;
    pos := ItcFirstGapOfLengthOne( ctSheet, strategy );
    if pos = fail then
      ItcFastCosetStepFelsch( ctSheet );
    else
      ItcFastCosetStepFill( ctSheet, pos[1], pos[2] );
    fi;
    ItcRelabelInfoLine( ctSheet );

    # check for a fail because of insufficient table size
    if ctSheet!.ndefs = ndefs then
      Error( "THIS IS A BUG (ITC 04), YOU SHOULD NEVER GET HERE" );
    fi;

    # if table has closed reconstruct the last preceding state.
    if ctSheet!.firstDef = 0 and count > 1 or not ctSheet!.coincs = [] then
      ItcExtractPrecedingTable( ctSheet );
    fi;
  od;
  ctSheet!.first := first;

  # save the current state.
  ItcExtractTable( ctSheet );

  # display the coset tables and set all variables
  ItcDisplayCosetTable( ctSheet );

  # update all active relator tables and subgroup generator tables
  ItcUpdateDisplayedLists(ctSheet);

  # if there are pending coincidences display them
  if not ctSheet!.coincs = [] then
    ItcDisplayPendingCoincidences( ctSheet );
  fi;

  ItcEnableMenu( ctSheet );

end );


#############################################################################
#
# ItcCloseTableHLT( <ctSheet>, <menu>, <entry> )
#
# is called by selecting the menu entry 'close table by HLT'.
#
InstallGlobalFunction( ItcCloseTableHLT, function( ctSheet, menu, entry )

  local coset, first, hlt, i, limit, maxdef, ndefs, nrels, nsgens, overflow,
        relColumnNums, subColumnNums, subgrp;

  # if the coset table is already closed return
  if ctSheet!.firstDef = 0 then
    Relabel( ctSheet!.messageText, "The tables are closed" );
    ctSheet!.message := true;
    return;
  fi;

  # new definitions are not allowed if there are pending coincidences
  if not ctSheet!.coincs = [] then
    Relabel( ctSheet!.messageText, "There are pending coincidences" );
    ctSheet!.message := true;
    return;
  fi;

  # if there is an actual message line, clear it
  if ctSheet!.message then
    Relabel( ctSheet!.messageText, "" );
    ctSheet!.message := false;
  fi;

  # echo the command
  if ctSheet!.echo then
    Print( ">> CLOSE HLT\n" );
  fi;

  # get some local variables
  subColumnNums := ctSheet!.subColumnNums;
  relColumnNums := ctSheet!.relColumnNums;
  subgrp := ctSheet!.subgrp;
  ndefs := ctSheet!.ndefs;
  nrels := Length( ctSheet!.rels );
  nsgens := Length( ctSheet!.fsgens );
  maxdef := 0;
  coset := ctSheet!.hltRow;
  overflow := false;
  hlt := [ coset, maxdef, overflow ];

  # fill the subgroup tables
  if not subgrp = [] then
    if coset <> 1 then
      Error( "THIS IS A BUG (ITC 05), YOU SHOULD NEVER GET HERE" );
    fi;
    i := 0;
    while i < nsgens do
      i := i + 1;
      ItcFillTraceHLT( ctSheet, hlt, subColumnNums[i] );
      overflow := hlt[3];
      if ctSheet!.firstDef = 0 or overflow or not ctSheet!.coincs = [] then
        # break the loop if the tables closed or in case of insufficient
        # table size or if there are pending coincidences
        i := nsgens;
        maxdef := ctSheet!.ndefs;
      fi;
    od;
  fi;

  coset := ctSheet!.hltRow;
  hlt[1] := coset;
  while maxdef <> ctSheet!.ndefs and coset <> 0 do
    ctSheet!.hltRow := coset;

    # fill the corresponding row in each relation table
    i := 0;
    while i < nrels do
      i := i + 1;
      ItcFillTraceHLT( ctSheet, hlt, relColumnNums[i] );
      overflow := hlt[3];
      # break the loops if the tables closed or in case of insufficient table
      # size or if there are pending coincidences
      if ctSheet!.firstDef = 0 or overflow or not ctSheet!.coincs = [] then
        maxdef := ctSheet!.ndefs;
      fi;
      # break the inner loop if the coset is not alive any more
      if ctSheet!.ndefs = maxdef or hlt[1] <> coset then
        i := nrels;
      fi;
    od;
    if hlt[1] = coset then
      coset := ctSheet!.next[coset];
      hlt[1] := coset;
    else
      coset := hlt[1];
    fi;

  od;

  if ctSheet!.ndefs > ndefs and not overflow then

    if ctSheet!.ndefs - ndefs > 1 then
      ItcExtractPrecedingTable( ctSheet );
    fi;

    # save the current state
    ItcExtractTable( ctSheet );

    # display the coset tables and set all variables
    ItcDisplayCosetTable( ctSheet );

    # update all active relator tables and subgroup generator tables
    ItcUpdateDisplayedLists( ctSheet );

    # if there are pending coincidences display them
    if not ctSheet!.coincs = [] then
      ItcDisplayPendingCoincidences( ctSheet );
    fi;

    ItcEnableMenu( ctSheet );
  fi;

end );


#############################################################################
#
# ItcCosetStepFelsch( <ctSheet> )
#
# defines  a  new  coset   (applying  the  Felsch  strategy),   computes  all
# consequences, and displays the resulting tables.
#
InstallGlobalFunction( ItcCosetStepFelsch, function( ctSheet )

  if ctSheet!.firstDef <> 0 then

    # define a new coset
    ItcFastCosetStepFelsch( ctSheet );

    # give some information
    ItcRelabelInfoLine( ctSheet );

  fi;
end );


#############################################################################
#
# ItcCosetStepFill( <ctSheet>, <coset>, <gen> )
#
# defines  a new coset  to fill the given coset table position,  computes all
# consequences, and displays the resulting tables.
#
InstallGlobalFunction( ItcCosetStepFill, function( ctSheet, coset, gen )

  # define the new coset
  ItcFastCosetStepFill( ctSheet, coset, gen );

  # give some information
  ItcRelabelInfoLine( ctSheet );

end );


#############################################################################
#
# ItcDisplayButtons( <ctSheet>, <y> )
#
# display the headers and buttons in the window 'Interactive Todd-Coxeter'.
#
InstallGlobalFunction( ItcDisplayButtons, function( ctSheet, y )

  local bar, blue, charWidth, distance, gap, green, height, infoLine,
       ItcButton, lineHeight, red, width1, width4, width6, white, x, x1, x2,
       x3, x4, x5, x6, y1, y2, y3;

  ItcButton := function( x, y, width, string, color )
    local button;
    # get the four colored bars
    button := Box( ctSheet, x, y, width, bar, color );
    button := Box( ctSheet, x, y + height - bar, width, bar, color );
    button := Box( ctSheet, x, y, bar, height, color );
    button := Box( ctSheet, x + width - bar, y, bar, height, color );
    # get the black inner rectangle
    button := Rectangle( ctSheet, x + bar + 1, y + bar + 1,
      width - 2 * ( bar + 1 ), height - 2 * ( bar + 1 ) );
    # get the black outer rectangle
    button := Rectangle( ctSheet, x - 1, y - 1, width + 2, height + 2 );
    # insert the text string
    x := x + QuoInt( width - Length( string ) * charWidth + 1, 2 );
    y := y + lineHeight - QuoInt( distance - 1, 2 );
    Text( ctSheet, FONTS.normal, x, y, string );
    return button;
  end;

  # get some local variables
  distance := ctSheet!.normal.distance;
  lineHeight := ctSheet!.normal.lineHeight;
  charWidth := ctSheet!.normal.charWidth;
  gap := ctSheet!.normal.gap;
  if distance < 3 then
    bar := distance - 2;
  else
    bar := distance - 1;
  fi;
  blue := rec( color := COLORS.blue );
  green := rec( color := COLORS.green );
  red := rec( color := COLORS.red );
  white := rec( color := COLORS.white );

  # define size and position of the buttons
  width1 := 10 * charWidth + 2 * distance;
  width4 := 12 * charWidth + 2 * distance;
  width6 := 7 * charWidth + 2 * distance;
  height := lineHeight + 2 * distance;
  x1 := gap;
  x2 := x1 + width1 + gap;
  x3 := x2 + width1 + gap;
  x4 := x3 + width1 + gap;
  x5 := x4 + width4 + gap;
  x6 := x5 + width4 + gap;
  y1 := y + gap;
  y2 := y1 + height + gap;
  y3 := y2 + height + gap;

  # define the buttons in the first column
  ctSheet!.scrollto := ItcButton( x1, y1, width1, "scroll to", blue );
  ctSheet!.scrollby := ItcButton( x1, y2, width1, "scroll by", blue );
  ctSheet!.backto := ItcButton( x1, y3, width1, "back to", green );

  # define the buttons in the second column
  ctSheet!.felsch := ItcButton( x2, y1, width1, "Felsch", green );
  ctSheet!.hlt := ItcButton( x2, y2, width1, "HLT", green );
  ctSheet!.sortdefs := ItcButton( x2, y3, width1, "sort defs", green );

  # define the buttons in the third column
  ctSheet!.fillgaps := ItcButton( x3, y1, width1, "fill gaps", green );
  ctSheet!.fillrows := ItcButton( x3, y2, width1, "fill rows", green );
  ctSheet!.shortcut := ItcButton( x3, y3, width1, "short-cut", green );

  # define the buttons in the fourth column
  ctSheet!.showrels := ItcButton( x4, y1, width4, "show rels", white );
  ctSheet!.showdefs := ItcButton( x4, y2, width4, "show defs", white );
  ctSheet!.showcoincs := ItcButton( x4, y3, width4, "show coincs", white );

  # define the buttons in the fifth column
  ctSheet!.showsubgrp := ItcButton( x5, y1, width4, "show subgrp", white );
  ctSheet!.showgaps := ItcButton( x5, y2, width4, "show gaps", white );
  ctSheet!.mark := ItcButton( x5, y3, width4, "mark cosets", white );

  # define the buttons in the sixth column
  ctSheet!.clear := ItcButton( x6, y1, width6, "clear", red );
  ctSheet!.reset := ItcButton( x6, y2, width6, "reset", red );
  ctSheet!.quitt := ItcButton( x6, y3, width6, "quit", red );

end );


#############################################################################
#
# ItcDisplayCosetTable( <ctSheet> )
#
# displays the coset tables in the window 'Interactive Todd-Coxeter'.
#
InstallGlobalFunction( ItcDisplayCosetTable, function( ctSheet )

  local alives, black, c, charWidth, color, coset, digits, distance, entry,
        first, green, i, j, lastline, line0, line1, lineHeight, marked,
        nalive, ncols, newtab, nlines, ndefs, oldrow, oldtab, px, py, red,
        renumbered, row, str, t, w, y;

  # get some local variables
  ncols := ctSheet!.ncols;
  newtab := ctSheet!.newtab;
  oldtab := ctSheet!.oldtab;
  ndefs := ctSheet!.ndefs;
  marked := ctSheet!.marked;
  renumbered := ctSheet!.renumbered;
  alives := ctSheet!.alives;
  nalive := Length( alives );
  first := ctSheet!.first;
  str := ctSheet!.digitString2;
  black := rec( color := COLORS.black );
  green := rec( color := COLORS.green );
  red := rec( color := COLORS.red );

  # get the character width and some other variables to display the table
  digits := ctSheet!.digits;
  distance := ctSheet!.small.distance;
  lineHeight := ctSheet!.small.lineHeight;
  charWidth := ctSheet!.small.charWidth;
  y := 3 * distance;
  w := ( digits + 2 ) * charWidth;

  # check the first line to be printed for being in range
  while first > ndefs or renumbered[first] = 0 do
    first := first - 1;
  od;
  line1 := Minimum( renumbered[first], nalive );
  if line1 < 1 then
    line1 := 1;
  fi;
  first := alives[line1];
  lastline := Minimum( line1 + 29, nalive );
  line0 := line1 - 1;

  # get the table and delete the old values
  t := Flat( ctSheet!.graphicTable );
  for i in [ 1 .. Length( t ) ] do
    Delete ( t[i] );
  od;
  if IsBound( ctSheet!.line ) then
    Delete( ctSheet!.line );
  fi;

  # delete the first column
  c := Flat( ctSheet!.firstCol );
  for i in [ 1 .. Length( c ) ] do
    Delete( c[i] );
  od;

  # display a vertical line
  nlines := lastline - line1 + 1;
  ctSheet!.line := Line( ctSheet, w + charWidth, y, 0,
    distance + ( nlines + 1 ) * lineHeight );

  # display the numbers in the first column
  FastUpdate( ctSheet, true );
  ctSheet!.firstCol := [];
  px := - charWidth;
  if nalive <> 1 then
    for i in [ line1 .. lastline ] do
      py := y + (i - line0 + 1) * lineHeight;
      ctSheet!.firstCol[i - line0] :=
        Text( ctSheet, FONTS.small, px, py, str[alives[i]+2] );
    od;
  elif ctSheet!.first = 1 then
    py := y + 2 * lineHeight;
    ctSheet!.firstCol[1] := Text( ctSheet, FONTS.small, px, py, str[3] );
  fi;

  # display the numbers
  t := [];
  for i in [ 1 .. nlines ] do
    coset := alives[line0 + i];
    row := newtab[coset];
    oldrow := oldtab[coset];
    t[i] := [];
    px := 0;
    for j in [ 1 .. ncols ] do
      px := px + w;
      py := y + (i + 1) * lineHeight;
      color := black;
      entry := row[j];
      if entry > 0 then
        if entry in marked then
          color := green;
        elif entry <> oldrow[j] then
          color := red;
        fi;
      elif entry < 0 and entry <> oldrow[j] then
        color := red;
      fi;
      t[i][j] := Text( ctSheet, FONTS.small, px, py, str[entry+2], color );
    od;
  od;
  FastUpdate( ctSheet, false );

  # save the table
  ctSheet!.first := first;
  ctSheet!.nlines := nlines;
  ctSheet!.graphicTable := t;

  # recolor the rows which belong to pending cosets
  ItcRecolorPendingCosets( ctSheet );
  # mark definitions in the coset table
  ItcRecolorDefs( ctSheet );

  # update the info line
  ItcRelabelInfoLine( ctSheet );

  ctSheet!.isActual := true;
end );


#############################################################################
#
# ItcDisplayDefinition( <ctSheet>, <coset> )
#
# installs the  methods for the right pointer button in the definitions list.
#
InstallGlobalFunction( ItcDisplayDefinition, function( ctSheet, coset )

  local charWidth, distance, height, length, lineHeight, name, pos, repLists,
        repNums, repSheets, sheet, string, width;

  # get some local variables
  distance := ctSheet!.normal.distance;
  lineHeight := ctSheet!.normal.lineHeight;
  charWidth := ctSheet!.normal.charWidth;
  repLists := ctSheet!.repLists;
  repNums := repLists[1];
--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.43 Sekunden  (vorverarbeitet)  ]