# GAP Implementation # This file was generated from # $Id: ordering.gi,v 1.2 2012/02/27 12:26:34 sunnyquiver Exp $
InstallMethod(LessThanByOrdering, "for orderings and two paths",
true,
[IsQuiverOrdering, IsPath, IsPath], 0, function(O,a,b)
return ComparisonFunction(O)(a,b) < 0; end
);
InstallMethod(IsWellOrdering, "for an ordering",
true,
[IsQuiverOrdering],0, function(O)
return IsWellSubset(O,GeneratorsOfQuiver(O!.quiver)); end
);
InstallMethod(IsWellReversedOrdering, "for an ordering",
true,
[IsQuiverOrdering],0, function(O)
return IsWellReversedSubset(O,GeneratorsOfQuiver(O!.quiver)); end
);
InstallMethod(IsTotalOrdering, "for an ordering",
true,
[IsQuiverOrdering],0, function(O)
return IsTotalSubset(O,GeneratorsOfQuiver(O!.quiver)); end
);
InstallMethod(IsAdmissibleOrdering, "for an ordering",
true,
[IsQuiverOrdering],0, function(O) #Check IsTotalOrdering() first, because it is often faster
return IsTotalOrdering(O) and IsWellOrdering(O); end
);
InstallGlobalFunction(CheckQuiverSubsetForCycles, function(Q,L)
local h,n,a,b,i,r,visit;
#Possibly a big shortcut if HasIsAcyclicQuiver(Q) and IsAcyclicQuiver(Q) then
return true; fi;
#Identify every arrow in the list, as well as every vertex we #can start from
h:=[]; for a in L do if IsArrow(a) then
i:=ExtRepOfObj(a)[1];
h[i]:=a;
b:=SourceOfPath(a);
h[ExtRepOfObj(b)[1]]:=b; fi;
od;
#If we have some arrows if Length(h)>0then
n:=[];
i:=1; #Visit a vertex #v is the vertex #j is 3 * the generator position of the vertex #c is the label of the source vertex for the last arrow which was in the subset #n[j] = the depth-first search label of the vertex #n[j-1] = true: the vertex was visited successfully; false: vertex is being visited #n[j-2] = index of the highest vertex reachable from cycles containing this vertex
visit:=function(v,j,c)
local adj,k,t,p,m;
n[j]:=i; #Label the vertex
n[j-1]:=true; #Mark us in the process of being visited
i:=i+1; #Check all the arrows
adj:=OutgoingArrowsOfVertex(v); for p in adj do
t:=TargetOfPath(p);
k:=ExtRepOfObj(t)[1]*3; #Arrow is inside our subset if IsBound(h[ExtRepOfObj(p)[1]]) then #Arrow points to an unvisited vertex if not IsBound(n[k]) then if not visit(t,k,n[j]) then
return false; fi; #The vertex can reach us #Or the vertex is part of a cycle that reaches us elif n[k-1] or (IsBound(n[k-2]) and n[n[k-2]-1]) then
return false; fi; #Arrow is outside our subset else #Arrow points to an unvisited vertex if not IsBound(n[k]) then if not visit(t,k,c) then
return false; #If it's part of a cycle that reaches us, mark us elif IsBound(n[k-2]) and n[n[k-2]-1] and
((not IsBound(n[j-2])) or n[n[j-2]]>n[n[k-2]]) then
n[j-2]:=n[k-2]; fi; #The vertex can reach us elif n[k-1] or (IsBound(n[k-2]) and n[n[k-2]-1]) then if IsBound(n[k-2]) then
m:=n[k-2]; else
m:=k; fi; #The cycle contains something from our set if n[m]<=c then
return false; #Mark us as belonging to the cycle elif (not IsBound(n[j-2])) or n[n[j-2]]>n[m] then
n[j-2]:=m; fi; fi; fi;
od;
n[j-1]:=false;
return true; end; for b in h do if not IsQuiverVertex(b) then
break; fi;
r:=ExtRepOfObj(b)[1]*3; if not IsBound(n[r]) then if not visit(b,r,0) then
return false; fi; fi;
od; fi;
return true; end
);
InstallGlobalFunction(LengthOrdering,function(arg)
local O,fam;
if not ((Length(arg) = 1 or (Length(arg) = 2 and IsQuiverOrdering(arg[2])))
and IsQuiver(arg[1])) then
Error("usage: LengthOrdering(Q) or LengthOrdering(Q,O)", " where Q is a quiver and O is an ordering"); fi;
fam := NewFamily("FamilyLengthOrdering", IsLengthOrdering);
O := Objectify(NewType(fam,IsLengthOrdering and IsAttributeStoringRep),
rec() );
SetOrderingName(O, "length");
# Set quiver in record:
O!.quiver:=arg[1];
# We already know that the argument is an ordering if Length(arg)=2then
SetNextOrdering(O, arg[2]); if HasLexicographicTable(arg[2]) then
SetLexicographicTable(O,LexicographicTable(arg[2]));
O!.lex:=arg[2]!.lex; fi; fi;
SetComparisonFunction(O,function(a,b)
local lena, lenb;
if HasWalkOfPath(a) then
lena := Length(WalkOfPath(a)); else
lena := 0; fi;
if HasWalkOfPath(b) then
lenb := Length(WalkOfPath(b)); else
lenb := 0; fi; #Print("lena: ",lena,", lenb: ",lenb,"\n"); if lena < lenb then
return -1; elif lena = lenb then if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; else
return 1; fi;
end
);
return O; end
);
InstallMethod(IsWellReversedOrdering, "for a length ordering",
true,
[IsLengthOrdering],0, function(O)
return IsFinite(O!.quiver); end
);
InstallMethod(IsTotalOrdering, "for a length ordering",
true,
[IsLengthOrdering],0, function(O) if Length(VerticesOfQuiver(O!.quiver))<1then
return true; elif HasNextOrdering(O) then
return IsTotalOrdering(NextOrdering(O)); else
return false; fi; end
);
InstallMethod(IsWellSubset, "for a length ordering and a list of generators",
true,
[IsLengthOrdering,IsHomogeneousList],0, function(O,L)
return true; end
);
InstallMethod(IsWellReversedSubset, "for a length ordering",
true,
[IsLengthOrdering,IsHomogeneousList],0, function(O,L)
return CheckQuiverSubsetForCycles(O!.quiver,L); end
);
InstallMethod(IsTotalSubset, "for a length ordering and a list of generators",
true,
[IsLengthOrdering,IsHomogeneousList],0, function(O,L) if Length(L)<1then
return true; elif HasNextOrdering(O) then
return IsTotalSubset(NextOrdering(O),L); else
return false; fi; end
);
InstallMethod(IsWellOrdering, "for a lexicographic ordering and a quiver",
true,
[IsLexicographicOrdering],0, function(O)
local i,l,a,v,m,ret; if IsFinite(O!.quiver) then
return true; else
l:=LexicographicTable(O); #This must be an arrow, or we wouldn't be infinite
a:=l[Length(l)];
v:=SourceOfPath(a);
i:=ExtRepOfObj(v)[1]; if i<>ExtRepOfObj(TargetOfPath(a))[1] or InDegreeOfVertex(v)>1then
return false; fi;
m:=AdjacencyMatrixOfQuiver(O!.quiver);
m[i][i]:=0;
ret:=IsFinite(Quiver(m));
m[i][i]:=1;
return ret; fi; end
);
InstallMethod(IsWellOrdering, "for a lexicographic ordering and a quiver",
true,
[IsLexicographicOrdering],0, function(O)
local i,l,a,v,m,ret; if IsFinite(O!.quiver) then
return true; else
l:=LexicographicTable(O); #This must be an arrow, or we wouldn't be infinite
a:=l[Length(VerticesOfQuiver(O!.quiver))+1];
v:=SourceOfPath(a);
i:=ExtRepOfObj(v)[1]; if i<>ExtRepOfObj(TargetOfPath(a))[1] or InDegreeOfVertex(v)>1then
return false; fi;
m:=AdjacencyMatrixOfQuiver(O!.quiver);
m[i][i]:=0;
ret:=IsFinite(Quiver(m));
m[i][i]:=1;
return ret; fi; end
);
InstallMethod(IsWellSubset, "for a lexicographic ordering and a list of generators",
true,
[IsLexicographicOrdering,IsHomogeneousList],0, function(O,L)
local h,n,a,b,i,r,lgst,lgst_lex,visit; #Possibly a big shortcut if HasIsAcyclicQuiver(O!.quiver) and IsAcyclicQuiver(O!.quiver) then
return true; fi; #Identify every arrow in the list, as well as every vertex we #can start from, and the largest arrow
h:=[]; for a in L do if IsArrow(a) then
i:=ExtRepOfObj(a)[1];
h[i]:=a; if not IsBound(lgst) or
lgst_lex<O!.lex[i] then
lgst:=a;
lgst_lex:=O!.lex[i]; fi;
b:=SourceOfPath(a);
h[ExtRepOfObj(b)[1]]:=b; fi;
od; #If we have some arrows if IsBound(lgst) then #The largest arrow may appear in cycles
Unbind(h[ExtRepOfObj(lgst)[1]]);
n:=[];
i:=1;
visit:=#Visit a vertex #v is the vertex #j is 3 * the generator position of the vertex #p is the 3 * the generator position of the vertex's parent, or -1 #c is the label of the source vertex for the last arrow which was a parent #n[j] = the depth-first search label of the vertex #n[j-1] = -1: being visited, -2: and has cycle, 1: done being visited, 2: and has cycle #n[j-2] = index of the highest vertex reachable from cycles containing this vertex function(v,j,c)
local adj,k,t,p,m;
n[j]:=i; #Label the vertex
n[j-1]:=-1; #Mark us as being visited
i:=i+1; #Check all the arrows
adj:=OutgoingArrowsOfVertex(v); for p in adj do
t:=TargetOfPath(p);
k:=ExtRepOfObj(t)[1]*3; #Arrow is inside our subset, and not the largest if IsBound(h[ExtRepOfObj(p)[1]]) then #Arrow points to an unvisited vertex if not IsBound(n[k]) then if not visit(t,k,n[j]) then
return false; fi; #Arrow points to the largest arrow and largest arrow belongs to a cycle #Or the vertex can reach us #Or the vertex is part of a cycle that reaches us elif (n[k]=1 and n[k-1]=2) or n[k-1]<0 or
(IsBound(n[k-2]) and n[n[k-2]-1]<0) then
return false; fi; #Arrow is outside our subset, or the largest else #Arrow points to an unvisited vertex if not IsBound(n[k]) then if p=lgst then if not visit(t,k,-1) then
return false; fi; else if not visit(t,k,c) then
return false; fi; fi; if IsBound(n[k-2]) and (n[n[k-2]-1]<0) and
((not IsBound(n[j-2])) or n[n[j-2]]>n[n[k-2]]) then
n[j-2]:=n[k-2]; fi; #The vertex can possibly reach us elif n[k-1]<0 or
(IsBound(n[k-2]) and n[n[k-2]-1]<0) then if IsBound(n[k-2]) then
m:=n[k-2]; else
m:=k; fi; #The cycle contains something from our set if n[m]<=c then
return false; #The cycle is outside our set elif (not IsBound(n[j-2])) or n[n[j-2]]>n[m] then
n[j-2]:=m; fi; #The cycle descends directly from the largest arrow if c<0 or p=lgst then
n[m-1]:=-2; fi; fi; fi;
od;
n[j-1]:=-n[j-1]; #Mark us as done being visited
return true; end; #Visit source of largest arrow first
b:=SourceOfPath(lgst);
r:=ExtRepOfObj(b)[1]*3; if not visit(b,r,0) then
return false; fi; #Visit any unconnected components reachable from our subset for b in h do if not IsQuiverVertex(b) then
break; fi;
r:=ExtRepOfObj(b)[1]*3; if not IsBound(n[r]) then if not visit(b,r,0) then
return false; fi; fi;
od; fi;
return true; end
);
InstallMethod(IsWellReversedSubset, "for a lexicographic ordering and a list of generators",
true,
[IsLexicographicOrdering,IsHomogeneousList],0, function(O,L)
local h,n,a,b,i,r,lgst,lgst_lex,visit; #Possibly a big shortcut if HasIsAcyclicQuiver(O!.quiver) and IsAcyclicQuiver(O!.quiver) then
return true; fi; #Identify every arrow in the list, as well as every vertex we #can start from, and the largest arrow
h:=[]; for a in L do if IsArrow(a) then
i:=ExtRepOfObj(a)[1];
h[i]:=a; if not IsBound(lgst) or
lgst_lex>O!.lex[i] then
lgst:=a;
lgst_lex:=O!.lex[i]; fi;
b:=SourceOfPath(a);
h[ExtRepOfObj(b)[1]]:=b; fi;
od; #If we have some arrows if IsBound(lgst) then #The largest arrow may appear in cycles
Unbind(h[ExtRepOfObj(lgst)[1]]);
n:=[];
i:=1;
visit:=#Visit a vertex #v is the vertex #j is 3 * the generator position of the vertex #p is the 3 * the generator position of the vertex's parent, or -1 #c is the label of the source vertex for the last arrow which was a parent #n[j] = the depth-first search label of the vertex #n[j-1] = -1: being visited, -2: and has cycle, 1: done being visited, 2: and has cycle #n[j-2] = index of the highest vertex reachable from cycles containing this vertex function(v,j,c)
local adj,k,t,p,m;
n[j]:=i; #Label the vertex
n[j-1]:=-1; #Mark us as being visited
i:=i+1; #Check all the arrows
adj:=OutgoingArrowsOfVertex(v); for p in adj do
t:=TargetOfPath(p);
k:=ExtRepOfObj(t)[1]*3; #Arrow is inside our subset, and not the largest if IsBound(h[ExtRepOfObj(p)[1]]) then #Arrow points to an unvisited vertex if not IsBound(n[k]) then if not visit(t,k,n[j]) then
return false; fi; #Arrow points to the largest arrow and largest arrow belongs to a cycle #Or the vertex can reach us #Or the vertex is part of a cycle that reaches us elif (n[k]=1 and n[k-1]=2) or n[k-1]<0 or
(IsBound(n[k-2]) and n[n[k-2]-1]<0) then
return false; fi; #Arrow is outside our subset, or the largest else #Arrow points to an unvisited vertex if not IsBound(n[k]) then if p=lgst then if not visit(t,k,-1) then
return false; fi; else if not visit(t,k,c) then
return false; fi; fi; if IsBound(n[k-2]) and (n[n[k-2]-1]<0) and
((not IsBound(n[j-2])) or n[n[j-2]]>n[n[k-2]]) then
n[j-2]:=n[k-2]; fi; #The vertex can possibly reach us elif n[k-1]<0 or
(IsBound(n[k-2]) and n[n[k-2]-1]<0) then if IsBound(n[k-2]) then
m:=n[k-2]; else
m:=k; fi; #The cycle contains something from our set if n[m]<=c then
return false; #The cycle is outside our set elif (not IsBound(n[j-2])) or n[n[j-2]]>n[m] then
n[j-2]:=m; fi; #The cycle descends directly from the largest arrow if c<0 or p=lgst then
n[m-1]:=-2; fi; fi; fi;
od;
n[j-1]:=-n[j-1]; #Mark us as done being visited
return true; end; #Visit source of largest arrow first
b:=SourceOfPath(lgst);
r:=ExtRepOfObj(b)[1]*3; if not visit(b,r,0) then
return false; fi; #Visit any unconnected components reachable from our subset for b in h do if not IsQuiverVertex(b) then
break; fi;
r:=ExtRepOfObj(b)[1]*3; if not IsBound(n[r]) then if not visit(b,r,0) then
return false; fi; fi;
od; fi;
return true; end
);
InstallMethod(IsTotalSubset, "for a lexicographic ordering and a list of generators",
true,
[IsLexicographicOrdering,IsHomogeneousList],0, function(O,L)
return true; end);
InstallGlobalFunction(LeftLexicographicOrdering,function(arg)
local fam,O,Q,lex,i,j,rep,gens,oldgens;
if not (Length(arg)=1 or (Length(arg)=2 and IsHomogeneousList(arg[2])) and IsQuiver(arg[1])) then
Error("usage: LeftLexicographicOrdering(Q,L), Q must be q quiver, L is an optional list of gens"); fi;
fam:=NewFamily("FamilyLeftLexicographicOrderings",
IsLeftLexicographicOrdering);
O:=Objectify(NewType(fam,IsLeftLexicographicOrdering and
IsAttributeStoringRep),rec());
Q:=arg[1];
O!.quiver:=Q;
oldgens:=GeneratorsOfQuiver(Q);
lex:=[];
gens:=[];
j:=1; if Length(arg)>=2then for i in arg[2] do if IsQuiverVertex(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(VerticesOfQuiver(Q))>=j then for i in oldgens do if not IsQuiverVertex(i) then
break; fi;
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi;
od; fi; if Length(arg)>=2then for i in arg[2] do if IsArrow(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(oldgens)>=j then for i in [Length(VerticesOfQuiver(Q))+1..Length(oldgens)] do
rep:=ExtRepOfObj(oldgens[i])[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,oldgens[i]); fi;
od; fi;
SetOrderingName(O,"left lexicographic");
SetLexicographicTable(O,gens);
O!.lex:=lex;
SetComparisonFunction(O,function(a,b)
local m,n,l,r,s,j; if IsZeroPath(a) then if IsZeroPath(b) then
return 0; else
return -1; fi; elif IsZeroPath(b) then
return 1; fi;
r:=ExtRepOfObj(a); # remember, these are paths
s:=ExtRepOfObj(b);
m:=Length(r);
n:=Length(s);
l:=Minimum(m, n); for j in [1..l] do if lex[r[j]]<>lex[s[j]] then if lex[r[j]]<lex[s[j]] then
return -1; else
return 1; fi; fi;
od; if m<n then
return -1; elif m=n then if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; else
return 1; fi; end);
return O;
end
);
InstallGlobalFunction(RightLexicographicOrdering,function(arg)
local fam,O,Q,lex,i,j,rep,gens,oldgens;
if not (Length(arg)=1 or (Length(arg)=2 and IsHomogeneousList(arg[2])) and IsQuiver(arg[1])) then
Error("usage: RightLexicographicOrdering(Q,L), Q must be q quiver, L is an optional list of gens"); fi;
fam:=NewFamily("FamilyRightLexicographicOrderings",
IsRightLexicographicOrdering);
O:=Objectify(NewType(fam,IsRightLexicographicOrdering and
IsAttributeStoringRep),rec());
Q:=arg[1];
O!.quiver:=Q;
oldgens:=GeneratorsOfQuiver(Q);
lex:=[];
gens:=[];
j:=1; if Length(arg)>=2then for i in arg[2] do if IsQuiverVertex(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(VerticesOfQuiver(Q))>=j then for i in oldgens do if not IsQuiverVertex(i) then
break; fi;
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi;
od; fi; if Length(arg)>=2then for i in arg[2] do if IsArrow(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(oldgens)>=j then for i in [Length(VerticesOfQuiver(Q))+1..Length(oldgens)] do
rep:=ExtRepOfObj(oldgens[i])[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,oldgens[i]); fi;
od; fi;
SetOrderingName(O,"right lexicographic");
SetLexicographicTable(O,gens);
O!.lex:=lex;
SetComparisonFunction(O,function(a,b)
local m,n,l,r,s,j;
if IsZeroPath(a) then if IsZeroPath(b) then
return 0; else
return -1; fi; elif IsZeroPath(b) then
return 1; fi;
r:=ExtRepOfObj(a); # remember, these are paths
s:=ExtRepOfObj(b);
m:=Length(r);
n:=Length(s);
l:=Minimum(m, n); for j in [0..l-1] do if lex[r[m-j]]<>lex[s[n-j]] then if lex[r[m-j]]<lex[s[n-j]] then
return -1; else
return 1; fi; fi;
od; if m<n then
return -1; elif m=n then if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; else
return 1; fi; end);
SetIsTotal(O,true);
return O;
end
);
InstallGlobalFunction(ReverseOrdering,function(arg)
local fam,O; if not (Length(arg)=2 and IsQuiverOrdering(arg[2]) and IsQuiver(arg[1])) then
Error("Usage: ReverseOrdering(Q,O) where Q is a quiver and O is an ordering"); fi;
fam:=NewFamily("FamilyReverseOrderings",IsReverseOrdering);
O:=Objectify(NewType(fam,IsReverseOrdering and IsAttributeStoringRep),
rec());
O!.quiver:=arg[1];
SetOrderingName(O,"reverse");
SetNextOrdering(O,arg[2]); if HasLexicographicTable(arg[2]) then
SetLexicographicTable(O,LexicographicTable(arg[2]));
O!.lex:=arg[2]!.lex; fi;
SetComparisonFunction(O,function(a,b)
local ret; if IsZeroPath(a) then if IsZeroPath(b) then
return 0; else
return ComparisonFunction(NextOrdering(O))(a,b); fi; elif IsZeroPath(b) then
return ComparisonFunction(NextOrdering(O))(a,b); fi; if IsQuiverVertex(a) then if not IsQuiverVertex(b) then
return ComparisonFunction(NextOrdering(O))(a,b); fi; elif IsQuiverVertex(b) then
return ComparisonFunction(NextOrdering(O))(a,b); fi;
return -ComparisonFunction(NextOrdering(O))(a,b); end);
return O; end
);
InstallMethod(IsWellOrdering, "for a reverse ordering and a quiver",
true,
[IsReverseOrdering],0, function(O)
return IsWellReversedOrdering(NextOrdering(O)); end
);
InstallMethod(IsWellReversedOrdering, "for a reverse ordering and a quiver",
true,
[IsReverseOrdering],0, function(O)
return IsWellOrdering(NextOrdering(O)); end
);
InstallMethod(IsTotalOrdering, "for a reverse ordering",
true,
[IsReverseOrdering],0, function(O)
return IsTotalOrdering(NextOrdering(O)); end
);
InstallMethod(IsWellSubset, "for a reverse ordering and a list of generators",
true,
[IsReverseOrdering,IsHomogeneousList],0, function(O,L)
return IsWellReversedSubset(NextOrdering(O),L); end
);
InstallMethod(IsWellReversedSubset, "for a reverse ordering and a list of generators",
true,
[IsReverseOrdering,IsHomogeneousList],0, function(O,L)
return IsWellSubset(NextOrdering(O),L); end
);
InstallMethod(IsTotalSubset, "for a reverse ordering and a list of generators",
true,
[IsReverseOrdering,IsHomogeneousList],0, function(O,L)
return IsTotalSubset(NextOrdering(O),L); end
);
InstallMethod(IsWellReversedOrdering, "for a vector ordering",
true,
[IsVectorOrdering],0, function(O)
return IsFinite(O!.quiver); end
);
InstallMethod(IsTotalOrdering, "for a vector ordering",
true,
[IsVectorOrdering],0, function(O) if Length(VerticesOfQuiver(O!.quiver))<1then
return true; elif HasNextOrdering(O) then
return IsTotalOrdering(NextOrdering(O)); else
return false; fi; end
);
InstallMethod(IsWellSubset, "for a vector ordering and a list of generators",
true,
[IsVectorOrdering,IsHomogeneousList],0, function(O,L)
return true; end
);
InstallMethod(IsWellReversedSubset, "for a vector ordering and a list of generators",
true,
[IsVectorOrdering,IsHomogeneousList],0, function(O,L)
return CheckQuiverSubsetForCycles(O!.quiver,L); end
);
InstallMethod(IsTotalSubset, "for a vector ordering and a list of generators",
true,
[IsVectorOrdering,IsHomogeneousList],0, function(O,L) if Length(L)<1then
return true; elif HasNextOrdering(O) then
return IsTotalSubset(NextOrdering(O),L); else
return false; fi; end
);
InstallGlobalFunction(LeftVectorOrdering,function(arg)
local fam,O,Q,lex,i,j,rep,gens,oldgens; if not (Length(arg)=1 or (Length(arg)=2 or (Length(arg)=3 and
IsQuiverOrdering(arg[3])) and IsHomogeneousList(arg[2])) and IsQuiver(arg[1])) then
Error("usage: LeftVectorOrdering(Q,L,O), the first arg must be a quiver, the second a list of generators, and the optional third argument an ordering"); fi;
fam:=NewFamily("FamilyLeftVectorOrderings",IsLeftVectorOrdering);
O:=Objectify(NewType(fam,IsLeftVectorOrdering and IsAttributeStoringRep),
rec());
Q:=arg[1];
O!.quiver:=Q;
if Length(arg)>=3 and HasLexicographicTable(arg[3]) then
oldgens:=LexicographicTable(arg[3]); else
oldgens:=GeneratorsOfQuiver(Q); fi;
lex:=[];
gens:=[];
j:=1; if Length(arg)>=2then for i in arg[2] do if IsQuiverVertex(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(VerticesOfQuiver(Q))>=j then for i in oldgens do if not IsQuiverVertex(i) then
break; fi;
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi;
od; fi; if Length(arg)>=2then for i in arg[2] do if IsArrow(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(oldgens)>=j then for i in [Length(VerticesOfQuiver(Q))+1..Length(oldgens)] do
rep:=ExtRepOfObj(oldgens[i])[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,oldgens[i]); fi;
od; fi;
if Length(arg)>=3then
SetNextOrdering(O,arg[3]); if HasLexicographicTable(arg[3]) then if LexicographicTable(arg[3])<>gens then
Error("Must use same lexicographic table"); fi;
O!.lex:=arg[3]!.lex;
SetLexicographicTable(O,LexicographicTable(arg[3])); else
O!.lex:=lex;
SetLexicographicTable(O,gens); fi; else
O!.lex:=lex;
SetLexicographicTable(O,gens); fi;
SetOrderingName(O,"left vector");
SetComparisonFunction(O,function(a,b)
local v,w,r,s,i,j,o; if IsQuiverVertex(a) or IsZeroPath(a) then if IsQuiverVertex(b) or IsZeroPath(b) then if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; else
return -1; fi; elif IsQuiverVertex(b) or IsZeroPath(b) then
return 1; fi; # At this point, both items are paths
o:=Length(VerticesOfQuiver(O!.quiver));
v:=ListWithIdenticalEntries(Length(gens)-o,0);
r:=ExtRepOfObj(a); for i in [1..Length(r)] do
j:=lex[r[i]]-o;
v[j]:=v[j]+1;
od;
w:=ListWithIdenticalEntries(Length(gens)-o,0);
s:=ExtRepOfObj(b); for i in [1..Length(s)] do
j:=lex[s[i]]-o;
w[j]:=w[j]+1;
od; for i in [1..Length(v)] do if v[i]<w[i] then
return -1; elif v[i]>w[i] then
return 1; fi;
od; if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; end);
return O;
end
);
InstallGlobalFunction(RightVectorOrdering,function(arg)
local fam,O,Q,lex,i,j,rep,gens,oldgens; if not (Length(arg)=1 or (Length(arg)=2 or (Length(arg)=3 and
IsQuiverOrdering(arg[3])) and IsHomogeneousList(arg[2])) and IsQuiver(arg[1])) then
Error("usage: RightVectorOrdering(Q,L,O), the first arg must be a quiver, the second a list of generators, and the optional third argument an ordering"); fi;
fam:=NewFamily("FamilyRightVectorOrderings",IsRightVectorOrdering);
O:=Objectify(NewType(fam,IsRightVectorOrdering and IsAttributeStoringRep),
rec());
Q:=arg[1];
O!.quiver:=Q;
if Length(arg)>=3 and HasLexicographicTable(arg[3]) then
oldgens:=LexicographicTable(arg[3]); else
oldgens:=GeneratorsOfQuiver(Q); fi;
lex:=[];
gens:=[];
j:=1; if Length(arg)>=2then for i in arg[2] do if IsQuiverVertex(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(VerticesOfQuiver(Q))>=j then for i in oldgens do if not IsQuiverVertex(i) then
break; fi;
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi;
od; fi; if Length(arg)>=2then for i in arg[2] do if IsArrow(i) then
rep:=ExtRepOfObj(i)[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,i); fi; fi;
od; fi; if Length(oldgens)>=j then for i in [Length(VerticesOfQuiver(Q))+1..Length(oldgens)] do
rep:=ExtRepOfObj(oldgens[i])[1]; if not IsBound(lex[rep]) then
lex[rep]:=j;
j:=j+1;
Add(gens,oldgens[i]); fi;
od; fi;
if Length(arg)>=3then
SetNextOrdering(O,arg[3]); if HasLexicographicTable(arg[3]) then if LexicographicTable(arg[3])<>gens then
Error("Must use same lexicographic table"); fi;
O!.lex:=arg[3]!.lex;
SetLexicographicTable(O,LexicographicTable(arg[3])); else
O!.lex:=lex;
SetLexicographicTable(O,gens); fi; else
O!.lex:=lex;
SetLexicographicTable(O,gens); fi;
SetOrderingName(O,"right vector");
SetComparisonFunction(O,function(a,b)
local v,w,r,s,i,j,l,o; if IsQuiverVertex(a) or IsZeroPath(a) then if IsQuiverVertex(b) or IsZeroPath(b) then if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; else
return -1; fi; elif IsQuiverVertex(b) or IsZeroPath(b) then
return 1; fi; # At this point, both items are paths
o:=Length(VerticesOfQuiver(O!.quiver));
v:=ListWithIdenticalEntries(Length(gens)-o,0);
r:=ExtRepOfObj(a); for i in [1..Length(r)] do
j:=lex[r[i]]-o;
v[j]:=v[j]+1;
od;
w:=ListWithIdenticalEntries(Length(gens)-o,0);
s:=ExtRepOfObj(b); for i in [1..Length(s)] do
j:=lex[s[i]]-o;
w[j]:=w[j]+1;
od;
l:=Length(v); for i in [0..l-1] do if v[l-i]<w[l-i] then
return -1; elif v[l-i]>w[l-i] then
return 1; fi;
od; if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; end);
return O; end
);
InstallGlobalFunction(WeightOrdering,function(arg)
local fam,O,Q,weight,i,j,rep,gens,p; if not (Length(arg)=1 or (Length(arg)=2 or (Length(arg)=3 and
IsQuiverOrdering(arg[3])) and IsHomogeneousList(arg[2])) and IsQuiver(arg[1])) then
Error("usage: WeightOrdering(Q,L,O), the first arg must be a quiver, the second a list of weights, one for each arrow in the quiver, and the optional third argument an ordering"); fi;
fam:=NewFamily("FamilyWeightOrderings",IsWeightOrdering);
O:=Objectify(NewType(fam,IsWeightOrdering and IsAttributeStoringRep),
rec());
Q:=arg[1];
O!.quiver:=Q;
weight:=ListWithIdenticalEntries(Length(ArrowsOfQuiver(Q)),0); if Length(arg)>=2 and Length(arg[2])>0then for p in [1..Length(arg[2])] do
weight[p]:=arg[2][p];
od; fi;
O!.weight:=weight;
if Length(arg)>=3then
SetNextOrdering(O,arg[3]); if HasLexicographicTable(arg[3]) then
SetLexicographicTable(O,LexicographicTable(arg[3]));
O!.lex:=arg[3]!.lex; fi; fi;
SetOrderingName(O,"weight");
SetComparisonFunction(O,function(a,b)
local v,w,r,s,i,o; if IsQuiverVertex(a) or IsZeroPath(a) then if IsQuiverVertex(b) or IsZeroPath(b) then if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; else
return -1; fi; elif IsQuiverVertex(b) or IsZeroPath(b) then
return 1; fi; # At this point, both items are paths
o:=Length(VerticesOfQuiver(O!.quiver));
r:=ExtRepOfObj(a);
s:=ExtRepOfObj(b);
w:=0; for i in r do
w:=w+weight[i-o];
od;
v:=0; for i in s do
v:=v+weight[i-o];
od; if w=v then if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); else
return 0; fi; else
return w-v; fi; end);
return O; end
);
InstallMethod(IsWellReversedOrdering, "for a weight ordering",
true,
[IsWeightOrdering],0, function(O)
local z,o; if IsFinite(O!.quiver) then
return true; fi;
o:=Length(VerticesOfQuiver(O!.quiver));
z:=Filtered(ArrowsOfQuiver(O!.quiver),function(a)
return O!.weight[ExtRepOfObj(a)[1]-o]<>0; end); if Length(z)>0 and not CheckQuiverSubsetForCycles(O!.quiver,z) then
return false; fi;
return not HasNextOrdering(O) or
IsWellReversedSubset(NextOrdering(O),z); end
);
InstallMethod(IsTotalOrdering, "for a weight ordering",
true,
[IsWeightOrdering],0, function(O) if Length(VerticesOfQuiver(O!.quiver))<1then
return true; elif HasNextOrdering(O) then
return IsTotalOrdering(NextOrdering(O)); else
return true; fi; end
);
InstallMethod(IsWellSubset, "for a weight ordering and a list of generators",
true,
[IsWeightOrdering,IsHomogeneousList],0, function(O,L)
return true; end
);
InstallMethod(IsWellReversedSubset, "for a weight ordering and a list of generators",
true,
[IsWeightOrdering,IsHomogeneousList],0, function(O,L)
local z,o; if HasIsAcyclicQuiver(O!.quiver) and IsAcyclicQuiver(O!.quiver) then
return true; fi;
o:=Length(VerticesOfQuiver(O!.quiver));
z:=Filtered(L,function(a)
return IsArrow(a) and O!.weight[ExtRepOfObj(a)[1]-o]<>0; end); if Length(z)>0 and not CheckQuiverSubsetForCycles(O!.quiver,z) then
return false; fi;
z:=Filtered(L,function(a)
return IsArrow(a) and O!.weight[ExtRepOfObj(a)[1]-o]=0; end); if Length(z)>0 and not CheckQuiverSubsetForCycles(O!.quiver,z) then
return not HasNextOrdering(O) or
IsWellReversedSubset(NextOrdering(O),z); fi;
return true; end
);
InstallMethod(IsTotalSubset, "for a weight ordering and a list of generators",
true,
[IsWeightOrdering,IsHomogeneousList],0, function(O,L) if Length(L)<1 or
(Length(L)=1 and IsArrow(L[1]) and
O!.weight[ExtRepOfObj(L[1])[1]-
Length(VerticesOfQuiver(O!.quiver))]<>0) then
return true; elif HasNextOrdering(O) then
return IsTotalSubset(NextOrdering(O,L)); else
return true; fi; end
);
InstallMethod(PathFromArrowList, "for a list of arrows",
true,
[IsQuiver,IsHomogeneousList],0, function(Q,L)
local ret; if Length(L)<1then
return Zero(Q); elif Length(L)=1then
return L[1]; #This handles vertices, too else
ret:=Objectify(NewType(FamilyObj(Q),
IsPath and IsAttributeStoringRep),
rec());
SetSourceOfPath(ret,SourceOfPath(L[1]));
SetTargetOfPath(ret,TargetOfPath(L[Length(L)]));
SetLengthOfPath(ret,Length(L));
SetWalkOfPath(ret,L);
SetIsZeroPath(ret,false);
return ret; fi; end
);
InstallMethod(CompareArrowLists, "for an ordering and two lists of arrows",
true,
[IsQuiverOrdering,IsHomogeneousList,IsHomogeneousList],0, function(O,a,b)
return ComparisonFunction(O)(PathFromArrowList(O!.quiver,a),
PathFromArrowList(O!.quiver,b)); end
);
InstallGlobalFunction(BlockOrdering,function(arg)
local fam,O,Q,L,block,orders,i,j,rep; if not (Length(arg)=1 or (Length(arg)=2 or (Length(arg)=3 and
IsQuiverOrdering(arg[3])) and IsHomogeneousList(arg[2])) and IsQuiver(arg[1])) then
Error("usage: BlockOrdering(Q,L,O), the first arg must be a quiver, the second a list of [ordering,[generator list]] pairs, and the optional third argument an ordering"); fi;
L:=arg[2]; if Length(L)<1then
Error("BlockOrdering: Subset list cannot be empty"); fi;
fam:=NewFamily("FamilyBlockOrderings",IsBlockOrdering);
O:=Objectify(NewType(fam,IsBlockOrdering and IsAttributeStoringRep),
rec());
Q:=arg[1];
O!.quiver:=Q;
block:=[];
orders:=[];
L:=Flat(L);
i:=1; while i<Length(L) do if not IsQuiverOrdering(L[i]) then
Error("Second argument must be a list of [ordering,[generator list]] pairs"); fi;
Add(orders,L[i]); if HasLexicographicTable(L[i]) then if HasLexicographicTable(O) then if LexicographicTable(O)<>LexicographicTable(L[i]) then
Error("Conflicting lexicographic tables"); fi; else
SetLexicographicTable(O,LexicographicTable(L[i]));
O!.lex:=L[i]!.lex; fi; fi;
i:=i+1; while i<Length(L) do if (not IsArrow(L[i])) and (not IsQuiverVertex(L[i])) then
break; fi;
block[ExtRepOfObj(L[i])[1]]:=Length(orders);
i:=i+1;
od;
od;
L:=Length(GeneratorsOfQuiver(Q)); if L>0then for i in [1..L] do if not IsBound(block[i]) then
block[i]:=Length(orders); fi;
od; fi;
O!.block:=block;
O!.orders:=orders;
if Length(arg)>=3then
SetNextOrdering(O,arg[3]); if HasLexicographicTable(arg[3]) then if HasLexicographicTable(O) then if LexicographicTable(O)<>LexicographicTable(arg[3]) then
Error("Conflicting lexicographic tables"); fi; else
SetLexicographicTable(O,LexicographicTable(arg[3]));
O!.lex:=arg[3]!.lex; fi; fi; fi;
SetOrderingName(O,"block");
SetComparisonFunction(O,function(a,b)
local ret,e,f,p,q,o,i,g;
o:=Length(O!.orders);
p:=[]; for i in [1..o] do
Add(p,[]);
od;
q:=StructuralCopy(p);
g:=GeneratorsOfQuiver(O!.quiver); if not IsZeroPath(a) then
e:=ExtRepOfObj(a); for i in e do
Add(p[block[i]],g[i]);
od; fi; if not IsZeroPath(b) then
f:=ExtRepOfObj(b); for i in f do
Add(q[block[i]],g[i]);
od; fi; while o>0do
ret:=CompareArrowLists(O!.orders[o],p[o],q[o]); if ret<>0then
return ret; fi;
o:=o-1;
od; if HasNextOrdering(O) then
return ComparisonFunction(NextOrdering(O))(a,b); fi;
return 0; end);
return O; end
);
DeclareGlobalFunction("CheckBlocksForCycles");
InstallGlobalFunction(CheckBlocksForCycles, function(O,block)
local i,r,n,visit; #Possibly a big shortcut if HasIsAcyclicQuiver(O!.quiver) and IsAcyclicQuiver(O!.quiver) then
return true; fi;
n:=[];
i:=1; #Visit a vertex #v is the vertex #j is 4 * the generator position of the vertex #c is the label of the source vertex for the last arrow which transitioned blocks #b is the current block number, or 0 #a is the label of the source vertex for highest previous 0 arrow in a row #n[j] = the depth-first search label of the vertex #n[j-1] = true: the vertex was visited successfully; false: vertex is being visited #n[j-2] = index of the highest vertex reachable from cycles containing this vertex #n[j-3] = the block number of any cycle this vertex belongs to, or 0
visit:=function(v,j,c,b,a)
local adj,k,t,p,d,e,f,m;
n[j]:=i;
n[j-1]:=true;
n[j-3]:=0;
i:=i+1; #Check all the arrows
adj:=OutgoingArrowsOfVertex(v); for p in adj do
t:=TargetOfPath(p);
k:=ExtRepOfObj(t)[1]*4; #Look for block transition
e:=block[ExtRepOfObj(p)[1]]; if e>0then if b>0 and e<>b then
f:=a; else
f:=c; fi;
d:=i; else
e:=b;
f:=c;
d:=a; fi; #Arrow points to an unvisited vertex if not IsBound(n[k]) then if not visit(t,k,f,e,d) then
return false; #If it's part of a cycle that reaches us elif IsBound(n[k-2]) and n[n[k-2]-1] then #Mark how high we can reach if (not IsBound(n[j-2])) or n[n[j-2]]>n[n[k-2]] then
n[j-2]:=n[k-2]; fi; #Mark what block the cycle is in if n[k-3]<>0then
n[j-3]:=n[k-3]; fi; fi; #The vertex can reach us elif n[k-1] or (IsBound(n[k-2]) and n[n[k-2]-1]) then if IsBound(n[k-2]) then
m:=[k-2]; else
m:=k; fi; #The cycle contains something outside our block if n[m]<f or (n[k-3]>0 and e>0 and n[k-3]<>e) then
return false; #Mark us a belonging to the cycle elif (not IsBound(n[j-2])) or n[n[j-2]]>n[m] then
n[j-2]:=m; fi; fi;
od;
n[j-1]:=false;
return true; end; for i in [1..Length(VerticesOfQuiver(O!.quiver))] do if block[i]>0then
r:=i*4; if not IsBound(n[r]) then if not visit(VerticesOfQuiver(O!.quiver)[i],r,0,0,0) then
return false; fi; fi; fi;
od;
return true; end
);
InstallMethod(IsTotalOrdering, "for a block ordering",
true,
[IsBlockOrdering],0, function(O)
local l,s,i,block;
l:=GeneratorsOfQuiver(O!.quiver);
s:=[];
block:=O!.block; for i in [1..Length(O!.orders)] do
Add(s,[]);
od; for i in l do
Add(s[block[ExtRepOfObj(i)[1]]],i);
od; for i in [1..Length(O!.orders)] do if not IsTotalSubset(O!.orders[i],s[i]) then if HasNextOrdering(O) then
return IsTotalOrdering(NextOrdering(O)); else
return false; fi; fi;
od; if Length(block)>0then if not CheckBlocksForCycles(O,block) then if HasNextOrdering(O) then
return IsTotalOrdering(NextOrdering(O)); else
return false; fi; fi; fi;
return true; end
);
InstallMethod(IsWellSubset, "for a block ordering and a list of generators",
true,
[IsBlockOrdering,IsHomogeneousList],0, function(O,L)
local s,i,block;
s:=[];
block:=O!.block; for i in [1..Length(O!.orders)] do
Add(s,[]);
od; for i in L do
Add(s[block[ExtRepOfObj(i)[1]]],i);
od; for i in [1..Length(O!.orders)] do if not IsWellSubset(O!.orders[i],s[i]) then
return false; fi;
od;
return true; end
);
InstallMethod(IsWellReversedSubset, "for a block ordering and a list of generators",
true,
[IsBlockOrdering,IsHomogeneousList],0, function(O,L)
local s,i,block;
s:=[];
block:=O!.block; for i in [1..Length(O!.orders)] do
Add(s,[]);
od; for i in L do
Add(s[block[ExtRepOfObj(i)[1]]],i);
od; for i in [1..Length(O!.orders)] do if not IsWellReversedSubset(O!.orders[i],s[i]) then
return false; fi;
od;
return true; end
);
InstallMethod(IsTotalSubset, "for a block ordering and a list of generators",
true,
[IsBlockOrdering,IsHomogeneousList],0, function(O,L)
local l,s,i,j,block;
s:=[];
block:=ListWithIdenticalEntries(Length(O!.block),0); for i in [1..Length(O!.orders)] do
Add(s,[]);
od; for i in L do if IsArrow(i) then
j:=ExtRepOfObj(SourceOfPath(i))[1];
block[j]:=O!.block[j]; fi;
j:=ExtRepOfObj(i)[1];
block[j]:=O!.block[j];
Add(s[block[j]],i);
od; for i in [1..Length(O!.orders)] do if not IsTotalSubset(O!.orders[i],s[i]) then if HasNextOrdering(O) then
return IsTotalSubset(NextOrdering(O),L); else
return false; fi; fi;
od; if Length(block)>0then if not CheckBlocksForCycles(O,block) then if HasNextOrdering(O) then
return IsTotalOrdering(NextOrdering(O)); else
return false; fi; fi; fi;
return true; end
);
InstallGlobalFunction(WreathOrdering,function(arg)
local fam,O,Q,L,block,orders,i,j,rep; if not (Length(arg)=1 or (Length(arg)=2 or (Length(arg)=3 and
IsQuiverOrdering(arg[3])) and IsHomogeneousList(arg[2])) and IsQuiver(arg[1])) then
Error("usage: WreathOrdering(Q,L,O), the first arg must be a quiver, the second a list of [ordering,[generator list]] pairs, and the optional third argument an ordering"); fi;
L:=arg[2]; if Length(L)<1then
Error("WreathOrdering: Subset list cannot be empty"); fi;
fam:=NewFamily("FamilyWreathOrderings",IsWreathOrdering);
O:=Objectify(NewType(fam,IsWreathOrdering and IsAttributeStoringRep),
rec());
Q:=arg[1];
O!.quiver:=Q;
block:=[];
orders:=[];
L:=Flat(L);
i:=1; while i<Length(L) do if not IsQuiverOrdering(L[i]) then
Error("Second argument must be a list of [ordering,[generator list]] pairs"); fi;
Add(orders,L[i]); if HasLexicographicTable(L[i]) then if HasLexicographicTable(O) then if LexicographicTable(O)<>LexicographicTable(L[i]) then
Error("Conflicting lexicographic tables"); fi; else
SetLexicographicTable(O,LexicographicTable(L[i]));
O!.lex:=L[i]!.lex; fi; fi;
i:=i+1; while i<Length(L) do if (not IsArrow(L[i])) and (not IsQuiverVertex(L[i])) then
break; fi;
block[ExtRepOfObj(L[i])[1]]:=Length(orders);
i:=i+1;
od;
od;
L:=Length(GeneratorsOfQuiver(Q)); if L>0then for i in [1..L] do if not IsBound(block[i]) then
block[i]:=Length(orders); fi;
od; fi;
O!.block:=block;
O!.orders:=orders;
if Length(arg)>=3then
SetNextOrdering(O,arg[3]); if HasLexicographicTable(arg[3]) then if HasLexicographicTable(O) then if LexicographicTable(O)<>LexicographicTable(arg[3]) then
Error("Conflicting lexicographic tables"); fi; else
SetLexicographicTable(O,LexicographicTable(arg[3]));
O!.lex:=arg[3]!.lex; fi; fi; fi;
SetOrderingName(O,"wreath");
SetComparisonFunction(O,function(a,b)
local ret,e,f,o,s,t,i,j,c,d,p,q,m,n,x,y,g; if IsZeroPath(a) then
e:=[]; else
e:=ExtRepOfObj(a); fi; if IsZeroPath(b) then
f:=[]; else
f:=ExtRepOfObj(b); fi;
o:=1;
i:=Minimum(Length(e),Length(f)); # Skip equal elements while o<=i do if e[o]<>f[o] then
break; fi;
o:=o+1;
od; # If we skipped everything, the paths are identical if o>Length(e) and o>Length(f) then
return 0; fi;
g:=GeneratorsOfQuiver(O!.quiver);
s:=0;
m:=0;
p:=[];
c:=[];
x:=[]; if o<=Length(e) then for i in [o..Length(e)] do
j:=block[e[i]]; if j>m then
s:=s+1;
m:=j;
Add(c,m);
Add(p,[g[e[i]]]); elif j=m then
Add(p[s],g[e[i]]); else
Add(x,g[e[i]]); fi;
od; fi;
t:=0;
n:=0;
q:=[];
d:=[];
y:=[]; if o<=Length(f) then for i in [o..Length(f)] do
j:=block[f[i]]; if j>n then
t:=t+1;
n:=j;
Add(d,n);
Add(q,[g[f[i]]]); elif j=n then
Add(q[t],g[f[i]]); else
Add(y,g[f[i]]); fi;
od; fi; while s>0 and t>0do if c[s]=d[t] then
ret:=CompareArrowLists(orders[c[s]],p[s],q[t]);
s:=s-1;
t:=t-1; elif c[s]>d[t] then
ret:=CompareArrowLists(orders[c[s]],p[s],[]);
s:=s-1; else
ret:=CompareArrowLists(orders[d[t]],[],q[t]);
t:=t-1; fi; if ret<>0then
return ret; fi;
od; while s>0do
ret:=CompareArrowLists(orders[c[s]],p[s],[]); if ret<>0then
return ret; fi;
s:=s-1;
od; while t>0do
ret:=CompareArrowLists(orders[d[t]],[],q[t]); if ret<>0then
return ret; fi;
t:=t-1;
od;
ret:=CompareArrowLists(O,x,y); if ret=0 and HasNextOrdering(O) then
ret:=ComparisonFunction(NextOrdering(O))(a,b); fi;
return ret; end);
return O;
end
);
PrintOrdering := function(O)
local done;
done := false;
Print("<"); while not donedo if HasOrderingName(O) then
Print(OrderingName(O)); else
Print("unnamed"); fi;
Print(" "); if HasNextOrdering(O) then
O := NextOrdering(O); else done := true; fi;
od;
Print("ordering>"); end;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.