Repository navigation
[P2] absolute-zero/proofs/coq: full rebuild on Coq 8.18 (split from standards#133 Coq half) #157
Description
Background
Filed as a properly-scoped successor to the Coq half of standards#133 (Lean half done in absolute-zero#23).
standards#133's body said "finish Lean CNO cons-case + Coq tier-0 rebuild" with a P2 label and OWED scope of "discharge 4 axioms". A build attempt (Coq 8.18.0) shows that framing under-specified the actual state by a wide margin. The file doesn't compile at all, and at least one theorem is false under the current definitions.
Actual state of proofs/coq/common/CNO.v on Coq 8.18
A. Build-blocking incompatibilities (≥ 3 systemic)
inversion ... ; subst.auto-naming clobber. The originaleval_appproof at-> direction, cons casereferencesH3, generated byinversion H; subst.. Coq 8.18'sinversionuses different positional auto-naming andH3doesn't exist. Same pattern repeats elsewhere.- Wrong-order
introspattern ineval_app<- direction. After threegeneralize dependentcalls andinduction p1, the goal binders are in the orderforall s sm, eval [] s sm -> forall s', eval p2 sm s' -> .... The code usesintros s sm s' Hp1 Hp2.which silently mis-bindss'to theeval [] s smpremise andHp1to the actuals', making subsequentinversion Hp1; subst.produce the famous error contexts' : eval [] s sm, Hp1 : ProgramState, Hp2 : eval p2 sm Hp1. Correct order:intros s sm Hp1 s' Hp2. repeat split+ bullets + cross-bullet identifier reuse. Coq 8.18 enforces stricter name hygiene: onceintros sruns in one bullet, the namesis "reserved" and a sibling bullet'sintros s s' Heval.fails with "s is already used". Fix is to convert each affected proof fromrepeat split.+-bullets tosplit; { ... }+ braces (which create a name scope reset). Affected: at leastcno_composition,empty_is_cno,nop_is_cno, plus 5+ more theorems following the same pattern. Totalrepeat splitcount in this file: 9.
B. Soundness defect (design decision required)
-
nop_is_cno : is_CNO [Nop]is false under the currentstate_eq.is_CNO's second clause requireseval p s s' -> s =st= s', andstate_eqrequiresstate_pc s1 = state_pc s2. Butstep s Nop = mkState s.(memory) s.(registers) s.(io) (S s.(state_pc))— Nop bumps PC. So Nop changes state understate_eq, andnop_is_cnois unprovable. The original proof usedinversion Heval; subst. inversion H; subst. inversion H0; subst. unfold state_eq. repeat split; try reflexivity. unfold mem_eq. reflexivity.— which only works if the underlying inversion silently absorbs the PC delta, which it doesn't on Coq 8.18 with strict checking. Two viable resolutions, owner-gated:- (a) Drop
nop_is_cno— Nop is not a CNO under the strict pc-equalitystate_eq. The intuition that "Nop does nothing" only holds modulo PC, which is a different equivalence. - (b) Redefine
state_eqto ignore PC. Thennop_is_cnois true and the file's CNO discourse becomes pc-agnostic. This is a bigger change because every theorem usingstate_eqre-checks under the relaxed definition.
Either way, no purely-mechanical fix to
nop_is_cno's proof works. This is a design call, not a proof debt. - (a) Drop
C. Existing 4 axioms (the original OWED)
These are the Axiom declarations standards#133's body actually referenced:
eval_deterministic(L445) — eval-relation is deterministic; proof comment says "TODO: Prove this axiom by induction on eval structure".cno_decidable(L523) —{is_CNO p} + {~ is_CNO p}. Decidability is non-trivial becauseis_CNOquantifies over all states.eval_respects_state_eq_right(L589) /eval_respects_state_eq_left(L601) — eval respects state-equality on both sides. Per the echo-types Agda↔Coq↔Lean4 correspondence (echo-types PR #64), these are precisely the 3 axioms that--safe --without-K(Agda) and Lean's no-axiom posture both forbid; they exist in Coq specifically to paper over the relationalevalmodel's inability to derive determinism by direct case-splitting on a Fixpoint.
The deeper fix is to either (i) re-route through a Functional.eval Fixpoint formulation matching Agda + Lean (Route A in the echo-types correspondence appendix), at which point all four axioms reduce to refl, or (ii) discharge each axiom in place by induction on the eval inductive — the comments claim this is "straightforward" but until A/B/C above are fixed, the file doesn't even compile so the proofs can't be checked.
Recommended scope for this issue
Tier-0 in standards#133's sense ("zero axioms") is achievable but is not a P2 fixup. Proposed staged plan:
- Stage 1 — Coq 8.18 build repair. Convert all 9
repeat split.+ bullet sites tosplit; { ... }blocks; fix theeval_app <-intros order; extracteval_nil_inv+eval_cons_invhelper lemmas to isolateinversionnoise. File compiles modulo whatever resolution is chosen for nop_is_cno. - Stage 2 —
nop_is_cnodesign call. Owner picks (a) drop or (b) relaxstate_eq. Apply the picked path. - Stage 3 — Tier-0 axiom discharge. Either rewrite
evalas a Fixpoint (Route A — affects every eval-using theorem) or prove each of the 4 axioms by induction (Route B — incremental). The echo-types correspondence appendix lays out the precise blockers.
Each stage is its own PR. Stage 1 is mechanical and high-value (currently CI can't even build this tree on 8.18). Stage 2 is a 30-minute decision + 1h application. Stage 3 is the real proof work.
Sub-issue of #124. PRs Refs hyperpolymath/standards#124. Joint-close only on explicit agreement.
🤖 Generated with Claude Code
Activity
hyperpolymath commentedon Aug 24, 2026
Closing as completed by the later implementation and verification recorded on #133. This successor proposed three stages: Coq 8.18 build repair, resolution of the
nop_is_cno/state_eqsoundness defect, and tier-0 axiom discharge/triage. absolute-zero#24 and #26 subsequently landed those changes; #133’s post-merge sweep rebuilt all 11 Coq files cleanly and recorded the remaining declarations as legitimate model assumptions (withcno_decidableseparately classified), rather than untracked proof escapes. The broader campaign remains #124.