diff --git a/gap/oper.gd b/gap/oper.gd index f6a37e0f8..08dbf19f5 100644 --- a/gap/oper.gd +++ b/gap/oper.gd @@ -161,3 +161,6 @@ DeclareOperation("PartialOrderDigraphJoinOfVertices", [IsDigraph, IsPosInt, IsPosInt]); DeclareOperation("PartialOrderDigraphMeetOfVertices", [IsDigraph, IsPosInt, IsPosInt]); + +DeclareOperation("IsJoinIrreducible", [IsDigraph, IsPosInt]); +DeclareOperation("IsMeetIrreducible", [IsDigraph, IsPosInt]); diff --git a/gap/oper.gi b/gap/oper.gi index 3876db50e..c652d8c91 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -2720,6 +2720,38 @@ function(D, i, j) return fail; end); +InstallMethod(IsJoinIrreducible, +"for a digraph and a positive integer", +[IsDigraph, IsPosInt], +function(D, v) + local hasse; + if not IsPartialOrderDigraph(D) then + ErrorNoReturn("the 1st argument must satisfy IsPartialOrderDigraph,"); + elif not v in DigraphVertices(D) then + ErrorNoReturn("the 2nd argument must be a vertex of the ", + "1st argument ,"); + fi; + hasse := DigraphReflexiveTransitiveReduction(DigraphMutableCopyIfMutable(D)); + # join-irreducible iff at most one lower cover in the Hasse diagram + return InDegreeOfVertexNC(hasse, v) <= 1; +end); + +InstallMethod(IsMeetIrreducible, +"for a digraph and a positive integer", +[IsDigraph, IsPosInt], +function(D, v) + local hasse; + if not IsPartialOrderDigraph(D) then + ErrorNoReturn("the 1st argument must satisfy IsPartialOrderDigraph,"); + elif not v in DigraphVertices(D) then + ErrorNoReturn("the 2nd argument must be a vertex of the ", + "1st argument ,"); + fi; + hasse := DigraphReflexiveTransitiveReduction(DigraphMutableCopyIfMutable(D)); + # meet-irreducible iff at most one upper cover in the Hasse diagram + return OutDegreeOfVertexNC(hasse, v) <= 1; +end); + InstallMethod(DigraphKings, "for a digraph and a positive integer", [IsDigraph, IsPosInt], function(D, n) diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index 1c813fe21..0bf0c42a1 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -17,6 +17,7 @@ #@local out, out1, out2, out3, p1, p2, path, preorder, qr, r, res, rtclosure, t #@local tclosure, u1, u2, x #@local p, q, idp, idt, M +#@local b2, chain, lattice, m3 gap> START_TEST("Digraphs package: standard/oper.tst"); gap> LoadPackage("digraphs", false);; @@ -1514,18 +1515,18 @@ gap> gr := ChainDigraph(5); gap> DigraphRandomWalk(gr, 2, 100); [ [ 2, 3, 4, 5 ], [ 1, 1, 1 ] ] -gap> DigraphRandomWalk(gr, 2, 2); +gap> DigraphRandomWalk(gr, 2, 2); [ [ 2, 3, 4 ], [ 1, 1 ] ] gap> DigraphRandomWalk(gr, 5, 100); [ [ 5 ], [ ] ] gap> gr := CompleteBipartiteDigraph(10, 8);; -gap> DigraphRandomWalk(gr, 3, 0); +gap> DigraphRandomWalk(gr, 3, 0); [ [ 3 ], [ ] ] gap> DigraphRandomWalk(gr, 19, 5); Error, the 2nd argument must be a vertex of the 1st argument , gap> DigraphRandomWalk(gr, 123, 5); Error, the 2nd argument must be a vertex of the 1st argument , -gap> DigraphRandomWalk(gr, 3, -1); +gap> DigraphRandomWalk(gr, 3, -1); Error, the 3rd argument must be a non-negative int, # DigraphLayers @@ -1822,6 +1823,108 @@ fail gap> PartialOrderDigraphJoinOfVertices(gr1, 3, 4); fail +# IsJoinIrreducible, IsMeetIrreducible + +# The pentagon lattice N5: 1 < {2, 3}, 3 < 4, {2, 4} < 5 +gap> gr := Digraph([[2, 3], [5], [4], [5], []]); + +gap> lattice := DigraphReflexiveTransitiveClosure(gr); + +gap> IsJoinIrreducible(lattice, 1); +true +gap> IsJoinIrreducible(lattice, 2); +true +gap> IsJoinIrreducible(lattice, 3); +true +gap> IsJoinIrreducible(lattice, 4); +true +gap> IsJoinIrreducible(lattice, 5); +false +gap> IsMeetIrreducible(lattice, 1); +false +gap> IsMeetIrreducible(lattice, 2); +true +gap> IsMeetIrreducible(lattice, 3); +true +gap> IsMeetIrreducible(lattice, 4); +true +gap> IsMeetIrreducible(lattice, 5); +true + +# A 4-element chain: every element is doubly irreducible +gap> chain := DigraphReflexiveTransitiveClosure(ChainDigraph(4)); + +gap> IsJoinIrreducible(chain, 1); +true +gap> IsJoinIrreducible(chain, 2); +true +gap> IsJoinIrreducible(chain, 3); +true +gap> IsJoinIrreducible(chain, 4); +true +gap> IsMeetIrreducible(chain, 1); +true +gap> IsMeetIrreducible(chain, 2); +true +gap> IsMeetIrreducible(chain, 3); +true +gap> IsMeetIrreducible(chain, 4); +true + +# The Boolean lattice B2: 1 < {2, 3} < 4 +gap> b2 := DigraphReflexiveTransitiveClosure(Digraph([[2, 3], [4], [4], []])); + +gap> IsJoinIrreducible(b2, 1); +true +gap> IsJoinIrreducible(b2, 2); +true +gap> IsJoinIrreducible(b2, 3); +true +gap> IsJoinIrreducible(b2, 4); +false +gap> IsMeetIrreducible(b2, 1); +false +gap> IsMeetIrreducible(b2, 2); +true +gap> IsMeetIrreducible(b2, 3); +true +gap> IsMeetIrreducible(b2, 4); +true + +# The M3 lattice: 1 < {2, 3, 4} < 5 +gap> m3 := DigraphReflexiveTransitiveClosure(Digraph([[2, 3, 4], [5], [5], [5], []])); + +gap> IsJoinIrreducible(m3, 1); +true +gap> IsJoinIrreducible(m3, 2); +true +gap> IsJoinIrreducible(m3, 3); +true +gap> IsJoinIrreducible(m3, 4); +true +gap> IsJoinIrreducible(m3, 5); +false +gap> IsMeetIrreducible(m3, 1); +false +gap> IsMeetIrreducible(m3, 2); +true +gap> IsMeetIrreducible(m3, 3); +true +gap> IsMeetIrreducible(m3, 4); +true +gap> IsMeetIrreducible(m3, 5); +true + +# Error handling +gap> IsJoinIrreducible(CycleDigraph(3), 1); +Error, the 1st argument must satisfy IsPartialOrderDigraph, +gap> IsMeetIrreducible(CycleDigraph(3), 1); +Error, the 1st argument must satisfy IsPartialOrderDigraph, +gap> IsJoinIrreducible(Digraph([[1]]), 2); +Error, the 2nd argument must be a vertex of the 1st argument , +gap> IsMeetIrreducible(Digraph([[1]]), 2); +Error, the 2nd argument must be a vertex of the 1st argument , + # DigraphClosure gap> gr := Digraph([[4, 5, 6, 7, 9], [7, 3], [2, 6, 7, 9, 10], > [5, 6, 7, 1, 9], [1, 4, 6, 7], [7, 1, 3, 4, 5], @@ -2460,9 +2563,9 @@ gap> ConormalProduct(CycleDigraph(2), CycleDigraph(8)); #HomomorphicProduct gap> D := Digraph([[2, 3], [1, 3, 3], [1, 2, 2]]); -gap> HomomorphicProduct(D, D); +gap> HomomorphicProduct(D, D); Error, the 1st argument (a digraph) must not satisfy IsMultiDigraph -gap> DigraphSymmetricClosure(CycleDigraph(6)); +gap> DigraphSymmetricClosure(CycleDigraph(6)); gap> HomomorphicProduct(PetersenGraph(), last); @@ -2525,7 +2628,7 @@ gap> StrongProduct(NullDigraph(0), CompleteDigraph(3)); gap> D1 := Digraph([[2], [1, 3, 4], [2, 5], [2, 5], [3, 4]]); -gap> D2 := Digraph([[2], [1, 3, 4], [2], [2]]); +gap> D2 := Digraph([[2], [1, 3, 4], [2], [2]]); gap> LexicographicProduct(D1, D2); @@ -2545,7 +2648,7 @@ gap> OutNeighbours(last); [ 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20 ], [ 9, 10, 11, 12, 13, 14, 15, 16, 18 ], [ 9, 10, 11, 12, 13, 14, 15, 16, 18 ] ] -gap> LexicographicProduct(ChainDigraph(3), CycleDigraph(7)); +gap> LexicographicProduct(ChainDigraph(3), CycleDigraph(7)); # SwapDigraphs @@ -3032,7 +3135,7 @@ Error, expected an edge between the 2nd and 3rd arguments (vertices) 1 and # DigraphContractEdge: Edge is a looped edge (u = v) gap> D := DigraphByEdges([[1, 1], [2, 1], [1, 2]]);; -gap> DigraphVertexLabels(D);; +gap> DigraphVertexLabels(D);; gap> C := DigraphContractEdge(D, 1, 1); Error, The 2nd argument must not be equal to the 3rd argument gap> DigraphHasLoops(D); @@ -3196,7 +3299,7 @@ Error, expected an edge between the 2nd and 3rd arguments (vertices) 1 and # DigraphContractEdge: Edge is a looped edge (u = v) (mutable) gap> D := DigraphByEdges(IsMutableDigraph, [[1, 1], [2, 1], [1, 2]]);; -gap> DigraphVertexLabels(D);; +gap> DigraphVertexLabels(D);; gap> DigraphContractEdge(D, 1, 1); Error, The 2nd argument must not be equal to the 3rd argument gap> DigraphHasLoops(D);