\Chapter{Graphic Posets} This chapter describes the part of {\XGAP} that allows the user to conveniently display posets graphically. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Introduction} A poset is just a partially ordered set. To display posets reasonably in a generic way we need additional structure. So for {\XGAP} a poset comes in so called levels. At all times in the life of a graphic poset there are only finitely many levels and they are totally ordered, that is for two levels we can always say, which one is ``higher''. The position within the graphic sheet reflects this ordering. The levels are parametrized by ``level parameters'', which can be any {\GAP} object but must be unique within a graphic poset. A level is always accessed by its level parameter and *not* by its number! The vertices in each level are grouped into classes. For example for graphic subgroup lattices vertices in the same class correspond to conjugate subgroups, vertices in the same level have the same size or index in the whole group. The classes within each level are parametrized by ``class parameters'', which can be any {\GAP} object but must be unique within a level. A class within a level is always accessed by its class parameter and *not* by its number! The user must supply a *partial order* for all of his levels. The mechanism to achieve this is the operation `CompareLevels', which compares two level parameters. The current *total order* of the levels is always a refinement of the partial order. The user can permute levels, if that does not contradict the partial order defined by `CompareLevels'. A vertex in the poset that is ``contained in'' another vertex in the poset order (we speak of ``inclusion'' like in the case of subgroup lattices) must always be in a level that is lower on the screen, because there is only a connecting line representing the inclusion. This is achieved by the fact, that inclusions of vertices are communicated to {\XGAP} just by creating an ``edge'' between them. This means, that the vertex in the ``lower'' level lies in the vertex in the ``higher'' level. There must not be edges between vertices in the same level! The terminology ``vertices'' and ``edges'' comes from the fact, that a graphic poset is just a special case of a graphic graph, where vertices can be placed anywhere in the sheet and edges have nothing to do with inclusion. It is planned that also a graphic graph library is implemented in {\XGAP} but it is not yet operational. However everything which could be done not only for posets but at the same time for graphs is implemented already within the poset package. This explains the usage of ``graph'' in many places where you would otherwise expect ``poset''. What you have to do to use the graphic poset package is create a graphic poset (a special instance of a graphic sheet), create some levels and perhaps classes within them. Then you can create vertices and edges, to encode the ordering. Everything else is done by the library. See the next section for details about the available operations. Note that we chose a functional approach for certain decision procedures. This means that for example if you create a vertex and do not specify a position, an operation (`ChoosePosition') is called to determine the actual position. You can use the generic routines or install your own methods for all of those decisions. In this case you just set a new filter for your posets and overload the generic methods by special routines for objects with your new filter set. You can see this approach in the example in "An Example". %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Operations} *Constructors:* \medskip% \Declaration{GraphicPoset} \Declaration{CreateLevel} \Declaration{CreateClass} \Declaration{Vertex}[poset] \Declaration{Edge} *Destructors:* \medskip% \>Delete( <poset>, <vertex1>, <vertex2> )!{for edge in poset} \>Delete( <poset>, <vertex1>)!{for vertex in poset} \>Delete( <poset>, <levelparam>, <classparam> )!{for class in poset} These three variants of the `Delete' operation delete an edge, a vertex and a class respectively. \Declaration{DeleteLevel} \medskip% *Operations to change a poset:* \medskip% \Declaration{ResizeLevel} \Declaration{MoveLevel} \Declaration{Relabel}[poset] \Declaration{Move}[poset] \Declaration{Reshape}[poset] \Declaration{Recolor}[poset] \Declaration{SetWidth}[poset] \Declaration{Highlight}[poset] \Declaration{Select} \Declaration{DeselectAll} \Declaration{Selected} \medskip% *Operations for decisions:* \medskip% \Declaration{ChooseLabel} \Declaration{ChooseLevel} \Declaration{ChooseClass} \Declaration{ChooseColor} \Declaration{ChooseHighlight} \Declaration{ChoosePosition} \Declaration{ChooseShape} \Declaration{ChooseWidth} \Declaration{CompareLevels} \medskip% *Operations to get information:* \medskip% \Declaration{WhichLevel} \Declaration{WhichClass} \Declaration{WhichVertex} \Declaration{WhichVertices} \Declaration{Levels} \Declaration{Classes} \Declaration{Vertices} \Declaration{Maximals} \Declaration{MaximalIn} \Declaration{PositionLevel} \medskip% *Operations for user communication:* \medskip% \Declaration{Menu}[poset] \Declaration{ModifyEnabled} \Declaration{InstallPopup} \Declaration{PosetLeftClick} \Declaration{PosetCtrlLeftClick} \Declaration{PosetRightClick} \medskip% *Operations for user actions:* \medskip% \Declaration{UserDeleteVerticesOp} \Declaration{UserDeleteEdgeOp} \Declaration{UserMergeClassesOp} \Declaration{UserMagnifyLattice} \Declaration{UserShrinkLattice} \Declaration{UserResizeLattice} \Declaration{UserResizeSheet} \Declaration{UserMoveLattice} \Declaration{UserChangeLabels} \Declaration{UserAverageY} \Declaration{UserAverageX} \Declaration{UserRearrangeClasses} \Declaration{UserUseBlackWhite} \Declaration{PosetShowLevels} \Declaration{PosetShowLevelparams} \Declaration{DoRedraw} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{An Example} This section shows how to use the poset package to display posets. The code presented here is actually part of the {\XGAP} library and makes up the link to the C MeatAxe. This is the declaration part: \begintt ############################################################################# ## #W meataxe.gd XGAP library Max Neunhoeffer ## #Y Copyright 1998, Max Neunhoeffer, Aachen, Germany ## ## This file contains declarations for MeatAxe posets ## DeclareFilter("IsMeatAxeLattice"); ############################################################################# ## #O GraphicMeatAxeLattice(<name>, <width>, <height>) . creates graphic poset ## ## creates a new graphic MeatAxe lattice which is a specialization of a ## graphic poset. Those posets have a new filter for method selection. ## DeclareOperation("GraphicMeatAxeLattice",[IsString, IsInt, IsInt]); \endtt The code only declares a new filter and declares a constructor operation for posets that lie in this new filter. The implementation: \begintt ############################################################################# ## #W meataxe.gi XGAP library Max Neunhoeffer ## #Y Copyright 1998, Max Neunhoeffer, Aachen, Germany ## ## This file contains code for MeatAxe posets ## ############################################################################# ## #M GraphicMeatAxeLattice(<name>, <width>, <height>) . creates graphic poset ## ## creates a new graphic MeatAxe lattice which is a specialization of a ## graphic poset. Those posets have a new filter for method selection. ## InstallMethod( GraphicMeatAxeLattice, "for a string, and two integers", true, [ IsString, IsInt, IsInt ], 0, function( name, width, height ) local P; P := GraphicPoset(name,width,height); SetFilterObj(P,IsMeatAxeLattice); return P; end); ############################################################################# ## #M CompareLevels(<poset>,<levelparam1>,<levelparam2>) . . . . . . . . . . . ## . . . . . . . . . . . . . . . . . . . . . . . . compares two levelparams ## ## Compare two level parameters. -1 means that <levelparam1> is "higher", ## 1 means that <levelparam2> is "higher", 0 means that they are equal. ## fail means that they are not comparable. This method is for the case ## if level parameters are integers and lower values mean lower levels ## like in the case of MeatAxe lattices of Michael Ringe. ## InstallMethod( CompareLevels, "for a graphic MeatAxe lattice, and two integers", true, [ IsGraphicPosetRep and IsMeatAxeLattice, IsInt, IsInt ], 0, function( poset, l1, l2 ) if l1 < l2 then return 1; elif l1 > l2 then return -1; else return 0; fi; end); \endtt Besides the new constructor (which only adds a new filter) we only have to supply a new method for comparison of level parameters for such posets. The levels are numbered with integer numbers such that lower numbers are lower in the lattice. There is a C program in the MeatAxe that exports a poset to a {\GAP} program which generates the lattice in a graphic poset sheet. The user can then interactively move around vertices and shrink or magnify levels. He can then export the resulting lattice to an encapsulated postscript file. Note that you need a full installation of the C MeatAxe apart from {\GAP} to use this feature. Another nice little example is in the `examples' subdirectory in the {\XGAP} distribution. It was written by Thomas Breuer (Aachen) to demonstrate the features of {\XGAP}. The user gets a small window with a puzzle and can solve it using the mouse. You can test this example by starting {\XGAP} and `Read'ing the file `pkg/xgap/examples/puzzle.g'. You can do this by using \begintt gap> ReadPkg("xgap","examples/puzzle.g"); gap> p := Puzzle(4,4); \endtt