Implement IsJoinIrreducible and IsMeetIrreducible#910
Implement IsJoinIrreducible and IsMeetIrreducible#910ThatOtherAndrew wants to merge 7 commits intodigraphs:mainfrom
Conversation
|
Requesting a review from @james-d-mitchell please - how does this look? Is the PR description sufficiently detailed and mathematically accurate? |
james-d-mitchell
left a comment
There was a problem hiding this comment.
Looks good to me! If you also resolve #714, then this PR (or the code if merged first) should be updated to check for that rather than IsPartialOrderDigraph. Otherwise, this looks good to me!
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #910 +/- ##
=======================================
Coverage 97.35% 97.36%
=======================================
Files 50 50
Lines 21045 21069 +24
Branches 639 639
=======================================
+ Hits 20489 20513 +24
Misses 491 491
Partials 65 65 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| fi; | ||
| hasse := DigraphReflexiveTransitiveReduction(DigraphMutableCopyIfMutable(D)); | ||
| # join-irreducible iff at most one lower cover in the Hasse diagram | ||
| return InDegreeOfVertexNC(hasse, v) <= 1; |
There was a problem hiding this comment.
| return InDegreeOfVertexNC(hasse, v) <= 1; | |
| return InDegrees(hasse)[v] <= 1; |
Turns out InDegreeOfVertexNC is rather slow if called repeatedly, in one example I have before this suggested change:
gap> D := DigraphReflexiveTransitiveClosure(DigraphRemoveAllMultipleEdges(D));
<immutable preorder digraph with 8146 vertices, 1768801 edges>
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
2180
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
1813
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
1799
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
1805
and after:
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
373
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
1
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
3
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
2
gap> Filtered(DigraphVertices(D), x-> IsJoinIrreducible(D, x)); time;
[ 1, 110, 111, 112, 113, 130, 163, 164, 210, 213, 218, 222, 225, 227, 230, 231, 232, 236, 237, 241, 242, 244, 246, 269, 270,
273, 274, 275, 276, 277, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331 ]
2
gap>
| fi; | ||
| hasse := DigraphReflexiveTransitiveReduction(DigraphMutableCopyIfMutable(D)); | ||
| # meet-irreducible iff at most one upper cover in the Hasse diagram | ||
| return OutDegreeOfVertexNC(hasse, v) <= 1; |
There was a problem hiding this comment.
This doesn't suffer in the same way as InDegree so no change suggested here.
Adds two new operations to section 10 (Operations for vertices) of
oper.gi/oper.gd:IsJoinIrreducible(D, v)— returnstrueif vertexvis not the join of any two distinct smaller nodes inDIsMeetIrreducible(D, v)— returnstrueif vertexvis not the meet of any two distinct larger nodes inDBoth were originally implemented by building the full O(N²) join/meet table, but then optimised to use
DigraphReflexiveTransitiveReduction, a function producing a Hasse diagram which allows for a computational shortcut (see SageMath docs below):https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/posets/hasse_diagram.html#sage.combinat.posets.hasse_diagram.HasseDiagram.find_nontrivial_congruence
Tests are merged into
tst/standard/oper.tst, covering N5, a chain, B2, M3, and error handling (two test case sets written by myself and the rest with LLM assistance because I do not think my mathematical knowledge of the underlying concepts is strong enough to come up with reasonably comprehensive/diverse test cases).Closes #400