collatz: add palier2p15/p16 artefacts and Sm refinement tooling

**Motivations:**
- Publish new Collatz palier runs and associated artefacts (C3 local descent, universal clauses, iteration protocol).
- Extend the scripts toolbox to generate/verify clauses and build refinement certificates over S_m.

**Root causes:**
- Universal clause witnesses were lifted to 2^(A+1) even when the witness is already fixed modulo the domain palier, leading to unstable or unnecessarily weak/ambiguous modulus choices.
- CSV palier inference in scission could mis-detect short column names (e.g. "m") by substring matching.

**Correctifs:**
- Lift D_exact/F witnesses to m_stable := max(m, A+1) in universal clause extraction and run reports.
- Make scission palier/m column detection exact-match to avoid false positives.
- Update C3 local descent verification/reporting to use strict fusion witness selection prioritizing lower modular stability and refreshed D/F metrics.
- Add a dedicated run report profile for per-palier universal clauses.

**Evolutions:**
- Add scripts for terminal clauses and minorated descent clauses over S_m, their deterministic verification, and multi-level refinement certificate building.
- Add modular tooling for register_K and incremental comparison of D_minor families.
- Add/update feature documentation for the new pipelines and generated reports.

**Pages affectées:**
- applications/collatz/collatz_k_scripts/README.md
- applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses.py
- applications/collatz/collatz_k_scripts/collatz_generate_run_report.py
- applications/collatz/collatz_k_scripts/collatz_iterate_palier_protocol.py
- applications/collatz/collatz_k_scripts/collatz_scission.py
- applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py
- applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py
- applications/collatz/collatz_k_scripts/*refinement*over_Sm*.py
- applications/collatz/collatz_k_scripts/collatz_generate_*clauses_over_Sm.py
- applications/collatz/collatz_k_scripts/collatz_verify_minorated_descent_clauses_over_Sm.py
- applications/collatz/collatz_k_scripts/collatz_build_register_K_modular.py
- applications/collatz/collatz_k_scripts/collatz_compare_dminor_families_incremental.py
- applications/collatz/*.md
- docs/features/*.md
- docs/artefacts/collatz/**
- docs/collatz_run_report_2026-03-09_*.md
This commit is contained in:
ncantu 2026-03-09 23:29:59 +01:00
parent 40fa3808a7
commit bd529682bf
1523 changed files with 21155413 additions and 356 deletions

View File

@ -6,6 +6,8 @@ Scripts Python nécessaires pour reproduire les calculs et audits produits jusqu
- génération des paquets D_k (au moins la branche "après fusion" pour D16 et D17) - génération des paquets D_k (au moins la branche "après fusion" pour D16 et D17)
- génération et audit des clauses de fusion (F) - génération et audit des clauses de fusion (F)
- production systématique des listes exhaustives en Markdown (bloc CSV) - production systématique des listes exhaustives en Markdown (bloc CSV)
- génération et vérification de clauses terminales sur \(S_M\) (exactes et minorées)
- certificats de raffinement (sur \(L\) et sur \(S_M\))
## Entrées ## Entrées
@ -27,3 +29,11 @@ python collatz_k_pipeline.py \
Orchestrateur: Orchestrateur:
python reproduce_all_audits.py --root /chemin/fichiers_source --out /chemin/sorties python reproduce_all_audits.py --root /chemin/fichiers_source --out /chemin/sorties
## Compléments (scripts unitaires)
- `collatz_generate_terminal_clauses_over_Sm.py` : clauses terminales (D/F) directement décidables sur \(S_M\).
- `collatz_generate_minorated_descent_clauses_over_Sm.py` : clauses de descente minorées (D_minor) sur \(S_M\).
- `collatz_verify_minorated_descent_clauses_over_Sm.py` : vérification déterministe des clauses D_minor.
- `collatz_build_refinement_certificate_over_Sm_multilevel.py` : audit de fermeture par raffinement (multi-niveaux) sur \(S_M\).
- `collatz_compare_dminor_families_incremental.py` : tableau dimpact incrémental (Δopen_roots, Δq_m, Δparents_one_child, quantiles lb) par ajout de familles D_minor groupées par \(k\).

View File

@ -0,0 +1,544 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_analyze_open_roots_refinement.py
Targeted analysis of open roots in S_M after a multilevel refinement closure attempt.
Goal:
- For each open root r in S_M, compute obstruction diagnostics on its two children at level M+1.
- Estimate a lower-bound "first possible closure depth" by searching for the minimal contractive
terminal clause (D or F) for each child residue, in terms of required m >= A+1.
This analysis is deterministic, versionable, and intended to decide whether open roots are
"structurally late" (require m >> M_max) or might be treated early by a grammar change.
"""
from __future__ import annotations
import argparse
import json
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Literal
from collatz_k_core import prefix_data, delta_D, fusion_choice_a, delta_F
Kind = Literal["D_exact", "F"]
def _read_json(path: Path) -> object:
return json.loads(path.read_text(encoding="utf-8", errors="strict"))
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _req_int(d: dict[str, object], key: str) -> int:
v = d.get(key)
if not isinstance(v, int):
raise ValueError(f"Expected int for {key}")
return v
@dataclass(frozen=True)
class BestClause:
kind: Kind
k_or_t: int
A: int
required_m: int
extra: dict[str, int]
def to_json(self) -> dict[str, object]:
return {
"kind": self.kind,
"k_or_t": self.k_or_t,
"A": self.A,
"required_m": self.required_m,
"extra": self.extra,
}
def _best_contractive_D(*, residue: int, k_max: int, max_required_m: int) -> BestClause | None:
best: BestClause | None = None
best_key: tuple[int, int, int] | None = None
for k in range(1, k_max + 1):
pref = prefix_data(residue, k)
req_m = pref.A + 1
if req_m > max_required_m:
break
if delta_D(pref.A, k) <= 0:
continue
key = (req_m, pref.A, k)
if best_key is None or key < best_key:
best_key = key
best = BestClause(kind="D_exact", k_or_t=k, A=pref.A, required_m=req_m, extra={"k": k})
return best
def _best_contractive_F(*, residue: int, t_max: int, max_required_m: int) -> BestClause | None:
best: BestClause | None = None
best_key: tuple[int, int, int] | None = None
for t in range(1, t_max + 1):
pref = prefix_data(residue, t)
req_m = pref.A + 1
if req_m > max_required_m:
break
a = fusion_choice_a(pref.y)
if a is None:
continue
if delta_F(pref.A, t, a) <= 0:
continue
key = (req_m, pref.A, t)
if best_key is None or key < best_key:
best_key = key
best = BestClause(kind="F", k_or_t=t, A=pref.A, required_m=req_m, extra={"t": t, "a": a})
return best
def _analyze_child(*, child_residue: int, k_max: int, t_max: int, max_required_m: int) -> dict[str, object]:
best_D = _best_contractive_D(residue=child_residue, k_max=k_max, max_required_m=max_required_m)
best_F = _best_contractive_F(residue=child_residue, t_max=t_max, max_required_m=max_required_m)
# obstruction markers at small depths (<=32)
any_deltaD_pos = False
first_k_deltaD_pos: int | None = None
for k in range(1, min(k_max, 32) + 1):
pref = prefix_data(child_residue, k)
if delta_D(pref.A, k) > 0:
any_deltaD_pos = True
first_k_deltaD_pos = k
break
any_y_mod3_nonzero = False
y_mod3_zero_count = 0
any_deltaF_pos = False
first_t_deltaF_pos: int | None = None
first_t_y_mod3_nonzero: int | None = None
for t in range(1, min(t_max, 32) + 1):
pref = prefix_data(child_residue, t)
a = fusion_choice_a(pref.y)
if a is None:
y_mod3_zero_count += 1
continue
any_y_mod3_nonzero = True
if first_t_y_mod3_nonzero is None:
first_t_y_mod3_nonzero = t
if delta_F(pref.A, t, a) > 0:
any_deltaF_pos = True
first_t_deltaF_pos = t
break
def req_m(b: BestClause | None) -> int | None:
return b.required_m if b is not None else None
req_D = req_m(best_D)
req_F = req_m(best_F)
req_any = min([x for x in [req_D, req_F] if x is not None], default=None)
return {
"child_residue_mod_2p": child_residue,
"best_D": (best_D.to_json() if best_D is not None else None),
"best_F": (best_F.to_json() if best_F is not None else None),
"required_m": {"D": req_D, "F": req_F, "any": req_any},
"obstructions": {
"any_contracting_D_found_up_to32": any_deltaD_pos,
"first_k_contracting_D_up_to32": first_k_deltaD_pos,
"any_y_mod3_nonzero_up_to32": any_y_mod3_nonzero,
"y_mod3_zero_count_up_to32": y_mod3_zero_count,
"first_t_y_mod3_nonzero_up_to32": first_t_y_mod3_nonzero,
"any_contracting_F_found_up_to32": any_deltaF_pos,
"first_t_contracting_F_up_to32": first_t_deltaF_pos,
},
}
def run(
*,
root_palier: int,
max_palier: int,
multilevel_json: Path,
output_dir: Path,
k_max: int,
t_max: int,
search_max_required_m: int,
) -> None:
obj = _read_json(multilevel_json)
if not isinstance(obj, dict):
raise ValueError("Invalid multilevel certificate JSON: expected object")
domain = obj.get("domain")
closure = obj.get("closure")
if not isinstance(domain, dict) or not isinstance(closure, dict):
raise ValueError("Invalid multilevel certificate JSON: missing domain/closure")
if _req_int(domain, "root_palier") != root_palier or _req_int(domain, "max_palier") != max_palier:
raise ValueError("multilevel certificate domain mismatch")
still_open_sample = closure.get("still_open_roots_sample")
if not isinstance(still_open_sample, list) or not all(isinstance(x, int) for x in still_open_sample):
raise ValueError("Invalid multilevel certificate JSON: missing still_open_roots_sample")
# The full open set is not stored by default; we recompute it from closed sample is insufficient.
# We therefore require the corresponding MD to list the open roots sample only, and analyze the full set by reconstruction.
# Reconstruction: scan all roots and check if they appear in first_close mapping.
first_close = obj.get("first_close_palier_by_root")
if not isinstance(first_close, dict):
raise ValueError("Invalid multilevel certificate JSON: missing first_close_palier_by_root")
open_roots: list[int] = []
for r0 in range(1, 1 << root_palier, 2):
if str(r0) not in first_close:
open_roots.append(r0)
rows: list[dict[str, object]] = []
bucket_any: dict[int, int] = {}
bucket_D: dict[int, int] = {}
bucket_F: dict[int, int] = {}
motif_counts: dict[str, int] = {}
hist_first_k_D: dict[int, int] = {}
hist_first_t_F: dict[int, int] = {}
hist_first_t_y_nonzero: dict[int, int] = {}
hist_y_mod3_zero_count: dict[int, int] = {}
hist_first_k_D_low: dict[int, int] = {}
hist_first_k_D_high: dict[int, int] = {}
hist_first_t_F_low: dict[int, int] = {}
hist_first_t_F_high: dict[int, int] = {}
hist_y_mod3_zero_count_low: dict[int, int] = {}
hist_y_mod3_zero_count_high: dict[int, int] = {}
hist_lbD_minus_lbF: dict[int, int] = {}
hist_lbAny_minus_lbD: dict[int, int] = {}
hist_lbAny_minus_lbF: dict[int, int] = {}
lb_any_values: list[int] = []
lb_D_values: list[int] = []
lb_F_values: list[int] = []
def bump(hist: dict[int, int], key: int | None) -> None:
if key is None:
return
hist[key] = hist.get(key, 0) + 1
for r0 in open_roots:
c0 = r0
c1 = r0 + (1 << root_palier)
a0 = _analyze_child(child_residue=c0, k_max=k_max, t_max=t_max, max_required_m=search_max_required_m)
a1 = _analyze_child(child_residue=c1, k_max=k_max, t_max=t_max, max_required_m=search_max_required_m)
def req_kind(x: dict[str, object], k: str) -> int | None:
req = x.get("required_m")
if not isinstance(req, dict):
return None
v = req.get(k)
return int(v) if isinstance(v, int) else None
req0_any = req_kind(a0, "any")
req1_any = req_kind(a1, "any")
lb_any = max([x for x in [req0_any, req1_any] if x is not None], default=0) or None
if lb_any is not None:
bucket_any[lb_any] = bucket_any.get(lb_any, 0) + 1
lb_any_values.append(int(lb_any))
req0_D = req_kind(a0, "D")
req1_D = req_kind(a1, "D")
lb_D = max([x for x in [req0_D, req1_D] if x is not None], default=0) or None
if lb_D is not None:
bucket_D[lb_D] = bucket_D.get(lb_D, 0) + 1
lb_D_values.append(int(lb_D))
req0_F = req_kind(a0, "F")
req1_F = req_kind(a1, "F")
lb_F = max([x for x in [req0_F, req1_F] if x is not None], default=0) or None
if lb_F is not None:
bucket_F[lb_F] = bucket_F.get(lb_F, 0) + 1
lb_F_values.append(int(lb_F))
# motifs (dominant obstructions at small depths)
o0 = a0.get("obstructions")
o1 = a1.get("obstructions")
if isinstance(o0, dict) and isinstance(o1, dict):
both_no_D32 = (o0.get("any_contracting_D_found_up_to32") is False) and (o1.get("any_contracting_D_found_up_to32") is False)
both_no_F32 = (o0.get("any_contracting_F_found_up_to32") is False) and (o1.get("any_contracting_F_found_up_to32") is False)
both_y3_nonzero = (o0.get("any_y_mod3_nonzero_up_to32") is True) and (o1.get("any_y_mod3_nonzero_up_to32") is True)
if both_no_D32:
motif_counts["both_children_no_contracting_D_up_to32"] = motif_counts.get("both_children_no_contracting_D_up_to32", 0) + 1
if both_no_F32:
motif_counts["both_children_no_contracting_F_up_to32"] = motif_counts.get("both_children_no_contracting_F_up_to32", 0) + 1
if both_no_F32 and both_y3_nonzero:
motif_counts["both_children_F_blocked_by_deltaF_up_to32"] = motif_counts.get("both_children_F_blocked_by_deltaF_up_to32", 0) + 1
if both_no_F32 and (not both_y3_nonzero):
motif_counts["some_child_y_mod3_zero_always_up_to32"] = motif_counts.get("some_child_y_mod3_zero_always_up_to32", 0) + 1
bump(hist_first_k_D, o0.get("first_k_contracting_D_up_to32") if isinstance(o0.get("first_k_contracting_D_up_to32"), int) else None)
bump(hist_first_k_D, o1.get("first_k_contracting_D_up_to32") if isinstance(o1.get("first_k_contracting_D_up_to32"), int) else None)
bump(hist_first_k_D_low, o0.get("first_k_contracting_D_up_to32") if isinstance(o0.get("first_k_contracting_D_up_to32"), int) else None)
bump(hist_first_k_D_high, o1.get("first_k_contracting_D_up_to32") if isinstance(o1.get("first_k_contracting_D_up_to32"), int) else None)
bump(hist_first_t_F, o0.get("first_t_contracting_F_up_to32") if isinstance(o0.get("first_t_contracting_F_up_to32"), int) else None)
bump(hist_first_t_F, o1.get("first_t_contracting_F_up_to32") if isinstance(o1.get("first_t_contracting_F_up_to32"), int) else None)
bump(hist_first_t_F_low, o0.get("first_t_contracting_F_up_to32") if isinstance(o0.get("first_t_contracting_F_up_to32"), int) else None)
bump(hist_first_t_F_high, o1.get("first_t_contracting_F_up_to32") if isinstance(o1.get("first_t_contracting_F_up_to32"), int) else None)
bump(hist_first_t_y_nonzero, o0.get("first_t_y_mod3_nonzero_up_to32") if isinstance(o0.get("first_t_y_mod3_nonzero_up_to32"), int) else None)
bump(hist_first_t_y_nonzero, o1.get("first_t_y_mod3_nonzero_up_to32") if isinstance(o1.get("first_t_y_mod3_nonzero_up_to32"), int) else None)
bump(hist_y_mod3_zero_count, o0.get("y_mod3_zero_count_up_to32") if isinstance(o0.get("y_mod3_zero_count_up_to32"), int) else None)
bump(hist_y_mod3_zero_count, o1.get("y_mod3_zero_count_up_to32") if isinstance(o1.get("y_mod3_zero_count_up_to32"), int) else None)
bump(hist_y_mod3_zero_count_low, o0.get("y_mod3_zero_count_up_to32") if isinstance(o0.get("y_mod3_zero_count_up_to32"), int) else None)
bump(hist_y_mod3_zero_count_high, o1.get("y_mod3_zero_count_up_to32") if isinstance(o1.get("y_mod3_zero_count_up_to32"), int) else None)
# Correlations based on lower bounds for this root
if lb_D is not None and lb_F is not None:
diff = int(lb_D) - int(lb_F)
hist_lbD_minus_lbF[diff] = hist_lbD_minus_lbF.get(diff, 0) + 1
if lb_any is not None and lb_D is not None:
diff = int(lb_any) - int(lb_D)
hist_lbAny_minus_lbD[diff] = hist_lbAny_minus_lbD.get(diff, 0) + 1
if lb_any is not None and lb_F is not None:
diff = int(lb_any) - int(lb_F)
hist_lbAny_minus_lbF[diff] = hist_lbAny_minus_lbF.get(diff, 0) + 1
rows.append(
{
"root_residue_mod_2p": r0,
"children_mod_2p16": [c0, c1],
"child0": a0,
"child1": a1,
"lower_bound_required_m_to_close_root": {"any": lb_any, "D": lb_D, "F": lb_F},
}
)
out_json = output_dir / f"open_roots_obstruction_profile_mod2p{root_palier}_to2p{max_palier}.json"
out_md = output_dir / f"open_roots_obstruction_profile_mod2p{root_palier}_to2p{max_palier}.md"
def quantiles(values: list[int]) -> dict[str, int]:
if not values:
return {}
s = sorted(values)
n = len(s)
def at(p: float) -> int:
idx = int((n - 1) * p)
return int(s[idx])
return {
"p50": at(0.50),
"p75": at(0.75),
"p90": at(0.90),
"p95": at(0.95),
"p99": at(0.99),
"max": int(s[-1]),
}
summary = {
"domain": {
"root_palier": root_palier,
"max_palier": max_palier,
"open_roots_count": len(open_roots),
},
"search": {
"k_max": k_max,
"t_max": t_max,
"search_max_required_m": search_max_required_m,
},
"lower_bound_required_m_bucket": {
"any": {str(k): v for k, v in sorted(bucket_any.items())},
"D": {str(k): v for k, v in sorted(bucket_D.items())},
"F": {str(k): v for k, v in sorted(bucket_F.items())},
},
"motifs_up_to32": motif_counts,
"histograms_up_to32": {
"first_k_contracting_D": {str(k): v for k, v in sorted(hist_first_k_D.items())},
"first_k_contracting_D_low": {str(k): v for k, v in sorted(hist_first_k_D_low.items())},
"first_k_contracting_D_high": {str(k): v for k, v in sorted(hist_first_k_D_high.items())},
"first_t_contracting_F": {str(k): v for k, v in sorted(hist_first_t_F.items())},
"first_t_contracting_F_low": {str(k): v for k, v in sorted(hist_first_t_F_low.items())},
"first_t_contracting_F_high": {str(k): v for k, v in sorted(hist_first_t_F_high.items())},
"first_t_y_mod3_nonzero": {str(k): v for k, v in sorted(hist_first_t_y_nonzero.items())},
"y_mod3_zero_count": {str(k): v for k, v in sorted(hist_y_mod3_zero_count.items())},
"y_mod3_zero_count_low": {str(k): v for k, v in sorted(hist_y_mod3_zero_count_low.items())},
"y_mod3_zero_count_high": {str(k): v for k, v in sorted(hist_y_mod3_zero_count_high.items())},
},
"correlations": {
"lb_D_minus_lb_F": {str(k): v for k, v in sorted(hist_lbD_minus_lbF.items())},
"lb_any_minus_lb_D": {str(k): v for k, v in sorted(hist_lbAny_minus_lbD.items())},
"lb_any_minus_lb_F": {str(k): v for k, v in sorted(hist_lbAny_minus_lbF.items())},
},
"quantiles": {
"lb_any": quantiles(lb_any_values),
"lb_D": quantiles(lb_D_values),
"lb_F": quantiles(lb_F_values),
},
"rows": rows,
}
_write_json(out_json, summary)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Profil dobstruction — racines ouvertes sur S_{root_palier} (raffinement jusquà 2^{max_palier})")
md.append("")
md.append("## Domaine")
md.append("")
md.append(f"- racine : 2^{root_palier}")
md.append(f"- max : 2^{max_palier}")
md.append(f"- open_roots : {len(open_roots)}")
md.append("")
md.append("## Recherche (borne inférieure de profondeur)")
md.append("")
md.append(f"- k_max : {k_max}")
md.append(f"- t_max : {t_max}")
md.append(f"- max_required_m (pruning) : {search_max_required_m}")
md.append("")
md.append("### Buckets — lower_bound_required_m_to_close_root")
md.append("")
md.append("Buckets (any):")
for k, v in sorted(bucket_any.items()):
md.append(f"- required_m={k} : {v}")
md.append("")
md.append("Buckets (D only):")
for k, v in sorted(bucket_D.items()):
md.append(f"- required_m={k} : {v}")
md.append("")
md.append("Buckets (F only):")
for k, v in sorted(bucket_F.items()):
md.append(f"- required_m={k} : {v}")
md.append("")
md.append("## Motifs dominants (<=32)")
md.append("")
for k, v in sorted(motif_counts.items(), key=lambda x: (-x[1], x[0])):
md.append(f"- {k} : {v}")
md.append("")
md.append("## Histogrammes (<=32, agrégés sur les deux enfants)")
md.append("")
md.append("### first_k_contracting_D_up_to32")
for k, v in sorted(hist_first_k_D.items()):
md.append(f"- k={k} : {v}")
md.append("")
md.append("### first_k_contracting_D_up_to32 (low child)")
for k, v in sorted(hist_first_k_D_low.items()):
md.append(f"- k={k} : {v}")
md.append("")
md.append("### first_k_contracting_D_up_to32 (high child)")
for k, v in sorted(hist_first_k_D_high.items()):
md.append(f"- k={k} : {v}")
md.append("")
md.append("### first_t_contracting_F_up_to32")
for k, v in sorted(hist_first_t_F.items()):
md.append(f"- t={k} : {v}")
md.append("")
md.append("### first_t_y_mod3_nonzero_up_to32")
for k, v in sorted(hist_first_t_y_nonzero.items()):
md.append(f"- t={k} : {v}")
md.append("")
md.append("### y_mod3_zero_count_up_to32")
for k, v in sorted(hist_y_mod3_zero_count.items()):
md.append(f"- count={k} : {v}")
md.append("")
md.append("### y_mod3_zero_count_up_to32 (low child)")
for k, v in sorted(hist_y_mod3_zero_count_low.items()):
md.append(f"- count={k} : {v}")
md.append("")
md.append("### y_mod3_zero_count_up_to32 (high child)")
for k, v in sorted(hist_y_mod3_zero_count_high.items()):
md.append(f"- count={k} : {v}")
md.append("")
md.append("## Corrélations (borne inférieure)")
md.append("")
md.append("### lb_D - lb_F")
for k, v in sorted(hist_lbD_minus_lbF.items()):
md.append(f"- diff={k} : {v}")
md.append("")
md.append("### lb_any - lb_D")
for k, v in sorted(hist_lbAny_minus_lbD.items()):
md.append(f"- diff={k} : {v}")
md.append("")
md.append("### lb_any - lb_F")
for k, v in sorted(hist_lbAny_minus_lbF.items()):
md.append(f"- diff={k} : {v}")
md.append("")
md.append("## Quantiles (borne inférieure)")
md.append("")
q_any = quantiles(lb_any_values)
q_D = quantiles(lb_D_values)
q_F = quantiles(lb_F_values)
md.append("| metric | p50 | p75 | p90 | p95 | p99 | max |")
md.append("| --- | --- | --- | --- | --- | --- | --- |")
if q_any:
md.append(f"| lb_any | {q_any['p50']} | {q_any['p75']} | {q_any['p90']} | {q_any['p95']} | {q_any['p99']} | {q_any['max']} |")
if q_D:
md.append(f"| lb_D | {q_D['p50']} | {q_D['p75']} | {q_D['p90']} | {q_D['p95']} | {q_D['p99']} | {q_D['max']} |")
if q_F:
md.append(f"| lb_F | {q_F['p50']} | {q_F['p75']} | {q_F['p90']} | {q_F['p95']} | {q_F['p99']} | {q_F['max']} |")
md.append("")
md.append("## Exemples (premières lignes)")
md.append("")
md.append("| r | child0 | child1 | lb_any | lb_D | lb_F |")
md.append("| --- | --- | --- | --- | --- | --- |")
for row in rows[:40]:
r0 = int(row["root_residue_mod_2p"]) # type: ignore[arg-type]
c0 = int(row["children_mod_2p16"][0]) # type: ignore[index]
c1 = int(row["children_mod_2p16"][1]) # type: ignore[index]
lb = row.get("lower_bound_required_m_to_close_root")
lb_any2 = ""
lb_D2 = ""
lb_F2 = ""
if isinstance(lb, dict):
lb_any2 = "" if lb.get("any") is None else str(lb.get("any"))
lb_D2 = "" if lb.get("D") is None else str(lb.get("D"))
lb_F2 = "" if lb.get("F") is None else str(lb.get("F"))
md.append(f"| {r0} | {c0} | {c1} | {lb_any2} | {lb_D2} | {lb_F2} |")
md.append("")
md.append("## Sorties")
md.append("")
md.append(f"- JSON : `{out_json}`")
md.append(f"- Markdown : `{out_md}`")
md.append("")
_write_md(out_md, md)
def main() -> None:
ap = argparse.ArgumentParser(description="Analyze open roots after multilevel refinement closure")
ap.add_argument("--root-palier", type=int, default=15)
ap.add_argument("--max-palier", type=int, default=18)
ap.add_argument("--multilevel-json", default="", help="Path to refinement_certificate_Sm_multilevel JSON")
ap.add_argument("--output-dir", default="", help="Output directory (defaults under docs/artefacts/...)")
ap.add_argument("--k-max", type=int, default=128)
ap.add_argument("--t-max", type=int, default=128)
ap.add_argument("--search-max-required-m", type=int, default=128)
args = ap.parse_args()
root_palier = int(args.root_palier)
max_palier = int(args.max_palier)
if args.multilevel_json.strip():
multilevel_json = Path(args.multilevel_json).resolve()
else:
multilevel_json = (
Path("docs")
/ "artefacts"
/ "collatz"
/ "refinement_K"
/ f"palier2p{root_palier}"
/ f"refinement_certificate_Sm_multilevel_mod2p{root_palier}_to2p{max_palier}.json"
).resolve()
if args.output_dir.strip():
output_dir = Path(args.output_dir).resolve()
else:
output_dir = (Path("docs") / "artefacts" / "collatz" / "refinement_K" / f"palier2p{root_palier}").resolve()
run(
root_palier=root_palier,
max_palier=max_palier,
multilevel_json=multilevel_json,
output_dir=output_dir,
k_max=int(args.k_max),
t_max=int(args.t_max),
search_max_required_m=int(args.search_max_required_m),
)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,338 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_build_refinement_certificate_modular.py
Build a deterministic refinement certificate at palier 2^M on the instrumented domain L.
This is an alternative to the "direct decidability" constraint m(c) <= M used in the modular register K_M.
Here, leaf clauses may live at modulus 2^m with m > M; a finite refinement path is recorded from the
root residue (mod 2^M) to the leaf residue (mod 2^m).
Scope (by design):
- The certificate is defined and audited on the finite C3 domain L (record n values), not on S_M.
Inputs:
- clauses_universelles.json (Option A) at the chosen palier
- the referenced C3 verification JSON (from clauses JSON inputs)
Outputs:
- refinement_certificate_mod2p<M>.{json,md}
- audit_refinement_certificate_mod2p<M>.{json,md}
"""
from __future__ import annotations
import argparse
import json
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Literal
from collatz_build_register_K_modular import _display_path, _generated_at_utc_from_mtime, _sha256_file
ClauseKind = Literal["D_exact", "F", "D_brother_local"]
def _read_json(path: Path) -> object:
return json.loads(path.read_text(encoding="utf-8", errors="strict"))
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _req_int(d: dict[str, object], key: str) -> int:
v = d.get(key)
if not isinstance(v, int):
raise ValueError(f"Expected int for {key}")
return v
def _opt_int(d: dict[str, object], key: str) -> int | None:
v = d.get(key)
if v is None:
return None
if not isinstance(v, int):
raise ValueError(f"Expected int|null for {key}")
return v
@dataclass(frozen=True)
class RefinementEntry:
n: int
kind: ClauseKind
root_modulus_power: int
root_residue_mod_2p: int
leaf_modulus_power: int
leaf_residue_mod_2p: int
# one decision per level m in [M..leaf_m-1]
decisions: tuple[int, ...]
# terminal clause info (minimal for auditing / traceability)
k_or_t: int | None
A: int | None
threshold: int | None
def to_json(self) -> dict[str, object]:
return {
"n": self.n,
"kind": self.kind,
"root_modulus_power": self.root_modulus_power,
"root_residue_mod_2p": self.root_residue_mod_2p,
"leaf_modulus_power": self.leaf_modulus_power,
"leaf_residue_mod_2p": self.leaf_residue_mod_2p,
"decisions": list(self.decisions),
"k_or_t": self.k_or_t,
"A": self.A,
"threshold": self.threshold,
}
def _infer_default_clauses_json(*, repo_root: Path, palier: int) -> Path:
base = repo_root / "docs" / "artefacts" / "collatz" / "universal_clauses"
if palier == 13:
return base / "clauses_universelles.json"
return base / f"palier2p{palier}" / "clauses_universelles.json"
def _infer_default_output_dir(*, repo_root: Path, palier: int) -> Path:
return repo_root / "docs" / "artefacts" / "collatz" / "refinement_K" / f"palier2p{palier}"
def _load_c3_verification_path_from_clauses(*, clauses_obj: dict[str, object], repo_root: Path) -> Path:
inputs = clauses_obj.get("inputs")
if not isinstance(inputs, dict):
raise ValueError("Invalid clauses JSON: missing inputs")
p = inputs.get("verification_c3_local_descent_json")
if not isinstance(p, str) or not p.strip():
raise ValueError("Invalid clauses JSON: missing inputs.verification_c3_local_descent_json")
path = Path(p)
if not path.is_absolute():
path = repo_root / path
return path.resolve()
def _refinement_decisions(*, root_residue: int, root_m: int, leaf_residue: int, leaf_m: int) -> tuple[int, ...]:
if leaf_m < root_m:
raise ValueError("leaf_m must be >= root_m")
if (leaf_residue % (1 << root_m)) != (root_residue % (1 << root_m)):
raise ValueError("leaf_residue must extend root_residue")
res = root_residue
out: list[int] = []
for m in range(root_m, leaf_m):
target_mod = 1 << (m + 1)
target = leaf_residue % target_mod
if target == res:
out.append(0)
continue
if target == res + (1 << m):
res = res + (1 << m)
out.append(1)
continue
raise ValueError(f"Inconsistent refinement at level m={m}: root={root_residue}, leaf={leaf_residue}, res={res}")
if res != leaf_residue:
raise ValueError("Refinement reconstruction failed")
return tuple(out)
def run(*, palier: int, clauses_json: Path, output_dir: Path, repo_root: Path) -> None:
cobj = _read_json(clauses_json)
if not isinstance(cobj, dict):
raise ValueError("Invalid clauses JSON: expected object")
domain = cobj.get("domain")
if not isinstance(domain, dict):
raise ValueError("Invalid clauses JSON: missing domain")
domain_palier = _req_int(domain, "palier")
if domain_palier != palier:
raise ValueError(f"Clauses domain palier mismatch: {domain_palier} != {palier}")
clauses = cobj.get("clauses")
if not isinstance(clauses, list) or not all(isinstance(x, dict) for x in clauses):
raise ValueError("Invalid clauses JSON: missing clauses list")
c3_verification_json = _load_c3_verification_path_from_clauses(clauses_obj=cobj, repo_root=repo_root)
vobj = _read_json(c3_verification_json)
if not isinstance(vobj, dict):
raise ValueError("Invalid C3 verification JSON: expected object")
vdomain = vobj.get("domain")
vrecords = vobj.get("records")
if not isinstance(vdomain, dict) or not isinstance(vrecords, list):
raise ValueError("Invalid C3 verification JSON: missing domain/records")
if _req_int(vdomain, "palier") != palier:
raise ValueError("C3 domain palier mismatch")
if not all(isinstance(r, dict) for r in vrecords):
raise ValueError("Invalid C3 records")
# Map by source_n for a direct, deterministic join
clause_by_source_n: dict[int, dict[str, object]] = {}
for c in clauses:
sn = c.get("source_n")
if isinstance(sn, int):
clause_by_source_n[sn] = c
entries: list[RefinementEntry] = []
missing: list[int] = []
for rec in vrecords:
n = rec.get("n")
if not isinstance(n, int):
raise ValueError("Invalid C3 record: missing n")
c = clause_by_source_n.get(n)
if c is None:
missing.append(n)
continue
kind = c.get("kind")
if not isinstance(kind, str) or kind not in ("D_exact", "F", "D_brother_local"):
raise ValueError(f"Invalid clause kind for source_n={n}")
stable_m = _opt_int(c, "stable_modulus_power")
stable_r = _opt_int(c, "stable_residue_mod_2p")
if stable_m is None or stable_r is None:
raise ValueError(f"Missing stable modulus/residue for source_n={n}")
root_r = n % (1 << palier)
decisions = _refinement_decisions(root_residue=root_r, root_m=palier, leaf_residue=stable_r, leaf_m=stable_m)
thr = _opt_int(c, "N0") if kind == "D_exact" else _opt_int(c, "Nf") if kind == "F" else None
entries.append(
RefinementEntry(
n=n,
kind=kind, # type: ignore[arg-type]
root_modulus_power=palier,
root_residue_mod_2p=root_r,
leaf_modulus_power=stable_m,
leaf_residue_mod_2p=stable_r,
decisions=decisions,
k_or_t=_opt_int(c, "k_or_t"),
A=_opt_int(c, "A"),
threshold=thr,
)
)
if missing:
raise ValueError(f"Missing extracted clauses for {len(missing)} C3 residues (e.g. {missing[:20]})")
generated_at = _generated_at_utc_from_mtime([clauses_json, c3_verification_json])
sha = {
_display_path(clauses_json, repo_root): _sha256_file(clauses_json),
_display_path(c3_verification_json, repo_root): _sha256_file(c3_verification_json),
}
depths = [e.leaf_modulus_power - palier for e in entries]
max_depth = max(depths, default=0)
direct = sum(1 for d in depths if d == 0)
refined = len(depths) - direct
depth_buckets: dict[int, int] = {}
for d in depths:
depth_buckets[d] = depth_buckets.get(d, 0) + 1
out_json = output_dir / f"refinement_certificate_mod2p{palier}.json"
out_md = output_dir / f"refinement_certificate_mod2p{palier}.md"
audit_json = output_dir / f"audit_refinement_certificate_mod2p{palier}.json"
audit_md = output_dir / f"audit_refinement_certificate_mod2p{palier}.md"
cert_obj: dict[str, object] = {
"inputs": {
"clauses_json": _display_path(clauses_json, repo_root),
"verification_c3_local_descent_json": _display_path(c3_verification_json, repo_root),
},
"domain": {
"palier": palier,
"L_size": len(entries),
},
"generated_at": generated_at,
"sha256": sha,
"entries": [e.to_json() for e in sorted(entries, key=lambda x: x.n)],
}
_write_json(out_json, cert_obj)
audit_obj: dict[str, object] = {
"domain": {
"palier": palier,
"L_size": len(entries),
},
"decidability": {
"direct_leaf_count": direct,
"refined_leaf_count": refined,
"max_refinement_depth": max_depth,
"depth_buckets": {str(k): v for k, v in sorted(depth_buckets.items())},
},
"generated_at": generated_at,
"sha256": {
"outputs": {
_display_path(out_json, repo_root): _sha256_file(out_json),
}
},
}
_write_json(audit_json, audit_obj)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Certificat de raffinement — décidabilité depuis 2^{palier} (domaine L)")
md.append("")
md.append("## Entrées")
md.append("")
md.append(f"- clauses : `{_display_path(clauses_json, repo_root)}`")
md.append(f"- C3 : `{_display_path(c3_verification_json, repo_root)}`")
md.append("")
md.append("## Domaine")
md.append("")
md.append(f"- palier : 2^{palier}")
md.append(f"- |L| : {len(entries)}")
md.append(f"- generated_at : {generated_at}")
md.append("")
md.append("## Décidabilité (sur L)")
md.append("")
md.append(f"- feuilles directes (m_leaf = {palier}) : {direct}")
md.append(f"- feuilles raffinées (m_leaf > {palier}) : {refined}")
md.append(f"- profondeur max : {max_depth}")
md.append("")
md.append("### Buckets (profondeur = m_leaf - M)")
md.append("")
for d, cnt in sorted(depth_buckets.items()):
md.append(f"- depth={d} : {cnt}")
md.append("")
md.append("## Sorties")
md.append("")
md.append(f"- JSON : `{_display_path(out_json, repo_root)}`")
md.append(f"- Audit JSON : `{_display_path(audit_json, repo_root)}`")
_write_md(out_md, md)
amd: list[str] = []
amd.append("**Auteur** : Équipe 4NK")
amd.append("")
amd.append(f"# Audit — certificat de raffinement (2^{palier}, domaine L)")
amd.append("")
amd.append(f"- direct : {direct}")
amd.append(f"- refined : {refined}")
amd.append(f"- max_depth : {max_depth}")
amd.append("")
_write_md(audit_md, amd)
def main() -> None:
ap = argparse.ArgumentParser(description="Build a deterministic refinement certificate at palier 2^M on domain L")
ap.add_argument("--repo-root", default=".", help="Repository root (defaults to current working directory)")
ap.add_argument("--palier", type=int, default=15, help="Root palier M for the refinement certificate")
ap.add_argument("--clauses-json", default="", help="Path to clauses_universelles.json (Option A)")
ap.add_argument("--output-dir", default="", help="Output directory for refinement artefacts")
args = ap.parse_args()
repo_root = Path(args.repo_root).resolve()
palier = int(args.palier)
clauses_json = Path(args.clauses_json).resolve() if args.clauses_json.strip() else _infer_default_clauses_json(repo_root=repo_root, palier=palier)
output_dir = Path(args.output_dir).resolve() if args.output_dir.strip() else _infer_default_output_dir(repo_root=repo_root, palier=palier)
run(palier=palier, clauses_json=clauses_json, output_dir=output_dir, repo_root=repo_root)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,414 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_build_refinement_certificate_over_Sm.py
Build a deterministic refinement certificate over the full odd residue space S_M
(all odd residues modulo 2^M), using a finite set of terminal clauses (Option A).
Interpretation (H2' style, "decidable by finite refinement"):
- A root residue r in S_M is considered *closed* if the full binary refinement tree
rooted at (M,r) can be finitely closed by terminal clauses D/F (at varying moduli).
- A node (m, r_m) is closed if:
- it has a terminal clause at modulus 2^m with residue r_m, OR
- both children (m+1, r_m) and (m+1, r_m + 2^m) are closed.
Scope:
- This construction uses only the finite clause set; it does not claim closure for
residues whose refinement subtrees are not fully covered by these clauses.
Inputs:
- clauses_universelles.json (Option A) at palier M
Outputs:
- refinement_certificate_Sm_mod2p<M>.{json,md}
- audit_refinement_certificate_Sm_mod2p<M>.{json,md}
"""
from __future__ import annotations
import argparse
import json
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Literal
from collatz_build_register_K_modular import _display_path, _generated_at_utc_from_mtime, _sha256_file
ClauseKind = Literal["D_exact", "F"]
def _read_json(path: Path) -> object:
return json.loads(path.read_text(encoding="utf-8", errors="strict"))
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _req_int(d: dict[str, object], key: str) -> int:
v = d.get(key)
if not isinstance(v, int):
raise ValueError(f"Expected int for {key}")
return v
def _opt_int(d: dict[str, object], key: str) -> int | None:
v = d.get(key)
if v is None:
return None
if not isinstance(v, int):
raise ValueError(f"Expected int|null for {key}")
return v
@dataclass(frozen=True)
class TerminalClause:
kind: ClauseKind
modulus_power: int
residue_mod_2p: int
threshold: int
source_n: int
k_or_t: int | None
A: int | None
def to_json(self) -> dict[str, object]:
return {
"kind": self.kind,
"modulus_power": self.modulus_power,
"residue_mod_2p": self.residue_mod_2p,
"threshold": self.threshold,
"source_n": self.source_n,
"k_or_t": self.k_or_t,
"A": self.A,
}
def _infer_default_clauses_json(*, repo_root: Path, palier: int) -> Path:
base = repo_root / "docs" / "artefacts" / "collatz" / "universal_clauses"
if palier == 13:
return base / "clauses_universelles.json"
return base / f"palier2p{palier}" / "clauses_universelles.json"
def _infer_default_terminal_over_sm_json(*, repo_root: Path, palier: int) -> Path:
return (
repo_root
/ "docs"
/ "artefacts"
/ "collatz"
/ "terminal_clauses_over_Sm"
/ f"palier2p{palier}"
/ f"clauses_terminal_over_Sm_mod2p{palier}.json"
)
def _infer_default_output_dir(*, repo_root: Path, palier: int) -> Path:
return repo_root / "docs" / "artefacts" / "collatz" / "refinement_K" / f"palier2p{palier}"
def _load_terminal_clauses_from_option_a(*, clauses_obj: dict[str, object], palier: int) -> list[TerminalClause]:
domain = clauses_obj.get("domain")
if not isinstance(domain, dict):
raise ValueError("Invalid clauses JSON: missing domain")
if _req_int(domain, "palier") != palier:
raise ValueError("Clauses domain palier mismatch")
clauses = clauses_obj.get("clauses")
if not isinstance(clauses, list) or not all(isinstance(x, dict) for x in clauses):
raise ValueError("Invalid clauses JSON: missing clauses list")
out: list[TerminalClause] = []
for c in clauses:
kind = c.get("kind")
if kind not in ("D_exact", "F"):
continue
stable_m = _opt_int(c, "stable_modulus_power")
stable_r = _opt_int(c, "stable_residue_mod_2p")
if stable_m is None or stable_r is None:
continue
thr = _opt_int(c, "N0") if kind == "D_exact" else _opt_int(c, "Nf")
if thr is None:
raise ValueError(f"Missing threshold for clause kind={kind}")
sn = _opt_int(c, "source_n")
if sn is None:
raise ValueError("Missing source_n")
out.append(
TerminalClause(
kind=kind,
modulus_power=stable_m,
residue_mod_2p=stable_r,
threshold=thr,
source_n=sn,
k_or_t=_opt_int(c, "k_or_t"),
A=_opt_int(c, "A"),
)
)
return out
def _load_terminal_clauses_from_over_sm(*, obj: dict[str, object], palier: int) -> list[TerminalClause]:
domain = obj.get("domain")
if not isinstance(domain, dict):
raise ValueError("Invalid terminal clauses JSON: missing domain")
if _req_int(domain, "palier") != palier:
raise ValueError("Terminal clauses domain palier mismatch")
clauses = obj.get("clauses")
if not isinstance(clauses, list) or not all(isinstance(x, dict) for x in clauses):
raise ValueError("Invalid terminal clauses JSON: missing clauses list")
out: list[TerminalClause] = []
for c in clauses:
kind = c.get("kind")
if kind not in ("D_exact", "F"):
continue
m = _opt_int(c, "modulus_power")
r = _opt_int(c, "residue_mod_2p")
thr = _opt_int(c, "threshold")
if m is None or r is None or thr is None:
raise ValueError("Invalid terminal clause entry: missing modulus/residue/threshold")
out.append(
TerminalClause(
kind=kind,
modulus_power=m,
residue_mod_2p=r,
threshold=thr,
source_n=_opt_int(c, "residue_mod_2p") or 0,
k_or_t=_opt_int(c, "k_or_t"),
A=_opt_int(c, "A"),
)
)
return out
def _parent_residue(*, r: int, m: int) -> int:
return r % (1 << m)
def _child_residues(*, r: int, m: int) -> tuple[int, int]:
return (r, r + (1 << m))
def run(*, palier: int, clauses_json: Path, output_dir: Path, repo_root: Path, source: str) -> None:
cobj = _read_json(clauses_json)
if not isinstance(cobj, dict):
raise ValueError("Invalid clauses JSON: expected object")
if source == "optionA":
terminal = _load_terminal_clauses_from_option_a(clauses_obj=cobj, palier=palier)
elif source == "overSm":
terminal = _load_terminal_clauses_from_over_sm(obj=cobj, palier=palier)
else:
raise ValueError("Invalid source (expected optionA or overSm)")
if not terminal:
raise ValueError("No terminal clauses found (D_exact/F with stable modulus)")
# De-duplicate terminal clauses by exact node (m,r), keep minimal threshold for determinism.
by_node: dict[tuple[int, int], TerminalClause] = {}
for c in terminal:
key = (c.modulus_power, c.residue_mod_2p)
prev = by_node.get(key)
if prev is None:
by_node[key] = c
continue
if (c.threshold, c.kind, c.source_n) < (prev.threshold, prev.kind, prev.source_n):
by_node[key] = c
max_m = max(m for (m, _) in by_node.keys())
if max_m < palier:
raise ValueError("Invalid clause set: max modulus < palier")
# Sparse node set: include all ancestors of terminal nodes down to palier.
nodes_by_level: dict[int, set[int]] = {m: set() for m in range(palier, max_m + 1)}
for (m, r) in by_node.keys():
cur_r = r
for mm in range(m, palier - 1, -1):
nodes_by_level[mm].add(_parent_residue(r=cur_r, m=mm))
cur_r = _parent_residue(r=cur_r, m=mm - 1) if mm - 1 >= palier else cur_r
# Bottom-up closure.
closed_by_level: dict[int, set[int]] = {m: set() for m in range(palier, max_m + 1)}
for m in range(max_m, palier - 1, -1):
for r in sorted(nodes_by_level[m]):
if (m, r) in by_node:
closed_by_level[m].add(r)
continue
if m == max_m:
continue
c0, c1 = _child_residues(r=r, m=m)
if (c0 in closed_by_level[m + 1]) and (c1 in closed_by_level[m + 1]):
closed_by_level[m].add(r)
closed_roots = sorted(closed_by_level[palier])
total_roots = 1 << (palier - 1) # odd residues modulo 2^M
# Collect leaves per closed root (clauses that close its refinement tree).
memo_leaves: dict[tuple[int, int], list[tuple[int, int]]] = {}
def leaves(m: int, r: int) -> list[tuple[int, int]]:
key = (m, r)
cached = memo_leaves.get(key)
if cached is not None:
return cached
if (m, r) in by_node:
res = [(m, r)]
memo_leaves[key] = res
return res
if m >= max_m:
raise ValueError("Closed node expected to have descendants")
c0, c1 = _child_residues(r=r, m=m)
if (c0 not in closed_by_level[m + 1]) or (c1 not in closed_by_level[m + 1]):
raise ValueError("Closed node has non-closed child")
res = leaves(m + 1, c0) + leaves(m + 1, c1)
memo_leaves[key] = res
return res
closed_entries: list[dict[str, object]] = []
for r0 in closed_roots:
lf = leaves(palier, r0)
lf_clauses = [by_node[(m, r)].to_json() for (m, r) in sorted(lf)]
max_leaf_m = max(m for (m, _) in lf)
closed_entries.append(
{
"root_residue_mod_2p": r0,
"root_modulus_power": palier,
"leaf_count": len(lf),
"max_leaf_modulus_power": max_leaf_m,
"max_refinement_depth": max_leaf_m - palier,
"leaves": lf_clauses,
}
)
generated_at = _generated_at_utc_from_mtime([clauses_json])
sha = {_display_path(clauses_json, repo_root): _sha256_file(clauses_json)}
out_json = output_dir / f"refinement_certificate_Sm_mod2p{palier}.json"
out_md = output_dir / f"refinement_certificate_Sm_mod2p{palier}.md"
audit_json = output_dir / f"audit_refinement_certificate_Sm_mod2p{palier}.json"
audit_md = output_dir / f"audit_refinement_certificate_Sm_mod2p{palier}.md"
cert_obj: dict[str, object] = {
"inputs": {
"clauses_json": _display_path(clauses_json, repo_root),
"source": source,
},
"domain": {
"palier": palier,
"S_M_size": total_roots,
"candidate_roots_with_descendant_clauses": len(nodes_by_level[palier]),
},
"generated_at": generated_at,
"sha256": sha,
"closed_roots": {
"count": len(closed_roots),
"rows": closed_entries,
},
}
_write_json(out_json, cert_obj)
open_count = total_roots - len(closed_roots)
audit_obj: dict[str, object] = {
"domain": {
"palier": palier,
"S_M_size": total_roots,
},
"closure": {
"closed_roots": len(closed_roots),
"open_roots": open_count,
"closed_ratio": (len(closed_roots) / total_roots) if total_roots else 0.0,
},
"generated_at": generated_at,
"sha256": {
"inputs": sha,
"outputs": {
_display_path(out_json, repo_root): _sha256_file(out_json),
},
},
}
_write_json(audit_json, audit_obj)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Certificat de raffinement sur S_M — palier 2^{palier}")
md.append("")
md.append("## Entrée")
md.append("")
md.append(f"- clauses : `{_display_path(clauses_json, repo_root)}`")
md.append("")
md.append("## Domaine")
md.append("")
md.append(f"- palier : 2^{palier}")
md.append(f"- |S_M| (impairs) : {total_roots}")
md.append(f"- racines candidates (au moins une clause descendante) : {len(nodes_by_level[palier])}")
md.append(f"- generated_at : {generated_at}")
md.append("")
md.append("## Fermeture (sur S_M)")
md.append("")
md.append(f"- racines fermées : {len(closed_roots)}")
md.append(f"- racines ouvertes : {open_count}")
md.append("")
md.append("### Racines fermées (extrait)")
md.append("")
for row in closed_entries[:20]:
md.append(
f"- r={row['root_residue_mod_2p']} leaves={row['leaf_count']} max_depth={row['max_refinement_depth']}"
)
if len(closed_entries) > 20:
md.append(f"- ... ({len(closed_entries)-20} more)")
md.append("")
md.append("## Sorties")
md.append("")
md.append(f"- JSON : `{_display_path(out_json, repo_root)}`")
md.append(f"- Audit JSON : `{_display_path(audit_json, repo_root)}`")
_write_md(out_md, md)
amd: list[str] = []
amd.append("**Auteur** : Équipe 4NK")
amd.append("")
amd.append(f"# Audit — certificat de raffinement sur S_M (2^{palier})")
amd.append("")
amd.append(f"- closed_roots : {len(closed_roots)}")
amd.append(f"- open_roots : {open_count}")
amd.append(f"- closed_ratio : {(len(closed_roots) / total_roots) if total_roots else 0.0}")
amd.append("")
_write_md(audit_md, amd)
def main() -> None:
ap = argparse.ArgumentParser(description="Build refinement certificate over the full S_M (odd residues modulo 2^M)")
ap.add_argument("--repo-root", default=".", help="Repository root (defaults to current working directory)")
ap.add_argument("--palier", type=int, default=15, help="Palier M for S_M")
ap.add_argument(
"--source",
default="optionA",
choices=["optionA", "overSm"],
help="Clause source: optionA (clauses_universelles.json) or overSm (directly decidable terminal clauses over S_M)",
)
ap.add_argument("--clauses-json", default="", help="Path to clauses JSON (source-dependent)")
ap.add_argument("--output-dir", default="", help="Output directory for refinement artefacts")
args = ap.parse_args()
repo_root = Path(args.repo_root).resolve()
palier = int(args.palier)
if args.clauses_json.strip():
clauses_json = Path(args.clauses_json).resolve()
else:
clauses_json = (
_infer_default_clauses_json(repo_root=repo_root, palier=palier)
if args.source == "optionA"
else _infer_default_terminal_over_sm_json(repo_root=repo_root, palier=palier)
)
output_dir = Path(args.output_dir).resolve() if args.output_dir.strip() else _infer_default_output_dir(repo_root=repo_root, palier=palier)
run(palier=palier, clauses_json=clauses_json, output_dir=output_dir, repo_root=repo_root, source=str(args.source))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,364 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_build_refinement_certificate_over_Sm_multilevel.py
Build a deterministic refinement-closure audit for roots in S_M using terminal leaves
provided at multiple modulus levels (e.g. direct decidability at 2^16 to close roots at 2^15).
Given a root palier M and a max palier M_max>=M, we consider the full refinement tree
of odd residues from level M to level M_max. A node (m,r) is closed if:
- it is a leaf: there exists a terminal clause provided at that exact level m and residue r, OR
- both children (m+1,r) and (m+1,r+2^m) are closed.
This artefact is purely structural ("closure by refinement") and does not claim global
termination beyond the validity of the terminal clauses used as leaves.
Inputs:
- one or more JSON files produced by collatz_generate_terminal_clauses_over_Sm.py
(clauses_terminal_over_Sm_mod2p<m>.json), each providing leaves at its palier.
Outputs:
- docs/artefacts/collatz/refinement_K/palier2p<M>/refinement_certificate_Sm_multilevel_mod2p<M>_to2p<M_max>.{json,md}
- docs/artefacts/collatz/refinement_K/palier2p<M>/audit_refinement_certificate_Sm_multilevel_mod2p<M>_to2p<M_max>.{json,md}
"""
from __future__ import annotations
import argparse
import hashlib
import json
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
def _read_json(path: Path) -> object:
return json.loads(path.read_text(encoding="utf-8", errors="strict"))
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _sha256_file(path: Path, chunk_size: int = 16 * 1024 * 1024) -> str:
h = hashlib.sha256()
with path.open("rb") as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
h.update(chunk)
return h.hexdigest()
def _utc_now_iso() -> str:
return datetime.now(tz=timezone.utc).isoformat().replace("+00:00", "Z")
def _req_int(d: dict[str, object], key: str) -> int:
v = d.get(key)
if not isinstance(v, int):
raise ValueError(f"Expected int for {key}")
return v
@dataclass(frozen=True)
class LeafSet:
palier: int
residues: set[int]
source_json: str
def _load_leaf_set(path: Path) -> LeafSet:
obj = _read_json(path)
if not isinstance(obj, dict):
raise ValueError(f"Invalid leaf JSON: expected object: {path}")
domain = obj.get("domain")
if not isinstance(domain, dict):
raise ValueError(f"Invalid leaf JSON: missing domain: {path}")
palier = _req_int(domain, "palier")
clauses = obj.get("clauses")
if not isinstance(clauses, list) or not all(isinstance(x, dict) for x in clauses):
raise ValueError(f"Invalid leaf JSON: missing clauses list: {path}")
residues: set[int] = set()
for c in clauses:
m = c.get("modulus_power")
r = c.get("residue_mod_2p")
if m != palier:
raise ValueError(f"Invalid clause entry: modulus_power mismatch vs file palier: got {m}, expected {palier}")
if not isinstance(r, int):
raise ValueError("Invalid clause entry: missing residue_mod_2p")
residues.add(r)
return LeafSet(palier=palier, residues=residues, source_json=str(path))
def run(*, root_palier: int, max_palier: int, leaf_json_paths: list[Path], output_dir: Path, repo_root: Path) -> None:
if max_palier < root_palier:
raise ValueError("max_palier must be >= root_palier")
if not leaf_json_paths:
raise ValueError("At least one leaf JSON must be provided")
leaf_sets = [_load_leaf_set(p) for p in leaf_json_paths]
leaves_by_m: dict[int, set[int]] = {}
for ls in leaf_sets:
leaves_by_m.setdefault(ls.palier, set()).update(ls.residues)
for m in range(root_palier, max_palier + 1):
leaves_by_m.setdefault(m, set())
def compute_closed_by_level(*, target_max: int) -> dict[int, set[int]]:
closed: dict[int, set[int]] = {m: set() for m in range(root_palier, target_max + 1)}
for m in range(root_palier, target_max + 1):
closed[m] |= leaves_by_m[m]
for m in range(target_max - 1, root_palier - 1, -1):
step = 1 << m
for r in range(1, 1 << m, 2):
if r in closed[m]:
continue
if (r in closed[m + 1]) and ((r + step) in closed[m + 1]):
closed[m].add(r)
return closed
def compute_closed_roots(*, target_max: int) -> set[int]:
closed = compute_closed_by_level(target_max=target_max)
return closed[root_palier]
total_roots = 1 << (root_palier - 1)
closed_roots_by_max: dict[int, set[int]] = {}
for target in range(root_palier, max_palier + 1):
closed_roots_by_max[target] = compute_closed_roots(target_max=target)
closed_roots = sorted(closed_roots_by_max[max_palier])
open_roots = total_roots - len(closed_roots)
closed_by_level_final = compute_closed_by_level(target_max=max_palier)
open_count_by_m: dict[int, int] = {}
q_by_m: dict[int, float] = {}
parents_one_child_by_m: dict[int, int] = {}
for m in range(root_palier, max_palier + 1):
total_nodes_m = 1 << (m - 1)
open_count_by_m[m] = total_nodes_m - len(closed_by_level_final[m])
for m in range(root_palier, max_palier):
denom = 2 * open_count_by_m[m]
q_by_m[m] = (open_count_by_m[m + 1] / denom) if denom else 0.0
step = 1 << m
parents_one_child = 0
for r in range(1, 1 << m, 2):
if r in closed_by_level_final[m]:
continue
child0_closed = r in closed_by_level_final[m + 1]
child1_closed = (r + step) in closed_by_level_final[m + 1]
# parent is open; count it if exactly one child is open
if child0_closed != child1_closed:
parents_one_child += 1
parents_one_child_by_m[m] = parents_one_child
# first closure depth per root (minimal target max palier where it becomes closed), if any
first_close: dict[int, int] = {}
for r0 in range(1, 1 << root_palier, 2):
for target in range(root_palier, max_palier + 1):
if r0 in closed_roots_by_max[target]:
first_close[r0] = target
break
newly_closed_by_target: dict[int, list[int]] = {}
prev_closed: set[int] = set()
for target in range(root_palier, max_palier + 1):
cur_closed = closed_roots_by_max[target]
newly = sorted([r for r in cur_closed if r not in prev_closed])
newly_closed_by_target[target] = newly
prev_closed = set(cur_closed)
still_open = sorted([r for r in range(1, 1 << root_palier, 2) if r not in closed_roots_by_max[max_palier]])
inputs_sha: dict[str, str] = {}
for p in leaf_json_paths:
rel = str(p.resolve().relative_to(repo_root.resolve())) if p.is_absolute() else str(p)
inputs_sha[rel] = _sha256_file(p)
cert_json = output_dir / f"refinement_certificate_Sm_multilevel_mod2p{root_palier}_to2p{max_palier}.json"
cert_md = output_dir / f"refinement_certificate_Sm_multilevel_mod2p{root_palier}_to2p{max_palier}.md"
audit_json = output_dir / f"audit_refinement_certificate_Sm_multilevel_mod2p{root_palier}_to2p{max_palier}.json"
audit_md = output_dir / f"audit_refinement_certificate_Sm_multilevel_mod2p{root_palier}_to2p{max_palier}.md"
generated_at = _utc_now_iso()
cert_obj: dict[str, object] = {
"domain": {
"root_palier": root_palier,
"max_palier": max_palier,
"S_root_size": total_roots,
},
"inputs": {
"leaf_sources": [str(p) for p in leaf_json_paths],
},
"generated_at": generated_at,
"sha256": {"inputs": inputs_sha},
"closure": {
"closed_roots": len(closed_roots),
"open_roots": open_roots,
"closed_ratio": (len(closed_roots) / total_roots) if total_roots else 0.0,
"closed_roots_sample": closed_roots[:200],
"still_open_roots_sample": still_open[:200],
},
"residue_audit": {
"open_count_by_palier": {str(k): v for k, v in open_count_by_m.items()},
"q_by_palier": {str(k): v for k, v in q_by_m.items()},
"parents_one_child_by_palier": {str(k): v for k, v in parents_one_child_by_m.items()},
},
"timeline": [
{
"target_max_palier": target,
"closed_roots": len(closed_roots_by_max[target]),
"open_roots": total_roots - len(closed_roots_by_max[target]),
"newly_closed_at_target": len(newly_closed_by_target[target]),
}
for target in range(root_palier, max_palier + 1)
],
"newly_closed_roots_by_target": {str(k): v for k, v in newly_closed_by_target.items()},
"first_close_palier_by_root": {str(k): v for k, v in first_close.items()},
}
_write_json(cert_json, cert_obj)
audit_obj: dict[str, object] = {
"domain": cert_obj["domain"],
"closure": cert_obj["closure"],
"generated_at": generated_at,
"sha256": {
"inputs": inputs_sha,
"outputs": {str(cert_json.relative_to(repo_root)): _sha256_file(cert_json)} if cert_json.is_absolute() else {},
},
}
_write_json(audit_json, audit_obj)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Certificat de raffinement multi-niveaux sur S_M — racine 2^{root_palier} vers 2^{max_palier}")
md.append("")
md.append("## Domaine")
md.append("")
md.append(f"- racine : 2^{root_palier}")
md.append(f"- profondeur max : 2^{max_palier}")
md.append(f"- |S_{root_palier}| (impairs) : {total_roots}")
md.append("")
md.append("## Entrées (feuilles terminales)")
md.append("")
for p in leaf_json_paths:
md.append(f"- `{p}`")
md.append("")
md.append("## Fermeture (sur S_M)")
md.append("")
md.append(f"- closed_roots : {len(closed_roots)}")
md.append(f"- open_roots : {open_roots}")
md.append(f"- closed_ratio : {(len(closed_roots) / total_roots) if total_roots else 0.0}")
md.append("")
md.append("## Timeline (première profondeur de fermeture)")
md.append("")
md.append("| cible | newly_closed | closed | open | closed_ratio |")
md.append("| --- | --- | --- | --- | --- |")
for row in cert_obj["timeline"]: # type: ignore[assignment]
target = int(row["target_max_palier"]) # type: ignore[index]
newly = int(row["newly_closed_at_target"]) # type: ignore[index]
closed_cnt = int(row["closed_roots"]) # type: ignore[index]
open_cnt = int(row["open_roots"]) # type: ignore[index]
ratio = closed_cnt / total_roots if total_roots else 0.0
md.append(f"| {target} | {newly} | {closed_cnt} | {open_cnt} | {ratio:.6f} |")
md.append("")
md.append("## Audit du résidu (comptes, q_m, parents à un enfant)")
md.append("")
md.append("| m | open_count | q_m | parents_one_child |")
md.append("| --- | --- | --- | --- |")
for m in range(root_palier, max_palier):
md.append(
f"| {m} | {open_count_by_m[m]} | {q_by_m[m]:.12f} | {parents_one_child_by_m[m]} |"
)
md.append(f"| {max_palier} | {open_count_by_m[max_palier]} | | |")
md.append("")
md.append("### Racines encore ouvertes (extrait)")
md.append("")
for r in still_open[:40]:
md.append(f"- r={r}")
if len(still_open) > 40:
md.append(f"- ... ({len(still_open)-40} more)")
md.append("")
md.append("### Racines fermées (extrait)")
md.append("")
for r in closed_roots[:40]:
md.append(f"- r={r}")
if len(closed_roots) > 40:
md.append(f"- ... ({len(closed_roots)-40} more)")
md.append("")
md.append("## Sorties")
md.append("")
md.append(f"- JSON : `{cert_json}`")
md.append(f"- Audit JSON : `{audit_json}`")
md.append("")
_write_md(cert_md, md)
amd: list[str] = []
amd.append("**Auteur** : Équipe 4NK")
amd.append("")
amd.append(f"# Audit — raffinement multi-niveaux sur S_M (2^{root_palier}→2^{max_palier})")
amd.append("")
amd.append(f"- closed_roots : {len(closed_roots)}")
amd.append(f"- open_roots : {open_roots}")
amd.append(f"- closed_ratio : {(len(closed_roots) / total_roots) if total_roots else 0.0}")
amd.append("")
_write_md(audit_md, amd)
def main() -> None:
ap = argparse.ArgumentParser(description="Build a multilevel refinement closure audit over S_M")
ap.add_argument("--repo-root", default=".", help="Repository root")
ap.add_argument("--root-palier", type=int, default=15, help="Root palier M")
ap.add_argument("--max-palier", type=int, default=16, help="Max palier for refinement")
ap.add_argument(
"--leaf-json",
action="append",
default=[],
help="Leaf JSON path (can be repeated). If omitted, uses terminal_clauses_over_Sm for root and max levels.",
)
ap.add_argument("--output-dir", default="", help="Output directory (defaults under docs/artefacts/...)")
args = ap.parse_args()
repo_root = Path(args.repo_root).resolve()
root_palier = int(args.root_palier)
max_palier = int(args.max_palier)
default_leafs: list[Path] = []
for m in range(root_palier, max_palier + 1):
default_leafs.append(
repo_root
/ "docs"
/ "artefacts"
/ "collatz"
/ "terminal_clauses_over_Sm"
/ f"palier2p{m}"
/ f"clauses_terminal_over_Sm_mod2p{m}.json"
)
leaf_paths = [Path(p).resolve() for p in args.leaf_json] if args.leaf_json else default_leafs
output_dir = Path(args.output_dir).resolve() if args.output_dir.strip() else (
repo_root / "docs" / "artefacts" / "collatz" / "refinement_K" / f"palier2p{root_palier}"
)
run(
root_palier=root_palier,
max_palier=max_palier,
leaf_json_paths=leaf_paths,
output_dir=output_dir,
repo_root=repo_root,
)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,990 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_build_register_K_modular.py
Build a deterministic, versionable modular register K_M and a finite coverage audit
from Option A artefacts.
Inputs:
- universal clauses artefact produced by `collatz_extract_universal_clauses.py`
(clauses_universelles.json)
- C3 verification JSON referenced by the clauses artefact, or provided explicitly
Outputs (versionable, no transcripts):
- register_K_mod2p<M>.{json,md}
- audit_register_K_mod2p<M>.{json,md}
- non_eligible_clauses_mod2p<M>.{json,md}
- manifest_register_K_mod2p<M>.{json,md}
Scope:
- K_M contains only clauses with modulus power m(c) <= M (decidable at palier 2^M).
- The coverage audit is performed on the finite C3 domain L (the record n's), not on S_M.
"""
from __future__ import annotations
import argparse
import hashlib
import json
import sys
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Literal
ClauseKind = Literal["D_exact", "F", "D_brother_local"]
def _read_json(path: Path) -> object:
return json.loads(path.read_text(encoding="utf-8", errors="strict"))
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _sha256_file(path: Path, chunk_size: int = 16 * 1024 * 1024) -> str:
h = hashlib.sha256()
with path.open("rb") as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
h.update(chunk)
return h.hexdigest()
def _file_size_bytes(path: Path) -> int:
if not path.exists():
raise FileNotFoundError(str(path))
return path.stat().st_size
def _file_mtime_utc_iso(path: Path) -> str:
if not path.exists():
raise FileNotFoundError(str(path))
ts = path.stat().st_mtime
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
return dt.isoformat().replace("+00:00", "Z")
def _file_mtime_epoch_seconds(path: Path) -> float:
if not path.exists():
raise FileNotFoundError(str(path))
return float(path.stat().st_mtime)
def _float_equal(a: float, b: float, eps: float = 1e-6) -> bool:
return abs(a - b) <= eps
class CheckMismatchError(Exception):
pass
def _generated_at_utc_from_mtime(paths: list[Path]) -> str:
mtimes = [p.stat().st_mtime for p in paths if p.exists()]
if not mtimes:
raise ValueError("Cannot infer generated_at: no existing input paths")
ts = max(mtimes)
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
return dt.isoformat().replace("+00:00", "Z")
def _display_path(path: Path, repo_root: Path) -> str:
try:
rel = path.resolve().relative_to(repo_root.resolve())
return str(rel)
except ValueError:
return str(path)
def _req_int(d: dict[str, object], key: str) -> int:
v = d.get(key)
if not isinstance(v, int):
raise ValueError(f"Expected int for {key}")
return v
def _opt_int(d: dict[str, object], key: str) -> int | None:
v = d.get(key)
if v is None:
return None
if not isinstance(v, int):
raise ValueError(f"Expected int|null for {key}")
return v
@dataclass(frozen=True)
class EligibleClause:
kind: ClauseKind
modulus_power: int
residue_mod_2p: int
threshold: int
source_n: int
# optional payload for traceability
k_or_t: int | None
A: int | None
C: int | None
a: int | None
y: int | None
preimage_m: int | None
DeltaF: int | None
def to_json(self) -> dict[str, object]:
return {
"kind": self.kind,
"modulus_power": self.modulus_power,
"residue_mod_2p": self.residue_mod_2p,
"threshold": self.threshold,
"source_n": self.source_n,
"k_or_t": self.k_or_t,
"A": self.A,
"C": self.C,
"a": self.a,
"y": self.y,
"preimage_m": self.preimage_m,
"DeltaF": self.DeltaF,
}
def _infer_default_clauses_json(*, repo_root: Path, palier: int) -> Path:
base = repo_root / "docs" / "artefacts" / "collatz" / "universal_clauses"
if palier == 13:
return base / "clauses_universelles.json"
return base / f"palier2p{palier}" / "clauses_universelles.json"
def _infer_default_output_dir(*, repo_root: Path, palier: int) -> Path:
return repo_root / "docs" / "artefacts" / "collatz" / "register_K" / f"palier2p{palier}"
def _load_c3_verification_path_from_clauses(*, clauses_obj: dict[str, object], repo_root: Path) -> Path:
inputs = clauses_obj.get("inputs")
if not isinstance(inputs, dict):
raise ValueError("Invalid clauses JSON: missing inputs")
p = inputs.get("verification_c3_local_descent_json")
if not isinstance(p, str) or not p.strip():
raise ValueError("Invalid clauses JSON: missing inputs.verification_c3_local_descent_json")
path = Path(p)
if not path.is_absolute():
path = repo_root / path
return path.resolve()
def _eligible_clause_from_extracted(obj: dict[str, object]) -> EligibleClause | None:
kind = obj.get("kind")
if not isinstance(kind, str):
raise ValueError("Invalid clause entry: missing kind")
if kind not in ("D_exact", "F", "D_brother_local"):
raise ValueError(f"Invalid clause entry: unknown kind {kind}")
stable_m = _opt_int(obj, "stable_modulus_power")
stable_r = _opt_int(obj, "stable_residue_mod_2p")
if stable_m is None or stable_r is None:
return None
source_n = _req_int(obj, "source_n")
k_or_t = _opt_int(obj, "k_or_t")
A = _opt_int(obj, "A")
C = _opt_int(obj, "C")
a = _opt_int(obj, "a")
y = _opt_int(obj, "y")
pre = _opt_int(obj, "preimage_m")
dF = _opt_int(obj, "DeltaF")
if kind == "D_exact":
thr = _opt_int(obj, "N0")
if thr is None:
raise ValueError("Invalid D_exact clause entry: missing N0")
return EligibleClause(
kind="D_exact",
modulus_power=stable_m,
residue_mod_2p=stable_r,
threshold=thr,
source_n=source_n,
k_or_t=k_or_t,
A=A,
C=C,
a=None,
y=None,
preimage_m=None,
DeltaF=None,
)
if kind == "F":
thr = _opt_int(obj, "Nf")
if thr is None:
raise ValueError("Invalid F clause entry: missing Nf")
return EligibleClause(
kind="F",
modulus_power=stable_m,
residue_mod_2p=stable_r,
threshold=thr,
source_n=source_n,
k_or_t=k_or_t,
A=A,
C=C,
a=a,
y=y,
preimage_m=pre,
DeltaF=dF,
)
return None
def _build_brother_local_entries(*, clauses: list[dict[str, object]], palier: int) -> list[EligibleClause]:
"""
Convert D_brother_local extracted entries into register entries that are decidable at the domain palier.
These entries are LOCAL to the instrumented domain L and are included only for traceability/piloting.
They are not claimed as standalone universal clauses on S_M.
"""
by_source_n: dict[int, dict[str, object]] = {}
for c in clauses:
sn = c.get("source_n")
if isinstance(sn, int):
by_source_n[sn] = c
out: list[EligibleClause] = []
for c in clauses:
if c.get("kind") != "D_brother_local":
continue
sn = c.get("source_n")
mate = c.get("mate_exact")
if not isinstance(sn, int) or not isinstance(mate, int):
raise ValueError("Invalid D_brother_local entry: missing source_n/mate_exact")
mate_obj = by_source_n.get(mate)
if mate_obj is None or mate_obj.get("kind") != "D_exact":
raise ValueError(f"Invalid D_brother_local entry: mate_exact is not a D_exact clause: source_n={sn} mate={mate}")
thr = _opt_int(mate_obj, "N0")
if thr is None:
raise ValueError(f"Invalid mate D_exact entry: missing N0: mate={mate}")
out.append(
EligibleClause(
kind="D_brother_local",
modulus_power=palier,
residue_mod_2p=sn,
threshold=thr,
source_n=sn,
k_or_t=_opt_int(mate_obj, "k_or_t"),
A=_opt_int(mate_obj, "A"),
C=_opt_int(mate_obj, "C"),
a=None,
y=None,
preimage_m=None,
DeltaF=None,
)
)
return out
def _compute_required_m_stable(*, domain_palier: int, record: dict[str, Any]) -> int | None:
kind = record.get("kind")
if kind == "D_exact":
A = record.get("A_k")
if not isinstance(A, int):
raise ValueError("Invalid D_exact record: missing A_k")
return max(domain_palier, A + 1)
if kind == "F":
A = record.get("A_t")
if not isinstance(A, int):
raise ValueError("Invalid F record: missing A_t")
return max(domain_palier, A + 1)
if kind == "D_brother":
return None
raise ValueError(f"Unknown C3 record kind: {kind}")
def _check_manual_edits_from_manifest(*, manifest_json: Path, repo_root: Path) -> None:
obj = _read_json(manifest_json)
if not isinstance(obj, dict):
raise ValueError("Invalid manifest JSON: expected object")
mtimes = obj.get("mtimes")
sizes = obj.get("sizes_bytes")
if not isinstance(mtimes, dict) or not isinstance(sizes, dict):
raise ValueError("Invalid manifest JSON: missing mtimes/sizes_bytes")
outs_mtimes = mtimes.get("outputs")
outs_sizes = sizes.get("outputs")
if not isinstance(outs_mtimes, dict) or not isinstance(outs_sizes, dict):
raise ValueError("Invalid manifest JSON: missing mtimes.outputs / sizes_bytes.outputs")
changed: list[str] = []
for rel_path, meta in outs_mtimes.items():
if not isinstance(rel_path, str) or not isinstance(meta, dict):
raise ValueError("Invalid manifest JSON: mtimes.outputs must be object of objects")
recorded_epoch = meta.get("mtime_epoch_seconds")
recorded_iso = meta.get("mtime_utc_iso")
if not isinstance(recorded_epoch, (int, float)) or not isinstance(recorded_iso, str):
raise ValueError(f"Invalid manifest JSON: bad mtime meta for {rel_path}")
rec_size = outs_sizes.get(rel_path)
if not isinstance(rec_size, int):
raise ValueError(f"Invalid manifest JSON: missing sizes_bytes.outputs for {rel_path}")
p = Path(rel_path)
abs_p = p if p.is_absolute() else (repo_root / p)
if not abs_p.exists():
changed.append(f"{rel_path}: missing (recorded mtime={recorded_iso}, size={rec_size})")
continue
cur_epoch = _file_mtime_epoch_seconds(abs_p)
cur_iso = _file_mtime_utc_iso(abs_p)
cur_size = _file_size_bytes(abs_p)
if (not _float_equal(cur_epoch, float(recorded_epoch))) or (cur_size != rec_size):
changed.append(
f"{rel_path}: recorded {recorded_iso} ({recorded_epoch}), size={rec_size}; current {cur_iso} ({cur_epoch}), size={cur_size}"
)
if changed:
details = "\n".join(changed[:60])
more = "" if len(changed) <= 60 else f"\n... ({len(changed)-60} more)"
raise CheckMismatchError(f"Detected output modifications since manifest:\n{details}{more}")
def _check_sha256_from_manifest(*, manifest_json: Path, repo_root: Path) -> None:
obj = _read_json(manifest_json)
if not isinstance(obj, dict):
raise ValueError("Invalid manifest JSON: expected object")
sha = obj.get("sha256")
if not isinstance(sha, dict):
raise ValueError("Invalid manifest JSON: missing sha256")
outs_sha = sha.get("outputs")
if not isinstance(outs_sha, dict):
raise ValueError("Invalid manifest JSON: missing sha256.outputs")
mismatches: list[str] = []
for rel_path, recorded in outs_sha.items():
if not isinstance(rel_path, str) or not isinstance(recorded, str):
raise ValueError("Invalid manifest JSON: sha256.outputs must be object of strings")
p = Path(rel_path)
abs_p = p if p.is_absolute() else (repo_root / p)
if not abs_p.exists():
mismatches.append(f"{rel_path}: missing (recorded sha256={recorded})")
continue
cur = _sha256_file(abs_p)
if cur != recorded:
mismatches.append(f"{rel_path}: recorded {recorded}, current {cur}")
if mismatches:
details = "\n".join(mismatches[:60])
more = "" if len(mismatches) <= 60 else f"\n... ({len(mismatches)-60} more)"
raise CheckMismatchError(f"Detected sha256 mismatches vs manifest:\n{details}{more}")
def _check_inputs_sha256_from_manifest(*, manifest_json: Path, repo_root: Path) -> None:
obj = _read_json(manifest_json)
if not isinstance(obj, dict):
raise ValueError("Invalid manifest JSON: expected object")
sha = obj.get("sha256")
if not isinstance(sha, dict):
raise ValueError("Invalid manifest JSON: missing sha256")
ins_sha = sha.get("inputs")
if not isinstance(ins_sha, dict):
raise ValueError("Invalid manifest JSON: missing sha256.inputs")
mismatches: list[str] = []
for rel_path, recorded in ins_sha.items():
if not isinstance(rel_path, str) or not isinstance(recorded, str):
raise ValueError("Invalid manifest JSON: sha256.inputs must be object of strings")
p = Path(rel_path)
abs_p = p if p.is_absolute() else (repo_root / p)
if not abs_p.exists():
mismatches.append(f"{rel_path}: missing (recorded sha256={recorded})")
continue
cur = _sha256_file(abs_p)
if cur != recorded:
mismatches.append(f"{rel_path}: recorded {recorded}, current {cur}")
if mismatches:
details = "\n".join(mismatches[:60])
more = "" if len(mismatches) <= 60 else f"\n... ({len(mismatches)-60} more)"
raise CheckMismatchError(f"Detected input sha256 mismatches vs manifest:\n{details}{more}")
def run(*, palier: int, horizon_k: int, clauses_json: Path, c3_verification_json: Path, output_dir: Path, repo_root: Path) -> None:
if palier < 1:
raise ValueError("palier must be >= 1")
if horizon_k < 1:
raise ValueError("horizon_k must be >= 1")
cobj = _read_json(clauses_json)
if not isinstance(cobj, dict):
raise ValueError("Invalid clauses JSON: expected object")
domain = cobj.get("domain")
if not isinstance(domain, dict):
raise ValueError("Invalid clauses JSON: missing domain")
domain_palier = _req_int(domain, "palier")
if domain_palier != palier:
raise ValueError(f"Clauses domain palier mismatch: {domain_palier} != {palier}")
clauses = cobj.get("clauses")
if not isinstance(clauses, list) or not all(isinstance(x, dict) for x in clauses):
raise ValueError("Invalid clauses JSON: missing clauses list")
eligible_raw: list[EligibleClause] = []
for c in clauses:
ec = _eligible_clause_from_extracted(c)
if ec is None:
continue
if ec.modulus_power <= palier:
eligible_raw.append(ec)
# Optional local entries: D_brother_local (decidable at domain palier, not universal on S_M)
eligible_raw.extend(_build_brother_local_entries(clauses=clauses, palier=palier))
# de-duplicate by (kind, modulus, residue)
seen: set[tuple[str, int, int]] = set()
eligible: list[EligibleClause] = []
for c in sorted(eligible_raw, key=lambda x: (x.kind, x.modulus_power, x.residue_mod_2p, x.threshold, x.source_n)):
key = (c.kind, c.modulus_power, c.residue_mod_2p)
if key in seen:
continue
seen.add(key)
eligible.append(c)
n_star = max([c.threshold for c in eligible], default=0)
# coverage audit on L = {record.n} from C3 verification
vobj = _read_json(c3_verification_json)
if not isinstance(vobj, dict):
raise ValueError("Invalid C3 verification JSON: expected object")
vdomain = vobj.get("domain")
vrecords = vobj.get("records")
if not isinstance(vdomain, dict) or not isinstance(vrecords, list):
raise ValueError("Invalid C3 verification JSON: missing domain/records")
vpal = _req_int(vdomain, "palier")
if vpal != palier:
raise ValueError(f"C3 domain palier mismatch: {vpal} != {palier}")
if not all(isinstance(r, dict) for r in vrecords):
raise ValueError("Invalid C3 verification JSON: records must be objects")
L: list[int] = []
by_n: dict[int, dict[str, Any]] = {}
for r in vrecords:
n = r.get("n")
if not isinstance(n, int):
raise ValueError("Invalid C3 record: missing n")
if n in by_n:
raise ValueError(f"Duplicate n in C3 records: {n}")
by_n[n] = r # type: ignore[assignment]
L.append(n)
L_sorted = sorted(L)
covered: set[int] = set()
for n in L_sorted:
for c in eligible:
mod = 1 << c.modulus_power
if (n % mod) == c.residue_mod_2p:
covered.add(n)
break
uncovered = [n for n in L_sorted if n not in covered]
uncovered_diagnostics: list[dict[str, object]] = []
for n in uncovered[:500]:
rec = by_n[n]
required = _compute_required_m_stable(domain_palier=palier, record=rec)
uncovered_diagnostics.append(
{
"n": n,
"kind": rec.get("kind"),
"required_m_stable": required,
}
)
# Non-eligible table (piloting): n in L whose required_m_stable > M, sorted by required_m_stable
non_eligible: list[dict[str, object]] = []
for n in L_sorted:
rec = by_n[n]
required = _compute_required_m_stable(domain_palier=palier, record=rec)
if required is None:
continue
if required <= palier:
continue
delta_to_next = required - palier
non_eligible.append(
{
"n": n,
"kind": rec.get("kind"),
"required_m_stable": required,
"delta_to_next": delta_to_next,
}
)
non_eligible_sorted = sorted(non_eligible, key=lambda x: (int(x["required_m_stable"]), int(x["n"]))) # type: ignore[arg-type]
buckets: dict[int, int] = {}
for x in non_eligible_sorted:
mreq = int(x["required_m_stable"]) # type: ignore[arg-type]
buckets[mreq] = buckets.get(mreq, 0) + 1
m_next = palier + 1
gains_next = buckets.get(m_next, 0)
max_required = max(buckets.keys(), default=palier)
cum_rows: list[dict[str, object]] = []
cum = 0
for target in range(palier + 1, max_required + 1):
newly = buckets.get(target, 0)
cum += newly
cum_rows.append(
{
"target_M": target,
"k": target - palier,
"newly_eligible_at_target": newly,
"cumulative_newly_eligible_up_to_target": cum,
"eligible_count_at_target": len(covered) + cum,
}
)
sha = {
_display_path(clauses_json, repo_root): _sha256_file(clauses_json),
_display_path(c3_verification_json, repo_root): _sha256_file(c3_verification_json),
}
generated_at = _generated_at_utc_from_mtime([clauses_json, c3_verification_json])
register_obj: dict[str, object] = {
"inputs": {
"clauses_universelles_json": _display_path(clauses_json, repo_root),
"verification_c3_local_descent_json": _display_path(c3_verification_json, repo_root),
},
"sha256": sha,
"domain": {
"palier": palier,
},
"generation": {
"horizon_k": horizon_k,
"generated_at": generated_at,
},
"register": {
"M": palier,
"n_star": n_star,
"clauses_total": len(eligible),
"clauses": [c.to_json() for c in eligible],
},
}
audit_obj: dict[str, object] = {
"inputs": register_obj["inputs"],
"sha256": sha,
"domain": {
"palier": palier,
"L_size": len(L_sorted),
"L_min_n": min(L_sorted) if L_sorted else None,
"L_max_n": max(L_sorted) if L_sorted else None,
},
"generation": {
"horizon_k": horizon_k,
"generated_at": generated_at,
},
"register": {
"M": palier,
"clauses_total": len(eligible),
"n_star": n_star,
},
"coverage": {
"covered_count": len(covered),
"uncovered_count": len(uncovered),
"uncovered_sample_limit": 500,
"uncovered_sample": uncovered_diagnostics,
},
"ok_full_coverage_on_L": len(uncovered) == 0,
}
non_eligible_obj: dict[str, object] = {
"inputs": register_obj["inputs"],
"sha256": sha,
"domain": {
"palier": palier,
"L_size": len(L_sorted),
},
"non_eligible": {
"criterion": "required_m_stable > M",
"M": palier,
"horizon_k": horizon_k,
"generated_at": generated_at,
"total": len(non_eligible_sorted),
"gains_expected_at_M_plus_1": {
"M_plus_1": m_next,
"newly_eligible_count": gains_next,
"eligible_count_at_M": len(covered),
"eligible_count_at_M_plus_1": len(covered) + gains_next,
},
"cumulative_gains_expected": {
"max_required_m_stable": max_required,
"rows": cum_rows,
},
"buckets_by_required_m_stable": {str(k): v for k, v in sorted(buckets.items())},
"rows": non_eligible_sorted,
},
}
out_json = output_dir / f"register_K_mod2p{palier}.json"
out_md = output_dir / f"register_K_mod2p{palier}.md"
audit_json = output_dir / f"audit_register_K_mod2p{palier}.json"
audit_md = output_dir / f"audit_register_K_mod2p{palier}.md"
non_eligible_json = output_dir / f"non_eligible_clauses_mod2p{palier}.json"
non_eligible_md = output_dir / f"non_eligible_clauses_mod2p{palier}.md"
manifest_json = output_dir / f"manifest_register_K_mod2p{palier}.json"
manifest_md = output_dir / f"manifest_register_K_mod2p{palier}.md"
_write_json(out_json, register_obj)
_write_json(audit_json, audit_obj)
_write_json(non_eligible_json, non_eligible_obj)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Registre modulaire — K_{palier} (palier 2^{palier})")
md.append("")
md.append("## Entrées")
md.append("")
md.append(f"- clauses : `{register_obj['inputs']['clauses_universelles_json']}`")
md.append(f"- C3 vérification : `{register_obj['inputs']['verification_c3_local_descent_json']}`")
md.append("")
md.append("## Paramètres")
md.append("")
md.append(f"- M : {palier}")
md.append(f"- generated_at : {generated_at}")
md.append(f"- N* (max seuils) : {n_star}")
md.append(f"- clauses retenues (m(c) <= M) : {len(eligible)}")
md.append("")
md.append("## Empreintes sha256")
md.append("")
for k in sorted(sha.keys()):
md.append(f"- `{k}` : `{sha[k]}`")
md.append("")
md.append("## Table (extrait)")
md.append("")
header = ["kind", "m", "residue", "threshold", "k/t", "A", "source_n"]
md.append("| " + " | ".join(header) + " |")
md.append("| " + " | ".join(["---"] * len(header)) + " |")
for c in eligible[:40]:
md.append(f"| {c.kind} | {c.modulus_power} | {c.residue_mod_2p} | {c.threshold} | {c.k_or_t or ''} | {c.A or ''} | {c.source_n} |")
if len(eligible) > 40:
md.append("| ... | ... | ... | ... | ... | ... | ... |")
_write_md(out_md, md)
amd: list[str] = []
amd.append("**Auteur** : Équipe 4NK")
amd.append("")
amd.append(f"# Audit — couverture modulaire de K_{palier} sur le domaine L (C3)")
amd.append("")
amd.append("## Domaine")
amd.append("")
amd.append(f"- palier : 2^{palier}")
amd.append(f"- |L| : {len(L_sorted)}")
amd.append(f"- generated_at : {generated_at}")
amd.append("")
amd.append("## Registre")
amd.append("")
amd.append(f"- clauses : {len(eligible)} (m(c) <= {palier})")
amd.append(f"- N* : {n_star}")
amd.append("")
amd.append("## Couverture sur L")
amd.append("")
amd.append(f"- covered : {len(covered)}")
amd.append(f"- uncovered : {len(uncovered)}")
amd.append(f"- ok_full_coverage_on_L : {len(uncovered) == 0}")
amd.append("")
if uncovered:
amd.append("### Uncovered (extrait)")
amd.append("")
for u in uncovered_diagnostics[:40]:
amd.append(f"- n={u['n']} kind={u['kind']} required_m_stable={u['required_m_stable']}")
if len(uncovered_diagnostics) > 40:
amd.append("- ...")
amd.append("")
amd.append("### Interprétation (indexée)")
amd.append("")
amd.append(f"- Pour les `F` avec required_m_stable > {palier}, la clause candidate exige un module > 2^{palier} et nest donc pas décidable au niveau des classes modulo 2^{palier}.")
amd.append("")
amd.append("## Planification — gains cumulés à horizon fixe")
amd.append("")
amd.append(f"Vue cumulée à horizon (M+k) avec k <= {horizon_k} (sur les témoins non éligibles, groupés par `required_m_stable`).")
amd.append("")
amd.append("| cible | k | newly | cumulative | eligible@cible | eligible@cible / |L| |")
amd.append("| --- | --- | --- | --- | --- | --- |")
if cum_rows:
fixed = [row for row in cum_rows if int(row["k"]) <= horizon_k]
for row in fixed:
eligible_at_target = int(row["eligible_count_at_target"])
pct = (eligible_at_target / len(L_sorted) * 100.0) if L_sorted else 0.0
amd.append(
f"| {row['target_M']} | {row['k']} | {row['newly_eligible_at_target']} | "
f"{row['cumulative_newly_eligible_up_to_target']} | {row['eligible_count_at_target']} | {pct:.2f}% |"
)
if len(fixed) < horizon_k:
amd.append("| ... | ... | ... | ... | ... | ... |")
amd.append("")
last_fixed = fixed[-1]
eligible_m_plus_5 = int(last_fixed["eligible_count_at_target"])
pct_m_plus_5 = (eligible_m_plus_5 / len(L_sorted) * 100.0) if L_sorted else 0.0
amd.append("Vue parallèle (comparaison inter-paliers).")
amd.append("")
amd.append(f"- eligible@M : {len(covered)}/{len(L_sorted)} ({(len(covered)/len(L_sorted)*100.0) if L_sorted else 0.0:.2f}%)")
amd.append(f"- eligible@M+{horizon_k} : {eligible_m_plus_5}/{len(L_sorted)} ({pct_m_plus_5:.2f}%)")
amd.append("")
else:
pct = (len(covered) / len(L_sorted) * 100.0) if L_sorted else 0.0
amd.append(f"| {palier+1} | 1 | 0 | 0 | {len(covered)} | {pct:.2f}% |")
amd.append("")
_write_md(audit_md, amd)
nmd: list[str] = []
nmd.append("**Auteur** : Équipe 4NK")
nmd.append("")
nmd.append(f"# Table — clauses non éligibles à 2^{palier} (triées par required_m_stable)")
nmd.append("")
nmd.append("## Critère")
nmd.append("")
nmd.append(f"- palier M : {palier}")
nmd.append("- non-éligible : `required_m_stable > M` (au sens m_stable=max(m_dom, A+1))")
nmd.append("")
nmd.append("## Buckets")
nmd.append("")
for k, v in sorted(buckets.items()):
nmd.append(f"- required_m_stable={k} : {v}")
nmd.append("")
nmd.append("## Gains attendus au palier suivant")
nmd.append("")
nmd.append(f"- M+1 : {m_next}")
nmd.append(f"- newly_eligible_count : {gains_next}")
nmd.append(f"- eligible_count_at_M : {len(covered)}")
nmd.append(f"- eligible_count_at_M_plus_1 : {len(covered) + gains_next}")
nmd.append(f"- eligible_count_at_M / |L| : {((len(covered) / len(L_sorted) * 100.0) if L_sorted else 0.0):.2f}%")
nmd.append(
f"- eligible_count_at_M_plus_1 / |L| : {(((len(covered) + gains_next) / len(L_sorted) * 100.0) if L_sorted else 0.0):.2f}%"
)
nmd.append("")
nmd.append("## Gains cumulés attendus (horizon fixe)")
nmd.append("")
if cum_rows:
fixed_rows = [row for row in cum_rows if int(row["k"]) <= horizon_k]
nmd.append("| cible | k | newly | cumulative | eligible@cible | eligible@cible / |L| |")
nmd.append("| --- | --- | --- | --- | --- | --- |")
for row in fixed_rows:
eligible_at_target = int(row["eligible_count_at_target"])
pct = (eligible_at_target / len(L_sorted) * 100.0) if L_sorted else 0.0
nmd.append(
f"| {row['target_M']} | {row['k']} | {row['newly_eligible_at_target']} | "
f"{row['cumulative_newly_eligible_up_to_target']} | {row['eligible_count_at_target']} | {pct:.2f}% |"
)
if len(fixed_rows) < horizon_k:
nmd.append("| ... | ... | ... | ... | ... | ... |")
nmd.append("")
nmd.append("## Gains cumulés attendus (planification complète)")
nmd.append("")
if cum_rows:
nmd.append("| cible | k | newly | cumulative | eligible@cible | eligible@cible / |L| |")
nmd.append("| --- | --- | --- | --- | --- | --- |")
for row in cum_rows[:12]:
eligible_at_target = int(row["eligible_count_at_target"])
pct = (eligible_at_target / len(L_sorted) * 100.0) if L_sorted else 0.0
nmd.append(
f"| {row['target_M']} | {row['k']} | {row['newly_eligible_at_target']} | "
f"{row['cumulative_newly_eligible_up_to_target']} | {row['eligible_count_at_target']} | {pct:.2f}% |"
)
if len(cum_rows) > 12:
last = cum_rows[-1]
eligible_last = int(last["eligible_count_at_target"])
pct_last = (eligible_last / len(L_sorted) * 100.0) if L_sorted else 0.0
nmd.append("| ... | ... | ... | ... | ... | ... |")
nmd.append(
f"| {last['target_M']} | {last['k']} | {last['newly_eligible_at_target']} | "
f"{last['cumulative_newly_eligible_up_to_target']} | {last['eligible_count_at_target']} | {pct_last:.2f}% |"
)
nmd.append("")
nmd.append("## Table (extrait)")
nmd.append("")
header2 = ["n", "kind", "required_m_stable", "delta_to_next"]
nmd.append("| " + " | ".join(header2) + " |")
nmd.append("| " + " | ".join(["---"] * len(header2)) + " |")
for row in non_eligible_sorted[:60]:
nmd.append(f"| {row['n']} | {row['kind']} | {row['required_m_stable']} | {row['delta_to_next']} |")
if len(non_eligible_sorted) > 60:
nmd.append("| ... | ... | ... | ... |")
_write_md(non_eligible_md, nmd)
outputs = [
out_json,
out_md,
audit_json,
audit_md,
non_eligible_json,
non_eligible_md,
]
outputs_sha = { _display_path(p, repo_root): _sha256_file(p) for p in outputs }
outputs_size = { _display_path(p, repo_root): _file_size_bytes(p) for p in outputs }
outputs_mtime = {
_display_path(p, repo_root): {
"mtime_epoch_seconds": _file_mtime_epoch_seconds(p),
"mtime_utc_iso": _file_mtime_utc_iso(p),
}
for p in outputs
}
inputs_size = {
_display_path(clauses_json, repo_root): _file_size_bytes(clauses_json),
_display_path(c3_verification_json, repo_root): _file_size_bytes(c3_verification_json),
}
inputs_mtime = {
_display_path(clauses_json, repo_root): {
"mtime_epoch_seconds": _file_mtime_epoch_seconds(clauses_json),
"mtime_utc_iso": _file_mtime_utc_iso(clauses_json),
},
_display_path(c3_verification_json, repo_root): {
"mtime_epoch_seconds": _file_mtime_epoch_seconds(c3_verification_json),
"mtime_utc_iso": _file_mtime_utc_iso(c3_verification_json),
},
}
manifest_obj: dict[str, object] = {
"domain": {
"palier": palier,
},
"generation": {
"horizon_k": horizon_k,
"generated_at": generated_at,
},
"inputs": {
"clauses_universelles_json": _display_path(clauses_json, repo_root),
"verification_c3_local_descent_json": _display_path(c3_verification_json, repo_root),
},
"sha256": {"inputs": sha, "outputs": outputs_sha},
"sizes_bytes": {"inputs": inputs_size, "outputs": outputs_size},
"mtimes": {"inputs": inputs_mtime, "outputs": outputs_mtime},
}
_write_json(manifest_json, manifest_obj)
mmd: list[str] = []
mmd.append("**Auteur** : Équipe 4NK")
mmd.append("")
mmd.append(f"# Manifest — register_K_mod2p{palier}")
mmd.append("")
mmd.append("## Generation")
mmd.append("")
mmd.append(f"- palier : 2^{palier}")
mmd.append(f"- horizon_k : {horizon_k}")
mmd.append(f"- generated_at : {generated_at}")
mmd.append("")
mmd.append("## Inputs (sha256)")
mmd.append("")
for k in sorted(sha.keys()):
mmd.append(f"- `{k}` : `{sha[k]}`")
mmd.append("")
mmd.append("## Inputs (size bytes)")
mmd.append("")
for k in sorted(inputs_size.keys()):
mmd.append(f"- `{k}` : {inputs_size[k]}")
mmd.append("")
mmd.append("## Inputs (mtime)")
mmd.append("")
for k in sorted(inputs_mtime.keys()):
v = inputs_mtime[k]
mmd.append(f"- `{k}` : {v['mtime_utc_iso']} ({v['mtime_epoch_seconds']})")
mmd.append("")
mmd.append("## Outputs (sha256)")
mmd.append("")
for k in sorted(outputs_sha.keys()):
mmd.append(f"- `{k}` : `{outputs_sha[k]}`")
mmd.append("")
mmd.append("## Outputs (size bytes)")
mmd.append("")
for k in sorted(outputs_size.keys()):
mmd.append(f"- `{k}` : {outputs_size[k]}")
mmd.append("")
mmd.append("## Outputs (mtime)")
mmd.append("")
for k in sorted(outputs_mtime.keys()):
v = outputs_mtime[k]
mmd.append(f"- `{k}` : {v['mtime_utc_iso']} ({v['mtime_epoch_seconds']})")
mmd.append("")
_write_md(manifest_md, mmd)
def main() -> None:
ap = argparse.ArgumentParser(description="Build a modular register K_M and a finite coverage audit from Option A artefacts")
ap.add_argument("--palier", type=int, required=True, help="Target palier M (power of 2 exponent)")
ap.add_argument("--horizon-k", type=int, default=5, help="Fixed horizon for the cumulative planning view in audit markdown (default 5)")
ap.add_argument(
"--check-manual-edits",
action="store_true",
help="Verify outputs match the last manifest (mtime + size) and exit without regenerating",
)
ap.add_argument(
"--check-sha256",
action="store_true",
help="Verify sha256 of outputs vs the manifest and exit without regenerating",
)
ap.add_argument(
"--check-inputs-sha256",
action="store_true",
help="Verify sha256 of inputs vs the manifest and exit without regenerating",
)
ap.add_argument(
"--check-all",
action="store_true",
help="Run all checks (outputs mtime+size, outputs sha256, inputs sha256) and exit without regenerating",
)
ap.add_argument("--clauses-json", default="", help="Path to clauses_universelles.json (defaults to the standard palier location)")
ap.add_argument("--c3-verification-json", default="", help="Override path to C3 verification JSON (defaults to clauses inputs)")
ap.add_argument("--output-dir", default="", help="Output directory (defaults to docs/artefacts/collatz/register_K/palier2pM)")
ap.add_argument("--repo-root", default="", help="Repository root for relative paths and defaults (defaults to cwd)")
args = ap.parse_args()
repo_root = Path(args.repo_root).resolve() if args.repo_root.strip() else Path.cwd().resolve()
palier = int(args.palier)
clauses_json = Path(args.clauses_json).resolve() if args.clauses_json.strip() else _infer_default_clauses_json(repo_root=repo_root, palier=palier)
clauses_obj = _read_json(clauses_json)
if not isinstance(clauses_obj, dict):
raise ValueError("Invalid clauses JSON: expected object")
c3_json = (
Path(args.c3_verification_json).resolve()
if args.c3_verification_json.strip()
else _load_c3_verification_path_from_clauses(clauses_obj=clauses_obj, repo_root=repo_root)
)
output_dir = Path(args.output_dir).resolve() if args.output_dir.strip() else _infer_default_output_dir(repo_root=repo_root, palier=palier)
check_manual = args.check_manual_edits or args.check_all
check_sha = args.check_sha256 or args.check_all
check_inputs_sha = args.check_inputs_sha256 or args.check_all
if check_manual or check_sha or check_inputs_sha:
manifest_json = output_dir / f"manifest_register_K_mod2p{palier}.json"
try:
if check_manual:
_check_manual_edits_from_manifest(manifest_json=manifest_json, repo_root=repo_root)
if check_sha:
_check_sha256_from_manifest(manifest_json=manifest_json, repo_root=repo_root)
if check_inputs_sha:
_check_inputs_sha256_from_manifest(manifest_json=manifest_json, repo_root=repo_root)
except CheckMismatchError as e:
print(f"MISMATCH {str(e)}", file=sys.stderr)
raise SystemExit(2) from e
checks: list[str] = []
if check_manual:
checks.append("manual-edits")
if check_sha:
checks.append("sha256-outputs")
if check_inputs_sha:
checks.append("sha256-inputs")
checks_str = ",".join(checks) if checks else "(none)"
print(f"OK checks={checks_str} palier=2^{palier} manifest={manifest_json}")
return
run(
palier=palier,
horizon_k=int(args.horizon_k),
clauses_json=clauses_json,
c3_verification_json=c3_json,
output_dir=output_dir,
repo_root=repo_root,
)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,620 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_compare_dminor_families_incremental.py
Build an automated, deterministic comparison table for incremental addition of D_minor families (grouped by k)
to the multilevel refinement closure over S_M.
Per step, the script:
- runs collatz_build_refinement_certificate_over_Sm_multilevel.py into a dedicated output directory,
- runs collatz_analyze_open_roots_refinement.py on the produced certificate (to extract lb quantiles),
- extracts metrics and computes deltas.
Selection strategy (aligned with "dette dobservabilité"):
- greedy: at each step, pick the k-family that best improves the "late extremes" objective
(by default: global lb_any max, then lb_any p99, then open_roots, then q_root, then parents_one_child_root).
- optional "target extremes" mode: track the baseline top-N open roots by lb_any, and score improvements
on this tracked subset first (tracked lb_any max/p99, then tracked open count, then global metrics).
"""
from __future__ import annotations
import argparse
import json
import re
import subprocess
from dataclasses import dataclass
from pathlib import Path
def _read_json(path: Path) -> object:
return json.loads(path.read_text(encoding="utf-8", errors="strict"))
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _req_int(d: dict[str, object], key: str) -> int:
v = d.get(key)
if not isinstance(v, int):
raise ValueError(f"Expected int for {key}")
return v
def _req_float(d: dict[str, object], key: str) -> float:
v = d.get(key)
if not isinstance(v, (int, float)):
raise ValueError(f"Expected float for {key}")
return float(v)
def _run(cmd: list[str]) -> None:
subprocess.run(cmd, check=True)
_DMINOR_RE = re.compile(r"clauses_D_minor_over_Sm_mod2p(?P<m>\d+)_k(?P<k>\d+)_u(?P<u>\d+)\.json$")
def _discover_dminor_families(*, repo_root: Path, root_palier: int, max_palier: int) -> dict[int, list[Path]]:
base = repo_root / "docs" / "artefacts" / "collatz" / "minorated_clauses_over_Sm"
families: dict[int, list[Path]] = {}
for m in range(root_palier, max_palier + 1):
d = base / f"palier2p{m}"
if not d.exists():
continue
for p in sorted(d.glob("clauses_D_minor_over_Sm_mod2p*_k*_u*.json")):
m2 = _DMINOR_RE.search(p.name)
if m2 is None:
continue
k = int(m2.group("k"))
families.setdefault(k, []).append(p)
return {k: v for k, v in sorted(families.items())}
def _default_terminal_leafs(*, repo_root: Path, root_palier: int, max_palier: int) -> list[Path]:
out: list[Path] = []
for m in range(root_palier, max_palier + 1):
out.append(
repo_root
/ "docs"
/ "artefacts"
/ "collatz"
/ "terminal_clauses_over_Sm"
/ f"palier2p{m}"
/ f"clauses_terminal_over_Sm_mod2p{m}.json"
)
return out
@dataclass(frozen=True)
class StepMetrics:
step_id: str
added_k: int | None
open_roots: int
q_root: float
parents_one_child_root: int
lb_any_p99: int
lb_any_max: int
tracked: dict[str, int] | None
def to_json(self) -> dict[str, object]:
out: dict[str, object] = {
"step_id": self.step_id,
"added_k": self.added_k,
"open_roots": self.open_roots,
"q_root": self.q_root,
"parents_one_child_root": self.parents_one_child_root,
"lb_any": {"p99": self.lb_any_p99, "max": self.lb_any_max},
}
if self.tracked is not None:
out["tracked"] = self.tracked
return out
def _extract_step_metrics(
*,
root_palier: int,
cert_json: Path,
obstruction_json: Path,
step_id: str,
added_k: int | None,
tracked_roots: set[int] | None,
) -> StepMetrics:
cert = _read_json(cert_json)
if not isinstance(cert, dict):
raise ValueError("Invalid certificate JSON")
closure = cert.get("closure")
if not isinstance(closure, dict):
raise ValueError("Invalid certificate JSON: missing closure")
residue_audit = cert.get("residue_audit")
if not isinstance(residue_audit, dict):
raise ValueError("Invalid certificate JSON: missing residue_audit")
open_roots = _req_int(closure, "open_roots")
q_by = residue_audit.get("q_by_palier")
p1c_by = residue_audit.get("parents_one_child_by_palier")
if not isinstance(q_by, dict) or not isinstance(p1c_by, dict):
raise ValueError("Invalid residue_audit structure")
q_root = float(q_by.get(str(root_palier), 0.0))
parents_one_child_root = int(p1c_by.get(str(root_palier), 0))
obs = _read_json(obstruction_json)
if not isinstance(obs, dict):
raise ValueError("Invalid obstruction JSON")
quantiles = obs.get("quantiles")
if not isinstance(quantiles, dict):
raise ValueError("Invalid obstruction JSON: missing quantiles")
q_any = quantiles.get("lb_any")
if not isinstance(q_any, dict):
raise ValueError("Invalid obstruction JSON: missing quantiles.lb_any")
lb_any_p99 = _req_int(q_any, "p99")
lb_any_max = _req_int(q_any, "max")
tracked: dict[str, int] | None = None
if tracked_roots is not None:
rows = obs.get("rows")
if not isinstance(rows, list) or not all(isinstance(x, dict) for x in rows):
raise ValueError("Invalid obstruction JSON: missing rows")
tracked_any_values: list[int] = []
tracked_still_open = 0
for row in rows:
r0 = row.get("root_residue_mod_2p")
if not isinstance(r0, int) or r0 not in tracked_roots:
continue
lb = row.get("lower_bound_required_m_to_close_root")
if not isinstance(lb, dict):
continue
lb_any = lb.get("any")
if not isinstance(lb_any, int):
continue
tracked_any_values.append(lb_any)
tracked_still_open += 1
if tracked_any_values:
s = sorted(tracked_any_values)
idx = int((len(s) - 1) * 0.99)
tracked = {
"tracked_top_n": len(tracked_roots),
"tracked_still_open": tracked_still_open,
"tracked_closed": len(tracked_roots) - tracked_still_open,
"tracked_lb_any_p99": int(s[idx]),
"tracked_lb_any_max": int(s[-1]),
}
else:
tracked = {
"tracked_top_n": len(tracked_roots),
"tracked_still_open": 0,
"tracked_closed": len(tracked_roots),
"tracked_lb_any_p99": 0,
"tracked_lb_any_max": 0,
}
return StepMetrics(
step_id=step_id,
added_k=added_k,
open_roots=open_roots,
q_root=q_root,
parents_one_child_root=parents_one_child_root,
lb_any_p99=lb_any_p99,
lb_any_max=lb_any_max,
tracked=tracked,
)
def _score_for_extremes(m: StepMetrics) -> tuple[int, int, int, float, int]:
return (m.lb_any_max, m.lb_any_p99, m.open_roots, m.q_root, m.parents_one_child_root)
def _score_for_targeted_extremes(m: StepMetrics) -> tuple[int, int, int, int, int, float, int]:
if m.tracked is None:
return (m.lb_any_max, m.lb_any_p99, m.open_roots, 0, 0, m.q_root, m.parents_one_child_root)
return (
int(m.tracked["tracked_lb_any_max"]),
int(m.tracked["tracked_lb_any_p99"]),
int(m.tracked["tracked_still_open"]),
m.lb_any_max,
m.lb_any_p99,
m.q_root,
m.parents_one_child_root,
)
def _baseline_top_roots_by_lb_any(*, obstruction_json: Path, top_n: int) -> list[int]:
obs = _read_json(obstruction_json)
if not isinstance(obs, dict):
raise ValueError("Invalid obstruction JSON")
rows = obs.get("rows")
if not isinstance(rows, list) or not all(isinstance(x, dict) for x in rows):
raise ValueError("Invalid obstruction JSON: missing rows")
entries: list[tuple[int, int]] = []
for row in rows:
r0 = row.get("root_residue_mod_2p")
if not isinstance(r0, int):
continue
lb = row.get("lower_bound_required_m_to_close_root")
if not isinstance(lb, dict):
continue
lb_any = lb.get("any")
if not isinstance(lb_any, int):
continue
entries.append((lb_any, r0))
entries.sort(key=lambda x: (-x[0], x[1]))
return [r for _, r in entries[:top_n]]
def _read_tracked_roots_file(path: Path) -> list[int]:
if not path.exists():
raise ValueError(f"tracked roots file not found: {path}")
roots: list[int] = []
seen: set[int] = set()
for line in path.read_text(encoding="utf-8", errors="strict").splitlines():
s = line.strip()
if not s or s.startswith("#"):
continue
if "#" in s:
s = s.split("#", 1)[0].strip()
if not s:
continue
try:
r = int(s, 10)
except ValueError as e:
raise ValueError(f"Invalid tracked root value in {path}: {line!r}") from e
if r <= 0 or (r % 2) == 0:
raise ValueError(f"Invalid tracked root (must be positive odd integer): {r}")
if r not in seen:
roots.append(r)
seen.add(r)
return roots
def _write_tracked_roots_file(path: Path, roots: list[int]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(str(r) for r in roots) + "\n", encoding="utf-8")
def run(
*,
repo_root: Path,
root_palier: int,
max_palier: int,
k_max: int,
t_max: int,
search_max_required_m: int,
out_dir: Path,
target_extremes_top_n: int,
tracked_roots_file: Path | None,
export_tracked_roots_file: Path | None,
) -> None:
families_by_k = _discover_dminor_families(repo_root=repo_root, root_palier=root_palier, max_palier=max_palier)
if not families_by_k:
raise ValueError("No D_minor families found. Generate them under docs/artefacts/.../minorated_clauses_over_Sm/ first.")
terminal_leafs = _default_terminal_leafs(repo_root=repo_root, root_palier=root_palier, max_palier=max_palier)
multilevel_script = repo_root / "applications" / "collatz" / "collatz_k_scripts" / "collatz_build_refinement_certificate_over_Sm_multilevel.py"
obstruction_script = repo_root / "applications" / "collatz" / "collatz_k_scripts" / "collatz_analyze_open_roots_refinement.py"
steps: list[StepMetrics] = []
selected_ks: list[int] = []
remaining_ks = list(families_by_k.keys())
tracked_roots: set[int] | None = None
tracked_roots_source: dict[str, object] | None = None
tracked_list: list[int] = []
def evaluate_step(*, step_id: str, added_k: int | None, ks: list[int]) -> StepMetrics:
step_dir = out_dir / step_id
leaf_args: list[str] = []
for p in terminal_leafs:
leaf_args.extend(["--leaf-json", str(p)])
for k in ks:
for p in families_by_k[k]:
leaf_args.extend(["--leaf-json", str(p)])
_run(
[
"python3",
str(multilevel_script),
"--repo-root",
str(repo_root),
"--root-palier",
str(root_palier),
"--max-palier",
str(max_palier),
"--output-dir",
str(step_dir),
*leaf_args,
]
)
cert_json = step_dir / f"refinement_certificate_Sm_multilevel_mod2p{root_palier}_to2p{max_palier}.json"
_run(
[
"python3",
str(obstruction_script),
"--root-palier",
str(root_palier),
"--max-palier",
str(max_palier),
"--multilevel-json",
str(cert_json),
"--output-dir",
str(step_dir),
"--k-max",
str(k_max),
"--t-max",
str(t_max),
"--search-max-required-m",
str(search_max_required_m),
]
)
obstruction_json = step_dir / f"open_roots_obstruction_profile_mod2p{root_palier}_to2p{max_palier}.json"
return _extract_step_metrics(
root_palier=root_palier,
cert_json=cert_json,
obstruction_json=obstruction_json,
step_id=step_id,
added_k=added_k,
tracked_roots=tracked_roots,
)
baseline = evaluate_step(step_id="step00_baseline_terminal_only", added_k=None, ks=[])
steps.append(baseline)
if tracked_roots_file is not None and target_extremes_top_n > 0:
raise ValueError("Use either --tracked-roots-file or --target-extremes-top-n, not both")
if tracked_roots_file is not None:
tracked_list = _read_tracked_roots_file(tracked_roots_file)
tracked_roots = set(tracked_list)
tracked_roots_source = {"kind": "file", "path": str(tracked_roots_file), "count": len(tracked_list)}
baseline = evaluate_step(step_id="step00_baseline_terminal_only", added_k=None, ks=[])
steps = [baseline]
elif target_extremes_top_n > 0:
baseline_dir = out_dir / "step00_baseline_terminal_only"
baseline_obstruction_json = baseline_dir / f"open_roots_obstruction_profile_mod2p{root_palier}_to2p{max_palier}.json"
tracked_list = _baseline_top_roots_by_lb_any(obstruction_json=baseline_obstruction_json, top_n=target_extremes_top_n)
tracked_roots = set(tracked_list)
tracked_roots_source = {"kind": "baseline_top_n", "top_n": target_extremes_top_n, "count": len(tracked_list)}
# Re-evaluate baseline to populate tracked metrics
baseline = evaluate_step(step_id="step00_baseline_terminal_only", added_k=None, ks=[])
steps = [baseline]
if export_tracked_roots_file is not None and tracked_list:
_write_tracked_roots_file(export_tracked_roots_file, tracked_list)
while remaining_ks:
best_k: int | None = None
best_metrics: StepMetrics | None = None
best_key: tuple[int, ...] | None = None
for k in remaining_ks:
ks2 = [*selected_ks, k]
step_id = f"step{len(steps):02d}_add_k{k}"
m = evaluate_step(step_id=step_id, added_k=k, ks=ks2)
key = _score_for_targeted_extremes(m) if tracked_roots is not None else _score_for_extremes(m)
if best_key is None or key < best_key:
best_key = key
best_k = k
best_metrics = m
if best_k is None or best_metrics is None:
raise ValueError("Internal error: greedy selection failed")
selected_ks.append(best_k)
remaining_ks = [k for k in remaining_ks if k != best_k]
steps.append(best_metrics)
# Build deltas table vs baseline and vs previous step
base = steps[0]
rows: list[dict[str, object]] = []
prev = base
for m in steps:
row: dict[str, object] = m.to_json()
row["delta_vs_baseline"] = {
"open_roots": m.open_roots - base.open_roots,
"q_root": m.q_root - base.q_root,
"parents_one_child_root": m.parents_one_child_root - base.parents_one_child_root,
"lb_any_p99": m.lb_any_p99 - base.lb_any_p99,
"lb_any_max": m.lb_any_max - base.lb_any_max,
}
row["delta_vs_prev"] = {
"open_roots": m.open_roots - prev.open_roots,
"q_root": m.q_root - prev.q_root,
"parents_one_child_root": m.parents_one_child_root - prev.parents_one_child_root,
"lb_any_p99": m.lb_any_p99 - prev.lb_any_p99,
"lb_any_max": m.lb_any_max - prev.lb_any_max,
}
rows.append(row)
prev = m
out_json = out_dir / f"impact_table_D_minor_incremental_mod2p{root_palier}_to2p{max_palier}.json"
out_md = out_dir / f"impact_table_D_minor_incremental_mod2p{root_palier}_to2p{max_palier}.md"
obj = {
"domain": {"root_palier": root_palier, "max_palier": max_palier},
"params": {"k_max": k_max, "t_max": t_max, "search_max_required_m": search_max_required_m},
"target_extremes_top_n": target_extremes_top_n,
"tracked_roots_source": tracked_roots_source,
"tracked_roots_by_baseline_lb_any": sorted(list(tracked_roots)) if tracked_roots is not None else [],
"families_by_k": {str(k): [str(p) for p in v] for k, v in families_by_k.items()},
"selected_order_by_k": selected_ks,
"baseline": base.to_json(),
"rows": rows,
}
_write_json(out_json, obj)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Impact incrémental des familles D_minor (par k) — S_{root_palier}→2^{max_palier}")
md.append("")
md.append("## Stratégie de sélection")
md.append("")
if tracked_roots is not None:
if tracked_roots_file is not None:
md.append(f"Mode “ciblage extrêmes” activé (liste fixe via fichier : `{tracked_roots_file}`).")
else:
md.append(f"Mode “ciblage extrêmes” activé (top-N baseline, N={target_extremes_top_n}).")
md.append("Sélection gloutonne, objectif “extrêmes tardifs” (lexicographique) :")
md.append("- minimiser `tracked.tracked_lb_any_max`")
md.append("- puis minimiser `tracked.tracked_lb_any_p99`")
md.append("- puis minimiser `tracked.tracked_still_open`")
md.append("- puis minimiser `lb_any.max` (global)")
md.append("- puis minimiser `lb_any.p99` (global)")
md.append("- puis minimiser `q_root`")
md.append("- puis minimiser `parents_one_child_root`")
else:
md.append("Sélection gloutonne, objectif “extrêmes tardifs” (global, lexicographique) :")
md.append("- minimiser `lb_any.max`")
md.append("- puis minimiser `lb_any.p99`")
md.append("- puis minimiser `open_roots`")
md.append("- puis minimiser `q_root`")
md.append("- puis minimiser `parents_one_child_root`")
md.append("")
md.append(f"Ordre sélectionné (k) : {', '.join(str(k) for k in selected_ks)}")
md.append("")
md.append("## Table (deltas vs baseline)")
md.append("")
if tracked_roots is not None:
md.append("| step | added_k | tracked.open | tracked.max | tracked.p99 | open_roots | Δopen | q_root | Δq | parents_one_child_root | Δparents | lb_any.p99 | Δp99 | lb_any.max | Δmax |")
md.append("| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |")
else:
md.append("| step | added_k | open_roots | Δopen | q_root | Δq | parents_one_child_root | Δparents | lb_any.p99 | Δp99 | lb_any.max | Δmax |")
md.append("| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |")
for r in rows:
m = r
dvb = m["delta_vs_baseline"] # type: ignore[index]
lb_any = m["lb_any"] # type: ignore[index]
if tracked_roots is not None:
tr = m.get("tracked") # type: ignore[assignment]
tr_open = ""
tr_max = ""
tr_p99 = ""
if isinstance(tr, dict):
tr_open = str(tr.get("tracked_still_open", ""))
tr_max = str(tr.get("tracked_lb_any_max", ""))
tr_p99 = str(tr.get("tracked_lb_any_p99", ""))
md.append(
"| "
+ str(m["step_id"])
+ " | "
+ ("" if m["added_k"] is None else str(m["added_k"]))
+ " | "
+ tr_open
+ " | "
+ tr_max
+ " | "
+ tr_p99
+ " | "
+ str(m["open_roots"])
+ " | "
+ str(dvb["open_roots"])
+ " | "
+ f"{float(m['q_root']):.12f}"
+ " | "
+ f"{float(dvb['q_root']):+.12f}"
+ " | "
+ str(m["parents_one_child_root"])
+ " | "
+ str(dvb["parents_one_child_root"])
+ " | "
+ str(lb_any["p99"])
+ " | "
+ str(dvb["lb_any_p99"])
+ " | "
+ str(lb_any["max"])
+ " | "
+ str(dvb["lb_any_max"])
+ " |"
)
else:
md.append(
"| "
+ str(m["step_id"])
+ " | "
+ ("" if m["added_k"] is None else str(m["added_k"]))
+ " | "
+ str(m["open_roots"])
+ " | "
+ str(dvb["open_roots"])
+ " | "
+ f"{float(m['q_root']):.12f}"
+ " | "
+ f"{float(dvb['q_root']):+.12f}"
+ " | "
+ str(m["parents_one_child_root"])
+ " | "
+ str(dvb["parents_one_child_root"])
+ " | "
+ str(lb_any["p99"])
+ " | "
+ str(dvb["lb_any_p99"])
+ " | "
+ str(lb_any["max"])
+ " | "
+ str(dvb["lb_any_max"])
+ " |"
)
md.append("")
md.append("## Sorties")
md.append("")
md.append(f"- JSON : `{out_json}`")
md.append(f"- Markdown : `{out_md}`")
md.append("")
_write_md(out_md, md)
def main() -> None:
ap = argparse.ArgumentParser(description="Incremental impact table for D_minor families (grouped by k)")
ap.add_argument("--repo-root", default=".", help="Repository root")
ap.add_argument("--root-palier", type=int, default=15)
ap.add_argument("--max-palier", type=int, default=18)
ap.add_argument("--k-max", type=int, default=256)
ap.add_argument("--t-max", type=int, default=256)
ap.add_argument("--search-max-required-m", type=int, default=256)
ap.add_argument(
"--target-extremes-top-n",
type=int,
default=0,
help="If >0, track baseline top-N open roots by lb_any, and score families primarily on this subset",
)
ap.add_argument(
"--tracked-roots-file",
default="",
help="If set, read a fixed list of roots (one odd integer per line) to track across runs (overrides --target-extremes-top-n)",
)
ap.add_argument(
"--export-tracked-roots-file",
default="",
help="If set, export the tracked roots list (after resolution) to this file",
)
ap.add_argument("--out-dir", default="", help="Output directory (defaults under docs/artefacts/...)")
args = ap.parse_args()
repo_root = Path(args.repo_root).resolve()
root_palier = int(args.root_palier)
max_palier = int(args.max_palier)
out_dir = Path(args.out_dir).resolve() if args.out_dir.strip() else (
repo_root / "docs" / "artefacts" / "collatz" / "refinement_K" / f"palier2p{root_palier}" / "incremental_D_minor"
)
tracked_roots_file = Path(args.tracked_roots_file).resolve() if args.tracked_roots_file.strip() else None
export_tracked_roots_file = (
Path(args.export_tracked_roots_file).resolve() if args.export_tracked_roots_file.strip() else None
)
run(
repo_root=repo_root,
root_palier=root_palier,
max_palier=max_palier,
k_max=int(args.k_max),
t_max=int(args.t_max),
search_max_required_m=int(args.search_max_required_m),
out_dir=out_dir,
target_extremes_top_n=int(args.target_extremes_top_n),
tracked_roots_file=tracked_roots_file,
export_tracked_roots_file=export_tracked_roots_file,
)
if __name__ == "__main__":
main()

View File

@ -15,7 +15,8 @@ Outputs (versionable, no transcripts):
- docs/artefacts/collatz/universal_clauses/clauses_universelles.md - docs/artefacts/collatz/universal_clauses/clauses_universelles.md
Notes: Notes:
- D_exact and F witnesses are lifted to modulus 2^(A+1) where A is the prefix sum. - D_exact and F witnesses are lifted to modulus 2^m_stable, where
m_stable := max(domain_palier, A+1), because the witness is already fixed modulo 2^domain_palier.
- D_brother witnesses are preserved as *local* dependencies (mate_exact) at the - D_brother witnesses are preserved as *local* dependencies (mate_exact) at the
domain palier; they are not asserted as standalone universal reductions here. domain palier; they are not asserted as standalone universal reductions here.
""" """
@ -167,7 +168,7 @@ def run(*, verification_json: Path, output_dir: Path, repo_root: Path) -> None:
pref = prefix_data(n, k) pref = prefix_data(n, k)
if pref.A != A_k or pref.C != C_k: if pref.A != A_k or pref.C != C_k:
raise ValueError(f"D_exact mismatch for n={n}: prefix_data differs from record") raise ValueError(f"D_exact mismatch for n={n}: prefix_data differs from record")
m_stab = A_k + 1 m_stab = max(palier, A_k + 1)
r_stab = _lift_to_stable_residue( r_stab = _lift_to_stable_residue(
n0=n, n0=n,
base_palier=palier, base_palier=palier,
@ -218,7 +219,7 @@ def run(*, verification_json: Path, output_dir: Path, repo_root: Path) -> None:
pref = prefix_data(n, t) pref = prefix_data(n, t)
if pref.A != A_t or pref.C != C_t or pref.y != y: if pref.A != A_t or pref.C != C_t or pref.y != y:
raise ValueError(f"F mismatch for n={n}: prefix_data differs from record") raise ValueError(f"F mismatch for n={n}: prefix_data differs from record")
m_stab = A_t + 1 m_stab = max(palier, A_t + 1)
r_stab = _lift_to_stable_residue( r_stab = _lift_to_stable_residue(
n0=n, n0=n,
base_palier=palier, base_palier=palier,
@ -354,7 +355,10 @@ def run(*, verification_json: Path, output_dir: Path, repo_root: Path) -> None:
lines.append("") lines.append("")
lines.append("## Notes") lines.append("## Notes")
lines.append("") lines.append("")
lines.append("- `D_exact` et `F` sont relevées au module minimal \\(2^{A+1}\\) qui fige le mot de valuations du témoin.") lines.append(
"- `D_exact` et `F` sont relevées au module \\(2^{m_{stable}}\\) avec "
"\\(m_{stable}=\\max(m, A+1)\\), où \\(m\\) est le palier du domaine, afin de figer le mot de valuations du témoin."
)
lines.append("- `D_brother_local` encode une dépendance locale (palier du domaine) vers un `mate_exact` ; elle nest pas utilisée ici comme clause universelle autonome.") lines.append("- `D_brother_local` encode une dépendance locale (palier du domaine) vers un `mate_exact` ; elle nest pas utilisée ici comme clause universelle autonome.")
lines.append("") lines.append("")
out_md.write_text("\n".join(lines) + "\n", encoding="utf-8") out_md.write_text("\n".join(lines) + "\n", encoding="utf-8")

View File

@ -0,0 +1,205 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_generate_minorated_descent_clauses_over_Sm.py
Generate deterministic "minorated" descent clauses (D_minor) over the full odd residue space S_m
(odd residues modulo 2^m).
Grammar (aligned with conjoncture_collatz.md, "clauses de descente par minoration"):
- Fix an horizon k.
- Require that the prefix word of length k-1 is stable at palier 2^m (so A_{k-1}, C_{k-1} are fixed).
- Let B_k := 3*C_{k-1} + 2^{A_{k-1}} so that 3*U^{(k-1)}(n)+1 = (3^k n + B_k)/2^{A_{k-1}}.
- Replace the exact last valuation by a lower bound: v2(3^k n + B_k) >= underlineA.
- Then A(n) >= underlineA implies U^k(n) <= (3^k n + B_k)/2^{underlineA}, and a standard threshold
yields a universal strict descent for n >= N0.
Outputs:
- docs/artefacts/collatz/minorated_clauses_over_Sm/palier2p<m>/clauses_D_minor_over_Sm_mod2p<m>.{json,md}
"""
from __future__ import annotations
import argparse
import hashlib
import json
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from collatz_k_core import prefix_data
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _sha256_file(path: Path, chunk_size: int = 16 * 1024 * 1024) -> str:
h = hashlib.sha256()
with path.open("rb") as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
h.update(chunk)
return h.hexdigest()
def _utc_now_iso() -> str:
return datetime.now(tz=timezone.utc).isoformat().replace("+00:00", "Z")
@dataclass(frozen=True)
class DMinorClause:
modulus_power: int
residue_mod_2p: int
k: int
underlineA: int
numerator_B_k: int
prefix_word_len_km1: tuple[int, ...] # word of length k-1
A_km1: int
C_km1: int
N0: int
delta_min: int
def to_json(self) -> dict[str, object]:
return {
"kind": "D_minor",
"modulus_power": self.modulus_power,
"residue_mod_2p": self.residue_mod_2p,
"k": self.k,
"underlineA": self.underlineA,
"numerator_B_k": self.numerator_B_k,
"prefix_word_len_km1": list(self.prefix_word_len_km1),
"A_km1": self.A_km1,
"C_km1": self.C_km1,
"delta_min": self.delta_min,
"N0": self.N0,
}
def run(*, palier: int, k: int, underlineA: int, output_dir: Path, repo_root: Path) -> None:
if palier < 2:
raise ValueError("palier must be >= 2")
if k < 2:
raise ValueError("k must be >= 2 (needs k-1 prefix)")
if underlineA < 1:
raise ValueError("underlineA must be >= 1")
if underlineA > palier:
raise ValueError("underlineA must be <= palier (decidable at 2^palier)")
alpha = 3**k
mod = 1 << palier
pow2u = 1 << underlineA
delta_min = (1 << underlineA) - alpha
if delta_min <= 0:
raise ValueError("delta_min <= 0: no structural contraction for this (k, underlineA)")
clauses: list[DMinorClause] = []
rejected_prefix_not_stable = 0
rejected_divisibility = 0
for r in range(1, mod, 2):
pref = prefix_data(r, k - 1)
w_prefix = tuple(int(x) for x in pref.word)
A_km1 = int(pref.A)
C_km1 = int(pref.C)
if A_km1 + 1 > palier:
rejected_prefix_not_stable += 1
continue
numerator_B_k = 3 * C_km1 + (1 << A_km1)
if ((alpha * r + numerator_B_k) % pow2u) != 0:
rejected_divisibility += 1
continue
N0 = (numerator_B_k // delta_min) + 1
clauses.append(
DMinorClause(
modulus_power=palier,
residue_mod_2p=r,
k=k,
underlineA=underlineA,
numerator_B_k=numerator_B_k,
prefix_word_len_km1=w_prefix,
A_km1=A_km1,
C_km1=C_km1,
N0=N0,
delta_min=delta_min,
)
)
out_json = output_dir / f"clauses_D_minor_over_Sm_mod2p{palier}_k{k}_u{underlineA}.json"
out_md = output_dir / f"clauses_D_minor_over_Sm_mod2p{palier}_k{k}_u{underlineA}.md"
generated_at = _utc_now_iso()
core_path = repo_root / "applications" / "collatz" / "collatz_k_scripts" / "collatz_k_core.py"
sha_inputs = {}
if core_path.exists():
sha_inputs[str(core_path.relative_to(repo_root))] = _sha256_file(core_path)
obj: dict[str, object] = {
"domain": {"palier": palier, "S_M_size": (1 << (palier - 1))},
"params": {"k": k, "underlineA": underlineA},
"generated_at": generated_at,
"sha256": {"inputs": sha_inputs},
"counts": {
"clauses": len(clauses),
"rejected_prefix_not_stable": rejected_prefix_not_stable,
"rejected_divisibility": rejected_divisibility,
},
"clauses": [c.to_json() for c in clauses],
}
_write_json(out_json, obj)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Clauses D minorées sur S_M — palier 2^{palier}")
md.append("")
md.append("## Paramètres")
md.append("")
md.append(f"- k : {k}")
md.append(f"- underlineA : {underlineA}")
md.append(f"- delta_min = 2^underlineA - 3^k : {delta_min}")
md.append("")
md.append("## Compteurs")
md.append("")
md.append(f"- clauses : {len(clauses)}")
md.append(f"- rejected_prefix_not_stable : {rejected_prefix_not_stable}")
md.append(f"- rejected_divisibility : {rejected_divisibility}")
md.append("")
md.append("## Sorties")
md.append("")
md.append(f"- JSON : `{out_json}`")
md.append(f"- Markdown : `{out_md}`")
md.append("")
_write_md(out_md, md)
def main() -> None:
ap = argparse.ArgumentParser(description="Generate minorated descent clauses over S_M (odd residues modulo 2^M)")
ap.add_argument("--repo-root", default=".", help="Repository root")
ap.add_argument("--palier", type=int, default=15)
ap.add_argument("--k", type=int, default=8)
ap.add_argument("--underlineA", type=int, default=13)
ap.add_argument("--output-dir", default="", help="Output directory (defaults under docs/artefacts/...)")
args = ap.parse_args()
repo_root = Path(args.repo_root).resolve()
palier = int(args.palier)
output_dir = Path(args.output_dir).resolve() if args.output_dir.strip() else (
repo_root / "docs" / "artefacts" / "collatz" / "minorated_clauses_over_Sm" / f"palier2p{palier}"
)
run(palier=palier, k=int(args.k), underlineA=int(args.underlineA), output_dir=output_dir, repo_root=repo_root)
if __name__ == "__main__":
main()

View File

@ -61,6 +61,14 @@ def read_text(path: Path) -> str:
return path.read_text(encoding="utf-8", errors="strict") return path.read_text(encoding="utf-8", errors="strict")
def display_path(path: Path, repo_root: Path) -> str:
try:
rel = path.resolve().relative_to(repo_root.resolve())
return str(rel)
except ValueError:
return str(path)
def parse_last_extend_run_date(pipeline_extend_log: str) -> str: def parse_last_extend_run_date(pipeline_extend_log: str) -> str:
""" """
Return YYYY-MM-DD for the last extend run that reached completion. Return YYYY-MM-DD for the last extend run that reached completion.
@ -148,10 +156,12 @@ class C2ProjectiveMetrics:
class C3LocalDescentMetrics: class C3LocalDescentMetrics:
palier: int palier: int
lifted_domain_size: int lifted_domain_size: int
d8_nodes: int d_nodes: int
d8_exact_nodes: int d_base_cases: int
d8_brother_nodes: int d_descent_witnesses: int
fusion_nodes: int f_nodes: int
f_base_cases: int
f_descent_witnesses: int
n_star: int n_star: int
base_checked_up_to: int base_checked_up_to: int
@ -276,10 +286,12 @@ def parse_c3_local_descent_metrics(verification_json: str) -> C3LocalDescentMetr
return C3LocalDescentMetrics( return C3LocalDescentMetrics(
palier=req_int(domain, "palier"), palier=req_int(domain, "palier"),
lifted_domain_size=req_int(domain, "lifted_domain_size"), lifted_domain_size=req_int(domain, "lifted_domain_size"),
d8_nodes=req_int(elim, "d8_nodes"), d_nodes=req_int(elim, "d_nodes"),
d8_exact_nodes=req_int(elim, "d8_exact_nodes"), d_base_cases=req_int(elim, "d_base_cases"),
d8_brother_nodes=req_int(elim, "d8_brother_nodes"), d_descent_witnesses=req_int(elim, "d_descent_witnesses"),
fusion_nodes=req_int(elim, "fusion_nodes"), f_nodes=req_int(elim, "f_nodes"),
f_base_cases=req_int(elim, "f_base_cases"),
f_descent_witnesses=req_int(elim, "f_descent_witnesses"),
n_star=req_int(elim, "N_star"), n_star=req_int(elim, "N_star"),
base_checked_up_to=req_int(base, "checked_up_to"), base_checked_up_to=req_int(base, "checked_up_to"),
) )
@ -450,8 +462,12 @@ def write_c3_local_descent_run_report(
lines.append("") lines.append("")
lines.append(f"- palier : 2^{metrics.palier}") lines.append(f"- palier : 2^{metrics.palier}")
lines.append(f"- |Lift(B12)| : {metrics.lifted_domain_size}") lines.append(f"- |Lift(B12)| : {metrics.lifted_domain_size}")
lines.append(f"- D8 : {metrics.d8_nodes} (exact={metrics.d8_exact_nodes}, brothers={metrics.d8_brother_nodes})") lines.append(
lines.append(f"- Fusion : {metrics.fusion_nodes}") f"- D : {metrics.d_nodes} (descente={metrics.d_descent_witnesses}, base_cases={metrics.d_base_cases})"
)
lines.append(
f"- Fusion : {metrics.f_nodes} (descente={metrics.f_descent_witnesses}, base_cases={metrics.f_base_cases})"
)
lines.append(f"- N* (max seuils N0/Nf calculés) : {metrics.n_star}") lines.append(f"- N* (max seuils N0/Nf calculés) : {metrics.n_star}")
lines.append(f"- base validation checked up to : {metrics.base_checked_up_to}") lines.append(f"- base validation checked up to : {metrics.base_checked_up_to}")
lines.append("") lines.append("")
@ -481,7 +497,10 @@ def write_universal_clauses_run_report(
lines.append("## Contexte") lines.append("## Contexte")
lines.append("") lines.append("")
lines.append("- **But du run** : extraire des clauses universelles candidates (Option A : Lift(B12)) depuis lartefact C3 local, et vérifier leur cohérence déterministe.") lines.append("- **But du run** : extraire des clauses universelles candidates (Option A : Lift(B12)) depuis lartefact C3 local, et vérifier leur cohérence déterministe.")
lines.append("- **Assertion vérifiée** : cohérence arithmétique des clauses extraites et cohérence des relèvements au module minimal \\(2^{A+1}\\).") lines.append(
"- **Assertion vérifiée** : cohérence arithmétique des clauses extraites et cohérence des relèvements "
"au module \\(2^{m_{stable}}\\) avec \\(m_{stable}=\\max(m, A+1)\\)."
)
lines.append("") lines.append("")
lines.append("## Code et reproductibilité") lines.append("## Code et reproductibilité")
lines.append("") lines.append("")
@ -1119,6 +1138,7 @@ def main() -> None:
"c3_local_descent", "c3_local_descent",
"c3_local_descent_palier", "c3_local_descent_palier",
"universal_clauses", "universal_clauses",
"universal_clauses_palier",
], ],
help="Report profile", help="Report profile",
) )
@ -1503,18 +1523,21 @@ def main() -> None:
return return
if args.profile == "universal_clauses": if args.profile == "universal_clauses":
command = (
args.command.strip()
if args.command.strip()
else "--profile universal_clauses --scope universal_clauses "
"--universal-clauses-artefacts-dir docs/artefacts/collatz/universal_clauses "
"--out-dir applications/collatz/out --docs-dir docs"
)
artefacts_dir = ( artefacts_dir = (
Path(args.universal_clauses_artefacts_dir).resolve() Path(args.universal_clauses_artefacts_dir).resolve()
if args.universal_clauses_artefacts_dir.strip() if args.universal_clauses_artefacts_dir.strip()
else (docs_dir / "artefacts" / "collatz" / "universal_clauses") else (docs_dir / "artefacts" / "collatz" / "universal_clauses")
) )
command = args.command.strip()
if not command:
artefacts_display = display_path(artefacts_dir, repo_root)
command = (
"python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py "
"--profile universal_clauses "
f"--scope {args.scope} "
"--out-dir applications/collatz/out --docs-dir docs "
f"--universal-clauses-artefacts-dir {artefacts_display}"
)
clauses_json = artefacts_dir / "clauses_universelles.json" clauses_json = artefacts_dir / "clauses_universelles.json"
clauses_md = artefacts_dir / "clauses_universelles.md" clauses_md = artefacts_dir / "clauses_universelles.md"
verification_json = artefacts_dir / "verification_universal_clauses.json" verification_json = artefacts_dir / "verification_universal_clauses.json"
@ -1550,6 +1573,57 @@ def main() -> None:
print(f"Wrote: {output_path}") print(f"Wrote: {output_path}")
return return
if args.profile == "universal_clauses_palier":
artefacts_dir = (
Path(args.universal_clauses_artefacts_dir).resolve()
if args.universal_clauses_artefacts_dir.strip()
else (docs_dir / "artefacts" / "collatz" / "universal_clauses")
)
command = args.command.strip()
if not command:
artefacts_display = display_path(artefacts_dir, repo_root)
command = (
"python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py "
"--profile universal_clauses_palier "
"--out-dir applications/collatz/out --docs-dir docs "
f"--universal-clauses-artefacts-dir {artefacts_display}"
)
clauses_json = artefacts_dir / "clauses_universelles.json"
clauses_md = artefacts_dir / "clauses_universelles.md"
verification_json = artefacts_dir / "verification_universal_clauses.json"
verification_md = artefacts_dir / "verification_universal_clauses.md"
metrics = parse_universal_clauses_metrics(
clauses_json_path=clauses_json,
verification_json_path=verification_json,
)
date_str = pick_report_date_from_mtime([clauses_json, clauses_md, verification_json, verification_md])
c3_input_json = _extract_universal_clauses_c3_input_path(clauses_json_path=clauses_json, repo_root=repo_root)
sha_paths: list[Path] = [
repo_root / "applications" / "collatz" / "collatz_k_scripts" / "collatz_generate_run_report.py",
repo_root / "applications" / "collatz" / "collatz_k_scripts" / "collatz_extract_universal_clauses.py",
repo_root / "applications" / "collatz" / "collatz_k_scripts" / "collatz_verify_universal_clauses.py",
c3_input_json,
clauses_json,
clauses_md,
verification_json,
verification_md,
]
sha_entries = compute_sha256_entries(sha_paths)
m = metrics.domain_palier
output_path = docs_dir / f"collatz_run_report_{date_str}_universal_clauses_palier2p{m}.md"
write_universal_clauses_run_report(
output_path=output_path,
report_title=f"Rapport dexécution — universal_clauses_palier2p{m}",
command=command,
git_commit=commit_hash,
sha_entries=sha_entries,
metrics=metrics,
artefacts_dir=artefacts_dir,
)
print(f"Wrote: {output_path}")
return
raise ValueError(f"Unknown profile: {args.profile}") raise ValueError(f"Unknown profile: {args.profile}")

View File

@ -0,0 +1,237 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_generate_terminal_clauses_over_Sm.py
Generate a deterministic set of terminal D/F clauses for the full odd residue space S_m
(odd residues modulo 2^m), optionally restricted to clauses *directly decidable* at 2^m
in the sense A+1 <= m (so stable_modulus_power == m).
This script is intended as an "Option A (expanded domain)" source of terminal clauses
to support refinement-closure audits over S_M.
Inputs:
- None (pure computation at a chosen modulus power), except the code of collatz_k_core.
Outputs:
- docs/artefacts/collatz/terminal_clauses_over_Sm/palier2p<m>/clauses_terminal_over_Sm_mod2p<m>.{json,md}
Notes:
- Clauses are generated from prefix_data and standard threshold formulas (N0_D, Nf_F).
- No claim of global correctness is made beyond the arithmetic validation of the clause parameters.
"""
from __future__ import annotations
import argparse
import hashlib
import json
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Literal
from collatz_k_core import prefix_data, N0_D, fusion_choice_a, delta_F, Nf_F
ClauseKind = Literal["D_exact", "F"]
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _sha256_file(path: Path, chunk_size: int = 16 * 1024 * 1024) -> str:
h = hashlib.sha256()
with path.open("rb") as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
h.update(chunk)
return h.hexdigest()
def _utc_now_iso() -> str:
return datetime.now(tz=timezone.utc).isoformat().replace("+00:00", "Z")
@dataclass(frozen=True)
class TerminalClause:
kind: ClauseKind
modulus_power: int
residue_mod_2p: int
threshold: int
k_or_t: int
A: int
C: int
def to_json(self) -> dict[str, object]:
return {
"kind": self.kind,
"modulus_power": self.modulus_power,
"residue_mod_2p": self.residue_mod_2p,
"threshold": self.threshold,
"k_or_t": self.k_or_t,
"A": self.A,
"C": self.C,
}
def _best_direct_clause_for_residue(*, r: int, m: int, k_max: int, t_max: int) -> TerminalClause | None:
"""
Return a clause with A+1 <= m (directly decidable at 2^m), preferring smaller A.
Deterministic tie-breakers: kind, k/t, threshold.
"""
best: TerminalClause | None = None
best_key: tuple[int, str, int, int] | None = None
for k in range(1, k_max + 1):
pref = prefix_data(r, k)
if pref.A + 1 > m:
break
try:
N0 = N0_D(pref.C, pref.A, k)
except ValueError:
continue
cand = TerminalClause(kind="D_exact", modulus_power=m, residue_mod_2p=r, threshold=N0, k_or_t=k, A=pref.A, C=pref.C)
key = (cand.A, cand.kind, cand.k_or_t, cand.threshold)
if best_key is None or key < best_key:
best_key = key
best = cand
for t in range(1, t_max + 1):
pref = prefix_data(r, t)
if pref.A + 1 > m:
break
a = fusion_choice_a(pref.y)
if a is None:
continue
if delta_F(pref.A, t, a) <= 0:
continue
try:
Nf = Nf_F(pref.C, pref.A, t, a)
except ValueError:
continue
cand = TerminalClause(kind="F", modulus_power=m, residue_mod_2p=r, threshold=Nf, k_or_t=t, A=pref.A, C=pref.C)
key = (cand.A, cand.kind, cand.k_or_t, cand.threshold)
if best_key is None or key < best_key:
best_key = key
best = cand
return best
def run(*, palier: int, k_max: int, t_max: int, output_dir: Path, repo_root: Path) -> None:
if palier < 2:
raise ValueError("palier must be >= 2")
if k_max < 1 or t_max < 1:
raise ValueError("k_max and t_max must be >= 1")
mod = 1 << palier
residues = list(range(1, mod, 2))
clauses: list[TerminalClause] = []
missing: list[int] = []
for r in residues:
c = _best_direct_clause_for_residue(r=r, m=palier, k_max=k_max, t_max=t_max)
if c is None:
missing.append(r)
continue
clauses.append(c)
out_json = output_dir / f"clauses_terminal_over_Sm_mod2p{palier}.json"
out_md = output_dir / f"clauses_terminal_over_Sm_mod2p{palier}.md"
generated_at = _utc_now_iso()
core_path = repo_root / "applications" / "collatz" / "collatz_k_scripts" / "collatz_k_core.py"
sha_inputs = {}
if core_path.exists():
sha_inputs[str(core_path.relative_to(repo_root))] = _sha256_file(core_path)
obj: dict[str, object] = {
"domain": {
"palier": palier,
"S_M_size": len(residues),
},
"params": {
"k_max": k_max,
"t_max": t_max,
"direct_decidability": "A+1 <= M (stable_modulus_power == M)",
},
"generated_at": generated_at,
"sha256": {"inputs": sha_inputs},
"counts": {
"total_roots": len(residues),
"clauses": len(clauses),
"missing": len(missing),
"D_exact": sum(1 for c in clauses if c.kind == "D_exact"),
"F": sum(1 for c in clauses if c.kind == "F"),
},
"missing_sample": missing[:64],
"clauses": [c.to_json() for c in clauses],
}
_write_json(out_json, obj)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Clauses terminales sur S_M — décidables directement à 2^{palier}")
md.append("")
md.append("## Domaine")
md.append("")
md.append(f"- palier : 2^{palier}")
md.append(f"- |S_M| (impairs) : {len(residues)}")
md.append("")
md.append("## Paramètres")
md.append("")
md.append(f"- k_max : {k_max}")
md.append(f"- t_max : {t_max}")
md.append("- critère : A+1 <= M (stable_modulus_power == M)")
md.append("")
md.append("## Compteurs")
md.append("")
md.append(f"- clauses : {len(clauses)}")
md.append(f"- missing : {len(missing)}")
md.append(f"- D_exact : {sum(1 for c in clauses if c.kind == 'D_exact')}")
md.append(f"- F : {sum(1 for c in clauses if c.kind == 'F')}")
md.append("")
if missing:
md.append("### Missing (extrait)")
md.append("")
md.append(", ".join(map(str, missing[:64])) + ("" if len(missing) > 64 else ""))
md.append("")
md.append("## Sorties")
md.append("")
md.append(f"- JSON : `{out_json}`")
md.append(f"- Markdown : `{out_md}`")
md.append("")
_write_md(out_md, md)
def main() -> None:
ap = argparse.ArgumentParser(description="Generate terminal clauses over S_M (directly decidable at 2^M)")
ap.add_argument("--repo-root", default=".", help="Repository root (defaults to current working directory)")
ap.add_argument("--palier", type=int, default=16, help="Palier M for S_M")
ap.add_argument("--k-max", type=int, default=14, help="Max k to search for D clauses")
ap.add_argument("--t-max", type=int, default=14, help="Max t to search for F clauses")
ap.add_argument("--output-dir", default="", help="Output directory (defaults under docs/artefacts/...)")
args = ap.parse_args()
repo_root = Path(args.repo_root).resolve()
palier = int(args.palier)
output_dir = Path(args.output_dir).resolve() if args.output_dir.strip() else (
repo_root / "docs" / "artefacts" / "collatz" / "terminal_clauses_over_Sm" / f"palier2p{palier}"
)
run(palier=palier, k_max=int(args.k_max), t_max=int(args.t_max), output_dir=output_dir, repo_root=repo_root)
if __name__ == "__main__":
main()

View File

@ -151,6 +151,12 @@ def run(
f"--clauses-json docs/artefacts/collatz/universal_clauses/palier2p{tgt}/clauses_universelles.json " f"--clauses-json docs/artefacts/collatz/universal_clauses/palier2p{tgt}/clauses_universelles.json "
f"--output-dir docs/artefacts/collatz/universal_clauses/palier2p{tgt}" f"--output-dir docs/artefacts/collatz/universal_clauses/palier2p{tgt}"
), ),
"Universal_clauses_run_report_palier": (
"python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py "
"--profile universal_clauses_palier "
f"--universal-clauses-artefacts-dir docs/artefacts/collatz/universal_clauses/palier2p{tgt} "
"--out-dir applications/collatz/out --docs-dir docs"
),
"C2_verify_projective": ( "C2_verify_projective": (
"python3 applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py " "python3 applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py "
"--repo-root /home/ncantu/code/algo --output-dir docs/artefacts/collatz/c2_projective" "--repo-root /home/ncantu/code/algo --output-dir docs/artefacts/collatz/c2_projective"

View File

@ -26,6 +26,22 @@ def _find_column(row: dict, *candidates: str) -> str | None:
return None return None
def _find_column_exact(row: dict, *candidates: str) -> str | None:
"""
Return the first column whose normalized key equals one of the candidates.
Use this for short keys like 'm' where substring matching is unsafe
(e.g. 'classe_mod_2^m' contains 'm' but is not an exponent column).
"""
keys = set(row.keys())
normalized: dict[str, str] = {k.replace(" ", "").lower(): k for k in keys}
for c in candidates:
ck = c.replace(" ", "").lower()
if ck in normalized:
return normalized[ck]
return None
def _try_parse_int(value: object) -> int | None: def _try_parse_int(value: object) -> int | None:
if value is None: if value is None:
return None return None
@ -53,12 +69,12 @@ def infer_palier(rows: list[dict], classe_col: str | None, csv_path: Path | None
- fallback heuristic from max class value (legacy; not reliable when values are sparse) - fallback heuristic from max class value (legacy; not reliable when values are sparse)
""" """
if rows: if rows:
pal_col = _find_column(rows[0], "palier") pal_col = _find_column_exact(rows[0], "palier")
if pal_col: if pal_col:
v = _try_parse_int(rows[0].get(pal_col)) v = _try_parse_int(rows[0].get(pal_col))
if v is not None and v > 0: if v is not None and v > 0:
return v return v
m_col = _find_column(rows[0], "m", "modulus_power") m_col = _find_column_exact(rows[0], "m", "modulus_power")
if m_col: if m_col:
v = _try_parse_int(rows[0].get(m_col)) v = _try_parse_int(rows[0].get(m_col))
if v is not None and v > 0: if v is not None and v > 0:

View File

@ -33,7 +33,7 @@ import re
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from collatz_k_core import U_step, prefix_data, N0_D, fusion_choice_a, delta_F, Nf_F from collatz_k_core import U_step, prefix_data, N0_D, fusion_choice_a, delta_F, Nf_F, preimage_m
def _read_json(path: Path) -> object: def _read_json(path: Path) -> object:
@ -47,16 +47,6 @@ def _discover_state_dirs(root: Path, palier: int) -> list[Path]:
return dirs return dirs
def _load_covered_from_cert(cert_path: Path) -> set[int]:
obj = _read_json(cert_path)
if not isinstance(obj, dict) or "covered" not in obj:
raise ValueError(f"Invalid certificate JSON (missing covered): {cert_path}")
cov = obj["covered"]
if not isinstance(cov, list) or not all(isinstance(x, int) for x in cov):
raise ValueError(f"Invalid certificate JSON covered list: {cert_path}")
return set(cov)
@dataclass(frozen=True) @dataclass(frozen=True)
class FusionWitness: class FusionWitness:
n: int n: int
@ -126,18 +116,30 @@ def _collatz_terminates(n: int) -> bool:
return True return True
def _pick_best_witness(witnesses: list[FusionWitness]) -> dict[int, FusionWitness]: def _pick_best_strict_witness(*, witnesses: list[FusionWitness], palier: int) -> dict[int, FusionWitness]:
""" """
For each n, choose a canonical witness: minimal t, then minimal preimage_m, For each n, choose a canonical STRICT fusion witness that prioritizes lower modular stability.
then lexical source_csv (for determinism).
Objective:
- minimize required_m_stable := max(palier, A_t+1), where A_t is computed from prefix_data(n,t)
(this increases the fraction of witnesses that can be turned into clauses decidable at 2^palier).
Tie-breakers (deterministic):
- minimal A_t
- minimal t
- minimal preimage_m
- lexical source_csv
""" """
out: dict[int, FusionWitness] = {} out: dict[int, FusionWitness] = {}
key_by_n: dict[int, tuple[int, int, int, int, str]] = {}
for w in witnesses: for w in witnesses:
prev = out.get(w.n) pref = prefix_data(w.n, w.t)
if prev is None: A_t = pref.A
out[w.n] = w required_m_stable = max(palier, A_t + 1)
continue key = (required_m_stable, A_t, w.t, w.preimage_m, w.source_csv)
if (w.t, w.preimage_m, w.source_csv) < (prev.t, prev.preimage_m, prev.source_csv): prev_key = key_by_n.get(w.n)
if prev_key is None or key < prev_key:
key_by_n[w.n] = key
out[w.n] = w out[w.n] = w
return out return out
@ -159,7 +161,6 @@ def run(
# Domain L as union of per-state lifted noyaux # Domain L as union of per-state lifted noyaux
L: set[int] = set() L: set[int] = set()
d8_covered: set[int] = set()
fusion_witnesses_all: list[FusionWitness] = [] fusion_witnesses_all: list[FusionWitness] = []
for sd in state_dirs: for sd in state_dirs:
@ -175,140 +176,159 @@ def run(
raise ValueError(f"Invalid lift noyau list: {lift_candidates[0]}") raise ValueError(f"Invalid lift noyau list: {lift_candidates[0]}")
L |= set(lift_list) L |= set(lift_list)
cert_d8 = sd / "certificats" / f"certificat_D8_E{sid}_palier2p{palier}.json"
if cert_d8.exists():
d8_covered |= _load_covered_from_cert(cert_d8)
fusion_witnesses_all.extend(_load_fusion_witnesses(sd, palier)) fusion_witnesses_all.extend(_load_fusion_witnesses(sd, palier))
if not L: if not L:
raise ValueError("Empty domain L") raise ValueError("Empty domain L")
fusion_by_n = _pick_best_witness(fusion_witnesses_all) strict_fusion_by_n = _pick_best_strict_witness(witnesses=fusion_witnesses_all, palier=palier)
d8_nodes = sorted([n for n in L if n in d8_covered])
f_nodes = sorted([n for n in L if n not in d8_covered])
missing_f = [n for n in f_nodes if n not in fusion_by_n]
if missing_f:
raise ValueError(f"Missing fusion witness for {len(missing_f)} residues (e.g. {missing_f[:20]})")
records: list[dict[str, object]] = [] records: list[dict[str, object]] = []
next_values: list[int] = [] next_values: list[int] = []
thresholds: list[int] = [] thresholds: list[int] = []
d8_exact_nodes = 0 d_nodes = 0
d8_brother_nodes = 0 d_base_cases = 0
d8_exact_base_cases = 0 d_descent_witnesses = 0
d8_exact_descent_witnesses = 0 f_nodes = 0
f_base_cases = 0
shift = 1 << (palier - 1) f_descent_witnesses = 0
d8_exact_set: set[int] = set() t_search_max = 14 # A_t <= 14 is required for m_stable <= 15 at palier 2^15
d8_brother_set: set[int] = set()
for n in d8_nodes:
pref = prefix_data(n, 8)
if pref.A == 13:
d8_exact_set.add(n)
else:
d8_brother_set.add(n)
for n in sorted(L): for n in sorted(L):
if n in d8_covered: # Try to produce a D_k witness with A_k <= 14 (so m_stable <= 15 at palier 2^15).
pref = prefix_data(n, 8) best_d: dict[str, object] | None = None
if n in d8_exact_set: best_d_key: tuple[int, int, int, int, int] | None = None
d8_exact_nodes += 1 for k in range(1, t_search_max + 1):
N0 = N0_D(pref.C, pref.A, 8) pref = prefix_data(n, k)
thresholds.append(N0) if pref.A > 14:
break
if n >= N0: try:
y = pref.y N0 = N0_D(pref.C, pref.A, k)
if y >= n: except ValueError:
raise ValueError(f"D8 descent check failed for n={n}: U^8(n)={y} not < n (N0={N0})") continue
next_values.append(y) base_case = n < N0
d8_exact_descent_witnesses += 1 if not base_case and pref.y >= n:
records.append( continue
{ key = (max(palier, pref.A + 1), 1 if base_case else 0, pref.A, k, N0)
"n": n, if best_d_key is None or key < best_d_key:
"kind": "D_exact", best_d_key = key
"k": 8, best_d = {
"A_k": pref.A, "n": n,
"C_k": pref.C, "kind": "D_exact",
"N0": N0, "k": k,
"next": y, "A_k": pref.A,
"base_case": False, "C_k": pref.C,
} "N0": N0,
) "next": (None if base_case else pref.y),
else: "base_case": base_case,
d8_exact_base_cases += 1 }
records.append( if best_d is not None:
{ d_nodes += 1
"n": n, N0v = int(best_d["N0"]) # type: ignore[arg-type]
"kind": "D_exact", thresholds.append(N0v)
"k": 8, if bool(best_d["base_case"]):
"A_k": pref.A, d_base_cases += 1
"C_k": pref.C,
"N0": N0,
"next": None,
"base_case": True,
}
)
else: else:
d8_brother_nodes += 1 d_descent_witnesses += 1
mate = n ^ shift next_values.append(int(best_d["next"])) # type: ignore[arg-type]
if mate not in d8_exact_set: records.append(best_d)
raise ValueError( continue
f"D8 brother check failed for n={n}: expected mate={mate} to be an exact D8 candidate (A8=13)"
) # Try to produce a short fusion witness (t<=14, A_t<=14). Allow base-case if n < Nf.
records.append( best_f: dict[str, object] | None = None
{ best_f_key: tuple[int, int, int, int, int, int] | None = None
"n": n, for t in range(1, t_search_max + 1):
"kind": "D_brother", pref = prefix_data(n, t)
"k": 8, if pref.A > 14:
"A_k": pref.A, break
"C_k": pref.C, a = fusion_choice_a(pref.y)
"mate_exact": mate,
}
)
else:
w = fusion_by_n[n]
pref = prefix_data(n, w.t)
y = pref.y
if y != w.y:
raise ValueError(f"Fusion witness y mismatch for n={n}: computed U^{w.t}(n)={y}, row y={w.y}")
m = w.preimage_m
if m >= n:
raise ValueError(f"Fusion witness preimage not smaller for n={n}: m={m} >= n")
y2, _ = U_step(m)
if y2 != y:
raise ValueError(f"Fusion witness invalid: U(m) != U^t(n) for n={n}: U({m})={y2}, U^{w.t}({n})={y}")
a = fusion_choice_a(y)
if a is None: if a is None:
raise ValueError(f"Fusion witness invalid: y mod 3 == 0 for n={n}, y={y}") continue
if a != w.a: dF = delta_F(pref.A, t, a)
raise ValueError(f"Fusion witness a mismatch for n={n}: computed a={a}, row a={w.a}")
dF = delta_F(pref.A, w.t, a)
if dF <= 0: if dF <= 0:
raise ValueError(f"Fusion witness invalid: DeltaF<=0 for n={n}: DeltaF={dF}") continue
Nf = Nf_F(pref.C, pref.A, w.t, a) Nf = Nf_F(pref.C, pref.A, t, a)
thresholds.append(Nf) m = preimage_m(pref.y, a)
if n < Nf: base_case = (n < Nf) or (m >= n)
raise ValueError(f"Fusion witness invalid: n < Nf for n={n}: Nf={Nf}") key = (max(palier, pref.A + 1), 1 if base_case else 0, pref.A, t, Nf, m)
records.append( if best_f_key is None or key < best_f_key:
{ best_f_key = key
best_f = {
"n": n, "n": n,
"kind": "F", "kind": "F",
"t": w.t, "t": t,
"a": a, "a": a,
"y": y, "y": pref.y,
"preimage_m": m, "preimage_m": m,
"A_t": pref.A, "A_t": pref.A,
"C_t": pref.C, "C_t": pref.C,
"DeltaF": dF, "DeltaF": dF,
"Nf": Nf, "Nf": Nf,
"source_csv": w.source_csv, "source_csv": "computed:short_fusion_search",
"next": m, "next": (None if base_case else m),
"base_case": base_case,
} }
) if best_f is not None:
next_values.append(m) f_nodes += 1
if bool(best_f["base_case"]):
f_base_cases += 1
else:
f_descent_witnesses += 1
thresholds.append(int(best_f["Nf"])) # type: ignore[arg-type]
next_values.append(int(best_f["next"])) # type: ignore[arg-type]
# Always verify U(m)=U^t(n) at the recorded y (even in base-case mode).
y2, _ = U_step(int(best_f["preimage_m"])) # type: ignore[arg-type]
if y2 != int(best_f["y"]): # type: ignore[arg-type]
raise ValueError(f"Computed fusion witness invalid for n={n}: U(m) != y")
records.append(best_f)
continue
# Fallback: strict fusion witness from local H6 artefacts (guarantees m<n for the representative).
w = strict_fusion_by_n.get(n)
if w is None:
raise ValueError(f"Missing strict fusion witness for n={n}")
pref = prefix_data(n, w.t)
y = pref.y
if y != w.y:
raise ValueError(f"Fusion witness y mismatch for n={n}: computed U^{w.t}(n)={y}, row y={w.y}")
m = w.preimage_m
y2, _ = U_step(m)
if y2 != y:
raise ValueError(f"Fusion witness invalid: U(m) != U^t(n) for n={n}: U({m})={y2}, U^{w.t}({n})={y}")
a = fusion_choice_a(y)
if a is None:
raise ValueError(f"Fusion witness invalid: y mod 3 == 0 for n={n}, y={y}")
if a != w.a:
raise ValueError(f"Fusion witness a mismatch for n={n}: computed a={a}, row a={w.a}")
dF = delta_F(pref.A, w.t, a)
if dF <= 0:
raise ValueError(f"Fusion witness invalid: DeltaF<=0 for n={n}: DeltaF={dF}")
Nf = Nf_F(pref.C, pref.A, w.t, a)
if n < Nf:
raise ValueError(f"Fusion witness invalid: n < Nf for n={n}: Nf={Nf}")
if m >= n:
raise ValueError(f"Fusion witness preimage not smaller for n={n}: m={m} >= n")
f_nodes += 1
f_descent_witnesses += 1
thresholds.append(Nf)
records.append(
{
"n": n,
"kind": "F",
"t": w.t,
"a": a,
"y": y,
"preimage_m": m,
"A_t": pref.A,
"C_t": pref.C,
"DeltaF": dF,
"Nf": Nf,
"source_csv": w.source_csv,
"next": m,
"base_case": False,
}
)
next_values.append(m)
max_n = max(L) max_n = max(L)
max_next = max(next_values) if next_values else 0 max_next = max(next_values) if next_values else 0
@ -337,12 +357,12 @@ def run(
"max_n": max_n, "max_n": max_n,
}, },
"elimination": { "elimination": {
"d8_nodes": len(d8_nodes), "d_nodes": d_nodes,
"d8_exact_nodes": d8_exact_nodes, "d_base_cases": d_base_cases,
"d8_exact_descent_witnesses": d8_exact_descent_witnesses, "d_descent_witnesses": d_descent_witnesses,
"d8_exact_base_cases": d8_exact_base_cases, "f_nodes": f_nodes,
"d8_brother_nodes": d8_brother_nodes, "f_base_cases": f_base_cases,
"fusion_nodes": len(f_nodes), "f_descent_witnesses": f_descent_witnesses,
"max_next": max_next, "max_next": max_next,
"N_star": N_star, "N_star": N_star,
}, },
@ -380,12 +400,11 @@ def run(
lines.append("## Élimination (témoins)") lines.append("## Élimination (témoins)")
lines.append("") lines.append("")
lines.append( lines.append(
f"- D8 : {len(d8_nodes)} (exact A8=13 : {d8_exact_nodes}, " f"- D : {d_nodes} (k variable, A_k<=14 ; descente vérifiée : {d_descent_witnesses}, cas de base : {d_base_cases})"
f"descente vérifiée pour n>=N0 : {d8_exact_descent_witnesses}, " )
f"cas de base n<N0 : {d8_exact_base_cases}, " lines.append(
f"frères (mate exact requis) : {d8_brother_nodes})" f"- Fusion : {f_nodes} (descente vérifiée : {f_descent_witnesses}, cas de base : {f_base_cases})"
) )
lines.append(f"- Fusion : {len(f_nodes)} (m<n, U(m)=U^t(n) vérifié)")
lines.append(f"- max(next) : {max_next}") lines.append(f"- max(next) : {max_next}")
lines.append(f"- N* (max des seuils N0/Nf calculés) : {N_star}") lines.append(f"- N* (max des seuils N0/Nf calculés) : {N_star}")
lines.append("") lines.append("")

View File

@ -0,0 +1,151 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
collatz_verify_minorated_descent_clauses_over_Sm.py
Deterministic verification of D_minor clauses produced by
collatz_generate_minorated_descent_clauses_over_Sm.py.
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from collatz_k_core import prefix_data
def _read_json(path: Path) -> object:
return json.loads(path.read_text(encoding="utf-8", errors="strict"))
def _write_json(path: Path, obj: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(obj, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
def _write_md(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def _req_int(d: dict[str, object], key: str) -> int:
v = d.get(key)
if not isinstance(v, int):
raise ValueError(f"Expected int for {key}")
return v
def run(*, clauses_json: Path, output_dir: Path) -> None:
obj = _read_json(clauses_json)
if not isinstance(obj, dict):
raise ValueError("Invalid D_minor clauses JSON: expected object")
domain = obj.get("domain")
params = obj.get("params")
clauses = obj.get("clauses")
if not isinstance(domain, dict) or not isinstance(params, dict) or not isinstance(clauses, list):
raise ValueError("Invalid D_minor clauses JSON: missing domain/params/clauses")
palier = _req_int(domain, "palier")
k = _req_int(params, "k")
underlineA = _req_int(params, "underlineA")
alpha = 3**k
pow2u = 1 << underlineA
delta_min = (1 << underlineA) - alpha
if delta_min <= 0:
raise ValueError("delta_min <= 0")
ok = 0
errors: list[str] = []
for c in clauses:
if not isinstance(c, dict):
raise ValueError("Invalid clause entry: expected object")
if c.get("kind") != "D_minor":
raise ValueError("Invalid clause entry: kind must be D_minor")
m = _req_int(c, "modulus_power")
r = _req_int(c, "residue_mod_2p")
kk = _req_int(c, "k")
uA = _req_int(c, "underlineA")
numerator_B_k = _req_int(c, "numerator_B_k")
A_km1 = _req_int(c, "A_km1")
C_km1 = _req_int(c, "C_km1")
N0 = _req_int(c, "N0")
w_prefix_raw = c.get("prefix_word_len_km1")
if not isinstance(w_prefix_raw, list) or not all(isinstance(x, int) for x in w_prefix_raw):
raise ValueError("Invalid prefix_word_len_km1")
if m != palier or kk != k or uA != underlineA:
raise ValueError("Clause params mismatch vs header")
if underlineA > palier:
raise ValueError("underlineA must be <= palier")
if A_km1 + 1 > palier:
raise ValueError("Prefix stability condition violated: A_km1+1 > palier")
if ((alpha * r + numerator_B_k) % pow2u) != 0:
errors.append(f"divisibility failed for r={r}")
continue
pref = prefix_data(r, k - 1)
w_prefix = [int(x) for x in pref.word]
if w_prefix != w_prefix_raw:
errors.append(f"prefix word mismatch for r={r}")
continue
if int(pref.A) != A_km1:
errors.append(f"A_km1 mismatch for r={r}")
continue
if int(pref.C) != C_km1:
errors.append(f"C_km1 mismatch for r={r}")
continue
expected_B_k = 3 * C_km1 + (1 << A_km1)
if expected_B_k != numerator_B_k:
errors.append(f"numerator_B_k mismatch for r={r}")
continue
expected_N0 = (numerator_B_k // delta_min) + 1
if expected_N0 != N0:
errors.append(f"N0 mismatch for r={r}: got {N0}, expected {expected_N0}")
continue
ok += 1
out_json = output_dir / f"verification_D_minor_over_Sm_mod2p{palier}_k{k}_u{underlineA}.json"
out_md = output_dir / f"verification_D_minor_over_Sm_mod2p{palier}_k{k}_u{underlineA}.md"
out = {
"domain": {"palier": palier},
"params": {"k": k, "underlineA": underlineA},
"counts": {"total": len(clauses), "ok": ok, "errors": len(errors)},
"ok": (ok == len(clauses)),
"errors_sample": errors[:50],
}
_write_json(out_json, out)
md: list[str] = []
md.append("**Auteur** : Équipe 4NK")
md.append("")
md.append(f"# Vérification — clauses D minorées sur S_M (2^{palier})")
md.append("")
md.append(f"- total : {len(clauses)}")
md.append(f"- ok : {ok}")
md.append(f"- errors : {len(errors)}")
md.append(f"- ok_all : {out['ok']}")
md.append("")
if errors:
md.append("## Erreurs (extrait)")
md.append("")
for e in errors[:30]:
md.append(f"- {e}")
md.append("")
_write_md(out_md, md)
def main() -> None:
ap = argparse.ArgumentParser(description="Verify D_minor clauses over S_M")
ap.add_argument("--clauses-json", required=True, help="Path to clauses_D_minor_over_Sm_mod2pM.json")
ap.add_argument("--output-dir", default="", help="Output directory (defaults to same directory as input)")
args = ap.parse_args()
clauses_json = Path(args.clauses_json).resolve()
output_dir = Path(args.output_dir).resolve() if args.output_dir.strip() else clauses_json.parent
run(clauses_json=clauses_json, output_dir=output_dir)
if __name__ == "__main__":
main()

View File

@ -168,8 +168,9 @@ def run(
raise ValueError(f"D_exact clause params mismatch for n={n}") raise ValueError(f"D_exact clause params mismatch for n={n}")
if m_stab is None or r_stab is None or word is None: if m_stab is None or r_stab is None or word is None:
raise ValueError(f"D_exact clause missing stability fields for n={n}") raise ValueError(f"D_exact clause missing stability fields for n={n}")
if m_stab != A_k + 1: m_expected = max(palier, A_k + 1)
raise ValueError(f"D_exact stable modulus mismatch for n={n}: {m_stab} != {A_k+1}") if m_stab != m_expected:
raise ValueError(f"D_exact stable modulus mismatch for n={n}: {m_stab} != {m_expected}")
pref = prefix_data(n, k) pref = prefix_data(n, k)
if pref.word != word or pref.A != A_k or pref.C != C_k: if pref.word != word or pref.A != A_k or pref.C != C_k:
raise ValueError(f"D_exact prefix mismatch for n={n}") raise ValueError(f"D_exact prefix mismatch for n={n}")
@ -211,8 +212,9 @@ def run(
raise ValueError(f"F clause params mismatch for n={n}") raise ValueError(f"F clause params mismatch for n={n}")
if m_stab is None or r_stab is None or word is None: if m_stab is None or r_stab is None or word is None:
raise ValueError(f"F clause missing stability fields for n={n}") raise ValueError(f"F clause missing stability fields for n={n}")
if m_stab != A_t + 1: m_expected = max(palier, A_t + 1)
raise ValueError(f"F stable modulus mismatch for n={n}: {m_stab} != {A_t+1}") if m_stab != m_expected:
raise ValueError(f"F stable modulus mismatch for n={n}: {m_stab} != {m_expected}")
pref = prefix_data(n, t) pref = prefix_data(n, t)
if pref.word != word or pref.A != A_t or pref.C != C_t or pref.y != y: if pref.word != word or pref.A != A_t or pref.C != C_t or pref.y != y:

View File

@ -190,13 +190,13 @@ On fixe un palier de relèvement \(m\ge 13\) et on partitionne explicitement les
Pour rendre cette complétude locale *citable* (et alignée avec la notion “certifié D/F”), lartefact attendu est un CSV+certificat construit sur un domaine fini explicitement défini : Pour rendre cette complétude locale *citable* (et alignée avec la notion “certifié D/F”), lartefact attendu est un CSV+certificat construit sur un domaine fini explicitement défini :
- domaine \(L\) : la liste explicite des relèvements impairs de \(B_{12}(E_1)\) au palier \(m\) (pour un premier essai : \(m=13\), donc \(L\) a cardinal \(2^{m-12}\cdot 16 = 32\)) ; - domaine \(L\) : la liste explicite des relèvements impairs de \(B_{12}(E_1)\) au palier \(m\) (pour un premier essai : \(m=13\), donc \(L\) a cardinal \(2^{m-12}\cdot 16 = 32\)) ;
- certificats produits : `certificat_D8_palier2p13.json` et/ou `certificat_Ft_palier2p13.json` (selon les horizons retenus), obtenus par les scripts existants `collatz_k_pipeline.py` (pour D) et `collatz_fusion_pipeline.py` + `collatz_scission.py` (pour F) appliqués à \(L\) ; - certificats produits : `certificat_D8_palier2p<m>.json` et/ou `certificat_Ft*_palier2p<m>.json` (selon les horizons retenus), obtenus par les scripts existants `collatz_k_pipeline.py` (pour D) et `collatz_fusion_pipeline.py` + `collatz_scission.py` (pour F) appliqués à \(L\) ;
- assertion (H6) : lunion des ensembles `covered` de ces certificats recouvre exactement \(L\). - assertion (H6) : lunion des ensembles `covered` de ces certificats recouvre exactement \(L\).
Note (versionnement, flux standard). Note (versionnement, flux standard).
Les artefacts locaux produits pour H6(E1) ne peuvent pas être versionnés dans `applications/collatz/out/` car ce répertoire est ignoré par Git. Une copie canonique (versionnée) est donc placée dans : Les artefacts locaux produits pour H6(E1) ne peuvent pas être versionnés dans `applications/collatz/out/` car ce répertoire est ignoré par Git. Une copie canonique (versionnée) est donc placée dans :
- `docs/artefacts/collatz/local_E1_palier2p13/` - `docs/artefacts/collatz/local_E1_palier2p<m>/` (par exemple `.../local_E1_palier2p15/`)
et sert de base pour les rapports dexécution générés. et sert de base pour les rapports dexécution générés.
@ -205,12 +205,11 @@ Un index versionné agrège \(\Delta m(E)\) et les horizons minimaux observés p
- `docs/artefacts/collatz/local_H6_index.md` - `docs/artefacts/collatz/local_H6_index.md`
Constats (à partir de lindex, palier cible \(2^{13}\)). Constats (à partir de lindex, palier cible \(2^{15}\)).
Les artefacts versionnés montrent, pour les 60 états \(E\) de \(B_{12}\) : Les artefacts versionnés montrent, pour les 60 états \(E\) de \(B_{12}\) :
- \(\Delta m(E)=1\) (donc relèvement \(12\to 13\)) ; - \(\Delta m(E)=3\) (donc relèvement \(12\to 15\)) ;
- lhorizon maximal observé pour la complétude par fusion est \(t_{\max}=51\) (états \(E9\) et \(E25\)) ; - lhorizon maximal observé pour la complétude par fusion est \(t_{\max,\mathrm{used}}=64\).
- certains états sont complets par D8 seul (pas de clause de fusion observée sur le complément après D8 : \(E56\), \(E57\), \(E58\)).
Ces constats sont des assertions daudit (égalité densembles sur artefacts) et ne remplacent pas la preuve des hypothèses (H4)(H5). Ces constats sont des assertions daudit (égalité densembles sur artefacts) et ne remplacent pas la preuve des hypothèses (H4)(H5).

View File

@ -73,7 +73,7 @@ Cette trajectoire isole une chaîne de vérifications citable (sans transcript)
- C1 (complétude locale H6(E) sur les états de \(B_{12}\)) : - C1 (complétude locale H6(E) sur les états de \(B_{12}\)) :
- index : `docs/artefacts/collatz/local_H6_index.md` - index : `docs/artefacts/collatz/local_H6_index.md`
- rapports : `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p13.md`, `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p14.md` - rapports : `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p13.md`, `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p14.md`, `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p15.md`
- C2 (réduction projective par complétion “one” et stabilité \(B_m\bmod 2^{12}=B_{12}\)) : - C2 (réduction projective par complétion “one” et stabilité \(B_m\bmod 2^{12}=B_{12}\)) :
- script : `applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py` - script : `applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py`
@ -84,15 +84,16 @@ Cette trajectoire isole une chaîne de vérifications citable (sans transcript)
- `applications/collatz/collatz_k_scripts/complétion_minorée_m15_vers_m16.md` - `applications/collatz/collatz_k_scripts/complétion_minorée_m15_vers_m16.md`
- `applications/collatz/collatz_k_scripts/complétion_minorée_m16_vers_m17.md` - `applications/collatz/collatz_k_scripts/complétion_minorée_m16_vers_m17.md`
- C3 (instance locale au palier \(2^{13}\) sur \(L=\mathrm{Lift}_{12\to 13}(B_{12})\)) : - C3 (instance locale au palier \(2^{m}\) sur \(L=\mathrm{Lift}_{12\to m}(B_{12})\), \(m\ge 13\)) :
- script : `applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py` - script : `applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py`
- sorties : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent.{json,md}` et `..._palier2p<m>.{json,md}` - sorties : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent.{json,md}` et `..._palier2p<m>.{json,md}`
- rapports : `docs/collatz_run_report_2026-03-09_c3_local_descent.md`, `docs/collatz_run_report_2026-03-09_c3_local_descent_palier2p14.md` - rapports : `docs/collatz_run_report_2026-03-09_c3_local_descent.md`, `docs/collatz_run_report_2026-03-09_c3_local_descent_palier2p14.md`, `docs/collatz_run_report_2026-03-09_c3_local_descent_palier2p15.md`
- Extraction de clauses universelles candidates (Option A : Lift(\(B_{12}\))) : - Extraction de clauses universelles candidates (Option A : Lift(\(B_{12}\))) :
- scripts : `applications/collatz/collatz_k_scripts/{collatz_extract_universal_clauses.py,collatz_verify_universal_clauses.py}` - scripts : `applications/collatz/collatz_k_scripts/{collatz_extract_universal_clauses.py,collatz_verify_universal_clauses.py}`
- sorties : `docs/artefacts/collatz/universal_clauses/{clauses_universelles,verification_universal_clauses}.{json,md}` et `docs/artefacts/collatz/universal_clauses/palier2p14/*` - stabilisation : pour un témoin au palier \(m\) avec somme \(A\), la clause candidate est indexée par \(m_{stable}=\max(m,A+1)\)
- rapports : `docs/collatz_run_report_2026-03-09_universal_clauses.md`, `docs/collatz_run_report_2026-03-09_universal_clauses_palier2p14.md` - sorties : `docs/artefacts/collatz/universal_clauses/{clauses_universelles,verification_universal_clauses}.{json,md}` et `docs/artefacts/collatz/universal_clauses/palier2p14/*`, `docs/artefacts/collatz/universal_clauses/palier2p15/*`
- rapports : `docs/collatz_run_report_2026-03-09_universal_clauses.md`, `docs/collatz_run_report_2026-03-09_universal_clauses_palier2p14.md`, `docs/collatz_run_report_2026-03-09_universal_clauses_palier2p15.md`
Le verrou restant est la transformation des témoins observés en clauses universelles valides “pour tout \(n\) dans une classe modulo \(2^m\), pour tout \(n\ge N\)”, et litération du schéma \(C1+C2\to C3\) à paliers arbitraires. La formalisation minimale visée est donnée dans : Le verrou restant est la transformation des témoins observés en clauses universelles valides “pour tout \(n\) dans une classe modulo \(2^m\), pour tout \(n\ge N\)”, et litération du schéma \(C1+C2\to C3\) à paliers arbitraires. La formalisation minimale visée est donnée dans :
- `applications/collatz/collatz_k_scripts/plan_lemmes_manquants_et_programme_de_preuve.md`. - `applications/collatz/collatz_k_scripts/plan_lemmes_manquants_et_programme_de_preuve.md`.
@ -175,6 +176,47 @@ on a \(m<n\) dès que \(n\ge N_F\).
La congruence \(y\equiv 2 \pmod 3\) assure l'intégralité de \((2y-1)/3\). Ensuite \(U(m)=y\) par construction de la branche impaire avec une seule division par 2. La borne \(m<n\) se réduit à une inégalité affine en \(n\), équivalente à \(\Delta_F n > 2C_k+1\). \(\square\) La congruence \(y\equiv 2 \pmod 3\) assure l'intégralité de \((2y-1)/3\). Ensuite \(U(m)=y\) par construction de la branche impaire avec une seule division par 2. La borne \(m<n\) se réduit à une inégalité affine en \(n\), équivalente à \(\Delta_F n > 2C_k+1\). \(\square\)
### Lemme 4 (Stabilité dun préfixe au module \(2^{m_{stable}}\))
**Hypothèses.**
- \(n_0\) impair, \(k\ge 1\);
- on fixe un mot \(w=(a_0,\dots,a_{k-1})\) et lon suppose que \(n_0\) réalise ce préfixe, cest-à-dire
\[
\forall i\in\{0,\dots,k-1\},\quad a_i=v_2(3n_i+1)\ \text{avec}\ n_{i+1}=U(n_i);
\]
- on note \(A:=\sum_{i=0}^{k-1} a_i\) et \(C_k\) la constante affine associée à \(w\) (lemme 1);
- on fixe un palier de domaine \(m_{\mathrm{dom}}\ge 1\) tel que \(n_0\) est interprété comme une classe modulo \(2^{m_{\mathrm{dom}}}\);
- on pose
\[
m_{stable}:=\max(m_{\mathrm{dom}},A+1).
\]
**Énoncé.**
Il existe un résidu unique \(r\in S_{m_{stable}}\) tel que \(r\equiv n_0\pmod{2^{m_{\mathrm{dom}}}}\) et tel que, pour tout impair \(n\) vérifiant \(n\equiv r\pmod{2^{m_{stable}}}\), on a :
1) le préfixe de valuations est constant et vaut \(w\) :
\[
\forall i\in\{0,\dots,k-1\},\quad v_2(3n_i+1)=a_i;
\]
2) les constantes affines sont identiques :
\[
U^{(k)}(n)=\frac{3^k n + C_k}{2^A},
\]
et \(A_k(n)=A\), \(C_k(n)=C_k\).
**Preuve.**
Pour chaque \(i\), la condition \(v_2(3n_i+1)=a_i\) est équivalente à une conjonction de congruences modulo des puissances de 2 ne dépassant pas \(2^{A+1}\) :
\[
3n_i+1\equiv 0\pmod{2^{a_i}}\quad\text{et}\quad 3n_i+1\not\equiv 0\pmod{2^{a_i+1}}.
\]
En réécrivant \(n_i\) sous la forme affine en fonction de \(n\) (lemme 1 appliqué aux préfixes \(<i\)), ces conditions deviennent des contraintes congruentielles sur \(n\) modulo une puissance de 2 dexposant \(\le A+1\). Ainsi, lensemble des impairs réalisant le préfixe \(w\) est une classe modulo \(2^{A+1}\). En imposant en outre la contrainte de domaine \(n\equiv n_0\pmod{2^{m_{\mathrm{dom}}}}\) et en prenant \(m_{stable}=\max(m_{\mathrm{dom}},A+1)\), on obtient une classe modulo \(2^{m_{stable}}\) qui fixe simultanément les \(m_{\mathrm{dom}}\) premiers bits et le préfixe \(w\). Lunicité du résidu \(r\) est immédiate.
Les égalités sur \(A_k\), \(C_k\) et \(U^{(k)}\) résultent alors du fait que \(w\) fixe \(A\) et \(C_k\) (lemme 1). \(\square\)
## Théorème-cadre conditionnel ## Théorème-cadre conditionnel
### Théorème 1 (Certificat fini \((K)\Rightarrow\) terminaison globale) ### Théorème 1 (Certificat fini \((K)\Rightarrow\) terminaison globale)
@ -186,6 +228,84 @@ La congruence \(y\equiv 2 \pmod 3\) assure l'intégralité de \((2y-1)/3\). Ensu
- (H3) chaque clause applicable produit une réduction stricte: soit \(U^{(k)}(n)<n\), soit \(U^{(k)}(n)=U(m)\) avec \(m<n\); - (H3) chaque clause applicable produit une réduction stricte: soit \(U^{(k)}(n)<n\), soit \(U^{(k)}(n)=U(m)\) avec \(m<n\);
- (H4) pour tout \(1\le n\le N^\ast\), la trajectoire atteint \(1\). - (H4) pour tout \(1\le n\le N^\ast\), la trajectoire atteint \(1\).
**Formalisation de (H2) : couverture modulaire au palier \(2^M\).**
On note \(\mathcal{K}\) un ensemble fini de clauses universelles de type \(D/F\). Chaque clause \(c\in\mathcal{K}\) est indexée par un module \(2^{m(c)}\), un résidu \(r(c)\in S_{m(c)}\) et un seuil \(N(c)\), et elle sapplique à tout impair \(n\) vérifiant :
\[
n\equiv r(c)\pmod{2^{m(c)}}\quad\text{et}\quad n\ge N(c).
\]
On dit que \(\mathcal{K}\) **couvre modulo** \(2^M\) (au-delà dun seuil \(N^\ast\)) si :
\[
\forall n\in 2\mathbb{N}+1,\quad n>N^\ast\ \Longrightarrow\ \exists c\in\mathcal{K},\ \bigl(n\equiv r(c)\!\!\!\pmod{2^{m(c)}}\ \wedge\ n\ge N(c)\bigr),
\]
avec la contrainte \(m(c)\le M\) pour que lapplicabilité soit décidée par la classe modulo \(2^M\).
Dans linstrumentation par témoins (C3 \(\to\) clauses candidates), le module \(2^{m(c)}\) est pris égal à \(2^{m_{stable}}\) où \(m_{stable}=\max(m_{\mathrm{dom}},A+1)\) (lemme 4). Lobligation de preuve associée à (H2) devient alors :
- exhiber un \(M\) et une famille finie \(\mathcal{K}\) telle que \(m(c)\le M\) pour tout \(c\in\mathcal{K}\),
- établir légalité densembles au niveau des classes modulo \(2^M\) (au-delà des seuils) entre les impairs et lunion des classes définies par les clauses de \(\mathcal{K}\).
**Version indexée par artefacts (registre + audit fini).**
Une matérialisation déterministe de \(\mathcal{K}_M\) et de laudit fini de couverture sur le domaine instrumenté \(L\) est produite par :
- script : `applications/collatz/collatz_k_scripts/collatz_build_register_K_modular.py --palier M`
- sorties : `docs/artefacts/collatz/register_K/palier2pM/{register_K_mod2pM,audit_register_K_mod2pM,non_eligible_clauses_mod2pM,manifest_register_K_mod2pM}.{json,md}`.
- exemple concret (palier \(2^{15}\)) :
- `docs/artefacts/collatz/register_K/palier2p15/register_K_mod2p15.{json,md}`
- `docs/artefacts/collatz/register_K/palier2p15/audit_register_K_mod2p15.{json,md}`
- `docs/artefacts/collatz/register_K/palier2p15/non_eligible_clauses_mod2p15.{json,md}`
- `docs/artefacts/collatz/register_K/palier2p15/manifest_register_K_mod2p15.{json,md}`
**Variante (H2) : couverture décidée par raffinement fini de lobservabilité.**
On fixe la projection \(\pi_M:2\mathbb{N}+1\to S_M\), \(\pi_M(n)=n\bmod 2^M\). La contrainte \(m(c)\le M\) impose une décidabilité “directe” à la granularité \(2^M\). Lorsque les clauses extraites ont typiquement \(m(c)>M\) (par exemple \(m(c)=m_{stable}=\max(M,A+1)\) avec \(A\) grand), une alternative consiste à décider lapplicabilité par un **raffinement fini** de la classe \(\pi_M(n)\) vers un module plus fin, puis appliquer une clause terminale \(D/F\).
### Définition 6 (Arbre de raffinement modulo \(2^M\) — domaine instrumenté)
**Hypothèses.**
- \(M\ge 1\) et \(L\subset 2\mathbb{N}+1\) est un domaine fini (par exemple \(L=\mathrm{Lift}_{12\to M}(B_{12})\) dans (C3));
- \(\mathcal{K}\) est une famille finie de clauses terminales \(D/F\), chacune indexée par \((m(c),r(c),N(c))\) comme ci-dessus, sans contrainte a priori \(m(c)\le M\).
**Énoncé.**
Un **arbre de raffinement** pour une classe \(r\in S_M\) est un arbre binaire fini \(T(r)\) tel que :
1) chaque nœud interne est étiqueté par une paire \((m,r_m)\) avec \(m\ge M\) et \(r_m\in S_m\), et a exactement deux enfants correspondant aux deux relèvements \(r_m\) et \(r_m+2^m\) dans \(S_{m+1}\);
2) chaque feuille est étiquetée par une clause \(c\in\mathcal{K}\) telle que \(m(c)=m_\ell\) et \(r(c)=r_{m_\ell}\) (la feuille “ferme” la branche);
3) la racine est \((M,r)\).
On dit quun tel arbre **certifie** la classe \(r\) (au-delà dun seuil \(N^\*\)) si \(N^\*\ge \max_{\ell\in\mathrm{Leaves}(T(r))} N(c_\ell)\).
### Proposition 2 (Décidabilité par raffinement fini, version instrumentée)
**Hypothèses.**
- hypothèses de la définition 6;
- pour chaque \(n\in L\), il existe un arbre \(T(\pi_M(n))\) dont la branche suivie par les bits 2adiques de \(n\) aboutit à une feuille \(c_n\in\mathcal{K}\);
- \(N^\*\) majore les seuils des feuilles comme ci-dessus.
**Énoncé.**
Pour tout \(n\in L\) vérifiant \(n\ge N^\*\), la procédure déterministe “raffiner \(\pi_M(n)\) jusquà la feuille, puis appliquer la clause terminale” produit une réduction stricte au sens de (H3).
**Preuve.**
Le raffinement ne fait quexpliciter la congruence \(n\bmod 2^{m(c_n)}=r(c_n)\) le long de la branche. Comme \(n\ge N^\*\ge N(c_n)\), la clause terminale est applicable et fournit une réduction stricte (lemme 2 ou lemme 3 selon le type). \(\square\)
**Version indexée par artefacts (raffinement sur \(L\) au palier \(2^{15}\)).**
Une matérialisation déterministe de chemins de raffinement (depuis \(\pi_{15}(n)\) jusquau module \(2^{m_{stable}}\) de la clause terminale) sur le domaine instrumenté \(L\) est produite par :
- script : `applications/collatz/collatz_k_scripts/collatz_build_refinement_certificate_modular.py --palier 15`
- sorties : `docs/artefacts/collatz/refinement_K/palier2p15/{refinement_certificate_mod2p15,audit_refinement_certificate_mod2p15}.{json,md}`.
**Version indexée par artefacts (raffinement sur \(S_M\), \(M=15\)).**
Une matérialisation déterministe de la fermeture (ou nonfermeture) de classes racines \(r\in S_{15}\) par raffinement fini (avec feuilles \(D/F\) extraites) est produite par :
- script : `applications/collatz/collatz_k_scripts/collatz_build_refinement_certificate_over_Sm.py --palier 15`
- sorties : `docs/artefacts/collatz/refinement_K/palier2p15/{refinement_certificate_Sm_mod2p15,audit_refinement_certificate_Sm_mod2p15}.{json,md}`.
**Version indexée par artefacts (raffinement multiniveaux sur \(S_{15}\to S_{16}\)).**
Une matérialisation déterministe de la fermeture de \(S_{15}\) par raffinement sur un niveau supplémentaire (feuilles directement décidables à \(2^{15}\) et \(2^{16}\)) est produite par :
- script : `applications/collatz/collatz_k_scripts/collatz_generate_terminal_clauses_over_Sm.py --palier 15` et `... --palier 16`
- script : `applications/collatz/collatz_k_scripts/collatz_build_refinement_certificate_over_Sm_multilevel.py --root-palier 15 --max-palier 16`
- sorties : `docs/artefacts/collatz/refinement_K/palier2p15/{refinement_certificate_Sm_multilevel_mod2p15_to2p16,audit_refinement_certificate_Sm_multilevel_mod2p15_to2p16}.{json,md}`.
**Analyse ciblée (racines ouvertes).**
Un profil dobstruction des racines encore ouvertes après raffinement jusquà \(2^{M_{\max}}\) (avec borne inférieure “première profondeur possible”) est produit par :
- script : `applications/collatz/collatz_k_scripts/collatz_analyze_open_roots_refinement.py --root-palier 15 --max-palier M_max`
- sorties : `docs/artefacts/collatz/refinement_K/palier2p15/open_roots_obstruction_profile_mod2p15_to2pM_max.{json,md}`.
**Énoncé.** **Énoncé.**
La conjecture de Collatz est vraie. La conjecture de Collatz est vraie.
@ -2327,6 +2447,32 @@ et la clause universelle est :
\forall n,\ C(n)\ \wedge\ n\ge N_0 \Rightarrow U^{(k)}(n)<n. \forall n,\ C(n)\ \wedge\ n\ge N_0 \Rightarrow U^{(k)}(n)<n.
] ]
### Lemme (validité dune clause (D) minorée, version congruentielle)
**Hypothèses.**
- Un horizon \(k\ge 2\) et un palier \(2^m\).
- Une condition \(C(n)\) de la forme :
1) *préfixe stabilisé*: \(n \equiv r \pmod{2^m}\) impose un mot de valuations fixé de longueur \(k-1\), donc fixe \(A_{k-1}\) et \(C_{k-1}\) (par la stabilité du préfixe) ;
2) on pose \(B_k=3C_{k-1}+2^{A_{k-1}}\), de sorte que \(3U^{(k-1)}(n)+1=(3^k n + B_k)/2^{A_{k-1}}\) ;
3) *divisibilité*: \(n \equiv r \pmod{2^m}\) implique \(v_2(3^k n + B_k)\ge \underline A\), avec \(\underline A\le m\).
**Conclusion.**
Si \(2^{\underline A}>3^k\), en posant
\[
N_0=\left\lfloor \frac{B_k}{2^{\underline A}-3^k}\right\rfloor +1,
\]
on a
\[
\forall n,\ C(n)\ \wedge\ n\ge N_0 \Rightarrow U^{(k)}(n)<n.
\]
**Preuve.**
Sous \(C(n)\), on a \(A(n)\ge \underline A\) et \(v_2(3^k n + B_k)\ge \underline A\), donc lexpression affine \(3^k n + B_k\) est divisible par \(2^{\underline A}\) et
\[
U^{(k)}(n)=\frac{3^k n + B_k}{2^{A(n)}} \le \frac{3^k n + B_k}{2^{\underline A}}.
\]
Si \(n\ge N_0\), alors \(B_k < (2^{\underline A}-3^k)n\), donc \((3^k n + B_k)/2^{\underline A}<n\), d \(U^{(k)}(n)<n\).
Point conceptuel Point conceptuel
Cette clause nexige pas que la dernière valuation soit figée “au bit près”. Une minoration suffit. Cest précisément le mécanisme qui ferme plus tôt les sommets. Cette clause nexige pas que la dernière valuation soit figée “au bit près”. Une minoration suffit. Cest précisément le mécanisme qui ferme plus tôt les sommets.

View File

@ -128,18 +128,23 @@ Pour chaque état \(E\) (mot de valuations sur \(B_{12}\) à horizon fixé), ét
Artefacts (H6 locale). Artefacts (H6 locale).
- index agrégé : `docs/artefacts/collatz/local_H6_index.md` - index agrégé : `docs/artefacts/collatz/local_H6_index.md`
- répertoires par état : `docs/artefacts/collatz/local_E*_palier2p13/`, `docs/artefacts/collatz/local_E*_palier2p14/` - répertoires par état : `docs/artefacts/collatz/local_E*_palier2p13/`, `docs/artefacts/collatz/local_E*_palier2p14/`, `docs/artefacts/collatz/local_E*_palier2p15/`
- rapports dexécution : `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p13.md`, `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p14.md` - rapports dexécution : `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p13.md`, `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p14.md`, `docs/collatz_run_report_2026-03-09_local_H6_E*_palier2p15.md`
6.3. C3 (instance locale : clôture sur Lift(\(B_{12}\)) au palier \(2^{13}\)) Constats daudit (index agrégé, palier \(2^{15}\)).
Les artefacts versionnés indiquent :
- \(\Delta m(E)=3\) pour les 60 états \(E\) (relèvement \(12\to 15\)) ;
- \(\max_E\ t_{\max,\mathrm{used}}(E)=64\) dans la complétude par fusion.
6.3. C3 (instance locale : clôture sur Lift(\(B_{12}\)) au palier \(2^{m}\))
But. But.
Sur le domaine \(L=\mathrm{Lift}_{12\to 13}(B_{12})\), exhiber pour chaque classe un témoin \(D\) (descente exacte ou frère) ou \(F\) (fusion vers un impair strictement plus petit) et fermer linstance par validation de base finie. Sur le domaine \(L=\mathrm{Lift}_{12\to m}(B_{12})\) (pour un palier \(m\ge 13\)), exhiber pour chaque classe un témoin \(D\) (descente exacte ou frère) ou \(F\) (fusion vers un impair strictement plus petit) et fermer linstance par validation de base finie.
Artefact déterministe (C3 local). Artefact déterministe (C3 local).
- script : `applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py` - script : `applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py`
- sorties versionnées : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent.{json,md}` et `..._palier2p<m>.{json,md}` - sorties versionnées : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent.{json,md}` et `..._palier2p<m>.{json,md}`
- rapports dexécution : `docs/collatz_run_report_2026-03-09_c3_local_descent.md`, `docs/collatz_run_report_2026-03-09_c3_local_descent_palier2p14.md` - rapports dexécution : `docs/collatz_run_report_2026-03-09_c3_local_descent.md`, `docs/collatz_run_report_2026-03-09_c3_local_descent_palier2p14.md`, `docs/collatz_run_report_2026-03-09_c3_local_descent_palier2p15.md`
6.4. Verrou formel restant (au-delà de \(2^{13}\)) 6.4. Verrou formel restant (au-delà de \(2^{13}\))
@ -150,20 +155,52 @@ La formalisation minimale de ces clauses universelles (formes D/F, seuils \(N_0/
6.5. Extraction déterministe de clauses universelles candidates (Option A : Lift(\(B_{12}\))) 6.5. Extraction déterministe de clauses universelles candidates (Option A : Lift(\(B_{12}\)))
À partir de lartefact déterministe C3 (témoins locaux sur \(L=\mathrm{Lift}_{12\to 13}(B_{12})\)), une procédure de relèvement transforme chaque témoin \(D\) exact ou \(F\) en une clause candidate stabilisée au module minimal \(2^{A+1}\) où le préfixe de valuations est figé. À partir de lartefact déterministe C3 (témoins locaux sur un domaine \(L=\mathrm{Lift}_{12\to m}(B_{12})\)), une procédure de relèvement transforme chaque témoin \(D\) exact ou \(F\) en une clause candidate stabilisée au module \(2^{m_{stable}}\), avec \(m_{stable}=\max(m,A+1)\), où le préfixe de valuations est figé.
Artefacts déterministes : Artefacts déterministes :
- extraction : `applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses.py` - extraction : `applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses.py`
- vérification : `applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py` - vérification : `applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py`
- sorties versionnées : `docs/artefacts/collatz/universal_clauses/{clauses_universelles,verification_universal_clauses}.{json,md}` et `docs/artefacts/collatz/universal_clauses/palier2p14/*` - sorties versionnées : `docs/artefacts/collatz/universal_clauses/{clauses_universelles,verification_universal_clauses}.{json,md}` et `docs/artefacts/collatz/universal_clauses/palier2p14/*`, `docs/artefacts/collatz/universal_clauses/palier2p15/*`
- rapports dexécution : `docs/collatz_run_report_2026-03-09_universal_clauses.md`, `docs/collatz_run_report_2026-03-09_universal_clauses_palier2p14.md` - rapports dexécution : `docs/collatz_run_report_2026-03-09_universal_clauses.md`, `docs/collatz_run_report_2026-03-09_universal_clauses_palier2p14.md`, `docs/collatz_run_report_2026-03-09_universal_clauses_palier2p15.md`
6.6. Protocole déterministe ditération de palier (au-delà de \(2^{13}\)) 6.6. Protocole déterministe ditération de palier (au-delà de \(2^{13}\))
Pour organiser litération \(2^m\to 2^{m+1}\) (C1→C2→C3) à partir des artefacts versionnés, un protocole déterministe produit un état courant (paliers certifiés, transitions C2 disponibles) et une checklist de commandes reproductibles pour un palier cible. Pour organiser litération \(2^m\to 2^{m+1}\) (C1→C2→C3) à partir des artefacts versionnés, un protocole déterministe produit un état courant (paliers certifiés, transitions C2 disponibles) et une checklist de commandes reproductibles pour un palier cible.
- script : `applications/collatz/collatz_k_scripts/collatz_iterate_palier_protocol.py` - script : `applications/collatz/collatz_k_scripts/collatz_iterate_palier_protocol.py`
- sorties : `docs/artefacts/collatz/iteration_protocol/{iteration_protocol.json,iteration_protocol.md}` - sorties : `docs/artefacts/collatz/iteration_protocol/palier2p<m>/{iteration_protocol.json,iteration_protocol.md}`
Le vérificateur C3 est paramétrable en palier : Le vérificateur C3 est paramétrable en palier :
- `applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py --palier m` - `applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py --palier m`
6.7. Clauses universelles (formes D/F) et compatibilité avec linduction bien fondée
Objectif.
Rendre explicite la forme “universelle” attendue des clauses, et linterface minimale requise pour les utiliser dans une preuve par descente bien fondée sur \(\mathbb{N}\).
Clause universelle D (descente exacte).
Une clause universelle D est indexée par \((m,k,A,C,N_0,r)\) et affirme :
\[
\forall n\in 2\mathbb{N}+1,\quad \bigl(n\equiv r \!\!\!\pmod{2^m}\ \wedge\ n\ge N_0\bigr)\ \Longrightarrow\ U^{(k)}(n)<n.
\]
Dans linstrumentation (Option A), le paramètre \(m\) est pris égal à \(m_{stable}=\max(m_{\mathrm{domaine}},A+1)\) et le résidu \(r\) est un représentant canonique relevé au palier \(m_{stable}\) ; lassertion à établir est que, sur la classe modulo \(2^{m_{stable}}\), le préfixe de valuations de longueur \(k\) est constant et égale le mot observé sur le témoin. Cette assertion est formalisée par le **lemme 4** de `applications/collatz/conjoncture_collatz.md`.
Clause universelle F (fusion).
Une clause universelle F est indexée par \((m,t,A,C,a,y,N_F,r)\) et affirme :
\[
\forall n\in 2\mathbb{N}+1,\quad \bigl(n\equiv r \!\!\!\pmod{2^m}\ \wedge\ n\ge N_F\bigr)\ \Longrightarrow\ \exists m'<n,\ U(m')=U^{(t)}(n),
\]
où \(m'\) est une préimage courte calculable à partir de \(y:=U^{(t)}(n)\) (dans les artefacts actuels : \(a=1\) et \(m'=(2y-1)/3\)). Ici aussi, \(m=m_{stable}=\max(m_{\mathrm{domaine}},A+1)\) est choisi pour figer le préfixe de valuations dhorizon \(t\). La stabilité du préfixe au module \(2^{m_{stable}}\) est formalisée par le **lemme 4** de `applications/collatz/conjoncture_collatz.md`.
Compatibilité avec linduction bien fondée.
Une famille finie de clauses universelles \(\mathcal{K}\) est compatible avec une preuve par bon ordre si elle satisfait :
- (I1) **Couverture** : il existe \(M\) et \(N^\ast\) tels que tout impair \(n>N^\ast\) satisfait la prémisse dau moins une clause de \(\mathcal{K}\) via sa classe modulo \(2^M\) ;
- (I2) **Réduction stricte** : toute clause applicable produit un entier impair strictement plus petit (descente D) ou un impair \(m'<n\) fusionné vers le même successeur accéléré (fusion F) ;
- (I3) **Base finie** : pour tout impair \(1\le n\le N^\ast\), la trajectoire atteint \(1\).
Statut (au regard des artefacts).
Les scripts dextraction/vérification produisent des clauses candidates et vérifient la cohérence arithmétique (constantes affines, seuils, relèvements) sur le domaine instrumenté, mais (I1)(I3) restent des obligations de preuve pour conclure globalement.
Point de passage “instance locale \(\to\) couverture modulo \(2^M\)”.
La formalisation opérationnelle de (I1) (couverture modulaire au palier \(2^M\)) et la contrainte \(m(c)\le M\) pour les clauses applicables par classes modulo \(2^M\) sont précisées dans la **formalisation de (H2)** sous le Théorème 1 de `applications/collatz/conjoncture_collatz.md`.
Une matérialisation déterministe (registre \(\mathcal{K}_M\) + audit fini de couverture sur le domaine \(L\) + table nonéligibles + manifeste) est produite par `applications/collatz/collatz_k_scripts/collatz_build_register_K_modular.py`.

View File

@ -0,0 +1,31 @@
**Auteur** : Équipe 4NK
# Vérification déterministe — C3 (clôture locale par descente/fusion)
## Entrées
- ARTEFACTS ROOT : `docs/artefacts/collatz`
## Domaine
- palier : 2^15
- |L| (Lift(B12) à 2^15) : 1536
- min(L) : 27, max(L) : 32767
## Élimination (témoins)
- D : 180 (k variable, A_k<=14 ; descente vérifiée : 180, cas de base : 0)
- Fusion : 1356 (descente vérifiée : 1356, cas de base : 0)
- max(next) : 31959
- N* (max des seuils N0/Nf calculés) : 138
## Validation de base (finie)
- Trajectoires vérifiées jusquà : 32767
- Résultat : True (toutes atteignent 1)
## Sorties
- JSON : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json`
- Markdown : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.md`

View File

@ -0,0 +1,31 @@
**Auteur** : Équipe 4NK
# Vérification déterministe — C3 (clôture locale par descente/fusion)
## Entrées
- ARTEFACTS ROOT : `docs/artefacts/collatz`
## Domaine
- palier : 2^16
- |L| (Lift(B12) à 2^16) : 3072
- min(L) : 27, max(L) : 65535
## Élimination (témoins)
- D : 360 (k variable, A_k<=14 ; descente vérifiée : 360, cas de base : 0)
- Fusion : 2712 (descente vérifiée : 2712, cas de base : 0)
- max(next) : 63543
- N* (max des seuils N0/Nf calculés) : 217
## Validation de base (finie)
- Trajectoires vérifiées jusquà : 65535
- Résultat : True (toutes atteignent 1)
## Sorties
- JSON : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p16.json`
- Markdown : `docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p16.md`

View File

@ -78,6 +78,7 @@
"C3_run_report_palier": "python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile c3_local_descent_palier --c3-artefacts-dir docs/artefacts/collatz/c3_local_descent --c3-palier 15 --out-dir applications/collatz/out --docs-dir docs", "C3_run_report_palier": "python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile c3_local_descent_palier --c3-artefacts-dir docs/artefacts/collatz/c3_local_descent --c3-palier 15 --out-dir applications/collatz/out --docs-dir docs",
"Universal_clauses_extract": "python3 applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p15", "Universal_clauses_extract": "python3 applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p15",
"Universal_clauses_verify": "python3 applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json --clauses-json docs/artefacts/collatz/universal_clauses/palier2p15/clauses_universelles.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p15", "Universal_clauses_verify": "python3 applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json --clauses-json docs/artefacts/collatz/universal_clauses/palier2p15/clauses_universelles.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p15",
"Universal_clauses_run_report_palier": "python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile universal_clauses_palier --universal-clauses-artefacts-dir docs/artefacts/collatz/universal_clauses/palier2p15 --out-dir applications/collatz/out --docs-dir docs",
"C2_verify_projective": "python3 applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py --repo-root /home/ncantu/code/algo --output-dir docs/artefacts/collatz/c2_projective" "C2_verify_projective": "python3 applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py --repo-root /home/ncantu/code/algo --output-dir docs/artefacts/collatz/c2_projective"
} }
} }

View File

@ -51,6 +51,12 @@ python3 applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses
python3 applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json --clauses-json docs/artefacts/collatz/universal_clauses/palier2p15/clauses_universelles.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p15 python3 applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json --clauses-json docs/artefacts/collatz/universal_clauses/palier2p15/clauses_universelles.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p15
``` ```
- **Universal_clauses_run_report_palier** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile universal_clauses_palier --universal-clauses-artefacts-dir docs/artefacts/collatz/universal_clauses/palier2p15 --out-dir applications/collatz/out --docs-dir docs
```
- **C2_verify_projective** : - **C2_verify_projective** :
```bash ```bash

View File

@ -0,0 +1,84 @@
{
"inputs": {
"local_h6_root": "/home/ncantu/code/algo/docs/artefacts/collatz",
"c2_verification_json": "/home/ncantu/code/algo/docs/artefacts/collatz/c2_projective/verification_c2_projective.json",
"c3_verification_json": "/home/ncantu/code/algo/docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json"
},
"state": {
"c3_palier": 15,
"c2_max_child_palier": 17,
"target_palier": 16,
"local_h6_states_found": 1,
"local_h6_missing_state_ids": [
1,
2,
3,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60
]
},
"commands": {
"C1_local_H6_generate": "python3 applications/collatz/collatz_k_scripts/collatz_generate_local_h6_artefacts.py --docs-dir docs --output-root docs/artefacts/collatz --state-ids all --palier-start 16 --palier-max 16 --t-min 9 --t-max 120 --write-index --index-path docs/artefacts/collatz/local_H6_index.md",
"C1_local_H6_run_reports": "python3 applications/collatz/collatz_k_scripts/collatz_generate_local_h6_run_reports.py --out-dir applications/collatz/out --docs-dir docs --local-h6-root docs/artefacts/collatz --palier 16 --index-path docs/artefacts/collatz/local_H6_index.md",
"C3_verify_local_descent": "python3 applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py --local-h6-root docs/artefacts/collatz --output-dir docs/artefacts/collatz/c3_local_descent --palier 16",
"C3_run_report_palier": "python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile c3_local_descent_palier --c3-artefacts-dir docs/artefacts/collatz/c3_local_descent --c3-palier 16 --out-dir applications/collatz/out --docs-dir docs",
"Universal_clauses_extract": "python3 applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p16.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p16",
"Universal_clauses_verify": "python3 applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p16.json --clauses-json docs/artefacts/collatz/universal_clauses/palier2p16/clauses_universelles.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p16",
"Universal_clauses_run_report_palier": "python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile universal_clauses_palier --universal-clauses-artefacts-dir docs/artefacts/collatz/universal_clauses/palier2p16 --out-dir applications/collatz/out --docs-dir docs",
"C2_verify_projective": "python3 applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py --repo-root /home/ncantu/code/algo --output-dir docs/artefacts/collatz/c2_projective"
}
}

View File

@ -0,0 +1,69 @@
**Auteur** : Équipe 4NK
# Protocole déterministe — itération de palier (C1→C2→C3)
## État courant (artefacts)
- C3 palier certifié : 2^15 (daprès `/home/ncantu/code/algo/docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p15.json`)
- C2 transition max auditée : palier enfant 2^17 (daprès `/home/ncantu/code/algo/docs/artefacts/collatz/c2_projective/verification_c2_projective.json`)
## Palier cible
- palier cible : 2^16
- H6 locale présente (états) : 1/60
- états manquants : [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]
## Étapes (commandes reproductibles)
- **C1_local_H6_generate** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_generate_local_h6_artefacts.py --docs-dir docs --output-root docs/artefacts/collatz --state-ids all --palier-start 16 --palier-max 16 --t-min 9 --t-max 120 --write-index --index-path docs/artefacts/collatz/local_H6_index.md
```
- **C1_local_H6_run_reports** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_generate_local_h6_run_reports.py --out-dir applications/collatz/out --docs-dir docs --local-h6-root docs/artefacts/collatz --palier 16 --index-path docs/artefacts/collatz/local_H6_index.md
```
- **C3_verify_local_descent** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_verify_c3_local_descent.py --local-h6-root docs/artefacts/collatz --output-dir docs/artefacts/collatz/c3_local_descent --palier 16
```
- **C3_run_report_palier** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile c3_local_descent_palier --c3-artefacts-dir docs/artefacts/collatz/c3_local_descent --c3-palier 16 --out-dir applications/collatz/out --docs-dir docs
```
- **Universal_clauses_extract** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_extract_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p16.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p16
```
- **Universal_clauses_verify** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_verify_universal_clauses.py --verification-json docs/artefacts/collatz/c3_local_descent/verification_c3_local_descent_palier2p16.json --clauses-json docs/artefacts/collatz/universal_clauses/palier2p16/clauses_universelles.json --output-dir docs/artefacts/collatz/universal_clauses/palier2p16
```
- **Universal_clauses_run_report_palier** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_generate_run_report.py --profile universal_clauses_palier --universal-clauses-artefacts-dir docs/artefacts/collatz/universal_clauses/palier2p16 --out-dir applications/collatz/out --docs-dir docs
```
- **C2_verify_projective** :
```bash
python3 applications/collatz/collatz_k_scripts/collatz_verify_c2_projective.py --repo-root /home/ncantu/code/algo --output-dir docs/artefacts/collatz/c2_projective
```
## Notes
- Pour `C3_verify_local_descent` : si `palier != 13`, les sorties attendues sont suffixées `..._palier2p<m>.{json,md}`.
- Les rapports C3 par palier sont générés via le profil `c3_local_descent_palier` (nom de fichier déterministe).

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E10) — couverture des relèvements au palier \(2^{15}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/noyaux/noyau_E10_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/noyaux/noyau_Lift_E10_palier2p15.json`
- taille : 32
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/certificats/certificat_D8_E10_palier2p15.json`
- covered : 2 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/certificats/certificat_F9to32_E10_palier2p15.json`
- covered : 30 classes
## Résultat
- |L| = 32
- |U| = 32
- |L \ U| = 0

View File

@ -0,0 +1,3 @@
classe_mod_2^m,sœur,A8,palier
5439,21823,13,15
21823,5439,13,15
1 classe_mod_2^m sœur A8 palier
2 5439 21823 13 15
3 21823 5439 13 15

View File

@ -0,0 +1,31 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,7487,15,9,1,16,1 1 1 1 1 3 1 2 5,23843,2249,2,157242,1,1499,10,3391
9,13631,15,9,1,15,1 1 1 1 1 3 1 5 1,38179,8189,2,58938,1,5459,10,1343
9,17727,15,9,1,15,1 1 1 1 1 3 1 3 3,25891,10649,2,58938,1,7099,10,1343
9,18751,15,9,1,25,1 1 1 1 1 3 1 1 15,22819,11,2,100623930,1,7,10,2367
9,23871,15,9,1,14,1 1 1 1 1 3 1 2 3,23843,28679,2,9786,4,19119,10,3391
9,30015,15,9,1,19,1 1 1 1 1 3 1 7 3,87331,1127,2,1533498,1,751,10,1343
10,2367,15,10,1,17,1 1 1 1 1 3 1 1 4 3,84841,1067,2,275118,1,711,10,2367
10,10559,15,10,1,16,1 1 1 1 1 3 1 1 3 3,76649,9515,2,78510,2,6343,10,2367
11,20799,15,11,1,21,1 1 1 1 1 3 1 1 1 1 9,215611,1757,2,5937162,1,1171,10,319
11,22847,15,11,1,22,1 1 1 1 1 3 1 1 2 1 9,225851,965,2,12228618,1,643,10,2367
11,26943,15,11,1,23,1 1 1 1 1 3 1 1 3 1 9,246331,569,2,24811530,1,379,10,2367
11,32063,15,11,1,20,1 1 1 1 1 3 1 2 2 2 5,271931,5417,2,2791434,1,3611,10,3391
13,319,15,13,2,23,1 1 1 1 1 3 1 1 1 4 2 2 4,3116051,61,1,18788532,1,81,10,319
13,11583,15,13,1,21,1 1 1 1 1 3 1 2 1 1 3 2 3,2574355,8807,2,3102810,1,5871,10,3391
13,15679,15,13,1,21,1 1 1 1 1 3 1 2 2 1 2 2 3,2758675,11921,2,3102810,2,7947,10,3391
14,1343,15,14,1,23,1 1 1 1 1 3 1 3 2 1 1 1 3 3,10534969,767,2,15599886,1,511,10,1343
14,6463,15,14,2,24,1 1 1 1 1 3 1 1 2 1 1 4 2 4,8080441,1843,1,31199772,1,2457,10,2367
14,9535,15,14,2,24,1 1 1 1 1 3 1 3 1 2 2 2 1 4,11640889,2719,1,31199772,1,3625,10,1343
14,12607,15,14,2,23,1 1 1 1 1 3 1 1 1 1 1 4 2 4,6812729,7189,1,6033948,4,9585,10,319
14,14655,15,14,1,23,1 1 1 1 1 3 1 1 2 3 1 2 2 3,9186361,8357,2,15599886,1,5571,10,2367
14,16703,15,14,1,22,1 1 1 1 1 3 1 1 1 3 1 2 2 3,7365689,19049,2,3016974,4,12699,10,319
17,4415,15,17,2,28,1 1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4,271524355,2125,1,288745716,3,2833,10,319
18,3391,15,18,2,29,1 1 1 1 1 3 1 2 1 3 2 2 1 1 1 2 1 4,1053985289,2449,1,60930780,61,3265,10,3391
18,8511,15,18,1,28,1 1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4 1,930665993,12287,2,30465390,53,8191,10,319
19,25919,15,19,2,31,1 1 1 1 1 3 1 3 1 1 1 2 2 1 1 2 1 1 6,2393134619,14029,1,1793405076,5,18705,10,1343
22,27967,15,22,2,38,1 1 1 1 1 3 1 2 1 1 1 1 1 1 1 1 3 1 2 4 3 6,51062787289,3193,1,699109482396,1,4257,10,3391
26,24895,15,26,2,42,1 1 1 1 1 3 1 1 1 2 1 1 1 1 1 1 1 3 1 1 3 3 2 2 1 6,3741452025001,14389,1,3026676219996,4,19185,10,319
27,19775,15,27,1,44,1 1 1 1 1 3 1 2 1 2 1 2 2 1 2 2 1 1 3 1 1 1 1 1 3 4 3,21620693160443,8573,2,37525363163274,1,5715,10,3391
31,28991,15,31,1,49,1 1 1 1 1 3 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 3 1 1 3 3 3 4 1 2 3,1031536617448555,31811,2,453503067696042,4,21207,10,319
32,31039,15,32,2,54,1 1 1 1 1 3 1 1 2 2 1 1 1 1 1 1 1 3 5 1 1 1 1 1 1 2 1 1 2 4 3 6,4080799003682113,3193,1,46631114773038588,1,4257,10,2367
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 7487 15 9 1 16 1 1 1 1 1 3 1 2 5 23843 2249 2 157242 1 1499 10 3391
3 9 13631 15 9 1 15 1 1 1 1 1 3 1 5 1 38179 8189 2 58938 1 5459 10 1343
4 9 17727 15 9 1 15 1 1 1 1 1 3 1 3 3 25891 10649 2 58938 1 7099 10 1343
5 9 18751 15 9 1 25 1 1 1 1 1 3 1 1 15 22819 11 2 100623930 1 7 10 2367
6 9 23871 15 9 1 14 1 1 1 1 1 3 1 2 3 23843 28679 2 9786 4 19119 10 3391
7 9 30015 15 9 1 19 1 1 1 1 1 3 1 7 3 87331 1127 2 1533498 1 751 10 1343
8 10 2367 15 10 1 17 1 1 1 1 1 3 1 1 4 3 84841 1067 2 275118 1 711 10 2367
9 10 10559 15 10 1 16 1 1 1 1 1 3 1 1 3 3 76649 9515 2 78510 2 6343 10 2367
10 11 20799 15 11 1 21 1 1 1 1 1 3 1 1 1 1 9 215611 1757 2 5937162 1 1171 10 319
11 11 22847 15 11 1 22 1 1 1 1 1 3 1 1 2 1 9 225851 965 2 12228618 1 643 10 2367
12 11 26943 15 11 1 23 1 1 1 1 1 3 1 1 3 1 9 246331 569 2 24811530 1 379 10 2367
13 11 32063 15 11 1 20 1 1 1 1 1 3 1 2 2 2 5 271931 5417 2 2791434 1 3611 10 3391
14 13 319 15 13 2 23 1 1 1 1 1 3 1 1 1 4 2 2 4 3116051 61 1 18788532 1 81 10 319
15 13 11583 15 13 1 21 1 1 1 1 1 3 1 2 1 1 3 2 3 2574355 8807 2 3102810 1 5871 10 3391
16 13 15679 15 13 1 21 1 1 1 1 1 3 1 2 2 1 2 2 3 2758675 11921 2 3102810 2 7947 10 3391
17 14 1343 15 14 1 23 1 1 1 1 1 3 1 3 2 1 1 1 3 3 10534969 767 2 15599886 1 511 10 1343
18 14 6463 15 14 2 24 1 1 1 1 1 3 1 1 2 1 1 4 2 4 8080441 1843 1 31199772 1 2457 10 2367
19 14 9535 15 14 2 24 1 1 1 1 1 3 1 3 1 2 2 2 1 4 11640889 2719 1 31199772 1 3625 10 1343
20 14 12607 15 14 2 23 1 1 1 1 1 3 1 1 1 1 1 4 2 4 6812729 7189 1 6033948 4 9585 10 319
21 14 14655 15 14 1 23 1 1 1 1 1 3 1 1 2 3 1 2 2 3 9186361 8357 2 15599886 1 5571 10 2367
22 14 16703 15 14 1 22 1 1 1 1 1 3 1 1 1 3 1 2 2 3 7365689 19049 2 3016974 4 12699 10 319
23 17 4415 15 17 2 28 1 1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4 271524355 2125 1 288745716 3 2833 10 319
24 18 3391 15 18 2 29 1 1 1 1 1 3 1 2 1 3 2 2 1 1 1 2 1 4 1053985289 2449 1 60930780 61 3265 10 3391
25 18 8511 15 18 1 28 1 1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4 1 930665993 12287 2 30465390 53 8191 10 319
26 19 25919 15 19 2 31 1 1 1 1 1 3 1 3 1 1 1 2 2 1 1 2 1 1 6 2393134619 14029 1 1793405076 5 18705 10 1343
27 22 27967 15 22 2 38 1 1 1 1 1 3 1 2 1 1 1 1 1 1 1 1 3 1 2 4 3 6 51062787289 3193 1 699109482396 1 4257 10 3391
28 26 24895 15 26 2 42 1 1 1 1 1 3 1 1 1 2 1 1 1 1 1 1 1 3 1 1 3 3 2 2 1 6 3741452025001 14389 1 3026676219996 4 19185 10 319
29 27 19775 15 27 1 44 1 1 1 1 1 3 1 2 1 2 1 2 2 1 2 2 1 1 3 1 1 1 1 1 3 4 3 21620693160443 8573 2 37525363163274 1 5715 10 3391
30 31 28991 15 31 1 49 1 1 1 1 1 3 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 3 1 1 3 3 3 4 1 2 3 1031536617448555 31811 2 453503067696042 4 21207 10 319
31 32 31039 15 32 2 54 1 1 1 1 1 3 1 1 2 2 1 1 1 1 1 1 1 3 5 1 1 1 1 1 1 2 1 1 2 4 3 6 4080799003682113 3193 1 46631114773038588 1 4257 10 2367

View File

@ -0,0 +1,11 @@
{
"clauses": [
5439,
21823
],
"covered": [
5439,
21823
],
"palier": 15
}

View File

@ -0,0 +1,67 @@
{
"clauses": [
319,
1343,
2367,
3391,
4415,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063
],
"covered": [
319,
1343,
2367,
3391,
4415,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063
],
"palier": 15
}

View File

@ -0,0 +1,25 @@
{
"state_id": 10,
"base_palier": 12,
"target_palier": 15,
"delta_m": 3,
"lift_size": 32,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 2,
"covered": 2,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/certificats/certificat_D8_E10_palier2p15.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 120,
"t_max_used": 32,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/candidats/candidats_F9to32_E10_palier2p15.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/certificats/certificat_F9to32_E10_palier2p15.json",
"clauses": 30,
"covered": 30
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p15/audits/verification_H6_E10_palier2p15.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
319,
1343,
2367,
3391
],
"palier": 12
}

View File

@ -0,0 +1,37 @@
{
"noyau": [
319,
1343,
2367,
3391,
4415,
5439,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
21823,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063
],
"palier": 15
}

View File

@ -0,0 +1,35 @@
{
"noyau": [
319,
1343,
2367,
3391,
4415,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063
],
"palier": 15
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E10) — couverture des relèvements au palier \(2^{16}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/noyaux/noyau_E10_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/noyaux/noyau_Lift_E10_palier2p16.json`
- taille : 64
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/certificats/certificat_D8_E10_palier2p16.json`
- covered : 4 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/certificats/certificat_F9to33_E10_palier2p16.json`
- covered : 60 classes
## Résultat
- |L| = 64
- |U| = 64
- |L \ U| = 0

View File

@ -0,0 +1,5 @@
classe_mod_2^m,sœur,A8,palier
5439,38207,13,16
21823,54591,13,16
38207,5439,13,16
54591,21823,13,16
1 classe_mod_2^m sœur A8 palier
2 5439 38207 13 16
3 21823 54591 13 16
4 38207 5439 13 16
5 54591 21823 13 16

View File

@ -0,0 +1,61 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,7487,16,9,1,16,1 1 1 1 1 3 1 2 5,23843,2249,2,157242,1,1499,10,3391
9,13631,16,9,1,15,1 1 1 1 1 3 1 5 1,38179,8189,2,58938,1,5459,10,1343
9,17727,16,9,1,15,1 1 1 1 1 3 1 3 3,25891,10649,2,58938,1,7099,10,1343
9,18751,16,9,1,25,1 1 1 1 1 3 1 1 15,22819,11,2,100623930,1,7,10,2367
9,23871,16,9,1,14,1 1 1 1 1 3 1 2 3,23843,28679,2,9786,4,19119,10,3391
9,30015,16,9,1,19,1 1 1 1 1 3 1 7 3,87331,1127,2,1533498,1,751,10,1343
9,40255,16,9,2,15,1 1 1 1 1 3 1 2 4,23843,24181,1,19572,4,32241,10,3391
9,46399,16,9,2,20,1 1 1 1 1 3 1 5 6,38179,871,1,3066996,1,1161,10,1343
9,50495,16,9,1,17,1 1 1 1 1 3 1 3 5,25891,7583,2,353850,1,5055,10,1343
9,51519,16,9,1,15,1 1 1 1 1 3 1 1 5,22819,30947,2,58938,1,20631,10,2367
9,56639,16,9,1,14,1 1 1 1 1 3 1 2 3,23843,68045,2,9786,4,45363,10,3391
9,62783,16,9,1,16,1 1 1 1 1 3 1 6 1,54563,18857,2,157242,1,12571,10,1343
10,2367,16,10,1,17,1 1 1 1 1 3 1 1 4 3,84841,1067,2,275118,1,711,10,2367
10,10559,16,10,1,16,1 1 1 1 1 3 1 1 3 3,76649,9515,2,78510,2,6343,10,2367
10,33087,16,10,1,16,1 1 1 1 1 3 1 1 1 5,70505,29813,2,78510,1,19875,10,319
10,34111,16,10,2,20,1 1 1 1 1 3 1 3 2 6,94057,1921,1,2909532,1,2561,10,1343
10,42303,16,10,1,16,1 1 1 1 1 3 1 3 1 3,85865,38117,2,78510,2,25411,10,1343
10,47423,16,10,1,17,1 1 1 1 1 3 1 1 2 5,72553,21365,2,275118,1,14243,10,2367
10,64831,16,10,1,16,1 1 1 1 1 3 1 2 2 3,79721,58415,2,78510,2,38943,10,3391
11,20799,16,11,1,21,1 1 1 1 1 3 1 1 1 1 9,215611,1757,2,5937162,1,1171,10,319
11,22847,16,11,1,22,1 1 1 1 1 3 1 1 2 1 9,225851,965,2,12228618,1,643,10,2367
11,26943,16,11,1,23,1 1 1 1 1 3 1 1 3 1 9,246331,569,2,24811530,1,379,10,2367
11,32063,16,11,1,20,1 1 1 1 1 3 1 2 2 2 5,271931,5417,2,2791434,1,3611,10,3391
11,35135,16,11,1,24,1 1 1 1 1 3 1 1 4 1 9,287291,371,2,49977354,1,247,10,2367
11,36159,16,11,2,20,1 1 1 1 1 3 1 2 1 4 4,292411,6109,1,2437140,1,8145,10,3391
11,49471,16,11,1,17,1 1 1 1 1 3 1 1 1 3 3,227899,66863,2,38922,9,44575,10,319
11,52543,16,11,1,17,1 1 1 1 1 3 1 2 1 2 3,243259,71015,2,38922,10,47343,10,3391
11,58687,16,11,1,17,1 1 1 1 1 3 1 3 1 1 3,273979,79319,2,38922,11,52879,10,1343
12,57663,16,12,1,19,1 1 1 1 1 3 1 1 1 2 1 5,675505,58451,2,509982,2,38967,10,319
12,60735,16,12,1,19,1 1 1 1 1 3 1 2 1 1 1 5,721585,61565,2,509982,2,41043,10,3391
12,63807,16,12,1,19,1 1 1 1 1 3 1 1 2 2 2 3,767665,64679,2,509982,2,43119,10,2367
13,319,16,13,2,23,1 1 1 1 1 3 1 1 1 4 2 2 4,3116051,61,1,18788532,1,81,10,319
13,11583,16,13,1,21,1 1 1 1 1 3 1 2 1 1 3 2 3,2574355,8807,2,3102810,1,5871,10,3391
13,15679,16,13,1,21,1 1 1 1 1 3 1 2 2 1 2 2 3,2758675,11921,2,3102810,2,7947,10,3391
14,1343,16,14,1,23,1 1 1 1 1 3 1 3 2 1 1 1 3 3,10534969,767,2,15599886,1,511,10,1343
14,6463,16,14,2,24,1 1 1 1 1 3 1 1 2 1 1 4 2 4,8080441,1843,1,31199772,1,2457,10,2367
14,9535,16,14,2,24,1 1 1 1 1 3 1 3 1 2 2 2 1 4,11640889,2719,1,31199772,1,3625,10,1343
14,12607,16,14,2,23,1 1 1 1 1 3 1 1 1 1 1 4 2 4,6812729,7189,1,6033948,4,9585,10,319
14,14655,16,14,1,23,1 1 1 1 1 3 1 1 2 3 1 2 2 3,9186361,8357,2,15599886,1,5571,10,2367
14,16703,16,14,1,22,1 1 1 1 1 3 1 1 1 3 1 2 2 3,7365689,19049,2,3016974,4,12699,10,319
15,53567,16,15,1,24,1 1 1 1 1 3 1 1 1 1 3 1 2 1 5,20249771,45815,2,21633834,2,30543,10,319
16,44351,16,16,1,27,1 1 1 1 1 3 1 2 1 1 2 3 1 2 1 5,82057729,14225,2,316559742,1,9483,10,3391
16,45375,16,16,2,26,1 1 1 1 1 3 1 1 1 1 1 2 5 2 2 2,92739073,29107,1,29139708,11,38809,10,319
16,55615,16,16,1,26,1 1 1 1 1 3 1 1 2 1 2 1 2 1 2 5,65334785,35675,2,115233150,1,23783,10,2367
17,4415,16,17,2,28,1 1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4,271524355,2125,1,288745716,3,2833,10,319
18,3391,16,18,2,29,1 1 1 1 1 3 1 2 1 3 2 2 1 1 1 2 1 4,1053985289,2449,1,60930780,61,3265,10,3391
18,8511,16,18,1,28,1 1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4 1,930665993,12287,2,30465390,53,8191,10,319
19,25919,16,19,2,31,1 1 1 1 1 3 1 3 1 1 1 2 2 1 1 2 1 1 6,2393134619,14029,1,1793405076,5,18705,10,1343
19,43327,16,19,1,30,1 1 1 1 1 3 1 1 3 2 1 1 1 1 1 1 1 5 3,2262706715,46901,2,896702538,4,31267,10,2367
19,48447,16,19,2,32,1 1 1 1 1 3 1 2 2 1 1 3 1 2 2 2 1 2 4,3234926107,13111,1,8235856020,2,17481,10,3391
22,27967,16,22,2,38,1 1 1 1 1 3 1 2 1 1 1 1 1 1 1 1 3 1 2 4 3 6,51062787289,3193,1,699109482396,1,4257,10,3391
23,37183,16,23,2,37,1 1 1 1 1 3 1 1 1 1 2 1 2 1 2 4 1 1 1 2 3 1 4,181765560971,25471,1,35744145108,17,33961,10,319
26,24895,16,26,2,42,1 1 1 1 1 3 1 1 1 2 1 1 1 1 1 1 1 3 1 1 3 3 2 2 1 6,3741452025001,14389,1,3026676219996,4,19185,10,319
26,59711,16,26,1,41,1 1 1 1 1 3 1 1 3 1 1 1 2 1 2 1 1 1 2 1 1 3 1 4 4 1,5831692612777,69023,2,1513338109998,7,46015,10,2367
27,19775,16,27,1,44,1 1 1 1 1 3 1 2 1 2 1 2 2 1 2 2 1 1 3 1 1 1 1 1 3 4 3,21620693160443,8573,2,37525363163274,1,5715,10,3391
27,39231,16,27,2,45,1 1 1 1 1 3 1 1 2 1 1 1 2 1 2 1 1 1 1 2 4 2 1 2 1 3 6,12900937813499,8503,1,75050726326548,1,11337,10,2367
29,41279,16,29,2,47,1 1 1 1 1 3 1 1 1 2 2 3 1 1 2 1 1 2 1 2 2 1 1 3 3 1 1 2 4,193030836102611,20131,1,147690955606452,5,26841,10,319
31,28991,16,31,1,49,1 1 1 1 1 3 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 3 1 1 3 3 3 4 1 2 3,1031536617448555,31811,2,453503067696042,4,21207,10,319
32,31039,16,32,2,54,1 1 1 1 1 3 1 1 2 2 1 1 1 1 1 1 1 3 5 1 1 1 1 1 1 2 1 1 2 4 3 6,4080799003682113,3193,1,46631114773038588,1,4257,10,2367
33,61759,16,33,1,52,1 1 1 1 1 3 1 1 1 1 1 1 1 2 1 1 2 5 1 1 1 1 1 2 4 1 1 2 2 1 1 4 3,9896062687217603,76235,2,2392677749000442,7,50823,10,319
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 7487 16 9 1 16 1 1 1 1 1 3 1 2 5 23843 2249 2 157242 1 1499 10 3391
3 9 13631 16 9 1 15 1 1 1 1 1 3 1 5 1 38179 8189 2 58938 1 5459 10 1343
4 9 17727 16 9 1 15 1 1 1 1 1 3 1 3 3 25891 10649 2 58938 1 7099 10 1343
5 9 18751 16 9 1 25 1 1 1 1 1 3 1 1 15 22819 11 2 100623930 1 7 10 2367
6 9 23871 16 9 1 14 1 1 1 1 1 3 1 2 3 23843 28679 2 9786 4 19119 10 3391
7 9 30015 16 9 1 19 1 1 1 1 1 3 1 7 3 87331 1127 2 1533498 1 751 10 1343
8 9 40255 16 9 2 15 1 1 1 1 1 3 1 2 4 23843 24181 1 19572 4 32241 10 3391
9 9 46399 16 9 2 20 1 1 1 1 1 3 1 5 6 38179 871 1 3066996 1 1161 10 1343
10 9 50495 16 9 1 17 1 1 1 1 1 3 1 3 5 25891 7583 2 353850 1 5055 10 1343
11 9 51519 16 9 1 15 1 1 1 1 1 3 1 1 5 22819 30947 2 58938 1 20631 10 2367
12 9 56639 16 9 1 14 1 1 1 1 1 3 1 2 3 23843 68045 2 9786 4 45363 10 3391
13 9 62783 16 9 1 16 1 1 1 1 1 3 1 6 1 54563 18857 2 157242 1 12571 10 1343
14 10 2367 16 10 1 17 1 1 1 1 1 3 1 1 4 3 84841 1067 2 275118 1 711 10 2367
15 10 10559 16 10 1 16 1 1 1 1 1 3 1 1 3 3 76649 9515 2 78510 2 6343 10 2367
16 10 33087 16 10 1 16 1 1 1 1 1 3 1 1 1 5 70505 29813 2 78510 1 19875 10 319
17 10 34111 16 10 2 20 1 1 1 1 1 3 1 3 2 6 94057 1921 1 2909532 1 2561 10 1343
18 10 42303 16 10 1 16 1 1 1 1 1 3 1 3 1 3 85865 38117 2 78510 2 25411 10 1343
19 10 47423 16 10 1 17 1 1 1 1 1 3 1 1 2 5 72553 21365 2 275118 1 14243 10 2367
20 10 64831 16 10 1 16 1 1 1 1 1 3 1 2 2 3 79721 58415 2 78510 2 38943 10 3391
21 11 20799 16 11 1 21 1 1 1 1 1 3 1 1 1 1 9 215611 1757 2 5937162 1 1171 10 319
22 11 22847 16 11 1 22 1 1 1 1 1 3 1 1 2 1 9 225851 965 2 12228618 1 643 10 2367
23 11 26943 16 11 1 23 1 1 1 1 1 3 1 1 3 1 9 246331 569 2 24811530 1 379 10 2367
24 11 32063 16 11 1 20 1 1 1 1 1 3 1 2 2 2 5 271931 5417 2 2791434 1 3611 10 3391
25 11 35135 16 11 1 24 1 1 1 1 1 3 1 1 4 1 9 287291 371 2 49977354 1 247 10 2367
26 11 36159 16 11 2 20 1 1 1 1 1 3 1 2 1 4 4 292411 6109 1 2437140 1 8145 10 3391
27 11 49471 16 11 1 17 1 1 1 1 1 3 1 1 1 3 3 227899 66863 2 38922 9 44575 10 319
28 11 52543 16 11 1 17 1 1 1 1 1 3 1 2 1 2 3 243259 71015 2 38922 10 47343 10 3391
29 11 58687 16 11 1 17 1 1 1 1 1 3 1 3 1 1 3 273979 79319 2 38922 11 52879 10 1343
30 12 57663 16 12 1 19 1 1 1 1 1 3 1 1 1 2 1 5 675505 58451 2 509982 2 38967 10 319
31 12 60735 16 12 1 19 1 1 1 1 1 3 1 2 1 1 1 5 721585 61565 2 509982 2 41043 10 3391
32 12 63807 16 12 1 19 1 1 1 1 1 3 1 1 2 2 2 3 767665 64679 2 509982 2 43119 10 2367
33 13 319 16 13 2 23 1 1 1 1 1 3 1 1 1 4 2 2 4 3116051 61 1 18788532 1 81 10 319
34 13 11583 16 13 1 21 1 1 1 1 1 3 1 2 1 1 3 2 3 2574355 8807 2 3102810 1 5871 10 3391
35 13 15679 16 13 1 21 1 1 1 1 1 3 1 2 2 1 2 2 3 2758675 11921 2 3102810 2 7947 10 3391
36 14 1343 16 14 1 23 1 1 1 1 1 3 1 3 2 1 1 1 3 3 10534969 767 2 15599886 1 511 10 1343
37 14 6463 16 14 2 24 1 1 1 1 1 3 1 1 2 1 1 4 2 4 8080441 1843 1 31199772 1 2457 10 2367
38 14 9535 16 14 2 24 1 1 1 1 1 3 1 3 1 2 2 2 1 4 11640889 2719 1 31199772 1 3625 10 1343
39 14 12607 16 14 2 23 1 1 1 1 1 3 1 1 1 1 1 4 2 4 6812729 7189 1 6033948 4 9585 10 319
40 14 14655 16 14 1 23 1 1 1 1 1 3 1 1 2 3 1 2 2 3 9186361 8357 2 15599886 1 5571 10 2367
41 14 16703 16 14 1 22 1 1 1 1 1 3 1 1 1 3 1 2 2 3 7365689 19049 2 3016974 4 12699 10 319
42 15 53567 16 15 1 24 1 1 1 1 1 3 1 1 1 1 3 1 2 1 5 20249771 45815 2 21633834 2 30543 10 319
43 16 44351 16 16 1 27 1 1 1 1 1 3 1 2 1 1 2 3 1 2 1 5 82057729 14225 2 316559742 1 9483 10 3391
44 16 45375 16 16 2 26 1 1 1 1 1 3 1 1 1 1 1 2 5 2 2 2 92739073 29107 1 29139708 11 38809 10 319
45 16 55615 16 16 1 26 1 1 1 1 1 3 1 1 2 1 2 1 2 1 2 5 65334785 35675 2 115233150 1 23783 10 2367
46 17 4415 16 17 2 28 1 1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4 271524355 2125 1 288745716 3 2833 10 319
47 18 3391 16 18 2 29 1 1 1 1 1 3 1 2 1 3 2 2 1 1 1 2 1 4 1053985289 2449 1 60930780 61 3265 10 3391
48 18 8511 16 18 1 28 1 1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4 1 930665993 12287 2 30465390 53 8191 10 319
49 19 25919 16 19 2 31 1 1 1 1 1 3 1 3 1 1 1 2 2 1 1 2 1 1 6 2393134619 14029 1 1793405076 5 18705 10 1343
50 19 43327 16 19 1 30 1 1 1 1 1 3 1 1 3 2 1 1 1 1 1 1 1 5 3 2262706715 46901 2 896702538 4 31267 10 2367
51 19 48447 16 19 2 32 1 1 1 1 1 3 1 2 2 1 1 3 1 2 2 2 1 2 4 3234926107 13111 1 8235856020 2 17481 10 3391
52 22 27967 16 22 2 38 1 1 1 1 1 3 1 2 1 1 1 1 1 1 1 1 3 1 2 4 3 6 51062787289 3193 1 699109482396 1 4257 10 3391
53 23 37183 16 23 2 37 1 1 1 1 1 3 1 1 1 1 2 1 2 1 2 4 1 1 1 2 3 1 4 181765560971 25471 1 35744145108 17 33961 10 319
54 26 24895 16 26 2 42 1 1 1 1 1 3 1 1 1 2 1 1 1 1 1 1 1 3 1 1 3 3 2 2 1 6 3741452025001 14389 1 3026676219996 4 19185 10 319
55 26 59711 16 26 1 41 1 1 1 1 1 3 1 1 3 1 1 1 2 1 2 1 1 1 2 1 1 3 1 4 4 1 5831692612777 69023 2 1513338109998 7 46015 10 2367
56 27 19775 16 27 1 44 1 1 1 1 1 3 1 2 1 2 1 2 2 1 2 2 1 1 3 1 1 1 1 1 3 4 3 21620693160443 8573 2 37525363163274 1 5715 10 3391
57 27 39231 16 27 2 45 1 1 1 1 1 3 1 1 2 1 1 1 2 1 2 1 1 1 1 2 4 2 1 2 1 3 6 12900937813499 8503 1 75050726326548 1 11337 10 2367
58 29 41279 16 29 2 47 1 1 1 1 1 3 1 1 1 2 2 3 1 1 2 1 1 2 1 2 2 1 1 3 3 1 1 2 4 193030836102611 20131 1 147690955606452 5 26841 10 319
59 31 28991 16 31 1 49 1 1 1 1 1 3 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 3 1 1 3 3 3 4 1 2 3 1031536617448555 31811 2 453503067696042 4 21207 10 319
60 32 31039 16 32 2 54 1 1 1 1 1 3 1 1 2 2 1 1 1 1 1 1 1 3 5 1 1 1 1 1 1 2 1 1 2 4 3 6 4080799003682113 3193 1 46631114773038588 1 4257 10 2367
61 33 61759 16 33 1 52 1 1 1 1 1 3 1 1 1 1 1 1 1 2 1 1 2 5 1 1 1 1 1 2 4 1 1 2 2 1 1 4 3 9896062687217603 76235 2 2392677749000442 7 50823 10 319

View File

@ -0,0 +1,15 @@
{
"clauses": [
5439,
21823,
38207,
54591
],
"covered": [
5439,
21823,
38207,
54591
],
"palier": 16
}

View File

@ -0,0 +1,127 @@
{
"clauses": [
319,
1343,
2367,
3391,
4415,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063,
33087,
34111,
35135,
36159,
37183,
39231,
40255,
41279,
42303,
43327,
44351,
45375,
46399,
47423,
48447,
49471,
50495,
51519,
52543,
53567,
55615,
56639,
57663,
58687,
59711,
60735,
61759,
62783,
63807,
64831
],
"covered": [
319,
1343,
2367,
3391,
4415,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063,
33087,
34111,
35135,
36159,
37183,
39231,
40255,
41279,
42303,
43327,
44351,
45375,
46399,
47423,
48447,
49471,
50495,
51519,
52543,
53567,
55615,
56639,
57663,
58687,
59711,
60735,
61759,
62783,
63807,
64831
],
"palier": 16
}

View File

@ -0,0 +1,25 @@
{
"state_id": 10,
"base_palier": 12,
"target_palier": 16,
"delta_m": 4,
"lift_size": 64,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 4,
"covered": 4,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/certificats/certificat_D8_E10_palier2p16.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 128,
"t_max_used": 33,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/candidats/candidats_F9to33_E10_palier2p16.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/certificats/certificat_F9to33_E10_palier2p16.json",
"clauses": 60,
"covered": 60
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E10_palier2p16/audits/verification_H6_E10_palier2p16.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
319,
1343,
2367,
3391
],
"palier": 12
}

View File

@ -0,0 +1,69 @@
{
"noyau": [
319,
1343,
2367,
3391,
4415,
5439,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
21823,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063,
33087,
34111,
35135,
36159,
37183,
38207,
39231,
40255,
41279,
42303,
43327,
44351,
45375,
46399,
47423,
48447,
49471,
50495,
51519,
52543,
53567,
54591,
55615,
56639,
57663,
58687,
59711,
60735,
61759,
62783,
63807,
64831
],
"palier": 16
}

View File

@ -0,0 +1,65 @@
{
"noyau": [
319,
1343,
2367,
3391,
4415,
6463,
7487,
8511,
9535,
10559,
11583,
12607,
13631,
14655,
15679,
16703,
17727,
18751,
19775,
20799,
22847,
23871,
24895,
25919,
26943,
27967,
28991,
30015,
31039,
32063,
33087,
34111,
35135,
36159,
37183,
39231,
40255,
41279,
42303,
43327,
44351,
45375,
46399,
47423,
48447,
49471,
50495,
51519,
52543,
53567,
55615,
56639,
57663,
58687,
59711,
60735,
61759,
62783,
63807,
64831
],
"palier": 16
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E11) — couverture des relèvements au palier \(2^{15}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/noyaux/noyau_E11_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/noyaux/noyau_Lift_E11_palier2p15.json`
- taille : 32
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/certificats/certificat_D8_E11_palier2p15.json`
- covered : 2 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/certificats/certificat_F9to45_E11_palier2p15.json`
- covered : 30 classes
## Résultat
- |L| = 32
- |U| = 32
- |L \ U| = 0

View File

@ -0,0 +1,3 @@
classe_mod_2^m,sœur,A8,palier
14751,31135,13,15
31135,14751,13,15
1 classe_mod_2^m sœur A8 palier
2 14751 31135 13 15
3 31135 14751 13 15

View File

@ -0,0 +1,31 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,415,15,9,1,16,1 1 1 1 2 1 2 2 5,23555,125,2,157242,1,83,11,415
9,6559,15,9,1,15,1 1 1 1 2 1 2 5 1,37891,3941,2,58938,1,2627,11,2463
9,10655,15,9,1,15,1 1 1 1 2 1 2 3 3,25603,6401,2,58938,1,4267,11,2463
9,11679,15,9,2,18,1 1 1 1 2 1 2 1 8,22531,877,1,707700,1,1169,11,3487
9,16799,15,9,1,14,1 1 1 1 2 1 2 2 3,23555,20183,2,9786,4,13455,11,415
9,22943,15,9,2,18,1 1 1 1 2 1 2 7 2,87043,1723,1,707700,1,2297,11,2463
10,3487,15,10,1,16,1 1 1 1 2 1 2 1 3 3,75785,3143,2,78510,2,2095,11,3487
10,26015,15,10,1,16,1 1 1 1 2 1 2 1 1 5,69641,23441,2,78510,1,15627,11,1439
10,27039,15,10,2,18,1 1 1 1 2 1 2 3 2 4,93193,6091,1,550236,1,8121,11,2463
11,13727,15,11,2,18,1 1 1 1 2 1 2 1 1 1 6,213019,9277,1,77844,8,12369,11,1439
11,15775,15,11,1,18,1 1 1 1 2 1 2 1 2 1 5,223259,10661,2,432138,1,7107,11,3487
11,19871,15,11,2,18,1 1 1 1 2 1 2 1 3 1 4,243739,13429,1,77844,10,17905,11,3487
11,24991,15,11,1,18,1 1 1 1 2 1 2 2 2 2 3,269339,16889,2,432138,1,11259,11,415
11,28063,15,11,1,18,1 1 1 1 2 1 2 1 4 1 3,284699,18965,2,432138,1,12643,11,3487
11,29087,15,11,2,18,1 1 1 1 2 1 2 2 1 4 2,289819,19657,1,77844,12,26209,11,415
12,1439,15,12,1,21,1 1 1 1 2 1 2 1 1 2 3 5,716881,365,2,5228574,1,243,11,1439
12,4511,15,12,2,20,1 1 1 1 2 1 2 2 1 1 3 4,762961,2287,1,1019964,2,3049,11,415
12,7583,15,12,2,22,1 1 1 1 2 1 2 1 2 3 1 6,809041,961,1,10457148,1,1281,11,3487
12,8607,15,12,2,20,1 1 1 1 2 1 2 2 2 1 2 4,824401,4363,1,1019964,3,5817,11,415
13,2463,15,13,2,22,1 1 1 1 2 1 2 3 1 2 2 1 4,3245299,937,1,6205620,2,1249,11,2463
14,32159,15,14,2,23,1 1 1 1 2 1 2 1 2 1 1 1 2 6,6404825,18337,1,6033948,3,24449,11,3487
15,30111,15,15,2,25,1 1 1 1 2 1 2 1 1 1 2 1 2 4 4,20482187,12877,1,43267668,2,17169,11,1439
16,23967,15,16,1,25,1 1 1 1 2 1 2 1 2 2 1 1 1 2 1 5,64467361,30749,2,14569854,7,20499,11,3487
17,5535,15,17,1,27,1 1 1 1 2 1 2 1 1 1 1 4 1 1 1 2 5,187034851,5327,2,144372858,2,3551,11,1439
17,18847,15,17,1,30,1 1 1 1 2 1 2 3 1 1 1 2 1 1 2 4 5,268062947,2267,2,2962945146,1,1511,11,2463
18,21919,15,18,1,28,1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1 8 1,622823081,31637,2,30465390,33,21091,11,1439
19,9631,15,19,1,30,1 1 1 1 2 1 2 1 1 3 1 2 1 1 1 4 1 2 3,2165810171,10427,2,896702538,4,6951,11,1439
23,17823,15,23,1,36,1 1 1 1 2 1 2 1 1 2 1 1 1 1 3 1 1 2 2 3 1 3 3,147026182763,24419,2,17872072554,13,16279,11,1439
43,12703,15,43,1,70,1 1 1 1 2 1 2 2 1 2 1 2 1 1 3 1 1 2 2 2 2 1 1 1 1 3 2 1 2 1 1 1 1 2 1 2 2 3 3 1 2 1 5,1181939181809637901211,3533,2,2885260927363159755018,1,2355,11,415
45,20895,15,45,1,72,1 1 1 1 2 1 2 2 1 1 1 1 1 1 4 1 1 1 1 1 1 2 1 1 1 1 1 3 2 2 1 1 1 1 2 1 1 5 2 2 2 3 3 1 5,5133027175201745502323,13073,2,8258474035507268243802,1,8715,11,415
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 415 15 9 1 16 1 1 1 1 2 1 2 2 5 23555 125 2 157242 1 83 11 415
3 9 6559 15 9 1 15 1 1 1 1 2 1 2 5 1 37891 3941 2 58938 1 2627 11 2463
4 9 10655 15 9 1 15 1 1 1 1 2 1 2 3 3 25603 6401 2 58938 1 4267 11 2463
5 9 11679 15 9 2 18 1 1 1 1 2 1 2 1 8 22531 877 1 707700 1 1169 11 3487
6 9 16799 15 9 1 14 1 1 1 1 2 1 2 2 3 23555 20183 2 9786 4 13455 11 415
7 9 22943 15 9 2 18 1 1 1 1 2 1 2 7 2 87043 1723 1 707700 1 2297 11 2463
8 10 3487 15 10 1 16 1 1 1 1 2 1 2 1 3 3 75785 3143 2 78510 2 2095 11 3487
9 10 26015 15 10 1 16 1 1 1 1 2 1 2 1 1 5 69641 23441 2 78510 1 15627 11 1439
10 10 27039 15 10 2 18 1 1 1 1 2 1 2 3 2 4 93193 6091 1 550236 1 8121 11 2463
11 11 13727 15 11 2 18 1 1 1 1 2 1 2 1 1 1 6 213019 9277 1 77844 8 12369 11 1439
12 11 15775 15 11 1 18 1 1 1 1 2 1 2 1 2 1 5 223259 10661 2 432138 1 7107 11 3487
13 11 19871 15 11 2 18 1 1 1 1 2 1 2 1 3 1 4 243739 13429 1 77844 10 17905 11 3487
14 11 24991 15 11 1 18 1 1 1 1 2 1 2 2 2 2 3 269339 16889 2 432138 1 11259 11 415
15 11 28063 15 11 1 18 1 1 1 1 2 1 2 1 4 1 3 284699 18965 2 432138 1 12643 11 3487
16 11 29087 15 11 2 18 1 1 1 1 2 1 2 2 1 4 2 289819 19657 1 77844 12 26209 11 415
17 12 1439 15 12 1 21 1 1 1 1 2 1 2 1 1 2 3 5 716881 365 2 5228574 1 243 11 1439
18 12 4511 15 12 2 20 1 1 1 1 2 1 2 2 1 1 3 4 762961 2287 1 1019964 2 3049 11 415
19 12 7583 15 12 2 22 1 1 1 1 2 1 2 1 2 3 1 6 809041 961 1 10457148 1 1281 11 3487
20 12 8607 15 12 2 20 1 1 1 1 2 1 2 2 2 1 2 4 824401 4363 1 1019964 3 5817 11 415
21 13 2463 15 13 2 22 1 1 1 1 2 1 2 3 1 2 2 1 4 3245299 937 1 6205620 2 1249 11 2463
22 14 32159 15 14 2 23 1 1 1 1 2 1 2 1 2 1 1 1 2 6 6404825 18337 1 6033948 3 24449 11 3487
23 15 30111 15 15 2 25 1 1 1 1 2 1 2 1 1 1 2 1 2 4 4 20482187 12877 1 43267668 2 17169 11 1439
24 16 23967 15 16 1 25 1 1 1 1 2 1 2 1 2 2 1 1 1 2 1 5 64467361 30749 2 14569854 7 20499 11 3487
25 17 5535 15 17 1 27 1 1 1 1 2 1 2 1 1 1 1 4 1 1 1 2 5 187034851 5327 2 144372858 2 3551 11 1439
26 17 18847 15 17 1 30 1 1 1 1 2 1 2 3 1 1 1 2 1 1 2 4 5 268062947 2267 2 2962945146 1 1511 11 2463
27 18 21919 15 18 1 28 1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1 8 1 622823081 31637 2 30465390 33 21091 11 1439
28 19 9631 15 19 1 30 1 1 1 1 2 1 2 1 1 3 1 2 1 1 1 4 1 2 3 2165810171 10427 2 896702538 4 6951 11 1439
29 23 17823 15 23 1 36 1 1 1 1 2 1 2 1 1 2 1 1 1 1 3 1 1 2 2 3 1 3 3 147026182763 24419 2 17872072554 13 16279 11 1439
30 43 12703 15 43 1 70 1 1 1 1 2 1 2 2 1 2 1 2 1 1 3 1 1 2 2 2 2 1 1 1 1 3 2 1 2 1 1 1 1 2 1 2 2 3 3 1 2 1 5 1181939181809637901211 3533 2 2885260927363159755018 1 2355 11 415
31 45 20895 15 45 1 72 1 1 1 1 2 1 2 2 1 1 1 1 1 1 4 1 1 1 1 1 1 2 1 1 1 1 1 3 2 2 1 1 1 1 2 1 1 5 2 2 2 3 3 1 5 5133027175201745502323 13073 2 8258474035507268243802 1 8715 11 415

View File

@ -0,0 +1,11 @@
{
"clauses": [
14751,
31135
],
"covered": [
14751,
31135
],
"palier": 15
}

View File

@ -0,0 +1,67 @@
{
"clauses": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
32159
],
"covered": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
32159
],
"palier": 15
}

View File

@ -0,0 +1,25 @@
{
"state_id": 11,
"base_palier": 12,
"target_palier": 15,
"delta_m": 3,
"lift_size": 32,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 2,
"covered": 2,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/certificats/certificat_D8_E11_palier2p15.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 120,
"t_max_used": 45,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/candidats/candidats_F9to45_E11_palier2p15.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/certificats/certificat_F9to45_E11_palier2p15.json",
"clauses": 30,
"covered": 30
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p15/audits/verification_H6_E11_palier2p15.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
415,
1439,
2463,
3487
],
"palier": 12
}

View File

@ -0,0 +1,37 @@
{
"noyau": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
14751,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
31135,
32159
],
"palier": 15
}

View File

@ -0,0 +1,35 @@
{
"noyau": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
32159
],
"palier": 15
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E11) — couverture des relèvements au palier \(2^{16}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/noyaux/noyau_E11_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/noyaux/noyau_Lift_E11_palier2p16.json`
- taille : 64
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/certificats/certificat_D8_E11_palier2p16.json`
- covered : 4 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/certificats/certificat_F9to45_E11_palier2p16.json`
- covered : 60 classes
## Résultat
- |L| = 64
- |U| = 64
- |L \ U| = 0

View File

@ -0,0 +1,5 @@
classe_mod_2^m,sœur,A8,palier
14751,47519,13,16
31135,63903,13,16
47519,14751,13,16
63903,31135,13,16
1 classe_mod_2^m sœur A8 palier
2 14751 47519 13 16
3 31135 63903 13 16
4 47519 14751 13 16
5 63903 31135 13 16

View File

@ -0,0 +1,61 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,415,16,9,1,16,1 1 1 1 2 1 2 2 5,23555,125,2,157242,1,83,11,415
9,6559,16,9,1,15,1 1 1 1 2 1 2 5 1,37891,3941,2,58938,1,2627,11,2463
9,10655,16,9,1,15,1 1 1 1 2 1 2 3 3,25603,6401,2,58938,1,4267,11,2463
9,11679,16,9,2,18,1 1 1 1 2 1 2 1 8,22531,877,1,707700,1,1169,11,3487
9,16799,16,9,1,14,1 1 1 1 2 1 2 2 3,23555,20183,2,9786,4,13455,11,415
9,22943,16,9,2,18,1 1 1 1 2 1 2 7 2,87043,1723,1,707700,1,2297,11,2463
9,33183,16,9,2,15,1 1 1 1 2 1 2 2 4,23555,19933,1,19572,4,26577,11,415
9,39327,16,9,2,18,1 1 1 1 2 1 2 5 4,37891,2953,1,707700,1,3937,11,2463
9,43423,16,9,1,17,1 1 1 1 2 1 2 3 5,25603,6521,2,353850,1,4347,11,2463
9,44447,16,9,1,15,1 1 1 1 2 1 2 1 5,22531,26699,2,58938,1,17799,11,3487
9,49567,16,9,1,14,1 1 1 1 2 1 2 2 3,23555,59549,2,9786,4,39699,11,415
9,55711,16,9,1,16,1 1 1 1 2 1 2 6 1,54275,16733,2,157242,1,11155,11,2463
10,3487,16,10,1,16,1 1 1 1 2 1 2 1 3 3,75785,3143,2,78510,2,2095,11,3487
10,26015,16,10,1,16,1 1 1 1 2 1 2 1 1 5,69641,23441,2,78510,1,15627,11,1439
10,27039,16,10,2,18,1 1 1 1 2 1 2 3 2 4,93193,6091,1,550236,1,8121,11,2463
10,35231,16,10,1,16,1 1 1 1 2 1 2 3 1 3,85001,31745,2,78510,2,21163,11,2463
10,40351,16,10,1,17,1 1 1 1 2 1 2 1 2 5,71689,18179,2,275118,1,12119,11,3487
10,57759,16,10,1,16,1 1 1 1 2 1 2 2 2 3,78857,52043,2,78510,2,34695,11,415
11,13727,16,11,2,18,1 1 1 1 2 1 2 1 1 1 6,213019,9277,1,77844,8,12369,11,1439
11,15775,16,11,1,18,1 1 1 1 2 1 2 1 2 1 5,223259,10661,2,432138,1,7107,11,3487
11,19871,16,11,2,18,1 1 1 1 2 1 2 1 3 1 4,243739,13429,1,77844,10,17905,11,3487
11,24991,16,11,1,18,1 1 1 1 2 1 2 2 2 2 3,269339,16889,2,432138,1,11259,11,415
11,28063,16,11,1,18,1 1 1 1 2 1 2 1 4 1 3,284699,18965,2,432138,1,12643,11,3487
11,29087,16,11,2,18,1 1 1 1 2 1 2 2 1 4 2,289819,19657,1,77844,12,26209,11,415
11,42399,16,11,1,17,1 1 1 1 2 1 2 1 1 3 3,225307,57305,2,38922,9,38203,11,1439
11,45471,16,11,1,17,1 1 1 1 2 1 2 2 1 2 3,240667,61457,2,38922,9,40971,11,415
11,51615,16,11,1,17,1 1 1 1 2 1 2 3 1 1 3,271387,69761,2,38922,11,46507,11,2463
11,60831,16,11,1,17,1 1 1 1 2 1 2 1 4 2 1,317467,82217,2,38922,13,54811,11,3487
12,1439,16,12,1,21,1 1 1 1 2 1 2 1 1 2 3 5,716881,365,2,5228574,1,243,11,1439
12,4511,16,12,2,20,1 1 1 1 2 1 2 2 1 1 3 4,762961,2287,1,1019964,2,3049,11,415
12,7583,16,12,2,22,1 1 1 1 2 1 2 1 2 3 1 6,809041,961,1,10457148,1,1281,11,3487
12,8607,16,12,2,20,1 1 1 1 2 1 2 2 2 1 2 4,824401,4363,1,1019964,3,5817,11,415
13,2463,16,13,2,22,1 1 1 1 2 1 2 3 1 2 2 1 4,3245299,937,1,6205620,2,1249,11,2463
13,37279,16,13,1,22,1 1 1 1 2 1 2 2 1 1 2 4 3,2714867,14171,2,9394266,1,9447,11,415
13,41375,16,13,1,26,1 1 1 1 2 1 2 2 2 1 1 4 7,2899187,983,2,198137946,1,655,11,415
13,46495,16,13,1,23,1 1 1 1 2 1 2 1 1 1 3 1 7,2081011,8837,2,21977178,1,5891,11,1439
13,48543,16,13,1,21,1 1 1 1 2 1 2 1 2 1 2 1 5,2173171,36905,2,3102810,1,24603,11,3487
13,50591,16,13,2,22,1 1 1 1 2 1 2 1 1 2 1 4 4,2265331,19231,1,6205620,1,25641,11,1439
13,52639,16,13,1,21,1 1 1 1 2 1 2 1 3 1 1 1 5,2357491,40019,2,3102810,1,26679,11,3487
13,56735,16,13,1,21,1 1 1 1 2 1 2 1 2 2 2 2 3,2541811,43133,2,3102810,1,28755,11,3487
13,58783,16,13,2,22,1 1 1 1 2 1 2 1 1 4 1 2 4,2633971,22345,1,6205620,2,29793,11,1439
14,32159,16,14,2,23,1 1 1 1 2 1 2 1 2 1 1 1 2 6,6404825,18337,1,6033948,3,24449,11,3487
14,34207,16,14,1,23,1 1 1 1 2 1 2 1 1 2 2 4 1 3,8778457,19505,2,15599886,1,13003,11,1439
14,59807,16,14,1,24,1 1 1 1 2 1 2 3 2 1 2 2 2 3,13283033,17051,2,40765710,1,11367,11,2463
15,30111,16,15,2,25,1 1 1 1 2 1 2 1 1 1 2 1 2 4 4,20482187,12877,1,43267668,2,17169,11,1439
15,61855,16,15,2,27,1 1 1 1 2 1 2 2 1 3 1 2 2 1 6,30192779,6613,1,345257556,1,8817,11,415
16,23967,16,16,1,25,1 1 1 1 2 1 2 1 2 2 1 1 1 2 1 5,64467361,30749,2,14569854,7,20499,11,3487
16,36255,16,16,2,26,1 1 1 1 2 1 2 1 3 2 1 1 3 1 1 4,91980193,23257,1,29139708,11,31009,11,3487
16,62879,16,16,1,25,1 1 1 1 2 1 2 1 1 1 2 2 2 3 1 3,67705249,80669,2,14569854,7,53779,11,1439
16,64927,16,16,1,25,1 1 1 1 2 1 2 1 2 1 1 2 2 4 2 1,89067937,83297,2,14569854,10,55531,11,3487
17,5535,16,17,1,27,1 1 1 1 2 1 2 1 1 1 1 4 1 1 1 2 5,187034851,5327,2,144372858,2,3551,11,1439
17,18847,16,17,1,30,1 1 1 1 2 1 2 3 1 1 1 2 1 1 2 4 5,268062947,2267,2,2962945146,1,1511,11,2463
17,53663,16,17,1,27,1 1 1 1 2 1 2 2 1 1 1 4 2 1 2 1 3,283818211,51635,2,144372858,4,34423,11,415
18,21919,16,18,1,28,1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1 8 1,622823081,31637,2,30465390,33,21091,11,1439
19,9631,16,19,1,30,1 1 1 1 2 1 2 1 1 3 1 2 1 1 1 4 1 2 3,2165810171,10427,2,896702538,4,6951,11,1439
20,54687,16,20,1,33,1 1 1 1 2 1 2 1 1 1 1 1 1 2 5 1 3 1 1 5,6179470321,22199,2,18796234974,1,14799,11,1439
23,17823,16,23,1,36,1 1 1 1 2 1 2 1 1 2 1 1 1 1 3 1 1 2 2 3 1 3 3,147026182763,24419,2,17872072554,13,16279,11,1439
41,38303,16,41,1,66,1 1 1 1 2 1 2 1 1 1 1 2 3 2 2 2 2 1 1 1 2 1 1 4 1 2 1 2 2 1 1 1 1 3 1 2 1 1 1 1 7,131215907988807801731,18935,2,148414936130173046586,2,12623,11,1439
43,12703,16,43,1,70,1 1 1 1 2 1 2 2 1 2 1 2 1 1 3 1 1 2 2 2 2 1 1 1 1 3 2 1 2 1 1 1 1 2 1 2 2 3 3 1 2 1 5,1181939181809637901211,3533,2,2885260927363159755018,1,2355,11,415
45,20895,16,45,1,72,1 1 1 1 2 1 2 2 1 1 1 1 1 1 4 1 1 1 1 1 1 2 1 1 1 1 1 3 2 2 1 1 1 1 2 1 1 5 2 2 2 3 3 1 5,5133027175201745502323,13073,2,8258474035507268243802,1,8715,11,415
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 415 16 9 1 16 1 1 1 1 2 1 2 2 5 23555 125 2 157242 1 83 11 415
3 9 6559 16 9 1 15 1 1 1 1 2 1 2 5 1 37891 3941 2 58938 1 2627 11 2463
4 9 10655 16 9 1 15 1 1 1 1 2 1 2 3 3 25603 6401 2 58938 1 4267 11 2463
5 9 11679 16 9 2 18 1 1 1 1 2 1 2 1 8 22531 877 1 707700 1 1169 11 3487
6 9 16799 16 9 1 14 1 1 1 1 2 1 2 2 3 23555 20183 2 9786 4 13455 11 415
7 9 22943 16 9 2 18 1 1 1 1 2 1 2 7 2 87043 1723 1 707700 1 2297 11 2463
8 9 33183 16 9 2 15 1 1 1 1 2 1 2 2 4 23555 19933 1 19572 4 26577 11 415
9 9 39327 16 9 2 18 1 1 1 1 2 1 2 5 4 37891 2953 1 707700 1 3937 11 2463
10 9 43423 16 9 1 17 1 1 1 1 2 1 2 3 5 25603 6521 2 353850 1 4347 11 2463
11 9 44447 16 9 1 15 1 1 1 1 2 1 2 1 5 22531 26699 2 58938 1 17799 11 3487
12 9 49567 16 9 1 14 1 1 1 1 2 1 2 2 3 23555 59549 2 9786 4 39699 11 415
13 9 55711 16 9 1 16 1 1 1 1 2 1 2 6 1 54275 16733 2 157242 1 11155 11 2463
14 10 3487 16 10 1 16 1 1 1 1 2 1 2 1 3 3 75785 3143 2 78510 2 2095 11 3487
15 10 26015 16 10 1 16 1 1 1 1 2 1 2 1 1 5 69641 23441 2 78510 1 15627 11 1439
16 10 27039 16 10 2 18 1 1 1 1 2 1 2 3 2 4 93193 6091 1 550236 1 8121 11 2463
17 10 35231 16 10 1 16 1 1 1 1 2 1 2 3 1 3 85001 31745 2 78510 2 21163 11 2463
18 10 40351 16 10 1 17 1 1 1 1 2 1 2 1 2 5 71689 18179 2 275118 1 12119 11 3487
19 10 57759 16 10 1 16 1 1 1 1 2 1 2 2 2 3 78857 52043 2 78510 2 34695 11 415
20 11 13727 16 11 2 18 1 1 1 1 2 1 2 1 1 1 6 213019 9277 1 77844 8 12369 11 1439
21 11 15775 16 11 1 18 1 1 1 1 2 1 2 1 2 1 5 223259 10661 2 432138 1 7107 11 3487
22 11 19871 16 11 2 18 1 1 1 1 2 1 2 1 3 1 4 243739 13429 1 77844 10 17905 11 3487
23 11 24991 16 11 1 18 1 1 1 1 2 1 2 2 2 2 3 269339 16889 2 432138 1 11259 11 415
24 11 28063 16 11 1 18 1 1 1 1 2 1 2 1 4 1 3 284699 18965 2 432138 1 12643 11 3487
25 11 29087 16 11 2 18 1 1 1 1 2 1 2 2 1 4 2 289819 19657 1 77844 12 26209 11 415
26 11 42399 16 11 1 17 1 1 1 1 2 1 2 1 1 3 3 225307 57305 2 38922 9 38203 11 1439
27 11 45471 16 11 1 17 1 1 1 1 2 1 2 2 1 2 3 240667 61457 2 38922 9 40971 11 415
28 11 51615 16 11 1 17 1 1 1 1 2 1 2 3 1 1 3 271387 69761 2 38922 11 46507 11 2463
29 11 60831 16 11 1 17 1 1 1 1 2 1 2 1 4 2 1 317467 82217 2 38922 13 54811 11 3487
30 12 1439 16 12 1 21 1 1 1 1 2 1 2 1 1 2 3 5 716881 365 2 5228574 1 243 11 1439
31 12 4511 16 12 2 20 1 1 1 1 2 1 2 2 1 1 3 4 762961 2287 1 1019964 2 3049 11 415
32 12 7583 16 12 2 22 1 1 1 1 2 1 2 1 2 3 1 6 809041 961 1 10457148 1 1281 11 3487
33 12 8607 16 12 2 20 1 1 1 1 2 1 2 2 2 1 2 4 824401 4363 1 1019964 3 5817 11 415
34 13 2463 16 13 2 22 1 1 1 1 2 1 2 3 1 2 2 1 4 3245299 937 1 6205620 2 1249 11 2463
35 13 37279 16 13 1 22 1 1 1 1 2 1 2 2 1 1 2 4 3 2714867 14171 2 9394266 1 9447 11 415
36 13 41375 16 13 1 26 1 1 1 1 2 1 2 2 2 1 1 4 7 2899187 983 2 198137946 1 655 11 415
37 13 46495 16 13 1 23 1 1 1 1 2 1 2 1 1 1 3 1 7 2081011 8837 2 21977178 1 5891 11 1439
38 13 48543 16 13 1 21 1 1 1 1 2 1 2 1 2 1 2 1 5 2173171 36905 2 3102810 1 24603 11 3487
39 13 50591 16 13 2 22 1 1 1 1 2 1 2 1 1 2 1 4 4 2265331 19231 1 6205620 1 25641 11 1439
40 13 52639 16 13 1 21 1 1 1 1 2 1 2 1 3 1 1 1 5 2357491 40019 2 3102810 1 26679 11 3487
41 13 56735 16 13 1 21 1 1 1 1 2 1 2 1 2 2 2 2 3 2541811 43133 2 3102810 1 28755 11 3487
42 13 58783 16 13 2 22 1 1 1 1 2 1 2 1 1 4 1 2 4 2633971 22345 1 6205620 2 29793 11 1439
43 14 32159 16 14 2 23 1 1 1 1 2 1 2 1 2 1 1 1 2 6 6404825 18337 1 6033948 3 24449 11 3487
44 14 34207 16 14 1 23 1 1 1 1 2 1 2 1 1 2 2 4 1 3 8778457 19505 2 15599886 1 13003 11 1439
45 14 59807 16 14 1 24 1 1 1 1 2 1 2 3 2 1 2 2 2 3 13283033 17051 2 40765710 1 11367 11 2463
46 15 30111 16 15 2 25 1 1 1 1 2 1 2 1 1 1 2 1 2 4 4 20482187 12877 1 43267668 2 17169 11 1439
47 15 61855 16 15 2 27 1 1 1 1 2 1 2 2 1 3 1 2 2 1 6 30192779 6613 1 345257556 1 8817 11 415
48 16 23967 16 16 1 25 1 1 1 1 2 1 2 1 2 2 1 1 1 2 1 5 64467361 30749 2 14569854 7 20499 11 3487
49 16 36255 16 16 2 26 1 1 1 1 2 1 2 1 3 2 1 1 3 1 1 4 91980193 23257 1 29139708 11 31009 11 3487
50 16 62879 16 16 1 25 1 1 1 1 2 1 2 1 1 1 2 2 2 3 1 3 67705249 80669 2 14569854 7 53779 11 1439
51 16 64927 16 16 1 25 1 1 1 1 2 1 2 1 2 1 1 2 2 4 2 1 89067937 83297 2 14569854 10 55531 11 3487
52 17 5535 16 17 1 27 1 1 1 1 2 1 2 1 1 1 1 4 1 1 1 2 5 187034851 5327 2 144372858 2 3551 11 1439
53 17 18847 16 17 1 30 1 1 1 1 2 1 2 3 1 1 1 2 1 1 2 4 5 268062947 2267 2 2962945146 1 1511 11 2463
54 17 53663 16 17 1 27 1 1 1 1 2 1 2 2 1 1 1 4 2 1 2 1 3 283818211 51635 2 144372858 4 34423 11 415
55 18 21919 16 18 1 28 1 1 1 1 2 1 2 1 1 1 1 1 2 1 1 1 8 1 622823081 31637 2 30465390 33 21091 11 1439
56 19 9631 16 19 1 30 1 1 1 1 2 1 2 1 1 3 1 2 1 1 1 4 1 2 3 2165810171 10427 2 896702538 4 6951 11 1439
57 20 54687 16 20 1 33 1 1 1 1 2 1 2 1 1 1 1 1 1 2 5 1 3 1 1 5 6179470321 22199 2 18796234974 1 14799 11 1439
58 23 17823 16 23 1 36 1 1 1 1 2 1 2 1 1 2 1 1 1 1 3 1 1 2 2 3 1 3 3 147026182763 24419 2 17872072554 13 16279 11 1439
59 41 38303 16 41 1 66 1 1 1 1 2 1 2 1 1 1 1 2 3 2 2 2 2 1 1 1 2 1 1 4 1 2 1 2 2 1 1 1 1 3 1 2 1 1 1 1 7 131215907988807801731 18935 2 148414936130173046586 2 12623 11 1439
60 43 12703 16 43 1 70 1 1 1 1 2 1 2 2 1 2 1 2 1 1 3 1 1 2 2 2 2 1 1 1 1 3 2 1 2 1 1 1 1 2 1 2 2 3 3 1 2 1 5 1181939181809637901211 3533 2 2885260927363159755018 1 2355 11 415
61 45 20895 16 45 1 72 1 1 1 1 2 1 2 2 1 1 1 1 1 1 4 1 1 1 1 1 1 2 1 1 1 1 1 3 2 2 1 1 1 1 2 1 1 5 2 2 2 3 3 1 5 5133027175201745502323 13073 2 8258474035507268243802 1 8715 11 415

View File

@ -0,0 +1,15 @@
{
"clauses": [
14751,
31135,
47519,
63903
],
"covered": [
14751,
31135,
47519,
63903
],
"palier": 16
}

View File

@ -0,0 +1,127 @@
{
"clauses": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
32159,
33183,
34207,
35231,
36255,
37279,
38303,
39327,
40351,
41375,
42399,
43423,
44447,
45471,
46495,
48543,
49567,
50591,
51615,
52639,
53663,
54687,
55711,
56735,
57759,
58783,
59807,
60831,
61855,
62879,
64927
],
"covered": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
32159,
33183,
34207,
35231,
36255,
37279,
38303,
39327,
40351,
41375,
42399,
43423,
44447,
45471,
46495,
48543,
49567,
50591,
51615,
52639,
53663,
54687,
55711,
56735,
57759,
58783,
59807,
60831,
61855,
62879,
64927
],
"palier": 16
}

View File

@ -0,0 +1,25 @@
{
"state_id": 11,
"base_palier": 12,
"target_palier": 16,
"delta_m": 4,
"lift_size": 64,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 4,
"covered": 4,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/certificats/certificat_D8_E11_palier2p16.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 128,
"t_max_used": 45,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/candidats/candidats_F9to45_E11_palier2p16.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/certificats/certificat_F9to45_E11_palier2p16.json",
"clauses": 60,
"covered": 60
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E11_palier2p16/audits/verification_H6_E11_palier2p16.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
415,
1439,
2463,
3487
],
"palier": 12
}

View File

@ -0,0 +1,69 @@
{
"noyau": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
14751,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
31135,
32159,
33183,
34207,
35231,
36255,
37279,
38303,
39327,
40351,
41375,
42399,
43423,
44447,
45471,
46495,
47519,
48543,
49567,
50591,
51615,
52639,
53663,
54687,
55711,
56735,
57759,
58783,
59807,
60831,
61855,
62879,
63903,
64927
],
"palier": 16
}

View File

@ -0,0 +1,65 @@
{
"noyau": [
415,
1439,
2463,
3487,
4511,
5535,
6559,
7583,
8607,
9631,
10655,
11679,
12703,
13727,
15775,
16799,
17823,
18847,
19871,
20895,
21919,
22943,
23967,
24991,
26015,
27039,
28063,
29087,
30111,
32159,
33183,
34207,
35231,
36255,
37279,
38303,
39327,
40351,
41375,
42399,
43423,
44447,
45471,
46495,
48543,
49567,
50591,
51615,
52639,
53663,
54687,
55711,
56735,
57759,
58783,
59807,
60831,
61855,
62879,
64927
],
"palier": 16
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E12) — couverture des relèvements au palier \(2^{15}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/noyaux/noyau_E12_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/noyaux/noyau_Lift_E12_palier2p15.json`
- taille : 32
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/certificats/certificat_D8_E12_palier2p15.json`
- covered : 2 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/certificats/certificat_F9to51_E12_palier2p15.json`
- covered : 30 classes
## Résultat
- |L| = 32
- |U| = 32
- |L \ U| = 0

View File

@ -0,0 +1,3 @@
classe_mod_2^m,sœur,A8,palier
10271,26655,13,15
26655,10271,13,15
1 classe_mod_2^m sœur A8 palier
2 10271 26655 13 15
3 26655 10271 13 15

View File

@ -0,0 +1,31 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,2079,15,9,2,16,1 1 1 1 2 2 1 5 2,39043,625,1,117876,1,833,12,2079
9,6175,15,9,2,16,1 1 1 1 2 2 1 3 4,26755,1855,1,117876,1,2473,12,2079
9,7199,15,9,1,15,1 1 1 1 2 2 1 1 5,23683,4325,2,58938,1,2883,12,3103
9,12319,15,9,1,14,1 1 1 1 2 2 1 2 3,24707,14801,2,9786,4,9867,12,31
9,18463,15,9,2,17,1 1 1 1 2 2 1 6 2,55427,2773,1,314484,1,3697,12,2079
9,28703,15,9,1,16,1 1 1 1 2 2 1 2 5,24707,8621,2,157242,1,5747,12,31
10,20511,15,10,2,17,1 1 1 1 2 2 1 2 2 4,82313,9241,1,157020,2,12321,12,31
10,23583,15,10,1,17,1 1 1 1 2 2 1 1 4 3,87433,10625,2,275118,1,7083,12,3103
10,31775,15,10,1,16,1 1 1 1 2 2 1 1 3 3,79241,28631,2,78510,2,19087,12,3103
11,3103,15,11,1,19,1 1 1 1 2 2 1 1 2 4 3,290971,1049,2,1218570,1,699,12,3103
11,19487,15,11,1,17,1 1 1 1 2 2 1 1 2 2 3,241819,26339,2,38922,10,17559,12,3103
12,25631,15,12,2,20,1 1 1 1 2 2 1 1 1 1 2 6,686545,12991,1,1019964,2,17321,12,1055
12,27679,15,12,2,20,1 1 1 1 2 2 1 1 2 1 1 6,717265,14029,1,1019964,2,18705,12,3103
12,29727,15,12,2,20,1 1 1 1 2 2 1 1 1 2 3 4,747985,15067,1,1019964,2,20089,12,1055
13,9247,15,13,1,21,1 1 1 1 2 2 1 1 1 1 3 3 3,2370931,7031,2,3102810,1,4687,12,1055
13,11295,15,13,1,23,1 1 1 1 2 2 1 1 2 1 2 3 5,2463091,2147,2,21977178,1,1431,12,3103
13,15391,15,13,2,22,1 1 1 1 2 2 1 1 3 1 1 3 4,2647411,5851,1,6205620,2,7801,12,3103
13,21535,15,13,1,21,1 1 1 1 2 2 1 1 1 4 2 1 3,2923891,16373,2,3102810,2,10915,12,1055
16,8223,15,16,1,28,1 1 1 1 2 2 1 2 1 2 2 1 1 4 1 5,93179681,1319,2,719212926,1,879,12,31
16,13343,15,16,2,30,1 1 1 1 2 2 1 1 1 2 1 2 1 3 4 6,79477537,535,1,3049038588,1,713,12,1055
16,14367,15,16,2,26,1 1 1 1 2 2 1 3 1 1 2 1 1 3 1 4,90158881,9217,1,29139708,11,12289,12,2079
17,16415,15,17,2,29,1 1 1 1 2 2 1 2 1 1 1 2 1 4 2 2 4,267455843,3949,1,1094052084,1,5265,12,31
21,5151,15,21,1,33,1 1 1 1 2 2 1 1 1 3 2 1 1 2 1 1 1 3 1 3 3,20560216147,6275,2,4849097370,7,4183,12,1055
21,17439,15,21,1,34,1 1 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 3 2 5,14931357779,10619,2,30618901146,1,7079,12,1055
21,30751,15,21,1,33,1 1 1 1 2 2 1 3 1 2 2 1 2 1 1 2 1 2 1 4 1,35319059539,37451,2,4849097370,13,24967,12,2079
25,24607,15,25,1,40,1 1 1 1 2 2 1 2 1 3 2 1 2 2 1 1 1 1 2 1 2 1 4 1 3,3007208207939,18965,2,1603957664442,4,12643,12,31
26,4127,15,26,1,42,1 1 1 1 2 2 1 2 2 1 1 1 1 1 2 2 4 2 1 1 2 2 1 1 3 3,7856748491465,2387,2,8110407876654,2,1591,12,31
35,31,15,35,1,56,1 1 1 1 2 2 1 2 1 1 2 1 1 1 2 3 1 1 2 1 2 1 1 1 1 1 3 1 1 1 4 2 2 4 3,106346764803351611,23,2,116109691915784394,2,15,12,31
50,1055,15,50,2,82,1 1 1 1 2 2 1 1 1 1 1 2 1 2 2 1 1 3 4 1 1 1 2 1 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5 1 1 1 1 4 2 6,1823037703082640562865833,157,1,11635517884608139741393116,1,209,12,1055
51,22559,15,51,1,82,1 1 1 1 2 2 1 3 2 1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5,8800132208126656285308923,10049,2,10199721909224434563852618,2,6699,12,2079
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 2079 15 9 2 16 1 1 1 1 2 2 1 5 2 39043 625 1 117876 1 833 12 2079
3 9 6175 15 9 2 16 1 1 1 1 2 2 1 3 4 26755 1855 1 117876 1 2473 12 2079
4 9 7199 15 9 1 15 1 1 1 1 2 2 1 1 5 23683 4325 2 58938 1 2883 12 3103
5 9 12319 15 9 1 14 1 1 1 1 2 2 1 2 3 24707 14801 2 9786 4 9867 12 31
6 9 18463 15 9 2 17 1 1 1 1 2 2 1 6 2 55427 2773 1 314484 1 3697 12 2079
7 9 28703 15 9 1 16 1 1 1 1 2 2 1 2 5 24707 8621 2 157242 1 5747 12 31
8 10 20511 15 10 2 17 1 1 1 1 2 2 1 2 2 4 82313 9241 1 157020 2 12321 12 31
9 10 23583 15 10 1 17 1 1 1 1 2 2 1 1 4 3 87433 10625 2 275118 1 7083 12 3103
10 10 31775 15 10 1 16 1 1 1 1 2 2 1 1 3 3 79241 28631 2 78510 2 19087 12 3103
11 11 3103 15 11 1 19 1 1 1 1 2 2 1 1 2 4 3 290971 1049 2 1218570 1 699 12 3103
12 11 19487 15 11 1 17 1 1 1 1 2 2 1 1 2 2 3 241819 26339 2 38922 10 17559 12 3103
13 12 25631 15 12 2 20 1 1 1 1 2 2 1 1 1 1 2 6 686545 12991 1 1019964 2 17321 12 1055
14 12 27679 15 12 2 20 1 1 1 1 2 2 1 1 2 1 1 6 717265 14029 1 1019964 2 18705 12 3103
15 12 29727 15 12 2 20 1 1 1 1 2 2 1 1 1 2 3 4 747985 15067 1 1019964 2 20089 12 1055
16 13 9247 15 13 1 21 1 1 1 1 2 2 1 1 1 1 3 3 3 2370931 7031 2 3102810 1 4687 12 1055
17 13 11295 15 13 1 23 1 1 1 1 2 2 1 1 2 1 2 3 5 2463091 2147 2 21977178 1 1431 12 3103
18 13 15391 15 13 2 22 1 1 1 1 2 2 1 1 3 1 1 3 4 2647411 5851 1 6205620 2 7801 12 3103
19 13 21535 15 13 1 21 1 1 1 1 2 2 1 1 1 4 2 1 3 2923891 16373 2 3102810 2 10915 12 1055
20 16 8223 15 16 1 28 1 1 1 1 2 2 1 2 1 2 2 1 1 4 1 5 93179681 1319 2 719212926 1 879 12 31
21 16 13343 15 16 2 30 1 1 1 1 2 2 1 1 1 2 1 2 1 3 4 6 79477537 535 1 3049038588 1 713 12 1055
22 16 14367 15 16 2 26 1 1 1 1 2 2 1 3 1 1 2 1 1 3 1 4 90158881 9217 1 29139708 11 12289 12 2079
23 17 16415 15 17 2 29 1 1 1 1 2 2 1 2 1 1 1 2 1 4 2 2 4 267455843 3949 1 1094052084 1 5265 12 31
24 21 5151 15 21 1 33 1 1 1 1 2 2 1 1 1 3 2 1 1 2 1 1 1 3 1 3 3 20560216147 6275 2 4849097370 7 4183 12 1055
25 21 17439 15 21 1 34 1 1 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 3 2 5 14931357779 10619 2 30618901146 1 7079 12 1055
26 21 30751 15 21 1 33 1 1 1 1 2 2 1 3 1 2 2 1 2 1 1 2 1 2 1 4 1 35319059539 37451 2 4849097370 13 24967 12 2079
27 25 24607 15 25 1 40 1 1 1 1 2 2 1 2 1 3 2 1 2 2 1 1 1 1 2 1 2 1 4 1 3 3007208207939 18965 2 1603957664442 4 12643 12 31
28 26 4127 15 26 1 42 1 1 1 1 2 2 1 2 2 1 1 1 1 1 2 2 4 2 1 1 2 2 1 1 3 3 7856748491465 2387 2 8110407876654 2 1591 12 31
29 35 31 15 35 1 56 1 1 1 1 2 2 1 2 1 1 2 1 1 1 2 3 1 1 2 1 2 1 1 1 1 1 3 1 1 1 4 2 2 4 3 106346764803351611 23 2 116109691915784394 2 15 12 31
30 50 1055 15 50 2 82 1 1 1 1 2 2 1 1 1 1 1 2 1 2 2 1 1 3 4 1 1 1 2 1 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5 1 1 1 1 4 2 6 1823037703082640562865833 157 1 11635517884608139741393116 1 209 12 1055
31 51 22559 15 51 1 82 1 1 1 1 2 2 1 3 2 1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5 8800132208126656285308923 10049 2 10199721909224434563852618 2 6699 12 2079

View File

@ -0,0 +1,11 @@
{
"clauses": [
10271,
26655
],
"covered": [
10271,
26655
],
"palier": 15
}

View File

@ -0,0 +1,67 @@
{
"clauses": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
27679,
28703,
29727,
30751,
31775
],
"covered": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
27679,
28703,
29727,
30751,
31775
],
"palier": 15
}

View File

@ -0,0 +1,25 @@
{
"state_id": 12,
"base_palier": 12,
"target_palier": 15,
"delta_m": 3,
"lift_size": 32,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 2,
"covered": 2,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/certificats/certificat_D8_E12_palier2p15.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 120,
"t_max_used": 51,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/candidats/candidats_F9to51_E12_palier2p15.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/certificats/certificat_F9to51_E12_palier2p15.json",
"clauses": 30,
"covered": 30
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p15/audits/verification_H6_E12_palier2p15.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
31,
1055,
2079,
3103
],
"palier": 12
}

View File

@ -0,0 +1,37 @@
{
"noyau": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
10271,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
26655,
27679,
28703,
29727,
30751,
31775
],
"palier": 15
}

View File

@ -0,0 +1,35 @@
{
"noyau": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
27679,
28703,
29727,
30751,
31775
],
"palier": 15
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E12) — couverture des relèvements au palier \(2^{16}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/noyaux/noyau_E12_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/noyaux/noyau_Lift_E12_palier2p16.json`
- taille : 64
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/certificats/certificat_D8_E12_palier2p16.json`
- covered : 4 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/certificats/certificat_F9to51_E12_palier2p16.json`
- covered : 60 classes
## Résultat
- |L| = 64
- |U| = 64
- |L \ U| = 0

View File

@ -0,0 +1,5 @@
classe_mod_2^m,sœur,A8,palier
10271,43039,13,16
26655,59423,13,16
43039,10271,13,16
59423,26655,13,16
1 classe_mod_2^m sœur A8 palier
2 10271 43039 13 16
3 26655 59423 13 16
4 43039 10271 13 16
5 59423 26655 13 16

View File

@ -0,0 +1,61 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,2079,16,9,2,16,1 1 1 1 2 2 1 5 2,39043,625,1,117876,1,833,12,2079
9,6175,16,9,2,16,1 1 1 1 2 2 1 3 4,26755,1855,1,117876,1,2473,12,2079
9,7199,16,9,1,15,1 1 1 1 2 2 1 1 5,23683,4325,2,58938,1,2883,12,3103
9,12319,16,9,1,14,1 1 1 1 2 2 1 2 3,24707,14801,2,9786,4,9867,12,31
9,18463,16,9,2,17,1 1 1 1 2 2 1 6 2,55427,2773,1,314484,1,3697,12,2079
9,28703,16,9,1,16,1 1 1 1 2 2 1 2 5,24707,8621,2,157242,1,5747,12,31
9,34847,16,9,1,15,1 1 1 1 2 2 1 5 1,39043,20933,2,58938,1,13955,12,2079
9,38943,16,9,1,15,1 1 1 1 2 2 1 3 3,26755,23393,2,58938,1,15595,12,2079
9,39967,16,9,2,18,1 1 1 1 2 2 1 1 8,23683,3001,1,707700,1,4001,12,3103
9,45087,16,9,1,14,1 1 1 1 2 2 1 2 3,24707,54167,2,9786,4,36111,12,31
9,51231,16,9,2,18,1 1 1 1 2 2 1 7 2,88195,3847,1,707700,1,5129,12,2079
9,61471,16,9,2,15,1 1 1 1 2 2 1 2 4,24707,36925,1,19572,4,49233,12,31
10,20511,16,10,2,17,1 1 1 1 2 2 1 2 2 4,82313,9241,1,157020,2,12321,12,31
10,23583,16,10,1,17,1 1 1 1 2 2 1 1 4 3,87433,10625,2,275118,1,7083,12,3103
10,31775,16,10,1,16,1 1 1 1 2 2 1 1 3 3,79241,28631,2,78510,2,19087,12,3103
10,54303,16,10,1,16,1 1 1 1 2 2 1 1 1 5,73097,48929,2,78510,2,32619,12,1055
10,55327,16,10,2,18,1 1 1 1 2 2 1 3 2 4,96649,12463,1,550236,1,16617,12,2079
10,63519,16,10,1,16,1 1 1 1 2 2 1 3 1 3,88457,57233,2,78510,2,38155,12,2079
11,3103,16,11,1,19,1 1 1 1 2 2 1 1 2 4 3,290971,1049,2,1218570,1,699,12,3103
11,19487,16,11,1,17,1 1 1 1 2 2 1 1 2 2 3,241819,26339,2,38922,10,17559,12,3103
11,42015,16,11,2,18,1 1 1 1 2 2 1 1 1 1 6,223387,28393,1,77844,9,37857,12,1055
11,44063,16,11,1,18,1 1 1 1 2 2 1 1 2 1 5,233627,29777,2,432138,1,19851,12,3103
11,48159,16,11,2,18,1 1 1 1 2 2 1 1 3 1 4,254107,32545,1,77844,10,43393,12,3103
11,53279,16,11,1,18,1 1 1 1 2 2 1 2 2 2 3,279707,36005,2,432138,1,24003,12,31
11,56351,16,11,1,18,1 1 1 1 2 2 1 1 4 1 3,295067,38081,2,432138,1,25387,12,3103
11,57375,16,11,2,18,1 1 1 1 2 2 1 2 1 4 2,300187,38773,1,77844,13,51697,12,31
12,25631,16,12,2,20,1 1 1 1 2 2 1 1 1 1 2 6,686545,12991,1,1019964,2,17321,12,1055
12,27679,16,12,2,20,1 1 1 1 2 2 1 1 2 1 1 6,717265,14029,1,1019964,2,18705,12,3103
12,29727,16,12,2,20,1 1 1 1 2 2 1 1 1 2 3 4,747985,15067,1,1019964,2,20089,12,1055
12,32799,16,12,2,24,1 1 1 1 2 2 1 2 1 1 3 8,794065,1039,1,48205884,1,1385,12,31
12,35871,16,12,2,20,1 1 1 1 2 2 1 1 2 3 1 4,840145,18181,1,1019964,3,24241,12,3103
12,36895,16,12,2,22,1 1 1 1 2 2 1 2 2 1 2 6,855505,4675,1,10457148,1,6233,12,31
13,9247,16,13,1,21,1 1 1 1 2 2 1 1 1 1 3 3 3,2370931,7031,2,3102810,1,4687,12,1055
13,11295,16,13,1,23,1 1 1 1 2 2 1 1 2 1 2 3 5,2463091,2147,2,21977178,1,1431,12,3103
13,15391,16,13,2,22,1 1 1 1 2 2 1 1 3 1 1 3 4,2647411,5851,1,6205620,2,7801,12,3103
13,21535,16,13,1,21,1 1 1 1 2 2 1 1 1 4 2 1 3,2923891,16373,2,3102810,2,10915,12,1055
13,62495,16,13,1,24,1 1 1 1 2 2 1 1 1 2 2 4 5,2669939,5939,2,47143002,1,3959,12,1055
14,64543,16,14,1,24,1 1 1 1 2 2 1 1 3 2 1 1 4 3,10383449,18401,2,40765710,1,12267,12,3103
15,37919,16,15,1,28,1 1 1 1 2 2 1 1 1 3 1 2 1 1 9,22464779,2027,2,776608554,1,1351,12,1055
15,52255,16,15,1,24,1 1 1 1 2 2 1 1 2 2 1 1 1 2 5,21979403,44693,2,21633834,2,29795,12,3103
16,8223,16,16,1,28,1 1 1 1 2 2 1 2 1 2 2 1 1 4 1 5,93179681,1319,2,719212926,1,879,12,31
16,13343,16,16,2,30,1 1 1 1 2 2 1 1 1 2 1 2 1 3 4 6,79477537,535,1,3049038588,1,713,12,1055
16,14367,16,16,2,26,1 1 1 1 2 2 1 3 1 1 2 1 1 3 1 4,90158881,9217,1,29139708,11,12289,12,2079
16,60447,16,16,1,25,1 1 1 1 2 2 1 1 2 1 1 1 2 3 2 3,67502881,77549,2,14569854,7,51699,12,3103
17,16415,16,17,2,29,1 1 1 1 2 2 1 2 1 1 1 2 1 4 2 2 4,267455843,3949,1,1094052084,1,5265,12,31
17,46111,16,17,2,31,1 1 1 1 2 2 1 1 1 2 1 1 1 1 4 2 8,190099811,2773,1,5925890292,1,3697,12,1055
18,33823,16,18,2,29,1 1 1 1 2 2 1 1 1 1 1 4 1 1 3 1 4 2,758891561,24409,1,60930780,42,32545,12,1055
18,58399,16,18,1,28,1 1 1 1 2 2 1 1 1 1 2 1 2 3 1 3 1 3,650142761,84287,2,30465390,34,56191,12,1055
21,5151,16,21,1,33,1 1 1 1 2 2 1 1 1 3 2 1 1 2 1 1 1 3 1 3 3,20560216147,6275,2,4849097370,7,4183,12,1055
21,17439,16,21,1,34,1 1 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 3 2 5,14931357779,10619,2,30618901146,1,7079,12,1055
21,30751,16,21,1,33,1 1 1 1 2 2 1 3 1 2 2 1 2 1 1 2 1 2 1 4 1,35319059539,37451,2,4849097370,13,24967,12,2079
24,49183,16,24,1,41,1 1 1 1 2 2 1 2 1 1 1 1 1 1 3 2 1 3 1 1 2 1 3 7,498012576961,6317,2,6032210693694,1,4211,12,31
25,24607,16,25,1,40,1 1 1 1 2 2 1 2 1 3 2 1 2 2 1 1 1 1 2 1 2 1 4 1 3,3007208207939,18965,2,1603957664442,4,12643,12,31
26,4127,16,26,1,42,1 1 1 1 2 2 1 2 2 1 1 1 1 1 2 2 4 2 1 1 2 2 1 1 3 3,7856748491465,2387,2,8110407876654,2,1591,12,31
27,47135,16,27,1,43,1 1 1 1 2 2 1 3 1 1 1 2 1 1 1 4 1 1 1 2 1 2 1 1 4 2 3,19803897667675,40865,2,11137084096650,3,27243,12,2079
32,40991,16,32,2,52,1 1 1 1 2 2 1 2 1 2 1 2 1 1 1 1 1 3 1 1 4 1 2 1 2 1 2 2 3 2 1 4,5064353632341601,16867,1,6098718126704124,3,22489,12,31
35,31,16,35,1,56,1 1 1 1 2 2 1 2 1 1 2 1 1 1 2 3 1 1 2 1 2 1 1 1 1 1 3 1 1 1 4 2 2 4 3,106346764803351611,23,2,116109691915784394,2,15,12,31
36,50207,16,36,1,59,1 1 1 1 2 2 1 1 1 1 1 1 2 1 1 1 1 1 3 2 2 1 1 1 1 2 1 1 5 2 2 2 3 3 1 5,270060506220390577,13073,2,1429192986316272222,1,8715,12,1055
50,1055,16,50,2,82,1 1 1 1 2 2 1 1 1 1 1 2 1 2 2 1 1 3 4 1 1 1 2 1 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5 1 1 1 1 4 2 6,1823037703082640562865833,157,1,11635517884608139741393116,1,209,12,1055
51,22559,16,51,1,82,1 1 1 1 2 2 1 3 2 1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5,8800132208126656285308923,10049,2,10199721909224434563852618,2,6699,12,2079
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 2079 16 9 2 16 1 1 1 1 2 2 1 5 2 39043 625 1 117876 1 833 12 2079
3 9 6175 16 9 2 16 1 1 1 1 2 2 1 3 4 26755 1855 1 117876 1 2473 12 2079
4 9 7199 16 9 1 15 1 1 1 1 2 2 1 1 5 23683 4325 2 58938 1 2883 12 3103
5 9 12319 16 9 1 14 1 1 1 1 2 2 1 2 3 24707 14801 2 9786 4 9867 12 31
6 9 18463 16 9 2 17 1 1 1 1 2 2 1 6 2 55427 2773 1 314484 1 3697 12 2079
7 9 28703 16 9 1 16 1 1 1 1 2 2 1 2 5 24707 8621 2 157242 1 5747 12 31
8 9 34847 16 9 1 15 1 1 1 1 2 2 1 5 1 39043 20933 2 58938 1 13955 12 2079
9 9 38943 16 9 1 15 1 1 1 1 2 2 1 3 3 26755 23393 2 58938 1 15595 12 2079
10 9 39967 16 9 2 18 1 1 1 1 2 2 1 1 8 23683 3001 1 707700 1 4001 12 3103
11 9 45087 16 9 1 14 1 1 1 1 2 2 1 2 3 24707 54167 2 9786 4 36111 12 31
12 9 51231 16 9 2 18 1 1 1 1 2 2 1 7 2 88195 3847 1 707700 1 5129 12 2079
13 9 61471 16 9 2 15 1 1 1 1 2 2 1 2 4 24707 36925 1 19572 4 49233 12 31
14 10 20511 16 10 2 17 1 1 1 1 2 2 1 2 2 4 82313 9241 1 157020 2 12321 12 31
15 10 23583 16 10 1 17 1 1 1 1 2 2 1 1 4 3 87433 10625 2 275118 1 7083 12 3103
16 10 31775 16 10 1 16 1 1 1 1 2 2 1 1 3 3 79241 28631 2 78510 2 19087 12 3103
17 10 54303 16 10 1 16 1 1 1 1 2 2 1 1 1 5 73097 48929 2 78510 2 32619 12 1055
18 10 55327 16 10 2 18 1 1 1 1 2 2 1 3 2 4 96649 12463 1 550236 1 16617 12 2079
19 10 63519 16 10 1 16 1 1 1 1 2 2 1 3 1 3 88457 57233 2 78510 2 38155 12 2079
20 11 3103 16 11 1 19 1 1 1 1 2 2 1 1 2 4 3 290971 1049 2 1218570 1 699 12 3103
21 11 19487 16 11 1 17 1 1 1 1 2 2 1 1 2 2 3 241819 26339 2 38922 10 17559 12 3103
22 11 42015 16 11 2 18 1 1 1 1 2 2 1 1 1 1 6 223387 28393 1 77844 9 37857 12 1055
23 11 44063 16 11 1 18 1 1 1 1 2 2 1 1 2 1 5 233627 29777 2 432138 1 19851 12 3103
24 11 48159 16 11 2 18 1 1 1 1 2 2 1 1 3 1 4 254107 32545 1 77844 10 43393 12 3103
25 11 53279 16 11 1 18 1 1 1 1 2 2 1 2 2 2 3 279707 36005 2 432138 1 24003 12 31
26 11 56351 16 11 1 18 1 1 1 1 2 2 1 1 4 1 3 295067 38081 2 432138 1 25387 12 3103
27 11 57375 16 11 2 18 1 1 1 1 2 2 1 2 1 4 2 300187 38773 1 77844 13 51697 12 31
28 12 25631 16 12 2 20 1 1 1 1 2 2 1 1 1 1 2 6 686545 12991 1 1019964 2 17321 12 1055
29 12 27679 16 12 2 20 1 1 1 1 2 2 1 1 2 1 1 6 717265 14029 1 1019964 2 18705 12 3103
30 12 29727 16 12 2 20 1 1 1 1 2 2 1 1 1 2 3 4 747985 15067 1 1019964 2 20089 12 1055
31 12 32799 16 12 2 24 1 1 1 1 2 2 1 2 1 1 3 8 794065 1039 1 48205884 1 1385 12 31
32 12 35871 16 12 2 20 1 1 1 1 2 2 1 1 2 3 1 4 840145 18181 1 1019964 3 24241 12 3103
33 12 36895 16 12 2 22 1 1 1 1 2 2 1 2 2 1 2 6 855505 4675 1 10457148 1 6233 12 31
34 13 9247 16 13 1 21 1 1 1 1 2 2 1 1 1 1 3 3 3 2370931 7031 2 3102810 1 4687 12 1055
35 13 11295 16 13 1 23 1 1 1 1 2 2 1 1 2 1 2 3 5 2463091 2147 2 21977178 1 1431 12 3103
36 13 15391 16 13 2 22 1 1 1 1 2 2 1 1 3 1 1 3 4 2647411 5851 1 6205620 2 7801 12 3103
37 13 21535 16 13 1 21 1 1 1 1 2 2 1 1 1 4 2 1 3 2923891 16373 2 3102810 2 10915 12 1055
38 13 62495 16 13 1 24 1 1 1 1 2 2 1 1 1 2 2 4 5 2669939 5939 2 47143002 1 3959 12 1055
39 14 64543 16 14 1 24 1 1 1 1 2 2 1 1 3 2 1 1 4 3 10383449 18401 2 40765710 1 12267 12 3103
40 15 37919 16 15 1 28 1 1 1 1 2 2 1 1 1 3 1 2 1 1 9 22464779 2027 2 776608554 1 1351 12 1055
41 15 52255 16 15 1 24 1 1 1 1 2 2 1 1 2 2 1 1 1 2 5 21979403 44693 2 21633834 2 29795 12 3103
42 16 8223 16 16 1 28 1 1 1 1 2 2 1 2 1 2 2 1 1 4 1 5 93179681 1319 2 719212926 1 879 12 31
43 16 13343 16 16 2 30 1 1 1 1 2 2 1 1 1 2 1 2 1 3 4 6 79477537 535 1 3049038588 1 713 12 1055
44 16 14367 16 16 2 26 1 1 1 1 2 2 1 3 1 1 2 1 1 3 1 4 90158881 9217 1 29139708 11 12289 12 2079
45 16 60447 16 16 1 25 1 1 1 1 2 2 1 1 2 1 1 1 2 3 2 3 67502881 77549 2 14569854 7 51699 12 3103
46 17 16415 16 17 2 29 1 1 1 1 2 2 1 2 1 1 1 2 1 4 2 2 4 267455843 3949 1 1094052084 1 5265 12 31
47 17 46111 16 17 2 31 1 1 1 1 2 2 1 1 1 2 1 1 1 1 4 2 8 190099811 2773 1 5925890292 1 3697 12 1055
48 18 33823 16 18 2 29 1 1 1 1 2 2 1 1 1 1 1 4 1 1 3 1 4 2 758891561 24409 1 60930780 42 32545 12 1055
49 18 58399 16 18 1 28 1 1 1 1 2 2 1 1 1 1 2 1 2 3 1 3 1 3 650142761 84287 2 30465390 34 56191 12 1055
50 21 5151 16 21 1 33 1 1 1 1 2 2 1 1 1 3 2 1 1 2 1 1 1 3 1 3 3 20560216147 6275 2 4849097370 7 4183 12 1055
51 21 17439 16 21 1 34 1 1 1 1 2 2 1 1 1 1 1 1 1 1 2 2 2 2 3 2 5 14931357779 10619 2 30618901146 1 7079 12 1055
52 21 30751 16 21 1 33 1 1 1 1 2 2 1 3 1 2 2 1 2 1 1 2 1 2 1 4 1 35319059539 37451 2 4849097370 13 24967 12 2079
53 24 49183 16 24 1 41 1 1 1 1 2 2 1 2 1 1 1 1 1 1 3 2 1 3 1 1 2 1 3 7 498012576961 6317 2 6032210693694 1 4211 12 31
54 25 24607 16 25 1 40 1 1 1 1 2 2 1 2 1 3 2 1 2 2 1 1 1 1 2 1 2 1 4 1 3 3007208207939 18965 2 1603957664442 4 12643 12 31
55 26 4127 16 26 1 42 1 1 1 1 2 2 1 2 2 1 1 1 1 1 2 2 4 2 1 1 2 2 1 1 3 3 7856748491465 2387 2 8110407876654 2 1591 12 31
56 27 47135 16 27 1 43 1 1 1 1 2 2 1 3 1 1 1 2 1 1 1 4 1 1 1 2 1 2 1 1 4 2 3 19803897667675 40865 2 11137084096650 3 27243 12 2079
57 32 40991 16 32 2 52 1 1 1 1 2 2 1 2 1 2 1 2 1 1 1 1 1 3 1 1 4 1 2 1 2 1 2 2 3 2 1 4 5064353632341601 16867 1 6098718126704124 3 22489 12 31
58 35 31 16 35 1 56 1 1 1 1 2 2 1 2 1 1 2 1 1 1 2 3 1 1 2 1 2 1 1 1 1 1 3 1 1 1 4 2 2 4 3 106346764803351611 23 2 116109691915784394 2 15 12 31
59 36 50207 16 36 1 59 1 1 1 1 2 2 1 1 1 1 1 1 2 1 1 1 1 1 3 2 2 1 1 1 1 2 1 1 5 2 2 2 3 3 1 5 270060506220390577 13073 2 1429192986316272222 1 8715 12 1055
60 50 1055 16 50 2 82 1 1 1 1 2 2 1 1 1 1 1 2 1 2 2 1 1 3 4 1 1 1 2 1 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5 1 1 1 1 4 2 6 1823037703082640562865833 157 1 11635517884608139741393116 1 209 12 1055
61 51 22559 16 51 1 82 1 1 1 1 2 2 1 3 2 1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5 8800132208126656285308923 10049 2 10199721909224434563852618 2 6699 12 2079

View File

@ -0,0 +1,15 @@
{
"clauses": [
10271,
26655,
43039,
59423
],
"covered": [
10271,
26655,
43039,
59423
],
"palier": 16
}

View File

@ -0,0 +1,127 @@
{
"clauses": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
27679,
28703,
29727,
30751,
31775,
32799,
33823,
34847,
35871,
36895,
37919,
38943,
39967,
40991,
42015,
44063,
45087,
46111,
47135,
48159,
49183,
50207,
51231,
52255,
53279,
54303,
55327,
56351,
57375,
58399,
60447,
61471,
62495,
63519,
64543
],
"covered": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
27679,
28703,
29727,
30751,
31775,
32799,
33823,
34847,
35871,
36895,
37919,
38943,
39967,
40991,
42015,
44063,
45087,
46111,
47135,
48159,
49183,
50207,
51231,
52255,
53279,
54303,
55327,
56351,
57375,
58399,
60447,
61471,
62495,
63519,
64543
],
"palier": 16
}

View File

@ -0,0 +1,25 @@
{
"state_id": 12,
"base_palier": 12,
"target_palier": 16,
"delta_m": 4,
"lift_size": 64,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 4,
"covered": 4,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/certificats/certificat_D8_E12_palier2p16.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 128,
"t_max_used": 51,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/candidats/candidats_F9to51_E12_palier2p16.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/certificats/certificat_F9to51_E12_palier2p16.json",
"clauses": 60,
"covered": 60
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E12_palier2p16/audits/verification_H6_E12_palier2p16.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
31,
1055,
2079,
3103
],
"palier": 12
}

View File

@ -0,0 +1,69 @@
{
"noyau": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
10271,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
26655,
27679,
28703,
29727,
30751,
31775,
32799,
33823,
34847,
35871,
36895,
37919,
38943,
39967,
40991,
42015,
43039,
44063,
45087,
46111,
47135,
48159,
49183,
50207,
51231,
52255,
53279,
54303,
55327,
56351,
57375,
58399,
59423,
60447,
61471,
62495,
63519,
64543
],
"palier": 16
}

View File

@ -0,0 +1,65 @@
{
"noyau": [
31,
1055,
2079,
3103,
4127,
5151,
6175,
7199,
8223,
9247,
11295,
12319,
13343,
14367,
15391,
16415,
17439,
18463,
19487,
20511,
21535,
22559,
23583,
24607,
25631,
27679,
28703,
29727,
30751,
31775,
32799,
33823,
34847,
35871,
36895,
37919,
38943,
39967,
40991,
42015,
44063,
45087,
46111,
47135,
48159,
49183,
50207,
51231,
52255,
53279,
54303,
55327,
56351,
57375,
58399,
60447,
61471,
62495,
63519,
64543
],
"palier": 16
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E13) — couverture des relèvements au palier \(2^{15}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/noyaux/noyau_E13_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/noyaux/noyau_Lift_E13_palier2p15.json`
- taille : 32
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/certificats/certificat_D8_E13_palier2p15.json`
- covered : 2 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/certificats/certificat_F9to42_E13_palier2p15.json`
- covered : 30 classes
## Résultat
- |L| = 32
- |U| = 32
- |L \ U| = 0

View File

@ -0,0 +1,3 @@
classe_mod_2^m,sœur,A8,palier
3551,19935,13,15
19935,3551,13,15
1 classe_mod_2^m sœur A8 palier
2 3551 19935 13 15
3 19935 3551 13 15

View File

@ -0,0 +1,31 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,5599,15,9,2,17,1 1 1 1 3 1 1 2 6,26435,841,1,314484,1,1121,13,1503
9,11743,15,9,1,15,1 1 1 1 3 1 1 5 1,40771,7055,2,58938,1,4703,13,3551
9,15839,15,9,1,15,1 1 1 1 3 1 1 3 3,28483,9515,2,58938,1,6343,13,3551
9,16863,15,9,2,16,1 1 1 1 3 1 1 1 6,25411,5065,1,117876,1,6753,13,479
9,21983,15,9,1,14,1 1 1 1 3 1 1 2 3,26435,26411,2,9786,4,17607,13,1503
9,28127,15,9,1,25,1 1 1 1 3 1 1 15 1,16801603,17,2,100623930,1,11,13,3551
10,8671,15,10,2,17,1 1 1 1 3 1 1 1 3 4,84425,3907,1,157020,2,5209,13,479
10,31199,15,10,1,20,1 1 1 1 3 1 1 1 1 9,78281,1757,2,3027630,1,1171,13,2527
11,479,15,11,2,18,1 1 1 1 3 1 1 1 4 2 2,343387,325,1,77844,15,433,13,479
11,13791,15,11,1,17,1 1 1 1 3 1 1 2 2 1 3,278875,18641,2,38922,11,12427,13,1503
11,32223,15,11,1,17,1 1 1 1 3 1 1 3 2 2 1,371035,43553,2,38922,16,29035,13,3551
13,1503,15,13,1,24,1 1 1 1 3 1 1 2 1 3 1 1 7,2874419,143,2,47143002,1,95,13,1503
13,9695,15,13,2,23,1 1 1 1 3 1 1 2 1 1 4 2 4,3243059,1843,1,18788532,1,2457,13,1503
13,10719,15,13,2,22,1 1 1 1 3 1 1 1 1 1 1 3 6,2240563,4075,1,6205620,1,5433,13,2527
13,14815,15,13,1,31,1 1 1 1 3 1 1 1 1 3 1 1 15,2424883,11,2,6439262298,1,7,13,2527
13,18911,15,13,2,22,1 1 1 1 3 1 1 1 1 1 4 2 4,2609203,7189,1,6205620,2,9585,13,2527
13,20959,15,13,1,21,1 1 1 1 3 1 1 1 2 1 3 2 3,2701363,15935,2,3102810,2,10623,13,479
13,25055,15,13,1,21,1 1 1 1 3 1 1 1 3 1 2 2 3,2885683,19049,2,3102810,2,12699,13,479
14,7647,15,14,1,22,1 1 1 1 3 1 1 3 1 2 1 1 4 1,11549849,8723,2,3016974,7,5815,13,3551
14,24031,15,14,1,23,1 1 1 1 3 1 1 3 1 1 1 1 4 3,9567385,13703,2,15599886,1,9135,13,3551
14,26079,15,14,1,22,1 1 1 1 3 1 1 2 1 1 1 1 4 3,7746713,29741,2,3016974,4,19827,13,1503
16,2527,15,16,2,27,1 1 1 1 3 1 1 1 1 1 2 2 1 1 5 4,71513441,811,1,230466300,1,1081,13,2527
16,6623,15,16,2,27,1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4,114238817,2125,1,230466300,2,2833,13,2527
16,12767,15,16,2,26,1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4,111218017,8191,1,29139708,13,10921,13,479
16,29151,15,16,2,28,1 1 1 1 3 1 1 1 2 2 1 2 2 1 2 6,80792929,4675,1,633119484,1,6233,13,479
17,30175,15,17,1,29,1 1 1 1 3 1 1 2 2 2 1 2 2 1 2 1 5,341531683,7259,2,1352332410,1,4839,13,1503
19,17887,15,19,1,32,1 1 1 1 3 1 1 2 1 2 1 1 4 1 1 1 1 1 7,2565819707,4841,2,10560378954,1,3227,13,1503
24,4575,15,24,1,38,1 1 1 1 3 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5,635666957057,4703,2,259774647870,4,3135,13,479
26,23007,15,26,1,41,1 1 1 1 3 1 1 1 1 2 1 1 4 1 1 1 3 2 1 1 1 2 1 3 4 1,6714415551241,26597,2,1513338109998,8,17731,13,2527
42,27103,15,42,1,68,1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5,358436715937075385417,10049,2,666605737275033759150,1,6699,13,2527
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 5599 15 9 2 17 1 1 1 1 3 1 1 2 6 26435 841 1 314484 1 1121 13 1503
3 9 11743 15 9 1 15 1 1 1 1 3 1 1 5 1 40771 7055 2 58938 1 4703 13 3551
4 9 15839 15 9 1 15 1 1 1 1 3 1 1 3 3 28483 9515 2 58938 1 6343 13 3551
5 9 16863 15 9 2 16 1 1 1 1 3 1 1 1 6 25411 5065 1 117876 1 6753 13 479
6 9 21983 15 9 1 14 1 1 1 1 3 1 1 2 3 26435 26411 2 9786 4 17607 13 1503
7 9 28127 15 9 1 25 1 1 1 1 3 1 1 15 1 16801603 17 2 100623930 1 11 13 3551
8 10 8671 15 10 2 17 1 1 1 1 3 1 1 1 3 4 84425 3907 1 157020 2 5209 13 479
9 10 31199 15 10 1 20 1 1 1 1 3 1 1 1 1 9 78281 1757 2 3027630 1 1171 13 2527
10 11 479 15 11 2 18 1 1 1 1 3 1 1 1 4 2 2 343387 325 1 77844 15 433 13 479
11 11 13791 15 11 1 17 1 1 1 1 3 1 1 2 2 1 3 278875 18641 2 38922 11 12427 13 1503
12 11 32223 15 11 1 17 1 1 1 1 3 1 1 3 2 2 1 371035 43553 2 38922 16 29035 13 3551
13 13 1503 15 13 1 24 1 1 1 1 3 1 1 2 1 3 1 1 7 2874419 143 2 47143002 1 95 13 1503
14 13 9695 15 13 2 23 1 1 1 1 3 1 1 2 1 1 4 2 4 3243059 1843 1 18788532 1 2457 13 1503
15 13 10719 15 13 2 22 1 1 1 1 3 1 1 1 1 1 1 3 6 2240563 4075 1 6205620 1 5433 13 2527
16 13 14815 15 13 1 31 1 1 1 1 3 1 1 1 1 3 1 1 15 2424883 11 2 6439262298 1 7 13 2527
17 13 18911 15 13 2 22 1 1 1 1 3 1 1 1 1 1 4 2 4 2609203 7189 1 6205620 2 9585 13 2527
18 13 20959 15 13 1 21 1 1 1 1 3 1 1 1 2 1 3 2 3 2701363 15935 2 3102810 2 10623 13 479
19 13 25055 15 13 1 21 1 1 1 1 3 1 1 1 3 1 2 2 3 2885683 19049 2 3102810 2 12699 13 479
20 14 7647 15 14 1 22 1 1 1 1 3 1 1 3 1 2 1 1 4 1 11549849 8723 2 3016974 7 5815 13 3551
21 14 24031 15 14 1 23 1 1 1 1 3 1 1 3 1 1 1 1 4 3 9567385 13703 2 15599886 1 9135 13 3551
22 14 26079 15 14 1 22 1 1 1 1 3 1 1 2 1 1 1 1 4 3 7746713 29741 2 3016974 4 19827 13 1503
23 16 2527 15 16 2 27 1 1 1 1 3 1 1 1 1 1 2 2 1 1 5 4 71513441 811 1 230466300 1 1081 13 2527
24 16 6623 15 16 2 27 1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4 114238817 2125 1 230466300 2 2833 13 2527
25 16 12767 15 16 2 26 1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4 111218017 8191 1 29139708 13 10921 13 479
26 16 29151 15 16 2 28 1 1 1 1 3 1 1 1 2 2 1 2 2 1 2 6 80792929 4675 1 633119484 1 6233 13 479
27 17 30175 15 17 1 29 1 1 1 1 3 1 1 2 2 2 1 2 2 1 2 1 5 341531683 7259 2 1352332410 1 4839 13 1503
28 19 17887 15 19 1 32 1 1 1 1 3 1 1 2 1 2 1 1 4 1 1 1 1 1 7 2565819707 4841 2 10560378954 1 3227 13 1503
29 24 4575 15 24 1 38 1 1 1 1 3 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5 635666957057 4703 2 259774647870 4 3135 13 479
30 26 23007 15 26 1 41 1 1 1 1 3 1 1 1 1 2 1 1 4 1 1 1 3 2 1 1 1 2 1 3 4 1 6714415551241 26597 2 1513338109998 8 17731 13 2527
31 42 27103 15 42 1 68 1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5 358436715937075385417 10049 2 666605737275033759150 1 6699 13 2527

View File

@ -0,0 +1,11 @@
{
"clauses": [
3551,
19935
],
"covered": [
3551,
19935
],
"palier": 15
}

View File

@ -0,0 +1,67 @@
{
"clauses": [
479,
1503,
2527,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223
],
"covered": [
479,
1503,
2527,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223
],
"palier": 15
}

View File

@ -0,0 +1,25 @@
{
"state_id": 13,
"base_palier": 12,
"target_palier": 15,
"delta_m": 3,
"lift_size": 32,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 2,
"covered": 2,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/certificats/certificat_D8_E13_palier2p15.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 120,
"t_max_used": 42,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/candidats/candidats_F9to42_E13_palier2p15.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/certificats/certificat_F9to42_E13_palier2p15.json",
"clauses": 30,
"covered": 30
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p15/audits/verification_H6_E13_palier2p15.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
479,
1503,
2527,
3551
],
"palier": 12
}

View File

@ -0,0 +1,37 @@
{
"noyau": [
479,
1503,
2527,
3551,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
19935,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223
],
"palier": 15
}

View File

@ -0,0 +1,35 @@
{
"noyau": [
479,
1503,
2527,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223
],
"palier": 15
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E13) — couverture des relèvements au palier \(2^{16}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/noyaux/noyau_E13_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/noyaux/noyau_Lift_E13_palier2p16.json`
- taille : 64
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/certificats/certificat_D8_E13_palier2p16.json`
- covered : 4 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/certificats/certificat_F9to44_E13_palier2p16.json`
- covered : 60 classes
## Résultat
- |L| = 64
- |U| = 64
- |L \ U| = 0

View File

@ -0,0 +1,5 @@
classe_mod_2^m,sœur,A8,palier
3551,36319,13,16
19935,52703,13,16
36319,3551,13,16
52703,19935,13,16
1 classe_mod_2^m sœur A8 palier
2 3551 36319 13 16
3 19935 52703 13 16
4 36319 3551 13 16
5 52703 19935 13 16

View File

@ -0,0 +1,61 @@
horizon_t,classe_mod_2^m,m,t,a,A_t,mot_a0..,C_t,y,y_mod_3,DeltaF,Nf,preimage_m,etat_id,base_mod_4096
9,5599,16,9,2,17,1 1 1 1 3 1 1 2 6,26435,841,1,314484,1,1121,13,1503
9,11743,16,9,1,15,1 1 1 1 3 1 1 5 1,40771,7055,2,58938,1,4703,13,3551
9,15839,16,9,1,15,1 1 1 1 3 1 1 3 3,28483,9515,2,58938,1,6343,13,3551
9,16863,16,9,2,16,1 1 1 1 3 1 1 1 6,25411,5065,1,117876,1,6753,13,479
9,21983,16,9,1,14,1 1 1 1 3 1 1 2 3,26435,26411,2,9786,4,17607,13,1503
9,28127,16,9,1,25,1 1 1 1 3 1 1 15 1,16801603,17,2,100623930,1,11,13,3551
9,38367,16,9,2,15,1 1 1 1 3 1 1 2 4,26435,23047,1,19572,4,30729,13,1503
9,44511,16,9,2,16,1 1 1 1 3 1 1 5 2,40771,13369,1,117876,1,17825,13,3551
9,48607,16,9,2,16,1 1 1 1 3 1 1 3 4,28483,14599,1,117876,1,19465,13,3551
9,49631,16,9,1,15,1 1 1 1 3 1 1 1 5,25411,29813,2,58938,1,19875,13,479
9,54751,16,9,1,14,1 1 1 1 3 1 1 2 3,26435,65777,2,9786,4,43851,13,1503
9,60895,16,9,2,17,1 1 1 1 3 1 1 6 2,57155,9145,1,314484,1,12193,13,3551
10,8671,16,10,2,17,1 1 1 1 3 1 1 1 3 4,84425,3907,1,157020,2,5209,13,479
10,31199,16,10,1,20,1 1 1 1 3 1 1 1 1 9,78281,1757,2,3027630,1,1171,13,2527
10,34271,16,10,1,21,1 1 1 1 3 1 1 2 1 9,83401,965,2,6173358,1,643,13,1503
10,40415,16,10,1,22,1 1 1 1 3 1 1 3 1 9,93641,569,2,12464814,1,379,13,3551
10,62943,16,10,2,17,1 1 1 1 3 1 1 2 2 4,87497,28357,1,157020,2,37809,13,1503
11,479,16,11,2,18,1 1 1 1 3 1 1 1 4 2 2,343387,325,1,77844,15,433,13,479
11,13791,16,11,1,17,1 1 1 1 3 1 1 2 2 1 3,278875,18641,2,38922,11,12427,13,1503
11,32223,16,11,1,17,1 1 1 1 3 1 1 3 2 2 1,371035,43553,2,38922,16,29035,13,3551
11,41439,16,11,1,20,1 1 1 1 3 1 1 1 3 2 5,286043,7001,2,2791434,1,4667,13,479
11,45535,16,11,2,20,1 1 1 1 3 1 1 1 2 4 4,306523,7693,1,2437140,1,10257,13,479
11,61919,16,11,1,17,1 1 1 1 3 1 1 1 2 2 3,257371,83687,2,38922,10,55791,13,479
13,1503,16,13,1,24,1 1 1 1 3 1 1 2 1 3 1 1 7,2874419,143,2,47143002,1,95,13,1503
13,9695,16,13,2,23,1 1 1 1 3 1 1 2 1 1 4 2 4,3243059,1843,1,18788532,1,2457,13,1503
13,10719,16,13,2,22,1 1 1 1 3 1 1 1 1 1 1 3 6,2240563,4075,1,6205620,1,5433,13,2527
13,14815,16,13,1,31,1 1 1 1 3 1 1 1 1 3 1 1 15,2424883,11,2,6439262298,1,7,13,2527
13,18911,16,13,2,22,1 1 1 1 3 1 1 1 1 1 4 2 4,2609203,7189,1,6205620,2,9585,13,2527
13,20959,16,13,1,21,1 1 1 1 3 1 1 1 2 1 3 2 3,2701363,15935,2,3102810,2,10623,13,479
13,25055,16,13,1,21,1 1 1 1 3 1 1 1 3 1 2 2 3,2885683,19049,2,3102810,2,12699,13,479
13,33247,16,13,1,21,1 1 1 1 3 1 1 1 4 1 1 2 3,3254323,25277,2,3102810,2,16851,13,479
14,7647,16,14,1,22,1 1 1 1 3 1 1 3 1 2 1 1 4 1,11549849,8723,2,3016974,7,5815,13,3551
14,24031,16,14,1,23,1 1 1 1 3 1 1 3 1 1 1 1 4 3,9567385,13703,2,15599886,1,9135,13,3551
14,26079,16,14,1,22,1 1 1 1 3 1 1 2 1 1 1 1 4 3,7746713,29741,2,3016974,4,19827,13,1503
14,51679,16,14,2,23,1 1 1 1 3 1 1 1 1 1 3 3 1 4,8056985,29467,1,6033948,4,39289,13,2527
14,63967,16,14,1,22,1 1 1 1 3 1 1 1 1 4 2 1 1 3,9715865,72947,2,3016974,6,48631,13,2527
16,2527,16,16,2,27,1 1 1 1 3 1 1 1 1 1 2 2 1 1 5 4,71513441,811,1,230466300,1,1081,13,2527
16,6623,16,16,2,27,1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4,114238817,2125,1,230466300,2,2833,13,2527
16,12767,16,16,2,26,1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4,111218017,8191,1,29139708,13,10921,13,479
16,29151,16,16,2,28,1 1 1 1 3 1 1 1 2 2 1 2 2 1 2 6,80792929,4675,1,633119484,1,6233,13,479
17,30175,16,17,1,29,1 1 1 1 3 1 1 2 2 2 1 2 2 1 2 1 5,341531683,7259,2,1352332410,1,4839,13,1503
18,46559,16,18,1,28,1 1 1 1 3 1 1 2 2 1 1 1 1 1 1 1 3 5,683660393,67199,2,30465390,37,44799,13,1503
18,64991,16,18,1,29,1 1 1 1 3 1 1 3 2 1 1 1 1 1 1 1 5 3,937643113,46901,2,835771758,2,31267,13,3551
19,17887,16,19,1,32,1 1 1 1 3 1 1 2 1 2 1 1 4 1 1 1 1 1 7,2565819707,4841,2,10560378954,1,3227,13,1503
19,47583,16,19,2,32,1 1 1 1 3 1 1 1 1 3 2 1 1 1 2 1 2 4 4,2406486331,12877,1,8235856020,1,17169,13,2527
21,50655,16,21,2,36,1 1 1 1 3 1 1 2 1 2 2 1 1 1 1 3 3 2 1 1 6,26693613331,7711,1,164317017396,1,10281,13,1503
22,39391,16,22,2,36,1 1 1 1 3 1 1 1 1 2 2 1 1 1 1 3 1 4 1 2 2 4,63347945785,17989,1,80634191772,3,23985,13,2527
22,55775,16,22,2,36,1 1 1 1 3 1 1 1 1 2 1 2 1 2 4 1 1 1 2 3 1 4,75192250681,25471,1,80634191772,3,33961,13,2527
23,57823,16,23,1,38,1 1 1 1 3 1 1 1 3 1 1 3 1 2 2 1 1 1 1 4 2 2 3,315917712299,19805,2,636347363178,1,13203,13,479
24,4575,16,24,1,38,1 1 1 1 3 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5,635666957057,4703,2,259774647870,4,3135,13,479
25,37343,16,25,2,41,1 1 1 1 3 1 1 1 2 1 1 1 1 1 1 1 3 1 1 3 3 2 2 1 6,1447081707779,14389,1,3207915328884,2,19185,13,479
25,53727,16,25,1,40,1 1 1 1 3 1 1 1 2 1 2 3 1 2 1 2 2 2 2 1 1 1 2 2 3,3003828521219,41405,2,1603957664442,4,27603,13,479
26,23007,16,26,1,41,1 1 1 1 3 1 1 1 1 2 1 1 4 1 1 1 3 2 1 1 1 2 1 3 4 1,6714415551241,26597,2,1513338109998,8,17731,13,2527
26,58847,16,26,2,44,1 1 1 1 3 1 1 2 1 1 1 2 1 2 1 1 1 1 2 4 2 1 2 1 3 6,5179535992585,8503,1,42609094819932,1,11337,13,1503
30,43487,16,30,1,48,1 1 1 1 3 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 3 1 1 3 3 3 4 1 2 3,412822742676953,31811,2,432642665942670,2,21207,13,2527
33,56799,16,33,1,53,1 1 1 1 3 1 1 3 1 1 2 1 1 1 1 1 2 1 4 1 1 1 2 3 1 1 2 1 1 4 1 3 3,16303153667805667,35057,2,15903476631111930,2,23371,13,3551
35,59871,16,35,2,58,1 1 1 1 3 1 1 1 1 1 1 1 1 1 2 1 5 1 2 1 4 1 2 1 1 1 3 1 1 2 3 1 2 1 6,139662722528697595,10393,1,664564948059136404,1,13857,13,2527
41,35295,16,41,1,65,1 1 1 1 3 1 1 1 1 1 2 1 1 1 1 1 2 2 1 1 3 1 4 1 1 5 1 1 1 1 1 2 2 2 1 1 2 1 3 3 3,83861771946701186755,34895,2,37734471687915736890,4,23263,13,2527
42,27103,16,42,1,68,1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5,358436715937075385417,10049,2,666605737275033759150,1,6699,13,2527
44,42463,16,44,1,71,1 1 1 1 3 1 1 2 1 1 2 1 1 1 1 1 2 4 3 1 2 1 1 1 1 1 1 1 1 1 3 1 2 2 4 1 1 2 1 1 1 1 3 7,2589569629459408059025,17711,2,5114007919937245354782,1,11807,13,1503
1 horizon_t classe_mod_2^m m t a A_t mot_a0.. C_t y y_mod_3 DeltaF Nf preimage_m etat_id base_mod_4096
2 9 5599 16 9 2 17 1 1 1 1 3 1 1 2 6 26435 841 1 314484 1 1121 13 1503
3 9 11743 16 9 1 15 1 1 1 1 3 1 1 5 1 40771 7055 2 58938 1 4703 13 3551
4 9 15839 16 9 1 15 1 1 1 1 3 1 1 3 3 28483 9515 2 58938 1 6343 13 3551
5 9 16863 16 9 2 16 1 1 1 1 3 1 1 1 6 25411 5065 1 117876 1 6753 13 479
6 9 21983 16 9 1 14 1 1 1 1 3 1 1 2 3 26435 26411 2 9786 4 17607 13 1503
7 9 28127 16 9 1 25 1 1 1 1 3 1 1 15 1 16801603 17 2 100623930 1 11 13 3551
8 9 38367 16 9 2 15 1 1 1 1 3 1 1 2 4 26435 23047 1 19572 4 30729 13 1503
9 9 44511 16 9 2 16 1 1 1 1 3 1 1 5 2 40771 13369 1 117876 1 17825 13 3551
10 9 48607 16 9 2 16 1 1 1 1 3 1 1 3 4 28483 14599 1 117876 1 19465 13 3551
11 9 49631 16 9 1 15 1 1 1 1 3 1 1 1 5 25411 29813 2 58938 1 19875 13 479
12 9 54751 16 9 1 14 1 1 1 1 3 1 1 2 3 26435 65777 2 9786 4 43851 13 1503
13 9 60895 16 9 2 17 1 1 1 1 3 1 1 6 2 57155 9145 1 314484 1 12193 13 3551
14 10 8671 16 10 2 17 1 1 1 1 3 1 1 1 3 4 84425 3907 1 157020 2 5209 13 479
15 10 31199 16 10 1 20 1 1 1 1 3 1 1 1 1 9 78281 1757 2 3027630 1 1171 13 2527
16 10 34271 16 10 1 21 1 1 1 1 3 1 1 2 1 9 83401 965 2 6173358 1 643 13 1503
17 10 40415 16 10 1 22 1 1 1 1 3 1 1 3 1 9 93641 569 2 12464814 1 379 13 3551
18 10 62943 16 10 2 17 1 1 1 1 3 1 1 2 2 4 87497 28357 1 157020 2 37809 13 1503
19 11 479 16 11 2 18 1 1 1 1 3 1 1 1 4 2 2 343387 325 1 77844 15 433 13 479
20 11 13791 16 11 1 17 1 1 1 1 3 1 1 2 2 1 3 278875 18641 2 38922 11 12427 13 1503
21 11 32223 16 11 1 17 1 1 1 1 3 1 1 3 2 2 1 371035 43553 2 38922 16 29035 13 3551
22 11 41439 16 11 1 20 1 1 1 1 3 1 1 1 3 2 5 286043 7001 2 2791434 1 4667 13 479
23 11 45535 16 11 2 20 1 1 1 1 3 1 1 1 2 4 4 306523 7693 1 2437140 1 10257 13 479
24 11 61919 16 11 1 17 1 1 1 1 3 1 1 1 2 2 3 257371 83687 2 38922 10 55791 13 479
25 13 1503 16 13 1 24 1 1 1 1 3 1 1 2 1 3 1 1 7 2874419 143 2 47143002 1 95 13 1503
26 13 9695 16 13 2 23 1 1 1 1 3 1 1 2 1 1 4 2 4 3243059 1843 1 18788532 1 2457 13 1503
27 13 10719 16 13 2 22 1 1 1 1 3 1 1 1 1 1 1 3 6 2240563 4075 1 6205620 1 5433 13 2527
28 13 14815 16 13 1 31 1 1 1 1 3 1 1 1 1 3 1 1 15 2424883 11 2 6439262298 1 7 13 2527
29 13 18911 16 13 2 22 1 1 1 1 3 1 1 1 1 1 4 2 4 2609203 7189 1 6205620 2 9585 13 2527
30 13 20959 16 13 1 21 1 1 1 1 3 1 1 1 2 1 3 2 3 2701363 15935 2 3102810 2 10623 13 479
31 13 25055 16 13 1 21 1 1 1 1 3 1 1 1 3 1 2 2 3 2885683 19049 2 3102810 2 12699 13 479
32 13 33247 16 13 1 21 1 1 1 1 3 1 1 1 4 1 1 2 3 3254323 25277 2 3102810 2 16851 13 479
33 14 7647 16 14 1 22 1 1 1 1 3 1 1 3 1 2 1 1 4 1 11549849 8723 2 3016974 7 5815 13 3551
34 14 24031 16 14 1 23 1 1 1 1 3 1 1 3 1 1 1 1 4 3 9567385 13703 2 15599886 1 9135 13 3551
35 14 26079 16 14 1 22 1 1 1 1 3 1 1 2 1 1 1 1 4 3 7746713 29741 2 3016974 4 19827 13 1503
36 14 51679 16 14 2 23 1 1 1 1 3 1 1 1 1 1 3 3 1 4 8056985 29467 1 6033948 4 39289 13 2527
37 14 63967 16 14 1 22 1 1 1 1 3 1 1 1 1 4 2 1 1 3 9715865 72947 2 3016974 6 48631 13 2527
38 16 2527 16 16 2 27 1 1 1 1 3 1 1 1 1 1 2 2 1 1 5 4 71513441 811 1 230466300 1 1081 13 2527
39 16 6623 16 16 2 27 1 1 1 1 3 1 1 1 1 2 4 2 1 2 1 4 114238817 2125 1 230466300 2 2833 13 2527
40 16 12767 16 16 2 26 1 1 1 1 3 1 1 1 2 3 2 2 1 1 1 4 111218017 8191 1 29139708 13 10921 13 479
41 16 29151 16 16 2 28 1 1 1 1 3 1 1 1 2 2 1 2 2 1 2 6 80792929 4675 1 633119484 1 6233 13 479
42 17 30175 16 17 1 29 1 1 1 1 3 1 1 2 2 2 1 2 2 1 2 1 5 341531683 7259 2 1352332410 1 4839 13 1503
43 18 46559 16 18 1 28 1 1 1 1 3 1 1 2 2 1 1 1 1 1 1 1 3 5 683660393 67199 2 30465390 37 44799 13 1503
44 18 64991 16 18 1 29 1 1 1 1 3 1 1 3 2 1 1 1 1 1 1 1 5 3 937643113 46901 2 835771758 2 31267 13 3551
45 19 17887 16 19 1 32 1 1 1 1 3 1 1 2 1 2 1 1 4 1 1 1 1 1 7 2565819707 4841 2 10560378954 1 3227 13 1503
46 19 47583 16 19 2 32 1 1 1 1 3 1 1 1 1 3 2 1 1 1 2 1 2 4 4 2406486331 12877 1 8235856020 1 17169 13 2527
47 21 50655 16 21 2 36 1 1 1 1 3 1 1 2 1 2 2 1 1 1 1 3 3 2 1 1 6 26693613331 7711 1 164317017396 1 10281 13 1503
48 22 39391 16 22 2 36 1 1 1 1 3 1 1 1 1 2 2 1 1 1 1 3 1 4 1 2 2 4 63347945785 17989 1 80634191772 3 23985 13 2527
49 22 55775 16 22 2 36 1 1 1 1 3 1 1 1 1 2 1 2 1 2 4 1 1 1 2 3 1 4 75192250681 25471 1 80634191772 3 33961 13 2527
50 23 57823 16 23 1 38 1 1 1 1 3 1 1 1 3 1 1 3 1 2 2 1 1 1 1 4 2 2 3 315917712299 19805 2 636347363178 1 13203 13 479
51 24 4575 16 24 1 38 1 1 1 1 3 1 1 1 2 1 1 2 1 1 3 2 3 1 1 2 1 1 1 5 635666957057 4703 2 259774647870 4 3135 13 479
52 25 37343 16 25 2 41 1 1 1 1 3 1 1 1 2 1 1 1 1 1 1 1 3 1 1 3 3 2 2 1 6 1447081707779 14389 1 3207915328884 2 19185 13 479
53 25 53727 16 25 1 40 1 1 1 1 3 1 1 1 2 1 2 3 1 2 1 2 2 2 2 1 1 1 2 2 3 3003828521219 41405 2 1603957664442 4 27603 13 479
54 26 23007 16 26 1 41 1 1 1 1 3 1 1 1 1 2 1 1 4 1 1 1 3 2 1 1 1 2 1 3 4 1 6714415551241 26597 2 1513338109998 8 17731 13 2527
55 26 58847 16 26 2 44 1 1 1 1 3 1 1 2 1 1 1 2 1 2 1 1 1 1 2 4 2 1 2 1 3 6 5179535992585 8503 1 42609094819932 1 11337 13 1503
56 30 43487 16 30 1 48 1 1 1 1 3 1 1 1 1 1 1 2 1 2 1 1 1 1 1 1 3 1 1 3 3 3 4 1 2 3 412822742676953 31811 2 432642665942670 2 21207 13 2527
57 33 56799 16 33 1 53 1 1 1 1 3 1 1 3 1 1 2 1 1 1 1 1 2 1 4 1 1 1 2 3 1 1 2 1 1 4 1 3 3 16303153667805667 35057 2 15903476631111930 2 23371 13 3551
58 35 59871 16 35 2 58 1 1 1 1 3 1 1 1 1 1 1 1 1 1 2 1 5 1 2 1 4 1 2 1 1 1 3 1 1 2 3 1 2 1 6 139662722528697595 10393 1 664564948059136404 1 13857 13 2527
59 41 35295 16 41 1 65 1 1 1 1 3 1 1 1 1 1 2 1 1 1 1 1 2 2 1 1 3 1 4 1 1 5 1 1 1 1 1 2 2 2 1 1 2 1 3 3 3 83861771946701186755 34895 2 37734471687915736890 4 23263 13 2527
60 42 27103 16 42 1 68 1 1 1 1 3 1 1 1 1 1 1 1 4 3 2 1 2 1 1 1 1 1 2 1 2 2 1 2 1 1 1 1 1 1 4 4 2 1 3 1 1 5 358436715937075385417 10049 2 666605737275033759150 1 6699 13 2527
61 44 42463 16 44 1 71 1 1 1 1 3 1 1 2 1 1 2 1 1 1 1 1 2 4 3 1 2 1 1 1 1 1 1 1 1 1 3 1 2 2 4 1 1 2 1 1 1 1 3 7 2589569629459408059025 17711 2 5114007919937245354782 1 11807 13 1503

View File

@ -0,0 +1,15 @@
{
"clauses": [
3551,
19935,
36319,
52703
],
"covered": [
3551,
19935,
36319,
52703
],
"palier": 16
}

View File

@ -0,0 +1,127 @@
{
"clauses": [
479,
1503,
2527,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223,
33247,
34271,
35295,
37343,
38367,
39391,
40415,
41439,
42463,
43487,
44511,
45535,
46559,
47583,
48607,
49631,
50655,
51679,
53727,
54751,
55775,
56799,
57823,
58847,
59871,
60895,
61919,
62943,
63967,
64991
],
"covered": [
479,
1503,
2527,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223,
33247,
34271,
35295,
37343,
38367,
39391,
40415,
41439,
42463,
43487,
44511,
45535,
46559,
47583,
48607,
49631,
50655,
51679,
53727,
54751,
55775,
56799,
57823,
58847,
59871,
60895,
61919,
62943,
63967,
64991
],
"palier": 16
}

View File

@ -0,0 +1,25 @@
{
"state_id": 13,
"base_palier": 12,
"target_palier": 16,
"delta_m": 4,
"lift_size": 64,
"d8": {
"k": 8,
"threshold_Ak": 13,
"candidates": 4,
"covered": 4,
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/certificats/certificat_D8_E13_palier2p16.json"
},
"fusion": {
"t_min": 9,
"t_max_search": 128,
"t_max_used": 44,
"merged_csv": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/candidats/candidats_F9to44_E13_palier2p16.csv",
"certificate": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/certificats/certificat_F9to44_E13_palier2p16.json",
"clauses": 60,
"covered": 60
},
"verification_md": "/home/ncantu/code/algo/docs/artefacts/collatz/local_E13_palier2p16/audits/verification_H6_E13_palier2p16.md",
"success": true
}

View File

@ -0,0 +1,9 @@
{
"noyau": [
479,
1503,
2527,
3551
],
"palier": 12
}

View File

@ -0,0 +1,69 @@
{
"noyau": [
479,
1503,
2527,
3551,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
19935,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223,
33247,
34271,
35295,
36319,
37343,
38367,
39391,
40415,
41439,
42463,
43487,
44511,
45535,
46559,
47583,
48607,
49631,
50655,
51679,
52703,
53727,
54751,
55775,
56799,
57823,
58847,
59871,
60895,
61919,
62943,
63967,
64991
],
"palier": 16
}

View File

@ -0,0 +1,65 @@
{
"noyau": [
479,
1503,
2527,
4575,
5599,
6623,
7647,
8671,
9695,
10719,
11743,
12767,
13791,
14815,
15839,
16863,
17887,
18911,
20959,
21983,
23007,
24031,
25055,
26079,
27103,
28127,
29151,
30175,
31199,
32223,
33247,
34271,
35295,
37343,
38367,
39391,
40415,
41439,
42463,
43487,
44511,
45535,
46559,
47583,
48607,
49631,
50655,
51679,
53727,
54751,
55775,
56799,
57823,
58847,
59871,
60895,
61919,
62943,
63967,
64991
],
"palier": 16
}

View File

@ -0,0 +1,27 @@
**Auteur** : Équipe 4NK
# Vérification H6(E14) — couverture des relèvements au palier \(2^{15}\)
## Objet
Vérifier, au sens “certifié D/F” (appartenance aux ensembles `covered` de certificats), que lunion des certificats locaux couvre le domaine des relèvements impairs.
## Domaine
- base : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E14_palier2p15/noyaux/noyau_E14_B12.json`
- relevé : `/home/ncantu/code/algo/docs/artefacts/collatz/local_E14_palier2p15/noyaux/noyau_Lift_E14_palier2p15.json`
- taille : 32
## Certificats utilisés (local)
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E14_palier2p15/certificats/certificat_D8_E14_palier2p15.json`
- covered : 2 classes
- `/home/ncantu/code/algo/docs/artefacts/collatz/local_E14_palier2p15/certificats/certificat_F9to41_E14_palier2p15.json`
- covered : 30 classes
## Résultat
- |L| = 32
- |U| = 32
- |L \ U| = 0

Some files were not shown because too many files have changed in this diff Show More