Quelle quiver.gi
Sprache: unbekannt
|
|
# GAP Implementation
# This file was generated from
# $Id: quiver.gi,v 1.5 2012/06/09 07:51:54 sunnyquiver Exp $
InstallGlobalFunction(
Path,
function( arg )
local path, vertex_name, u, v, arrow_name, arrow_list;
# single vertex name
if Length( arg ) = 2 and IsFamily( arg[1] ) and IsString( arg[2] ) then
vertex_name := arg[2];
path:= Objectify( NewType( arg[1],
IsQuiverVertex and IsQuiverVertexRep and IsAttributeStoringRep ),
rec( vertex_name := vertex_name ) );
SetSourceOfPath( path, path );
SetTargetOfPath( path, path );
SetLengthOfPath( path, 0 );
SetWalkOfPath( path, [] );
SetIsZeroPath( path, false );
SetIncomingArrowsOfVertex( path, [] );
SetOutgoingArrowsOfVertex( path, [] );
SetOutDegreeOfVertex( path, 0 );
SetInDegreeOfVertex( path, 0 );
SetNeighborsOfVertex( path, [] );
return path;
# arrow from two vertices
elif Length( arg ) = 4 and IsFamily( arg[1]) and IsQuiverVertex( arg[2] )
and IsQuiverVertex( arg[3] ) and IsString( arg[4] ) then
u := arg[2];
v := arg[3];
arrow_name := arg[4];
path:= Objectify( NewType( arg[1],
IsArrow and IsArrowRep and IsAttributeStoringRep ),
rec( arrow_name := arrow_name ) );
SetSourceOfPath( path, u );
SetTargetOfPath( path, v );
SetLengthOfPath( path, 1 );
SetWalkOfPath( path, [ path ] );
SetIsZeroPath( path, false );
SetOutgoingArrowsOfVertex( u,
Concatenation( OutgoingArrowsOfVertex(u), [ path ] ) );
SetIncomingArrowsOfVertex( v,
Concatenation( IncomingArrowsOfVertex(v), [ path ] ) );
SetOutDegreeOfVertex( u, Length( OutgoingArrowsOfVertex(u) ) );
SetInDegreeOfVertex( v, Length( IncomingArrowsOfVertex(v) ) );
# Don't add neighbor more than once.
if not (v in NeighborsOfVertex(u)) then
SetNeighborsOfVertex( u, Concatenation(NeighborsOfVertex(u), [ v ]) );
fi;
return path;
# list of arrows
elif Length( arg ) = 2 and IsFamily( arg[1] ) and IsList( arg[2] ) then
arrow_list := arg[2];
return Product( arrow_list );
fi;
# no argument given, error
Error("usage: Path(<Fam>, <vertex_name>), \
(<Fam>, <U>, <V>, <arrow_name>), (<Fam>, < [ A1, A2, ... ] >)");
end
);
InstallMethod(ExtRepOfObj,
"for zero paths",
true, [IsZeroPath], 0,
P -> [0]
);
InstallMethod(ExtRepOfObj,
"for vertices",
true, [IsQuiverVertex], 0,
V -> [V!.gen_pos]
);
InstallMethod(ExtRepOfObj,
"for paths",
true, [IsPath], 0,
function(P)
local g, rep;
rep := [];
for g in WalkOfPath(P) do
Add(rep, g!.gen_pos);
od;
return rep;
end
);
InstallMethod( ObjByExtRep,
"for quiver elements family and lists",
true,
[IsPathFamily, IsList], 0,
function( Fam, descr )
local Q, gens, walk;
Q := Fam!.quiver;
gens := GeneratorsOfQuiver(Q);
walk := List( descr, function(i)
if i <> 0 then
return gens[i];
else
return Zero(Q);
fi;
end );
return Product(walk);
end
);
InstallMethod( \*,
"for vertices",
IsIdenticalObj,
[ IsQuiverVertex, IsQuiverVertex ], 0,
function( u, v )
if( IsIdenticalObj(u, v) ) then
return u;
else
return Zero(FamilyObj(u));
fi;
end
);
InstallMethod( \*,
"for a vertex and a path",
IsIdenticalObj,
[ IsQuiverVertex, IsPath ], 0,
function( vert, path )
if( IsIdenticalObj(vert, SourceOfPath(path)) ) then
return path;
else
return Zero(FamilyObj(vert));
fi;
end
);
InstallMethod( \*,
"for a path and a vertex",
IsIdenticalObj,
[ IsPath, IsQuiverVertex ], 0,
function( path, vert )
if( IsIdenticalObj(TargetOfPath(path), vert) ) then
return path;
else
return Zero(FamilyObj(path));
fi;
end
);
InstallMethod( \*,
"for the ZeroPath and a path",
IsIdenticalObj,
[ IsZeroPath, IsPath ], 0,
function( zero, path )
return zero;
end
);
InstallMethod( \*,
"for a path and the ZeroPath",
IsIdenticalObj,
[ IsPath, IsZeroPath ], 0,
function( path, zero )
return zero;
end
);
InstallMethod( \*,
"for a path and a path",
IsIdenticalObj,
[ IsPath, IsPath ], 0,
function( path1, path2 )
local result;
if( IsIdenticalObj(TargetOfPath(path1), SourceOfPath(path2) ) ) then
result:= Objectify( NewType( FamilyObj(path1),
IsPath and IsAttributeStoringRep ),
rec() );
SetSourceOfPath( result, SourceOfPath(path1) );
SetTargetOfPath( result, TargetOfPath(path2) );
SetLengthOfPath( result, LengthOfPath(path1) + LengthOfPath(path2) );
SetWalkOfPath( result,
Concatenation( WalkOfPath(path1), WalkOfPath(path2) ) );
SetIsZeroPath( result, false );
return result;
else
return Zero(FamilyObj(path1));
fi;
end
);
InstallMethod( \=,
"for vertices",
IsIdenticalObj,
[ IsQuiverVertex, IsQuiverVertex ], 0,
function( u, v )
return IsIdenticalObj(u, v);
end
);
InstallMethod( \=,
"for arrows",
IsIdenticalObj,
[ IsArrow, IsArrow ], 0,
function( a, b )
return IsIdenticalObj(a, b);
end
);
InstallMethod( \=,
"for the ZeroPath and the ZeroPath",
IsIdenticalObj,
[ IsZeroPath, IsZeroPath ], 0,
function( a, b )
return true;
end
);
InstallMethod( \=,
"for the ZeroPath and a path",
IsIdenticalObj,
[ IsZeroPath, IsPath ], 0,
function( a, b )
return false;
end
);
InstallMethod( \=,
"for a path and the ZeroPath",
IsIdenticalObj,
[ IsPath, IsZeroPath ], 0,
function( a, b )
return false;
end
);
InstallMethod( \=,
"for path",
IsIdenticalObj,
[ IsPath, IsPath ], 0,
function( p1, p2 )
if( not IsIdenticalObj(SourceOfPath(p1) , SourceOfPath(p2)) ) then
return false;
elif( not IsIdenticalObj(SourceOfPath(p1), SourceOfPath(p2)) ) then
return false;
elif( LengthOfPath(p1) <> LengthOfPath(p2)) then
return false;
else
return WalkOfPath(p1) = WalkOfPath(p2);
fi;
end
);
InstallMethod( \<, "for paths",
IsIdenticalObj,
[IsPath, IsPath], 0,
function(p, q)
local O;
if IsZeroPath(p) and not IsZeroPath(q) then
return true;
elif (IsZeroPath(q) and not IsZeroPath(p)) or (p = q) then
return false;
else
O := OrderingOfQuiver(FamilyObj(p)!.quiver);
return LessThanByOrdering(O, p, q);
fi;
end
);
InstallMethod( PrintObj,
"for ZeroPath",
true,
[ IsZeroPath ], 0,
function( obj )
Print( "0" );;
end
);
InstallMethod( String,
"for vertex",
true,
[ IsQuiverVertex and IsQuiverVertexRep ], 0,
function( obj )
return obj!.vertex_name;
end
);
InstallMethod( PrintObj,
"for vertex",
true,
[ IsQuiverVertex and IsQuiverVertexRep ], 0,
function( obj )
Print( obj!.vertex_name );
end
);
InstallMethod( String,
"for arrow",
true,
[ IsArrow and IsArrowRep ], 0,
function( obj )
return obj!.arrow_name;
end
);
InstallMethod( PrintObj,
"for arrow",
true,
[ IsArrow and IsArrowRep ], 0,
function( obj )
Print( obj!.arrow_name );
end
);
InstallMethod( PrintObj,
"for paths of length > 1",
true,
[ IsPath ], 0,
function( obj )
local walk, i, l, exponent;
walk := WalkOfPath(obj);
l := Length(walk);
Print(walk[1]);
exponent := 1;
for i in [2..l] do
if walk[i] <> walk[i-1] then
if exponent > 1 then
Print("^", exponent);
fi;
Print("*", walk[i]);
exponent := 1;
else
exponent := exponent + 1;
fi;
od;
if exponent > 1 then
Print("^", exponent);
fi;
end
);
InstallGlobalFunction( Quiver,
function( arg )
local temp, vertices, arrows, vertices_by_name, arrow_spec_size,
name, u, v, i, j, k, msg, arrow_count, Q,
matrix, record, Fam, zero, frompos, topos;
vertices := [];
arrows := [];
# Create a new family for paths in this quiver.
Fam := NewFamily( Concatenation( "FamilyOfPathsWithin", UniqueQuiverName() ), IsPath );
SetFilterObj( Fam, IsPathFamily );
zero := Objectify( NewType( Fam, IsPath and IsAttributeStoringRep ), rec() );
SetIsZeroPath( zero, true );
SetSourceOfPath( zero, zero );
SetTargetOfPath( zero, zero );
SetZero(Fam, zero);
temp := 0;
# Quiver(N, [arrow_spec])
if Length( arg ) = 2 and IsPosInt( arg[1] ) and IsList( arg[2] ) then
matrix := [];
for i in [ 1 .. arg[1] ] do
name := Concatenation( "v", String(i) );
vertices[i] := Path( Fam, name );
matrix[i] := [];
for j in [ 1 .. arg[1] ] do
matrix[i][j] := 0;
od;
od;
if( Length( arg[2] ) > 0 ) then
arrow_spec_size := Length( arg[2][1] );
else
arrow_spec_size := -1;
fi;
for i in [ 1 .. Length(arg[2]) ] do
if( not Length( arg[2][i] ) = arrow_spec_size ) then
Error("All of the entries in the [arrow_spec] list must be of the same size.");
return 0;
fi;
if( not IsPosInt( arg[2][i][1] ) or not IsPosInt( arg[2][i][2]) ) then
Error("You must use vertex numbers in arrow_spec \
when using Quiver( <N>, <Arrow_spec> ).");
return 0;
fi;
frompos := arg[2][i][1];
topos := arg[2][i][2];
matrix[frompos][topos] := matrix[frompos][topos] + 1;
u := vertices[ frompos ];
v := vertices[ topos ];
if( arrow_spec_size = 3 ) then
name := arg[2][i][3];
else
name := Concatenation( "a", String(i) );
fi;
arrows[i] := Path( Fam, u, v, name );
od;
temp := 1;
for i in [1..Length(arg[2])] do
if String(arrows[i]) <> [CharInt(i+96)] then
temp := 0;
break;
fi;
od;
# Quiver([vertex_name, ...], [arrow_spec, ...])
elif Length( arg ) = 2 and IsList( arg[1] ) and IsList( arg[2] ) then
matrix := [];
for i in [ 1 .. Length( arg[1] ) ] do
vertices[i] := Path( Fam, arg[1][i] );
matrix[i] := [];
for j in [ 1 .. Length( arg[1] ) ] do
matrix[i][j] := 0;
od;
od;
if( Length( arg[2] ) > 0 ) then
arrow_spec_size := Length( arg[2][1] );
vertices_by_name := not IsPosInt( arg[2][1][1] );
fi;
for i in [ 1 .. Length(arg[2]) ] do
if( not Length( arg[2][i] ) = arrow_spec_size ) then
Error("All of the entries in the [arrow_spec] list must be of the same size.");
return 0;
fi;
if( vertices_by_name ) then
j := Position( arg[1], arg[2][i][1] );
if(j = fail) then
msg := "Cannot find vertex: ";
Append( msg, arg[2][i][1]);
Append( msg, " in the list of vertices:\n");
Append( msg, String( arg[1] ) );
Error( msg );
return 0;
fi;
frompos := j;
u := vertices[ j ];
j := Position( arg[1], arg[2][i][2] );
if(j = fail) then
msg := "Cannot find vertex: ";
Append( msg, arg[2][i][2]);
Append( msg, " in the list of vertices:\n");
Append( msg, String( arg[1] ) );
Error( msg );
return 0;
fi;
topos := j;
v := vertices[ j ];
matrix[frompos][topos] := matrix[frompos][topos] + 1;
else
frompos := arg[2][i][1];
topos := arg[2][i][2];
u := vertices[ frompos ];
v := vertices[ topos ];
matrix[frompos][topos] := matrix[frompos][topos] + 1;
fi;
if( arrow_spec_size = 3 ) then
name := arg[2][i][3];
else
name := Concatenation( "a", String(i) );
fi;
arrows[i] := Path( Fam, u, v, name );
od;
# Quiver(adj_matrix)
elif Length( arg ) = 1 and IsMatrix( arg[1] ) then
matrix := arg[1];
for i in [ 1 .. Length( matrix ) ] do
name := Concatenation( "v", String(i) );
vertices[i] := Path( Fam, name );
od;
arrow_count := 0;
for i in [ 1 .. Length( matrix ) ] do
if( not Length( matrix ) = Length( matrix[i] ) ) then
Error("The adjacency matrix must be square.");
return 0;
fi;
for j in [ 1 .. Length( matrix[i] ) ] do
for k in [ 1 .. matrix[i][j] ] do
arrow_count := arrow_count + 1;
u := vertices[i];
v := vertices[j];
name := Concatenation( "a", String(arrow_count) );
arrows[arrow_count] := Path( Fam, u, v, name );
od;
od;
od;
else
# no argument given, error
Error("usage: Quiver(<N>, <[arrow_spec, ...]>), \
(<[vertex_name, ...]>, [arrow_spec, ...]>), (<adj_matrix>)");
fi;
record := rec();
for i in vertices do
record.( String(i) ) := i;
od;
for i in arrows do
record.( String(i) ) := i;
od;
if temp = 1 then
Q:= Objectify( NewType( CollectionsFamily(Fam),
IsQuiverSA and IsQuiverRep and IsAttributeStoringRep ),
rec( pieces := record ) );
else
Q:= Objectify( NewType( CollectionsFamily(Fam),
IsQuiverRep and IsAttributeStoringRep ),
rec( pieces := record ) );
fi;
Fam!.quiver := Q;
SetVerticesOfQuiver( Q, vertices );
SetArrowsOfQuiver( Q, arrows );
SetNumberOfVertices( Q, Length( vertices ) );
SetNumberOfArrows( Q, Length( arrows ) );
SetGeneratorsOfMagma( Q, Concatenation( vertices, arrows ) );
SetAdjacencyMatrixOfQuiver( Q, matrix );
SetIsWholeFamily(Q, true);
SetIsAssociative(Q, true);
# This is used to construct the external representations of elements
for i in [1..Length(GeneratorsOfMagma(Q))] do
GeneratorsOfMagma(Q)[i]!.gen_pos := i;
od;
SetOrderingOfQuiver( Q,
LengthOrdering(Q,LeftLexicographicOrdering(Q,GeneratorsOfMagma( Q )))
);
SetZero(Q, zero);
return Q;
end
);
InstallMethod( \.,
"for a quiver",
true,
[ IsQuiver, IsPosInt ], 0,
function( Q, nam )
return Q!.pieces.( NameRNam(nam) );
end
);
GlobalQuiverCount := 0;
InstallGlobalFunction( UniqueQuiverName,
function( arg )
GlobalQuiverCount := GlobalQuiverCount + 1;
return Concatenation( "Quiver_", String(GlobalQuiverCount) );
end
);
InstallMethod( OrderedBy,
"for a quiver and an ordering",
true,
[IsQuiver, IsQuiverOrdering], 0,
function(Q, O)
local Fam, new_vertices, new_arrows, new_Q, v, a, new_v, new_a,
record, zero;
# Create a new family for paths in this quiver.
Fam := NewFamily( Concatenation( "FamilyOfPathsWithin", UniqueQuiverName() ), IsPath );
SetFilterObj( Fam, IsPathFamily );
zero := Objectify( NewType( Fam, IsPath and IsAttributeStoringRep ), rec() );
SetIsZeroPath( zero, true );
SetSourceOfPath( zero, zero );
SetTargetOfPath( zero, zero );
SetZero(Fam, zero);
new_vertices := [];
for v in VerticesOfQuiver(Q) do
new_v := Path(Fam, v!.vertex_name);
new_v!.gen_pos := v!.gen_pos;
Add(new_vertices, new_v);
od;
new_arrows := [];
for a in ArrowsOfQuiver(Q) do
new_a := Path(Fam, new_vertices[SourceOfPath(a)!.gen_pos],
new_vertices[TargetOfPath(a)!.gen_pos],
a!.arrow_name);
new_a!.gen_pos := a!.gen_pos;
Add(new_arrows, new_a);
od;
record := rec();
for v in new_vertices do
record.( String(v) ) := v;
od;
for a in new_arrows do
record.( String(a) ) := a;
od;
new_Q:= Objectify( NewType( CollectionsFamily(Fam),
IsQuiverRep and IsAttributeStoringRep ),
rec( pieces := record ) );
Fam!.quiver := new_Q;
SetVerticesOfQuiver( new_Q, new_vertices );
SetArrowsOfQuiver( new_Q, new_arrows );
SetNumberOfVertices( new_Q, Length( new_vertices ) );
SetNumberOfArrows( new_Q, Length( new_arrows ) );
SetGeneratorsOfMagma( new_Q, Concatenation( new_vertices, new_arrows ) );
SetAdjacencyMatrixOfQuiver( new_Q, AdjacencyMatrixOfQuiver(Q) );
SetOrderingOfQuiver( new_Q, O );
SetZero(new_Q, zero);
SetIsWholeFamily(new_Q, true);
return new_Q;
end
);
InstallMethod( IsFinite,
"for quivers",
true,
[ IsQuiver ], 0,
IsAcyclicQuiver
);
InstallMethod( Size,
"for quivers",
true,
[IsQuiver], 0,
function(Q)
local tsorted, node, arrow, count, nodeNum, child, childNum, total;
if IsFinite(Q) then
count := [];
total := 1; # for 0 element
tsorted := Q!.tsorted;
for node in tsorted do
count[ExtRepOfObj(node)[1]] := 0;
od;
for node in tsorted do
nodeNum := ExtRepOfObj(node)[1];
for arrow in OutgoingArrowsOfVertex(node) do
child := TargetOfPath(arrow);
childNum := ExtRepOfObj(child)[1];
# Add one for the arrow
count[childNum] := count[childNum] + count[nodeNum] + 1;
od;
total := total + count[nodeNum] + 1; # One for the vertex
od;
return total;
else
return infinity;
fi;
end
);
InstallMethod( Iterator,
"method for quivers",
true,
[ IsQuiver ], 0,
function( Q )
local iter;
iter := Objectify( NewType( IteratorsFamily,
IsIterator and IsMutable and IsQuiverIteratorRep ),
rec( quiver := Q, position := 0 ) );
return iter;
end
);
InstallMethod( Enumerator,
"method for quivers",
true,
[ IsQuiver ], 0,
function( Q )
local enum;
enum := Objectify( NewType( FamilyObj( Q ), IsQuiverEnumerator ),
rec( quiver := Q ) );
return enum;
end
);
InstallMethod( IsDoneIterator,
"method for iterator of quivers",
true,
[ IsIterator and IsMutable and IsQuiverIteratorRep ], 0,
function( iter )
return iter!.position = [];
end
);
InstallMethod( NextIterator,
"method for iterator of quivers",
true,
[ IsIterator and IsMutable and IsQuiverIteratorRep ], 0,
function( iter )
local next;
next := NextPath( iter!.quiver, iter!.position );
if( next = fail ) then
return fail;
else
iter!.position := next[2];
return next[1];
fi;
end
);
InstallMethod( \[\],
true,
[ IsQuiverEnumerator, IsPosInt ],
0,
function( enum, number )
local i, pos, res;
i := 0;
pos := 0;
for i in [1..number] do
res := NextPath(enum!.quiver, pos);
if res = fail then
return fail;
fi;
pos := res[2];
od;
return res[1];
end
);
InstallMethod( NextPath,
"helper method for iterator and enumerator of quivers",
true,
[ IsQuiver, IsObject ], 0,
function( Q, list )
local current_position, res, next_arrow;
current_position := ShallowCopy( list );
if current_position = 0 then
current_position := ShallowCopy( VerticesOfQuiver(Q) );
fi;
if current_position = [] then
return fail;
fi;
for next_arrow in OutgoingArrowsOfVertex( TargetOfPath(current_position[1]) ) do
Add(current_position, current_position[1]*next_arrow);
od;
res := current_position[1];
Remove(current_position, 1);
return [res, current_position];
end
);
InstallMethod( ViewObj,
"for quiver",
true,
[ IsQuiver ], NICE_FLAGS + 1,
function( Q )
Print( "<quiver with " );
Print( NumberOfVertices(Q) );
Print( " vertices and " );
Print( NumberOfArrows(Q) );
Print( " arrows>" );
end
);
InstallMethod( PrintObj,
"for quiver",
true,
[ IsQuiverRep ], 0,
function( Q )
local i, first;
Print( "Quiver( [" );
first := true;
for i in VerticesOfQuiver(Q) do
if( not first ) then
Print(",");
fi;
Print("\"");
Print( i );
Print( "\"");
first := false;
od;
Print( "], [" );
first := true;
for i in ArrowsOfQuiver(Q) do
if( not first ) then
Print(",");
fi;
Print( "[\"" );
Print( SourceOfPath(i) );
Print( "\",\"" );
Print( TargetOfPath(i) );
Print( "\",\"" );
Print( i );
Print( "\"]" );
first := false;
od;
Print( "] )" );
end
);
InstallMethod( QuiverContainingPath,
"for a path",
[ IsPath ],
function( p )
return FamilyObj( p )!.quiver;
end );
InstallMethod( VertexIndex,
"for a vertex",
true,
[ IsQuiverVertex ],
function( v )
return v!.gen_pos;
end );
InstallMethod( ArrowIndex,
"for an arrow",
true,
[ IsArrow ],
function( a )
return a!.gen_pos - Length( VerticesOfQuiver( QuiverContainingPath( a ) ) );
end );
InstallMethod( GeneratorIndex,
"for a vertex",
true,
[ IsQuiverVertex ],
function( v )
return v!.gen_pos;
end );
InstallMethod( GeneratorIndex,
"for an arrow",
true,
[ IsArrow ],
function( a )
return a!.gen_pos;
end );
InstallMethod( OppositeQuiver,
"for a quiver",
[ IsQuiver ],
function( Q )
local op_name, deop_name, op_vertex, op_arrow, Q_op;
op_name :=
function( name )
return Concatenation( name, "_op" );
end;
deop_name :=
function( name )
return name{ [ 1 .. Length(name)-3 ] };
end;
op_vertex :=
function( v )
return op_name( String( v ) );
end;
op_arrow :=
function( a )
return [ op_vertex( TargetOfPath( a ) ),
op_vertex( SourceOfPath( a ) ),
op_name( String( a ) ) ];
end;
Q_op := Quiver( List( VerticesOfQuiver( Q ), op_vertex ),
List( ArrowsOfQuiver( Q ), op_arrow ) );
SetOppositeQuiver( Q_op, Q );
SetOppositeQuiverNameMap( Q, op_name );
SetOppositeQuiverNameMap( Q_op, deop_name );
return Q_op;
end );
InstallMethod( OppositePath,
"for a path",
[ IsPath ],
function( p )
local Q, Q_op, walk_names, walk_op, walk_op_names;
Q := QuiverContainingPath( p );
Q_op := OppositeQuiver( Q );
walk_names := List( WalkOfPathOrVertex( p ), String );
walk_op_names := List( Reversed( walk_names ), OppositeQuiverNameMap( Q ) );
walk_op := List( walk_op_names,
function( name ) return Q_op.( name ); end );
return Product( walk_op );
end );
InstallMethod( SeparatedQuiver,
"for a quiver",
true,
[ IsQuiver ],
0,
function( Q )
local oldarrows, vertices, arrows;
#
# Calling the vertices in the separated quiver for <label> and <label>', when
# <label> is the name of a vertex in the old quiver. For an arrow a : v ---> w
# in the quiver, we call the corresponding arrow v ---> w' also a in the
# separated quiver.
#
vertices := List(VerticesOfQuiver(Q), v -> String(v));
Append(vertices, List(vertices, v -> Concatenation(v,"'")));
oldarrows := ArrowsOfQuiver(Q);
arrows := List(oldarrows, a -> [String(SourceOfPath(a)),Concatenation(String(TargetOfPath(a)),"'"),String(a)]);
return Quiver(vertices,arrows);
end
);
##########################################################################
##
#O DeclearOperations( "DynkinQuiverAn", [ n, orientation ] )
##
## Returns the Dynkin quiver A_n with n vertices names 1, 2, 3,..., n,
## and arrows with names 1 -- a_1 -- 2 -- a_2 -- .... -- a_{n-1} -- n.
## The orientation is given by a list of l's and r's, ["r","l","l",...],
## where an l in coordinate i means that the i-th arrow is oriented
## to the left and an r means oriented to the right.
##
InstallMethod( DynkinQuiverAn,
"for a positive integer and a list",
[ IS_INT, IsList ],
function( n, orientation )
local vertices, arrows, i, Q;
if n <= 0 then
Error("the quiver must have at least one vertex,\n ");
fi;
if Length(orientation) > n - 1 then
Error("too many orientation parameters compared to the number of arrows,\n ");
fi;
if Length(orientation) < n - 1 then
Error("too few orientation parameters compared to the number of arrows,\n ");
fi;
if not IsSubset(Set(["l","r"]), Set(orientation)) then
Error("the orientation parameters are not in the set [\"l\",\"r\"],\n");
fi;
#
# Naming the verties and the arrows in A_n. The vertices are named
# "1", "2", "3", and so on. The arrows are named as follows
# 1 -- a_1 -- 2 -- a_2 -- 3 .... n - 1 -- a_{n-1} -- n
#
vertices := List([1..n], i -> String(i));
arrows := [];
for i in [1..n-1] do
if orientation[i] = "l" then
Add(arrows, [vertices[i+1], vertices[i], Concatenation("a_",String(i))]);
else
Add(arrows, [vertices[i], vertices[i+1], Concatenation("a_",String(i))]);
fi;
od;
Q := Quiver(vertices, arrows);
SetIsDynkinQuiver(Q, true);
return Q;
end
);
##########################################################################
##
#O DeclearOperations( "DynkinQuiverEn", [ n, orientation ] )
##
## Returns the Dynkin quiver E_n with n + 1 vertices, for n = 6, 7, 8,
## names 1, 2, 3,..., n + 1, and arrows with names
## n
## |
## a_{n-1}
## |
## 1 -- a_1 -- 2 -- a_2 -- 3 -- a_3 -- 4 -- a_4 -- .... -- a_{n-2} -- n - 1.
##
## The orientation is given by a list of n - 2 characters l's and r's
## for the orientation of the arrows {a_1, a_2,..., a_{n-2}} and one d
## or u for the orientation down or up for the arrow a_{n-1}, for instance,
## ["r","l","l",...,"r","d"],
## where an l in coordinate i means that the i-th arrow is oriented
## to the left and an r means oriented to the right.
##
InstallMethod( DynkinQuiverEn,
"for a positive integer and a list",
[ IS_INT, IsList ],
function( n, orientation )
local vertices, arrows, i, Q;
if not n in [6, 7, 8] then
Error("the entered value n is not 6, 7 or 8,\n");
fi;
if Length(orientation) > n - 1 then
Error("too many orientation parameters compared to the number of arrows,\n ");
fi;
if Length(orientation) < n - 1 then
Error("too few orientation parameters compared to the number of arrows,\n ");
fi;
if not IsSubset(Set(["l","r"]), Set(orientation{[1..n - 2]})) then
Error("the ",n - 1," first orientation parameters are not in the set [\"l\",\"r\"],\n");
fi;
if not orientation[n - 1] in Set(["d","u"]) then
Error("the last orientation parameter is not in the set [\"d\",\"u\"],\n");
fi;
#
# Naming the verties and the arrows in E_n. The vertices are named
# "1", "2", "3", and so on in the following way. The arrows are named as follows
# n
# |
# a_{n-1}
# |
# 1 -- a_1 -- 2 -- a_2 -- 3 -- a_3 -- 4 -- a_4 -- 5 .... -- a_{n-2} -- n - 1.
#
vertices := List([1..n], i -> String(i));
arrows := [];
for i in [1..n - 2] do
if orientation[i] = "l" then
Add(arrows, [vertices[i+1], vertices[i], Concatenation("a_",String(i))]);
else
Add(arrows, [vertices[i], vertices[i+1], Concatenation("a_",String(i))]);
fi;
od;
if orientation[n - 1] = "d" then
Add(arrows, [vertices[n], vertices[3], Concatenation("a_",String(n - 1))]);
else
Add(arrows, [vertices[3], vertices[n], Concatenation("a_",String(n - 1))]);
fi;
Q := Quiver(vertices, arrows);
SetIsDynkinQuiver(Q, true);
return Q;
end
);
##########################################################################
##
#O DeclearOperations( "DynkinQuiverDn", [ n, orientation ] )
##
## Returns the Dynkin quiver D_n with n vertices, for n >= 4, with
## names 4, 5, 6,..., n, and arrows with names
##
## 1
## \
## a_1
## \
## 3 -- a_3 -- 4 -- a_2 -- .... n - 1 -- a_{n-1} -- n.
## /
## a_2
## /
## 2
##
## The orientation is given by a list of n - 1 characters l's and r's for the
## orientation of the arrows {a_1, a_2,..., a_{n-1}}, for instance,
## ["r","l","l",...,"r"], where an l in coordinate i means that the
## i-th arrow is oriented to the left and an r means oriented to the right.
##
InstallMethod( DynkinQuiverDn,
"for a positive integer and a list",
[ IS_INT, IsList ],
function( n, orientation )
local vertices, arrows, i, Q;
if not n >= 4 then
Error("the entered value n is not greater or equal to 4,\n");
fi;
if Length(orientation) > n - 1 then
Error("too many orientation parameters compared to the number of arrows,\n ");
fi;
if Length(orientation) < n - 1 then
Error("too few orientation parameters compared to the number of arrows,\n ");
fi;
if not IsSubset(Set(["l","r"]), Set(orientation{[1..n-1]})) then
Error("the orientation parameters are not in the set [\"l\",\"r\"],\n");
fi;
#
# Naming the verties and the arrows in D_n. The vertices are named
# "1", "2", "3", and so on in the following way. The arrows are named as follows
# 1
# \
# a_1
# \
# 3 -- a_3 -- 4 -- a_2 -- .... n - 1 -- a_{n-1} -- n.
# /
# a_2
# /
# 2
#
vertices := List([1..n], i -> String(i));
arrows := [];
for i in [1..2] do
if orientation[i] = "l" then
Add(arrows, [vertices[3], vertices[i], Concatenation("a_",String(i))]);
else
Add(arrows, [vertices[i], vertices[3], Concatenation("a_",String(i))]);
fi;
od;
for i in [3..n-1] do
if orientation[i] = "l" then
Add(arrows, [vertices[i+1], vertices[i], Concatenation("a_",String(i))]);
else
Add(arrows, [vertices[i], vertices[i+1], Concatenation("a_",String(i))]);
fi;
od;
Q := Quiver(vertices, arrows);
SetIsDynkinQuiver(Q, true);
return Q;
end
);
##########################################################################
##
#O DeclearOperation( "DynkinQuiver", [ Delta, n, orientation ] )
##
## Returns the Dynkin quiver of type Delta, where Delta is A, D or E.
##
InstallMethod( DynkinQuiver,
"for a positive integer and a list",
[ IsString, IS_INT, IsList ],
function( Delta, n, orientation );
if String(Delta) = "A" then
return DynkinQuiverAn(n, orientation);
fi;
if String(Delta) = "D" then
return DynkinQuiverDn(n, orientation);
fi;
if String(Delta) = "E" then
return DynkinQuiverEn(n, orientation);
fi;
end
);
##########################################################################
##
#A DeclearAttribute( "DoubleQuiver", [ Q ] )
##
## Returns the double of the quiver Q where each arrow a in Q gets a
## companion abar going in the opposite direction.
##
InstallMethod( DoubleQuiver,
"for a quiver",
[ IsQuiver ], 0,
function( Q )
local vertices, arrows, newvertices, newarrows, a, origin, terminus;
vertices := VerticesOfQuiver( Q );
arrows := ArrowsOfQuiver( Q );
newvertices := List( vertices, String );
newarrows := [];
for a in arrows do
origin := String( SourceOfPath( a ) );
terminus := String( TargetOfPath( a ) );
Add( newarrows, [ origin, terminus, String( a ) ] );
Add( newarrows, [ terminus, origin, Concatenation( String( a ), "bar" ) ] );
od;
return Quiver( newvertices, newarrows );
end
);
[ Dauer der Verarbeitung: 0.33 Sekunden
(vorverarbeitet)
]
|
2026-04-02
|