From ce4c099cd080395e8e3f74d3916c0b0c1287b4e5 Mon Sep 17 00:00:00 2001 From: Thomas Marchand Date: Sat, 25 Jul 2026 14:30:59 +0100 Subject: [PATCH 1/3] Run unconditional class-group certification for the five (2,3,11) fields --- .../beal_2311_classgroup_certification.yml | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 .github/workflows/beal_2311_classgroup_certification.yml diff --git a/.github/workflows/beal_2311_classgroup_certification.yml b/.github/workflows/beal_2311_classgroup_certification.yml new file mode 100644 index 0000000..22ac29c --- /dev/null +++ b/.github/workflows/beal_2311_classgroup_certification.yml @@ -0,0 +1,151 @@ +name: Beal (2,3,11) class-group certification + +on: + push: + branches: + - research/beal-2311-classgroup-certification + paths: + - ".github/workflows/beal_2311_classgroup_certification.yml" + pull_request: + paths: + - ".github/workflows/beal_2311_classgroup_certification.yml" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: beal-2311-classgroup-${{ github.ref }} + cancel-in-progress: false + +jobs: + certify: + strategy: + fail-fast: false + max-parallel: 5 + matrix: + include: + - label: 54a1 + f12: "x^12 - 6*x^10 + 6*x^9 - 6*x^8 - 126*x^7 + 104*x^6 + 468*x^5 + 258*x^4 - 456*x^3 - 1062*x^2 - 774*x - 380" + - label: 96a1 + f12: "x^12 - 4*x^11 - 264*x^7 + 66*x^6 - 132*x^5 - 2112*x^4 - 1320*x^3 - 660*x^2 - 6240*x - 8007" + - label: 864a1 + f12: "x^12 - 6*x^11 + 110*x^9 - 132*x^8 - 528*x^7 + 1100*x^6 + 330*x^5 - 2508*x^4 + 2134*x^3 - 594*x^2 + 456*x - 371" + - label: 864b1 + f12: "x^12 - 6*x^11 + 22*x^9 + 99*x^8 - 396*x^7 + 440*x^6 - 132*x^5 - 6501*x^4 + 33506*x^3 - 23760*x^2 - 92418*x + 193081" + - label: 864c1 + f12: "x^12 - 44*x^9 - 264*x^8 - 264*x^7 - 2266*x^6 - 4488*x^5 - 264*x^4 - 17644*x^3 - 7128*x^2 + 144*x - 15191" + runs-on: ubuntu-latest + timeout-minutes: 355 + env: + LABEL: ${{ matrix.label }} + F12: ${{ matrix.f12 }} + steps: + - name: Install PARI/GP + run: | + sudo apt-get update + sudo apt-get install -y pari-gp + gp --version-short + + - name: Build the degree-36 field and certify its class group + id: certify + shell: bash + run: | + set -u + cat > certify.gp < "classgroup-${LABEL}.status" + + python3 - <<'PY' + import hashlib, json, os, pathlib, re + label = os.environ["LABEL"] + log_path = pathlib.Path(f"classgroup-{label}.log") + text = log_path.read_text(errors="replace") if log_path.exists() else "" + def marker(name): + match = re.search(rf"(?:^|\n){re.escape(name)}=(.*)", text) + return None if match is None else match.group(1).strip() + status_path = pathlib.Path(f"classgroup-{label}.status") + exit_status = int(status_path.read_text().strip()) if status_path.exists() else -1 + body = { + "schema_version": 1, + "label": label, + "source_paper": "Freitas--Naskrecki--Stoll, The generalized Fermat equation with exponents 2, 3, n", + "degree12_polynomial": os.environ["F12"], + "degree3_polynomial": "x^3-4*x^2-160*x-1264", + "compositum_degree": marker("COMPOSITUM_DEGREE"), + "reduced_polynomial": marker("REDUCED_POLYNOMIAL"), + "field_signature": marker("FIELD_SIGNATURE"), + "field_discriminant": marker("FIELD_DISCRIMINANT"), + "nfcertify_obstructions": marker("NFCERTIFY_OBSTRUCTIONS"), + "class_group": marker("CLASS_GROUP"), + "class_quotient_certified": marker("CLASS_QUOTIENT_CERTIFIED"), + "full_bnf_certified": marker("FULL_BNF_CERTIFIED"), + "result": marker("RESULT"), + "exit_status": exit_status, + "complete": exit_status == 0 and marker("RESULT") == "UNCONDITIONALLY_CERTIFIED", + "log_sha256": hashlib.sha256(text.encode()).hexdigest(), + } + encoded = json.dumps(body, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode() + body["certificate_sha256"] = hashlib.sha256(encoded).hexdigest() + pathlib.Path(f"classgroup-{label}.json").write_text(json.dumps(body, sort_keys=True, indent=2) + "\n") + print(json.dumps(body, sort_keys=True, indent=2)) + PY + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: beal-2311-classgroup-${{ matrix.label }} + path: | + certify.gp + classgroup-${{ matrix.label }}.log + classgroup-${{ matrix.label }}.status + classgroup-${{ matrix.label }}.json + if-no-files-found: error + + - name: Require unconditional certification + if: steps.certify.outputs.exit_status != '0' + run: exit 1 From 93c884f49ce8c040fe56da05cb95855661cf0933 Mon Sep 17 00:00:00 2001 From: Thomas Marchand Date: Sat, 25 Jul 2026 14:35:25 +0100 Subject: [PATCH 2/3] Make the degree-36 class-group jobs fail closed --- .../beal_2311_classgroup_certification.yml | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/.github/workflows/beal_2311_classgroup_certification.yml b/.github/workflows/beal_2311_classgroup_certification.yml index 22ac29c..3fc4453 100644 --- a/.github/workflows/beal_2311_classgroup_certification.yml +++ b/.github/workflows/beal_2311_classgroup_certification.yml @@ -78,7 +78,7 @@ jobs: print("NFCERTIFY_OBSTRUCTIONS=", NFbad); if (#NFbad, error("maximal-order certification failed")); print("PHASE=bnfinit-start"); - B = bnfinit(NF, 1, [0,0,0,0,0,1]); + B = bnfinit(Tred, 1, [0,0,0,0,0,1]); print("CLASS_GROUP=", B.clgp); print("REGULATOR=", B.reg); print("PHASE=class-quotient-certification-start"); @@ -95,10 +95,9 @@ jobs: set +e timeout --signal=TERM --kill-after=60s 19800s gp -q certify.gp 2>&1 | tee "classgroup-${LABEL}.log" - status=${PIPESTATUS[0]} + gp_status=${PIPESTATUS[0]} set -e - echo "exit_status=${status}" >> "$GITHUB_OUTPUT" - printf '%s\n' "${status}" > "classgroup-${LABEL}.status" + printf '%s\n' "${gp_status}" > "classgroup-${LABEL}.status" python3 - <<'PY' import hashlib, json, os, pathlib, re @@ -110,8 +109,20 @@ jobs: return None if match is None else match.group(1).strip() status_path = pathlib.Path(f"classgroup-{label}.status") exit_status = int(status_path.read_text().strip()) if status_path.exists() else -1 + gp_error = "***" in text or "I/O: closing file" in text + checks = { + "gp_exit_zero": exit_status == 0, + "no_gp_error_text": not gp_error, + "degree_is_36": marker("COMPOSITUM_DEGREE") == "36", + "maximal_order_certified": marker("NFCERTIFY_OBSTRUCTIONS") == "[]", + "class_group_present": marker("CLASS_GROUP") is not None, + "class_quotient_certified": marker("CLASS_QUOTIENT_CERTIFIED") == "1", + "full_bnf_certified": marker("FULL_BNF_CERTIFIED") == "1", + "result_marker": marker("RESULT") == "UNCONDITIONALLY_CERTIFIED", + } + complete = all(checks.values()) body = { - "schema_version": 1, + "schema_version": 2, "label": label, "source_paper": "Freitas--Naskrecki--Stoll, The generalized Fermat equation with exponents 2, 3, n", "degree12_polynomial": os.environ["F12"], @@ -122,19 +133,24 @@ jobs: "field_discriminant": marker("FIELD_DISCRIMINANT"), "nfcertify_obstructions": marker("NFCERTIFY_OBSTRUCTIONS"), "class_group": marker("CLASS_GROUP"), + "regulator": marker("REGULATOR"), "class_quotient_certified": marker("CLASS_QUOTIENT_CERTIFIED"), "full_bnf_certified": marker("FULL_BNF_CERTIFIED"), "result": marker("RESULT"), - "exit_status": exit_status, - "complete": exit_status == 0 and marker("RESULT") == "UNCONDITIONALLY_CERTIFIED", + "gp_exit_status": exit_status, + "checks": checks, + "complete": complete, "log_sha256": hashlib.sha256(text.encode()).hexdigest(), } encoded = json.dumps(body, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode() body["certificate_sha256"] = hashlib.sha256(encoded).hexdigest() pathlib.Path(f"classgroup-{label}.json").write_text(json.dumps(body, sort_keys=True, indent=2) + "\n") + pathlib.Path(f"classgroup-{label}.complete").write_text("true\n" if complete else "false\n") print(json.dumps(body, sort_keys=True, indent=2)) PY + echo "complete=$(tr -d '\n' < "classgroup-${LABEL}.complete")" >> "$GITHUB_OUTPUT" + - uses: actions/upload-artifact@v4 if: always() with: @@ -143,9 +159,10 @@ jobs: certify.gp classgroup-${{ matrix.label }}.log classgroup-${{ matrix.label }}.status + classgroup-${{ matrix.label }}.complete classgroup-${{ matrix.label }}.json if-no-files-found: error - name: Require unconditional certification - if: steps.certify.outputs.exit_status != '0' + if: always() && steps.certify.outputs.complete != 'true' run: exit 1 From 2dfbe659d23b4c0b3c9edb860652c5f18d06d012 Mon Sep 17 00:00:00 2001 From: Thomas Marchand Date: Sat, 25 Jul 2026 14:37:15 +0100 Subject: [PATCH 3/3] Use the PARI bnfinit syntax supported by the runner --- .github/workflows/beal_2311_classgroup_certification.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/beal_2311_classgroup_certification.yml b/.github/workflows/beal_2311_classgroup_certification.yml index 3fc4453..bad5c66 100644 --- a/.github/workflows/beal_2311_classgroup_certification.yml +++ b/.github/workflows/beal_2311_classgroup_certification.yml @@ -78,7 +78,7 @@ jobs: print("NFCERTIFY_OBSTRUCTIONS=", NFbad); if (#NFbad, error("maximal-order certification failed")); print("PHASE=bnfinit-start"); - B = bnfinit(Tred, 1, [0,0,0,0,0,1]); + B = bnfinit(Tred, 1); print("CLASS_GROUP=", B.clgp); print("REGULATOR=", B.reg); print("PHASE=class-quotient-certification-start");