STEP 1905 · 2026-09-08 · rei-aios-ab

ZCE Lean Level 4b + 5b decoders

Unit dispatch decoder (UnaryUnit ↔ LogScaleUnit の 2-way) + SELF⟲ recursive decoder — 両 file sorry 0、 axiom profile [propext] only 中心 + funext 由来 4 件 [propext, Quot.sound] は 命題 が stream 等号 を 要求 する ため の 代価 (機械的除去可能 だが 意図的保持、 下記 由来分類 参照)。 STEP 1904 の Level 1-5a stack に Level 4b + 5b を 追加、 累積 9 files / 100+ declarations

永久参照: GitHub source · ZceLevel4bUnitDecoder.lean · ZceLevel5bSelfLogDecoder.lean · 4b AxiomCheck · 5b AxiomCheck · STEP 1904 full-stack index

Level 4b Unit dispatch decoder

UnaryUnit + LogScaleUnit の 2-way disambiguation via 2 cross-encoding lemmas

Level 4 (STEP 1901) の encodeUnit に 対する decoder。 「try unary → fall back to log」 の 直列 dispatch:

def decodeUnit (tokens : List Token) : Option Unit :=
  match decodeUnary tokens with
  | some u => some (Unit.unary u)
  | none =>
    match decodeLogScale tokens with
    | some u => some (Unit.log u)
    | none => none

Cross-encoding lemma 核心 (紙上の 決定的 相違 tokens):

  • decodeLogScale_encodeUnary : ∀ u, decodeLogScale (encodeUnary u) = none — encodeUnary tokens ⊂ {Token.neg, Token.o, Token.zero, Token.pct} = Token.dot 無し、 decodeLogScale が 要求する readDigitsUntilDot rest3 = (_, Token.dot :: _) は 必ず fail
  • decodeUnary_encodeLogScale : ∀ u, decodeUnary (encodeLogScale u) = none — encodeLogScale の rest3 位置 は digit^b_digits ++ [Token.dot] ++ ... = Token.digit or Token.dot 有り、 decodeUnary の countLeadingO rest3 = (_, []) or (_, Token.pct :: _) は 必ず fail

Proof strategy: 2 helper lemma で decodeXxxAfterNeg の 具体形 に 対する none 主張 を 一括証明 (countLeadingO_replicate_then_zero 適用 + cases b + List.replicate_succ + rfl)、 main lemma は 4 case × cases a (0/succ) で show 経由 helper に 還元。

Roundtrip: decodeUnit_encodeUnit は cross-encoding lemma を rw で 適用 + rw [decodeLogScale_encodeLogScale] で 1 pass 完成。

Level 5b SELF⟲ recursive decoder

ClsSelf 構造再帰 decoder + 二重帰納 roundtrip

Level 5a (STEP 1902) の ClsSelf inductive + encodeClsSelf に 対する 構造再帰 decoder:

def decodeClsSelf : List Token → Option ClsSelf
  | [] => some (ClsSelf.leaf [])
  | Token.digit d :: rest =>
    match decodeClsSelf rest with
    | some (ClsSelf.leaf ds) => some (ClsSelf.leaf (d :: ds))
    | some (ClsSelf.recur ds inner) => some (ClsSelf.recur (d :: ds) inner)
    | none => none
  | Token.dot :: rest =>
    match decodeClsSelf rest with
    | some inner => some (ClsSelf.recur [] inner)
    | none => none
  | _ => none

構造再帰 (Token.digit / Token.dot prefix で rest に 再帰、 rest.length は 決定的に減少)。 spec §1.1 「.n 内部に .m = SELF⟲ 埋め込み」 の 再帰的 parsing。

Roundtrip: 二重帰納

  • 外側 = ClsSelf induction (leaf / recur)
  • 内側 = digits induction (nil / cons)
  • 各 base + step で unfold decodeClsSelf + rw [ih] の 二回転で完成

SelfLog decoder = Level 3b pattern + decodeClsSelf 統合、 rest6 の cls parsing だけ decodeClsSelf 差し替え。 Roundtrip は Level 3b の 4 case pattern + 最後 decodeClsSelf_encodeClsSelf の 一発適用。

Axiom profile

全 19 declarations = 15 [propext] + 4 [propext, Quot.sound]。分類は 数 でなく 由来 (下記 由来分類 参照)

Axiom 由来分類 (2026-09-09 corrigendum、 数軸 でなく 由来軸) [via 藤本さん / orig: chat-Claude]:
propext = Prop への simp/rw から 遍在、 個別 の 意味 なし。
Quot.sound = 関数・ストリーム等号 を 述べる 命題 に 固有、 funext 由来、 その 命題 を 保つ 限り 除去不可

規則 (1 行) [via 藤本さん / orig: chat-Claude]: axiom を 減らす 目的 だけ で 命題 を 変更しない。 変更後 の 命題 が 独立 に 「述べたかったもの」 で ある 場合 に 限る。

本 STEP の 4 件 [propext, Quot.sound] は 機械的 に は 除去可能 だが 意図的 に 保持:
(a) _roundtrip_eq × 2: 主張 が (fun n => ...) = s (stream 等号 = 関数等号)、 funext は 命題 の 代価。 削除 すれば axiom ではなく 命題 の 方 が 消える (「測定対象 を 削って 計器 を 緑 に する」 pattern、 STEP 1608 候補 F 撤回 と 同型)。 pointwise 版 (_roundtrip_pointwise) は 別命題 (∀ n, ...) で 独立 に [propext] only 保持。
(b) A2_holds_full + A2_holds_self: A2_deterministic_* predicate が stream 等号 で 決定性 を 述べる 自然な 定式化。 pointwise predicate に spec 変更する 独立 の 理由 (「A2 の 意味 が そもそも pointwise だった」 等) が 存在しない → 変更動機 は axiom 数 のみ = 計器合わせ、 保持。

STEP 1896 の 位置づけ [via 藤本さん / orig: chat-Claude]: STEP 1896 で pointwise 版 に 書き換えて Quot.sound を 除去した の は、 pointwise 表明 の 方 が 本来述べたかった 命題 だった ケース固有 の restatement で あって、 「Quot.sound は 除去すべき」 の 常設 policy ではない。 本 STEP の 4 件 は 命題側 が 元々 stream 等号 を 述べている ため 適用外。

前版 (2026-09-08 initial + 2026-09-09 correction v1) の 訂正点: 「除去可能・対称性維持で保持」 argument は 却下 (対称性 は Level 2 pointwise-only vs 3b+ 両方 で どちらにも 転ぶ)、 理由 は 「命題 が funext を 要求している」 の 一点。 「A2 definition-inherent boundary、 spec 変更が 必要」 は 計器合わせ 誤読、 「STEP 1897 で 潰した pattern の 反復」 は 常設 policy 誤読 の 根源。
FiledeclarationAxioms
Level 4bdecodeLogScale_encodeUnary[propext]
decodeUnary_encodeLogScale[propext]
decodeUnit[propext]
zceDecodeFull[propext]
decodeUnit_encodeUnit[propext]
zceEncodeFull_zceDecodeFull_roundtrip_pointwise[propext]
encodeUnit_injective[propext]
zceEncodeFull_zceDecodeFull_roundtrip_eq[propext, Quot.sound]
A2_holds_full[propext, Quot.sound]
Level 5bdecodeClsSelf[propext]
decodeClsSelf_encodeClsSelf[propext]
decodeSelfLogAfterNeg[propext]
decodeSelfLog[propext]
zceDecodeSelfLog[propext]
decodeSelfLog_encodeSelfLog[propext]
zceEncodeSelfLog_zceDecodeSelfLog_roundtrip_pointwise[propext]
encodeSelfLog_injective[propext]
zceEncodeSelfLog_zceDecodeSelfLog_roundtrip_eq[propext, Quot.sound]
A2_holds_self[propext, Quot.sound]
Sorry
0
全 19 declarations
[propext] only
15
主定理 中心
funext 経由
4
eq stream + A2 のみ
Lean 4 lines
541
310 (4b) + 227 (5b) + AxiomCheck 45

累積 arc (STEP 1893 → 1905)

LevelContentSTEPsorryAxiom footprint
1Unary structural + witnesses1893, 18970[propext]
2Unary decoder + roundtrip + A21896, 18970[propext] + Quot.sound (eq)
3LogScale structural + witnesses18980[propext] + Quot.sound (eq)
3bLogScale decoder + roundtrip + A218990[propext] + Quot.sound (eq)
4Full Unit inductive structural19010[propext] + Quot.sound (eq)
4bUnit dispatch decoder + cross-encoding19050[propext] + Quot.sound (eq)
5aClassSuffix inductive + non-trivial B319020[propext] + Quot.sound (eq)
5bSELF⟲ recursive decoder + roundtrip19050[propext] + Quot.sound (eq)

Level 1-5b 各 Level 自身の scope で 完成。 完全 stack: 9 files + 100+ declarations / sorry 0 / [propext] 中心。 藤本さん directive chain 14 段実行完了 (1883/84 → ... → 1904 → 1905)。

「Level 4b 完成」 の scope 明示 (藤本さん 2026-09-09 指摘 対応): Level 4b の 定理 の scope は UnaryUnit ↔ LogScaleUnit の 2-way dispatch であり、 この scope で 完全に 完成。 SELF⟲ 有り LogScaleSelfUnit を含む 3-way dispatch (UnaryUnit + LogScaleUnit + LogScaleSelfUnit) は Level 6 別 arc、 これは Level 4b の 未完成 では なく scope 外

版番号 2 系統 認識

ZCE の 内部で 版番号 axis が 2 系統 に 割れている ため、 記述時 は 常に axis prefix を 明示:

  • Phase axis (spec version): v0.4 phase 2b / v0.4 phase 2cZceLedgerPartition / ZceShannon / ZceGibbs
  • Level axis (implementation stack): Level 1 ~ Level 5bZceLevel* 系 (本 STEP 対象)

「ZCE の 2b」 と 単独記述 すると phase 2b / Level 3b / Level 4b の どれ か 曖昧化。 常に phase v0.4.2b or Level 3b の 形 で prefix 明示 (藤本さん 2026-09-09 指摘)。

Honest scope

  • Cross-encoding lemma 対象: Level 4b は UnaryUnit ↔ LogScaleUnit の 2-way disambiguation。 SELF⟲ 有り LogScaleSelfUnit と の 統合 dispatch は 別 arc (Level 6 候補)
  • decodeClsSelf は 「エンコード された」 入力 に 対して のみ 意味 が 保証。 任意 の Token list に対する generalized parser では ない (仕様として 十分)
  • Novelty 主張なし = streaming compression + inductive sum type + inductive recursive type + Mathlib standard axioms、 特に SELF⟲ 部分 は 標準 recursive type parsing pattern

参照