From 73757f276c5150ecbaf2df4e0d6808a5a8c6e6f4 Mon Sep 17 00:00:00 2001 From: Cora Aked Date: Wed, 3 Dec 2025 15:57:03 +0000 Subject: [PATCH 1/7] Working IsCograph code --- IsCograph.g | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 IsCograph.g diff --git a/IsCograph.g b/IsCograph.g new file mode 100644 index 000000000..365d82c76 --- /dev/null +++ b/IsCograph.g @@ -0,0 +1,178 @@ +# Function that identifies a cograph from a symmetric digraph +# Created from the algorithm described in the paper "A Simple Linear Time Recognition Algorithm for Cographs" +# Habib, M & Paul, C & Viennot (2005). A Simple Linear Time Recognition Algorithm for Cographs. Discrete Applied Mathematics. 145(2). 183-197. https://doi.org/10.1016/j.dam.2004.01.011. + +IsCograph := function(D) + local verts, P, origin, adj, part, neighbours, n_x, + used_parts, unused_parts, unused_parts_refined, + k, y, N_y, M, p, m, ma, j,n,v, + zl, zr, prevorigin, new_P, t, current_part, zrpart, pivot, + upd_part, zlpart, upd_m, pivotset, sigma, succz, precz, z, N_z, N_precz, N_succz, options, list, subpart; + + # input must be symmetric + if not IsSymmetricDigraph(D) then; + Error("IsCograph: argument must be a symmetric digraph"); + fi; + + verts := DigraphVertices(D); + P := [verts]; + + # a graph with fewer than 4 vertices cannot contain a P4 graph + if Length(verts) < 4 then + return true; + fi; + + origin := 1; + adj := OutNeighboursOfVertex(D, origin); + if Length(adj) = 0 or Length(adj) = Length(verts) - 1 then + return IsCograph(InducedSubdigraph(D, Filtered(verts, v -> v <> origin))); + fi; + + # Algorithm 3: Partition Refinement + while ForAll(P, part -> Length(part) <= 1) = false do + k := PositionProperty(P, part -> origin in part); + if Length(P[k]) > 1 then + part := Remove(P, k); + neighbours := OutNeighboursOfVertex(D, origin); + part := [Filtered(neighbours, p -> p in part), [origin], Difference(part, Union([origin], neighbours))]; + unused_parts := [part[1], part[3]]; + used_parts := [origin]; + for p in Filtered(part, u -> u <> []) do + Add(P, p, k); + od; + fi; + + # Procedure 3 + new_P := ShallowCopy(P); + if ForAll(new_P, part -> Length(part) <= 1) = true then + break; + fi; + + while Length(Filtered(unused_parts, u -> u <> [])) > 0 do + options := Filtered(unused_parts, part -> Length(part) > 0); + list := List(options, j -> Minimum(j)); + subpart := unused_parts[Position(list, Minimum(list))]; + + if Filtered(subpart, u -> u in used_parts) = [] then + pivot := Minimum(subpart); + else + pivot := subpart[part -> p in used_parts][1]; + fi; + + # Procedure 4 + M := []; + current_part := ShallowCopy(new_P[PositionProperty(new_P, part -> pivot in part)]); + pivotset := OutNeighboursOfVertex(D, pivot); + + for p in Difference(new_P, [current_part]) do + if Intersection(p, pivotset) <> [] and Intersection(p, pivotset) <> p and Intersection(p, pivotset) <> [origin] then + k := ShallowCopy(Position(new_P, p)); + Remove(new_P, k); + Add(M, p); + fi; + od; + + if M <> [] then + for m in M do + ma := Filtered(m, p -> p in pivotset); + upd_m := [ma, Difference(m, ma)]; + for t in Filtered(upd_m, x -> x <> []) do + Add(new_P, t, k); + od; + if m in unused_parts then + Remove(unused_parts, Position(unused_parts, m)); + if not ma in unused_parts and ma <> [] then + Add(unused_parts, ma); + fi; + if not Difference(m, ma) in unused_parts and Difference(m,ma) <> [] then + Add(unused_parts, Difference(m, ma)); + fi; + else + if Minimum(m) in upd_m[1] then + Add(unused_parts, upd_m[2]); + else + Add(unused_parts, upd_m[1]); + fi; + fi; + Add(used_parts, m); + Add(used_parts, pivot); + od; + fi; + if current_part in unused_parts then + Remove(unused_parts, Position(unused_parts, current_part)); + fi; + Add(used_parts, current_part); + od; + + P := ShallowCopy(new_P); + prevorigin := ShallowCopy(origin); + + zlpart := PositionProperty(P, part -> Length(part) > 1 and Position(P, [origin]) > Position(P, part)); + zrpart := PositionProperty(P, part -> Length(part) > 1 and Position(P, [origin]) < Position(P, part)); + + if zlpart = fail or zrpart = fail then + if zlpart = fail and zrpart = fail then + continue; + elif zrpart = fail then + zl := ShallowCopy(Minimum(P[zlpart])); + origin := ShallowCopy(zl); + else + zr := ShallowCopy(Minimum(P[zrpart])); + origin := ShallowCopy(zr); + fi; + else + zl := ShallowCopy(Minimum(P[zlpart])); + zr := ShallowCopy(Minimum(P[zrpart])); + if zl in OutNeighboursOfVertex(D, zr) then + origin := ShallowCopy(zl); + else + origin := ShallowCopy(zr); + fi; + fi; + od; + + # Algorithm 5: Recognition Test + + sigma := [0]; + for p in P do + for v in p do + Add(sigma, v); + od; + od; + Add(sigma, Length(verts) + 1); + + z := sigma[2]; + + while z <> Length(verts) + 1 do + succz := sigma[Position(sigma, z) + 1]; + precz := sigma[Position(sigma, z) - 1]; + N_z := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, z)); + if precz <> 0 then + N_precz := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, precz)); + else + N_precz := [0]; + fi; + + if succz <> Length(verts) + 1 then + N_succz := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, succz)); + else + N_succz := [0]; + fi; + + if N_z = N_precz or Union(N_z, [z]) = Union(N_precz, [precz]) then + Remove(sigma, Position(sigma, precz)); + elif N_z = N_succz or Union(N_z, [z]) = Union(N_succz, [succz]) then + z := succz; + Remove(sigma, Position(sigma, precz) + 1); + else + z := succz; + fi; + od; + + if Length(Difference(sigma, [0, Length(verts)+1])) = 1 then + return true; + else + return false; + fi; + +end; \ No newline at end of file From 888fe0f1ffd22412752a8a3fe4c38d09a6ed57a6 Mon Sep 17 00:00:00 2001 From: Cora Aked Date: Wed, 3 Dec 2025 16:44:39 +0000 Subject: [PATCH 2/7] gaplint flagged changes --- IsCograph.g | 65 ++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/IsCograph.g b/IsCograph.g index 365d82c76..0904c84cb 100644 --- a/IsCograph.g +++ b/IsCograph.g @@ -1,13 +1,17 @@ # Function that identifies a cograph from a symmetric digraph -# Created from the algorithm described in the paper "A Simple Linear Time Recognition Algorithm for Cographs" -# Habib, M & Paul, C & Viennot (2005). A Simple Linear Time Recognition Algorithm for Cographs. Discrete Applied Mathematics. 145(2). 183-197. https://doi.org/10.1016/j.dam.2004.01.011. + +# Created from the algorithm described in the paper "A Simple +# Linear Time Recognition Algorithm for Cographs" + +# Habib, M & Paul, C & Viennot (2005). A Simple Linear Time +# Recognition Algorithm for Cographs. Discrete Applied Mathematics. +# 145(2). 183-197. https://doi.org/10.1016/j.dam.2004.01.011. IsCograph := function(D) - local verts, P, origin, adj, part, neighbours, n_x, - used_parts, unused_parts, unused_parts_refined, - k, y, N_y, M, p, m, ma, j,n,v, - zl, zr, prevorigin, new_P, t, current_part, zrpart, pivot, - upd_part, zlpart, upd_m, pivotset, sigma, succz, precz, z, N_z, N_precz, N_succz, options, list, subpart; + local verts, P, origin, adj, part, neighbours, used_parts, unused_parts, + k, M, p, m, ma, j, n, v, zl, zr, prevorigin, new_P, t, current_part, zrpart, + pivot, zlpart, upd_m, pivotset, sigma, succz, precz, z, N_z, N_precz, + N_succz, options, list, subpart; # input must be symmetric if not IsSymmetricDigraph(D) then; @@ -34,7 +38,8 @@ IsCograph := function(D) if Length(P[k]) > 1 then part := Remove(P, k); neighbours := OutNeighboursOfVertex(D, origin); - part := [Filtered(neighbours, p -> p in part), [origin], Difference(part, Union([origin], neighbours))]; + part := [Filtered(neighbours, p -> p in part), [origin], + Difference(part, Union([origin], neighbours))]; unused_parts := [part[1], part[3]]; used_parts := [origin]; for p in Filtered(part, u -> u <> []) do @@ -61,11 +66,14 @@ IsCograph := function(D) # Procedure 4 M := []; - current_part := ShallowCopy(new_P[PositionProperty(new_P, part -> pivot in part)]); + current_part := ShallowCopy(new_P[PositionProperty(new_P, + part -> pivot in part)]); pivotset := OutNeighboursOfVertex(D, pivot); for p in Difference(new_P, [current_part]) do - if Intersection(p, pivotset) <> [] and Intersection(p, pivotset) <> p and Intersection(p, pivotset) <> [origin] then + if Intersection(p, pivotset) <> [] and + Intersection(p, pivotset) <> p + and Intersection(p, pivotset) <> [origin] then k := ShallowCopy(Position(new_P, p)); Remove(new_P, k); Add(M, p); @@ -84,7 +92,8 @@ IsCograph := function(D) if not ma in unused_parts and ma <> [] then Add(unused_parts, ma); fi; - if not Difference(m, ma) in unused_parts and Difference(m,ma) <> [] then + if not Difference(m, ma) in unused_parts and + Difference(m,ma) <> [] then Add(unused_parts, Difference(m, ma)); fi; else @@ -105,10 +114,11 @@ IsCograph := function(D) od; P := ShallowCopy(new_P); - prevorigin := ShallowCopy(origin); - zlpart := PositionProperty(P, part -> Length(part) > 1 and Position(P, [origin]) > Position(P, part)); - zrpart := PositionProperty(P, part -> Length(part) > 1 and Position(P, [origin]) < Position(P, part)); + zlpart := PositionProperty(P, part -> Length(part) > 1 + and Position(P, [origin]) > Position(P, part)); + zrpart := PositionProperty(P, part -> Length(part) > 1 + and Position(P, [origin]) < Position(P, part)); if zlpart = fail or zrpart = fail then if zlpart = fail and zrpart = fail then @@ -140,39 +150,34 @@ IsCograph := function(D) od; od; Add(sigma, Length(verts) + 1); - z := sigma[2]; - while z <> Length(verts) + 1 do succz := sigma[Position(sigma, z) + 1]; precz := sigma[Position(sigma, z) - 1]; - N_z := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, z)); + N_z := Filtered(sigma, n -> n in + OutNeighboursOfVertex(D, z)); if precz <> 0 then - N_precz := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, precz)); + N_precz := Filtered(sigma, n -> n in + OutNeighboursOfVertex(D, precz)); else N_precz := [0]; fi; - if succz <> Length(verts) + 1 then - N_succz := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, succz)); + N_succz := Filtered(sigma, n -> n in + OutNeighboursOfVertex(D, succz)); else N_succz := [0]; fi; - - if N_z = N_precz or Union(N_z, [z]) = Union(N_precz, [precz]) then + if N_z = N_precz or Union(N_z, [z]) = + Union(N_precz, [precz]) then Remove(sigma, Position(sigma, precz)); - elif N_z = N_succz or Union(N_z, [z]) = Union(N_succz, [succz]) then + elif N_z = N_succz or Union(N_z, [z]) = + Union(N_succz, [succz]) then z := succz; Remove(sigma, Position(sigma, precz) + 1); else z := succz; fi; od; - - if Length(Difference(sigma, [0, Length(verts)+1])) = 1 then - return true; - else - return false; - fi; - + return Length(Difference(sigma, [0, Length(verts)+1])) = 1; end; \ No newline at end of file From 63f151e134574fec4a1cc8906b35e326bc1d9975 Mon Sep 17 00:00:00 2001 From: Cora Aked Date: Wed, 3 Dec 2025 17:19:24 +0000 Subject: [PATCH 3/7] Fix further gaplint flagged errors and comments --- IsCograph.g | 82 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/IsCograph.g b/IsCograph.g index 0904c84cb..0b0e17090 100644 --- a/IsCograph.g +++ b/IsCograph.g @@ -1,15 +1,15 @@ # Function that identifies a cograph from a symmetric digraph -# Created from the algorithm described in the paper "A Simple +# Created from the algorithm described in the paper "A Simple # Linear Time Recognition Algorithm for Cographs" -# Habib, M & Paul, C & Viennot (2005). A Simple Linear Time -# Recognition Algorithm for Cographs. Discrete Applied Mathematics. +# Habib, M & Paul, C & Viennot (2005). A Simple Linear Time +# Recognition Algorithm for Cographs. Discrete Applied Mathematics. # 145(2). 183-197. https://doi.org/10.1016/j.dam.2004.01.011. IsCograph := function(D) - local verts, P, origin, adj, part, neighbours, used_parts, unused_parts, - k, M, p, m, ma, j, n, v, zl, zr, prevorigin, new_P, t, current_part, zrpart, + local verts, P, origin, adj, part, neighbours, used_parts, unused_parts, + k, M, p, m, ma, j, n, v, zl, zr, new_P, t, current_part, zrpart, pivot, zlpart, upd_m, pivotset, sigma, succz, precz, z, N_z, N_precz, N_succz, options, list, subpart; @@ -21,24 +21,27 @@ IsCograph := function(D) verts := DigraphVertices(D); P := [verts]; - # a graph with fewer than 4 vertices cannot contain a P4 graph + # a graph with fewer than 4 vertices cannot contain P4 graph if Length(verts) < 4 then return true; fi; + # set origin to be a non-isolated or universal vertex origin := 1; adj := OutNeighboursOfVertex(D, origin); if Length(adj) = 0 or Length(adj) = Length(verts) - 1 then - return IsCograph(InducedSubdigraph(D, Filtered(verts, v -> v <> origin))); + return IsCograph(InducedSubdigraph(D, Filtered(verts, v -> + v <> origin))); fi; - # Algorithm 3: Partition Refinement + # Algorithm 2: Partition Refinement + # while there exist non-singleton parts, refine using rule 1 while ForAll(P, part -> Length(part) <= 1) = false do k := PositionProperty(P, part -> origin in part); if Length(P[k]) > 1 then part := Remove(P, k); neighbours := OutNeighboursOfVertex(D, origin); - part := [Filtered(neighbours, p -> p in part), [origin], + part := [Filtered(neighbours, p -> p in part), [origin], Difference(part, Union([origin], neighbours))]; unused_parts := [part[1], part[3]]; used_parts := [origin]; @@ -49,10 +52,8 @@ IsCograph := function(D) # Procedure 3 new_P := ShallowCopy(P); - if ForAll(new_P, part -> Length(part) <= 1) = true then - break; - fi; - + # while we have unused parts, pick an unused part, set an unused pivot + # and refine with rule 2 using the neighbours of the pivot while Length(Filtered(unused_parts, u -> u <> [])) > 0 do options := Filtered(unused_parts, part -> Length(part) > 0); list := List(options, j -> Minimum(j)); @@ -66,20 +67,19 @@ IsCograph := function(D) # Procedure 4 M := []; - current_part := ShallowCopy(new_P[PositionProperty(new_P, + current_part := ShallowCopy(new_P[PositionProperty(new_P, part -> pivot in part)]); - pivotset := OutNeighboursOfVertex(D, pivot); + pivotset := OutNeighboursOfVertex(D, pivot); for p in Difference(new_P, [current_part]) do - if Intersection(p, pivotset) <> [] and - Intersection(p, pivotset) <> p + if Intersection(p, pivotset) <> [] and + Intersection(p, pivotset) <> p and Intersection(p, pivotset) <> [origin] then k := ShallowCopy(Position(new_P, p)); Remove(new_P, k); Add(M, p); fi; od; - if M <> [] then for m in M do ma := Filtered(m, p -> p in pivotset); @@ -93,7 +93,7 @@ IsCograph := function(D) Add(unused_parts, ma); fi; if not Difference(m, ma) in unused_parts and - Difference(m,ma) <> [] then + Difference(m, ma) <> [] then Add(unused_parts, Difference(m, ma)); fi; else @@ -110,39 +110,41 @@ IsCograph := function(D) if current_part in unused_parts then Remove(unused_parts, Position(unused_parts, current_part)); fi; - Add(used_parts, current_part); - od; - + Add(used_parts, current_part); + od; P := ShallowCopy(new_P); - - zlpart := PositionProperty(P, part -> Length(part) > 1 + # consider the pivots either side of origin + zlpart := PositionProperty(P, part -> Length(part) > 1 and Position(P, [origin]) > Position(P, part)); - zrpart := PositionProperty(P, part -> Length(part) > 1 + zrpart := PositionProperty(P, part -> Length(part) > 1 and Position(P, [origin]) < Position(P, part)); - + # if there is no part on rhs or lhs, consider + # only the existing ones if zlpart = fail or zrpart = fail then if zlpart = fail and zrpart = fail then continue; - elif zrpart = fail then + elif zrpart = fail then zl := ShallowCopy(Minimum(P[zlpart])); origin := ShallowCopy(zl); else zr := ShallowCopy(Minimum(P[zrpart])); origin := ShallowCopy(zr); fi; + # if both exist, if they are adjacent in G, set + # origin to be the left pivot, else the right pivot else zl := ShallowCopy(Minimum(P[zlpart])); zr := ShallowCopy(Minimum(P[zrpart])); if zl in OutNeighboursOfVertex(D, zr) then origin := ShallowCopy(zl); - else + else origin := ShallowCopy(zr); fi; fi; od; - - # Algorithm 5: Recognition Test + # Algorithm 5: Recognition Test + # add markers to either end of permutation sigma := [0]; for p in P do for v in p do @@ -150,14 +152,20 @@ IsCograph := function(D) od; od; Add(sigma, Length(verts) + 1); + + # move left to right z := sigma[2]; while z <> Length(verts) + 1 do + # calculate neighbours of z, predecessor and + # successor succz := sigma[Position(sigma, z) + 1]; precz := sigma[Position(sigma, z) - 1]; - N_z := Filtered(sigma, n -> n in + N_z := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, z)); + # deal with cases where predecessor or + # successor is a marker if precz <> 0 then - N_precz := Filtered(sigma, n -> n in + N_precz := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, precz)); else N_precz := [0]; @@ -168,10 +176,12 @@ IsCograph := function(D) else N_succz := [0]; fi; - if N_z = N_precz or Union(N_z, [z]) = + # if z shares a neighbourhood with predecessor or successor, + # remove the predecessor and move right + if N_z = N_precz or Union(N_z, [z]) = Union(N_precz, [precz]) then Remove(sigma, Position(sigma, precz)); - elif N_z = N_succz or Union(N_z, [z]) = + elif N_z = N_succz or Union(N_z, [z]) = Union(N_succz, [succz]) then z := succz; Remove(sigma, Position(sigma, precz) + 1); @@ -179,5 +189,7 @@ IsCograph := function(D) z := succz; fi; od; - return Length(Difference(sigma, [0, Length(verts)+1])) = 1; + # continue until we hit end marker + # if only markers remain, G is a cograph + return Length(Difference(sigma, [0, Length(verts) + 1])) = 1; end; \ No newline at end of file From e94f027da1dda95fe755ef2418e725bed99c5edc Mon Sep 17 00:00:00 2001 From: Cora Aked Date: Wed, 3 Dec 2025 17:44:30 +0000 Subject: [PATCH 4/7] Fix whitespace issues and add further comments --- IsCograph.g | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/IsCograph.g b/IsCograph.g index 0b0e17090..03abcc88e 100644 --- a/IsCograph.g +++ b/IsCograph.g @@ -8,7 +8,7 @@ # 145(2). 183-197. https://doi.org/10.1016/j.dam.2004.01.011. IsCograph := function(D) - local verts, P, origin, adj, part, neighbours, used_parts, unused_parts, + local verts, P, origin, adj, part, used_parts, unused_parts, k, M, p, m, ma, j, n, v, zl, zr, new_P, t, current_part, zrpart, pivot, zlpart, upd_m, pivotset, sigma, succz, precz, z, N_z, N_precz, N_succz, options, list, subpart; @@ -39,18 +39,18 @@ IsCograph := function(D) while ForAll(P, part -> Length(part) <= 1) = false do k := PositionProperty(P, part -> origin in part); if Length(P[k]) > 1 then - part := Remove(P, k); - neighbours := OutNeighboursOfVertex(D, origin); - part := [Filtered(neighbours, p -> p in part), [origin], - Difference(part, Union([origin], neighbours))]; + part := [Filtered(OutNeighboursOfVertex(D, origin), p -> p in P[k]), + [origin], Difference(P[k], Union([origin], OutNeighboursOfVertex + (D, origin)))]; unused_parts := [part[1], part[3]]; used_parts := [origin]; + Remove(P,k); for p in Filtered(part, u -> u <> []) do Add(P, p, k); od; fi; - # Procedure 3 + # Procedure 3 new_P := ShallowCopy(P); # while we have unused parts, pick an unused part, set an unused pivot # and refine with rule 2 using the neighbours of the pivot @@ -66,6 +66,8 @@ IsCograph := function(D) fi; # Procedure 4 + # M is the set of parts strictly intersected by the + # neighbourhood of the pivot M := []; current_part := ShallowCopy(new_P[PositionProperty(new_P, part -> pivot in part)]); @@ -80,22 +82,29 @@ IsCograph := function(D) Add(M, p); fi; od; + # if we have parts to refine, do so if M <> [] then + # for each part in M, split into those in pivot set + # and those not for m in M do ma := Filtered(m, p -> p in pivotset); upd_m := [ma, Difference(m, ma)]; for t in Filtered(upd_m, x -> x <> []) do Add(new_P, t, k); od; + # if our part is unused, mark the new parts as unused + # and mark this one as used if m in unused_parts then Remove(unused_parts, Position(unused_parts, m)); if not ma in unused_parts and ma <> [] then Add(unused_parts, ma); fi; - if not Difference(m, ma) in unused_parts and + if not Difference(m, ma) in unused_parts and Difference(m, ma) <> [] then Add(unused_parts, Difference(m, ma)); fi; + # otherwise the new subpart not containing the pivot + # is unused else if Minimum(m) in upd_m[1] then Add(unused_parts, upd_m[2]); @@ -111,9 +120,9 @@ IsCograph := function(D) Remove(unused_parts, Position(unused_parts, current_part)); fi; Add(used_parts, current_part); - od; + od; P := ShallowCopy(new_P); - # consider the pivots either side of origin + # consider the pivots either side of origin zlpart := PositionProperty(P, part -> Length(part) > 1 and Position(P, [origin]) > Position(P, part)); zrpart := PositionProperty(P, part -> Length(part) > 1 @@ -130,7 +139,7 @@ IsCograph := function(D) zr := ShallowCopy(Minimum(P[zrpart])); origin := ShallowCopy(zr); fi; - # if both exist, if they are adjacent in G, set + # if both exist, if they are adjacent in G, set # origin to be the left pivot, else the right pivot else zl := ShallowCopy(Minimum(P[zlpart])); @@ -156,14 +165,14 @@ IsCograph := function(D) # move left to right z := sigma[2]; while z <> Length(verts) + 1 do - # calculate neighbours of z, predecessor and - # successor + # calculate neighbours of z, predecessor and + # successor succz := sigma[Position(sigma, z) + 1]; precz := sigma[Position(sigma, z) - 1]; N_z := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, z)); - # deal with cases where predecessor or - # successor is a marker + # deal with cases where predecessor or + # successor is a marker if precz <> 0 then N_precz := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, precz)); @@ -171,18 +180,18 @@ IsCograph := function(D) N_precz := [0]; fi; if succz <> Length(verts) + 1 then - N_succz := Filtered(sigma, n -> n in + N_succz := Filtered(sigma, n -> n in OutNeighboursOfVertex(D, succz)); else N_succz := [0]; fi; - # if z shares a neighbourhood with predecessor or successor, - # remove the predecessor and move right + # if z shares a neighbourhood with predecessor or successor, + # remove the predecessor and move right if N_z = N_precz or Union(N_z, [z]) = - Union(N_precz, [precz]) then + Union(N_precz, [precz]) then Remove(sigma, Position(sigma, precz)); elif N_z = N_succz or Union(N_z, [z]) = - Union(N_succz, [succz]) then + Union(N_succz, [succz]) then z := succz; Remove(sigma, Position(sigma, precz) + 1); else From c91bd5b84bd4c708e3090af4f08f4bb7c7f85cec Mon Sep 17 00:00:00 2001 From: Cora Aked Date: Wed, 3 Dec 2025 17:49:47 +0000 Subject: [PATCH 5/7] indentation issues fixed --- IsCograph.g | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/IsCograph.g b/IsCograph.g index 03abcc88e..8bd9679c7 100644 --- a/IsCograph.g +++ b/IsCograph.g @@ -39,12 +39,14 @@ IsCograph := function(D) while ForAll(P, part -> Length(part) <= 1) = false do k := PositionProperty(P, part -> origin in part); if Length(P[k]) > 1 then - part := [Filtered(OutNeighboursOfVertex(D, origin), p -> p in P[k]), - [origin], Difference(P[k], Union([origin], OutNeighboursOfVertex - (D, origin)))]; + part := [Filtered(OutNeighboursOfVertex(D, origin), p -> p + in P[k]), [origin], Difference(P[k], Union([origin], + OutNeighboursOfVertex(D, origin)))]; + # make note of unused and used parts unused_parts := [part[1], part[3]]; used_parts := [origin]; - Remove(P,k); + # replace the used part with our new refinement + Remove(P, k); for p in Filtered(part, u -> u <> []) do Add(P, p, k); od; @@ -58,7 +60,8 @@ IsCograph := function(D) options := Filtered(unused_parts, part -> Length(part) > 0); list := List(options, j -> Minimum(j)); subpart := unused_parts[Position(list, Minimum(list))]; - + # pick our pivot to be either an unused vertex in the subpart, + # or if none exist, any vertex in the subpart if Filtered(subpart, u -> u in used_parts) = [] then pivot := Minimum(subpart); else @@ -72,7 +75,8 @@ IsCograph := function(D) current_part := ShallowCopy(new_P[PositionProperty(new_P, part -> pivot in part)]); pivotset := OutNeighboursOfVertex(D, pivot); - + # Add to M any part that is strictly intersected + # by pivotset for p in Difference(new_P, [current_part]) do if Intersection(p, pivotset) <> [] and Intersection(p, pivotset) <> p @@ -188,10 +192,10 @@ IsCograph := function(D) # if z shares a neighbourhood with predecessor or successor, # remove the predecessor and move right if N_z = N_precz or Union(N_z, [z]) = - Union(N_precz, [precz]) then + Union(N_precz, [precz]) then Remove(sigma, Position(sigma, precz)); elif N_z = N_succz or Union(N_z, [z]) = - Union(N_succz, [succz]) then + Union(N_succz, [succz]) then z := succz; Remove(sigma, Position(sigma, precz) + 1); else From 21387de74ca75d474788ba8c3e1685e21547de74 Mon Sep 17 00:00:00 2001 From: Cora Aked Date: Wed, 3 Dec 2025 17:58:32 +0000 Subject: [PATCH 6/7] Change j -> Minimum(j) to 'minimum' --- IsCograph.g | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IsCograph.g b/IsCograph.g index 8bd9679c7..1e1a84c15 100644 --- a/IsCograph.g +++ b/IsCograph.g @@ -58,7 +58,7 @@ IsCograph := function(D) # and refine with rule 2 using the neighbours of the pivot while Length(Filtered(unused_parts, u -> u <> [])) > 0 do options := Filtered(unused_parts, part -> Length(part) > 0); - list := List(options, j -> Minimum(j)); + list := List(options, Minimum); subpart := unused_parts[Position(list, Minimum(list))]; # pick our pivot to be either an unused vertex in the subpart, # or if none exist, any vertex in the subpart From c6e970a13d1f6a652e955b1bab06e2e08347047d Mon Sep 17 00:00:00 2001 From: Cora Aked Date: Wed, 3 Dec 2025 18:00:25 +0000 Subject: [PATCH 7/7] remove unused local variable --- IsCograph.g | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IsCograph.g b/IsCograph.g index 1e1a84c15..375081fb6 100644 --- a/IsCograph.g +++ b/IsCograph.g @@ -9,7 +9,7 @@ IsCograph := function(D) local verts, P, origin, adj, part, used_parts, unused_parts, - k, M, p, m, ma, j, n, v, zl, zr, new_P, t, current_part, zrpart, + k, M, p, m, ma, n, v, zl, zr, new_P, t, current_part, zrpart, pivot, zlpart, upd_m, pivotset, sigma, succz, precz, z, N_z, N_precz, N_succz, options, list, subpart;