Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #29 +/- ##
===========================================
+ Coverage 72.23% 83.44% +11.20%
===========================================
Files 15 11 -4
Lines 868 767 -101
===========================================
+ Hits 627 640 +13
+ Misses 241 127 -114
🚀 New features to boost your workflow:
|
fingolfin
force-pushed
the
polymake-json
branch
from
August 16, 2026 20:41
fbf9c4e to
2c8dc43
Compare
fingolfin
force-pushed
the
polymake-json
branch
from
August 16, 2026 21:45
2635b15 to
def48f4
Compare
fingolfin
force-pushed
the
polymake-json
branch
from
August 16, 2026 21:51
def48f4 to
959d25c
Compare
fingolfin
force-pushed
the
polymake-json
branch
from
August 16, 2026 21:58
959d25c to
522c707
Compare
polymaking spoke to polymake through the pre-4 plain file format: it wrote files in it, and lib/pm_script_arg.pl stringified results so that GAP could scrape them back out of standard output. Reconstructing typed values from that text needed a table mapping each of 58 keywords to a hand written parser, one of which had to guess whether a block was a matrix or a list of sets by looking for a brace. polymake 4 has its own JSON format, and the json package can read it, so do that instead. lib/pm.pl evaluates each requested property, serializes it with polymake's own serializer and writes one JSON file, which GAP reads back. Going through a file rather than standard output means results can never be confused with anything polymake prints. Values are now decoded by polymake's type rather than by keyword, so properties polymaking has never heard of decode correctly too. Only the conventions that genuinely depend on the keyword are left: stripping the homogenizing 1 from points, and the two node indices that the type system cannot flag as indices. Sets, incidence matrices and adjacency lists are recognised as index containers by their type, so the 0-based to 1-based shift no longer needs a table either. Consequences: - Files are written as JSON, so polymake never converts them and never warns that it did. This is the rest of issue #23. - Nested properties can be named directly: Polymake(poly, "HASSE_DIAGRAM.FACES") rather than the keyword rewriting in workaround_maps.gi. This restores full access to the Hasse diagram. DIMS is not among them; polymake 4 cannot compute it from a polytope's Hasse diagram and says so. - Polymake(poly, "GRAPH") works again. It used to fail with POSITION_SUBSTRING: <string> must be a string. - Keywords are evaluated independently, so one failing no longer discards the results of the others. - Floating point properties such as MINIMAL_VERTEX_ANGLE return a GAP float rather than a rational approximation of one. polymake before 4.0 cannot read the files polymaking now writes, so it is rejected with a clear error on the first call rather than left to fail obscurely. The version is detected lazily; loading the package still spawns no processes. AppendToPolymakeObject now takes a GAP value rather than a string to append verbatim, since JSON is not append friendly: the file is rewritten from the properties set so far. As a result polymaking refuses to write to a file it did not create, rather than corrupting it. Fixes #22. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Also avoid the two argument form of Set, declared only in GAP 4.11, in the decoder; the version bump makes it available, but there is no reason to depend on it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The version gate is a hard error on a path users can hit, but nothing exercised it. Drive it through POLYMAKING_STATE rather than a stub binary, so the test needs no subprocess. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A SparseMatrix may mix sparse rows with dense ones, and an all-zero row serializes as an empty record; both are easy to get wrong. The shapes here were taken from polymake 4.15 output rather than invented. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The remark only made sense to readers who knew what polymaking used to write. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fingolfin
force-pushed
the
polymake-json
branch
from
August 16, 2026 22:06
522c707 to
4338f18
Compare
hap and hapcryst are needed-dependency consumers of polymaking, and neither pins an upper bound, so 0.9.0 will be paired with existing releases of both. Measured against them, the rewrite broke hapcryst's test suite entirely (9 failures, 0 before) and hap's IsAspherical. Three things they rely on come back: - POLYMAKE_COMMAND and POLYMAKE_DATA_DIR are set again, for code that reads them. Whether the *user* bound them before loading is recorded once, in POLYMAKING_LEGACY_SET, so our own values are not mistaken for theirs and the preferences stay the source of truth. A post restore hook refreshes them, so unlike in 0.8.9 they do not go stale with a saved workspace. - ConvertMatrixToPolymakeString and the two argument AppendToPolymakeObject work together as before. Nothing appends verbatim to a JSON file, so the former now passes the section along as a record rather than as a string; code composing the two, which is how both packages use them, is unaffected. Appending a bare string reports what to use instead. - The polymake 2.3 era type names that CheckAppVerTypList accepts are mapped to their polymake 4 spellings. hapcryst asks for RationalPolytope, which polymake 4 knows as Polytope<Rational> and would otherwise reject. The deprecation notices for the second group are issued at InfoObsolete level 2 rather than 1: warning by default would change the output of the packages this is meant to keep working, and so break their tests. With this, hapcryst is back to 0 failures and hap's IsAspherical answers again, both unmodified. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #22.
Net: +787 / −1224 lines.
What was there
polymaking spoke to polymake through the pre-4 plain format: it wrote files in
it, and
pm_script_arg.plstringified results so GAP could scrape them offstandard output. Rebuilding typed values from that text needed
ObjectConverters, a table mapping 58 keywords to hand-written parsers -- oneof which guessed whether a block was a matrix or a list of sets by checking for
a
{.What it is now
lib/pm.plevaluates each requested property, serializes it with polymake'sown serializer, and writes one JSON file that GAP reads with the
jsonpackage. A file rather than stdout, because polymake's own output shares that
channel and one stray line would corrupt the document.
Values are decoded by polymake's type, not by keyword, so properties
polymaking has never heard of decode correctly too. What survives is only what
the type genuinely cannot tell us:
POINTS,VERTICES,REL_INT_POINT,VALID_POINT,VERTEX_BARYCENTER) --VERTICESandFACETSare bothMatrix<Rational>and only one is a list of points;TOP_NODE,BOTTOM_NODE).The 0-based to 1-based shift is derivable:
Set<Int>,IncidenceMatrixandGraphAdjacencyare index containers, whileArray<Int>(e.g.FACET_DEGREES) holds values. That is what retiresConvertPolymakeMatrixOrListOfSetsToGAP{,PlusOne}.So
convert.gd/gi(20 parsers),ObjectConverters.gd/gi(58 entries),workaround_maps.gd/giandpm_script_arg.plare gone;json.gd/giandpm.plreplace them.Consequences
so. That is the remainder of Allow to silence certain polymake messages to stderr #23 -- verified: loading a polymaking-written
file produces completely empty stderr.
Polymake(poly, "HASSE_DIAGRAM.FACES").This is the "fully support HASSE_DIAGRAM again" the issue asks for.
FACES,ADJACENCYandGRAPHremain as aliases.Polymake(poly,"GRAPH")works again -- on master it fails outright withPOSITION_SUBSTRING: <string> must be a string.the other results.
approximation with a warning.
Things worth knowing before reviewing
Two findings changed the design, and both came from probing polymake 4.15
rather than from the docs:
Serializing a nested big object is a trap. It emits only the properties
that happen to be computed and storable, and carries no
_typeat all:Requested individually the same values are complete and typed. So polymaking
always asks for leaf properties, and
GRAPHis an alias forGRAPH.ADJACENCY.DIMSis genuinely gone. polymake 4.15 warnsavailable properties insufficient to compute 'DIMS'and returns null, so it is not aliased. Theexisting
failexpectation in the test suite was recording exactly that.Also worth noting:
RationalandIntegerserialize as JSON strings, evenwhen integral, and
Vector<Integer>gives["8","12","6"]whileArray<Int>gives
[8,12,6]-- so the scalar decoder accepts both spellings. Sparsematrices carry a trailing
{"cols": n};cube(3)->FACETSis sparse, so thisis a common path, not an exotic one.
Breaking changes
polymaking now writes, so this is a hard error on the first call rather than
an obscure later failure. The version is detected lazily; loading the package
still spawns no processes. Users needing polymake 3 should stay on polymaking
0.8.9.
jsonis a new needed dependency.AppendToPolymakeObject(poly, name, value)takes a GAP value, not astring to append verbatim; JSON is not append-friendly, so the file is
rewritten from the properties set so far. Consequently polymaking refuses to
write to a file it did not create, instead of corrupting it.
ConvertMatrixToPolymakeString,ObjectConvertersand theConvertPolymake...functions are removed.NamesKnownPropertiesOfPolymakeObjectreturns names in a different order(it always returned
RecNames, i.e. unordered).Testing
cddand
beneath_beyond.tst/json.tstunit-tests the decoder against the exact shapes polymakeemits: string and native scalars, big integers, sparse vectors and matrices,
the trailing
colsmarker, index shifting vs. plain integer arrays,dehomogenization, and the writer.
HASSE_DIAGRAM.FACESagrees withFACES, thatGRAPHhas the documented shape, and that the file on disk really ispolymake JSON.
the same polytope before the old code was deleted.
makedoc.gbuilds with no warnings and no unresolved references.🤖 Generated with Claude Code