Recovering a formula from a code

解码。给定一个在某载体上既封闭又成形的集合,一个以「某个已言明元数处的键」的形式递交过来的成员,就是该载体之上某条公式的键,而那条公式可以被造出来。

那条公式落在哪个字母表上,是整章的要害,而它在此处定案、不在末尾。模型之上的公式会由同样六个框架还原出来,而对消费方毫无用处,因为它的索引类型是单个载体之上的诸公式。故目标在一个字母表上陈述,字母表是一个参数,而关于它的、形状谓词供不出的那一件事,即载体的诸成员就是字母表的像,作为一条假设摆在旁边。

目标取字母表自己的编码,也使诸框架变短、而不是变长。在模型之上,每个框架先得把模型的与层级的两套编码搭起桥来,才能把一个码与一个载荷相比;在字母表之上,码本来就是层级的元素,那座桥没有了。

此处没有证明的是「每个成员都是这样一个键」,而欠这笔账的是那个集合。形状把元数分量存在量化、且对它不加任何条件,故一个持有「第一分量不是数码的对」的集合同样满足两半,而本定理对它什么也没说。下一章所造的那个集合从外面把元数钉住,即在一个固定元数上被索引的族之内作分离,这正是不去要求那条谓词的原因。

递归跑在码的秩上,不跑在码上、也不跑在键上。不跑在码上,是因为成员关系不下降进 Kuratowski 的对;不跑在键上,是因为键在码旁边还带着元数,而「对的秩的算术」是一条没人证过的事实。把元数作为一个自然数在旁边带着、只对码下降,两者都不需要。

一步是 peel,一次下降是上一章,而十二个情形收拢为六个,因为十二个标签之间只有六种形状,而一种形状之内变动的只是一个标签与一个构造子。

{-# OPTIONS --cubical --safe --guardedness #-}

open import Base.Prelude
open import Base.Truth

module L.Coding.Recover { : Level} where

open import FOL.ZFStructure using ( module hPropStructure )
open import FOL.Syntax
  using ( Term; Formula; _∈̇_; _≐_; _∧̇_; _∨̇_; _⇒̇_; ¬̇_; ⊤̇; ⊥̇; ∃̇_; ∀̇_; ∀̇∈; ∃̇∈ )
open import FOL.Manipulation.Relabelling using ( mapTm; mapFo )
import FOL.Absoluteness
open import V.Hierarchy {} using ( 𝒮ᵥ; ∈-induction )
open import V.Coding {} using ( pr; pr-inj; module VCode )
open import L.Constructible {} using ( 𝒮ʟ; isL; isL-trans )
open import L.Rank {} using ( rank )
open import L.Axioms.Numerals {} using ( numeralL; numeralL-fst )
open import L.Coding.Model {} using ( prʟ; prʟ-fst; closedAt )
open import L.Coding.Descent {} using ( payload≺; leftPart; rightPart )
open import L.Coding.Shape {}
  using ( shapedAt; isTmAt-decode; Onto; BinWit; UnWit; bothTm; zeroPay
        ; module Peel )

open import Cubical.Data.Sum using ( inl; inr )
import Cubical.HITs.PropositionalTruncation as PT
open PT using ( ∥_∥₁; ∣_∣₁; squash₁ )
open import Cubical.HITs.CumulativeHierarchy.Base using ( V; _∈_ )
open import Cubical.HITs.CumulativeHierarchy.Constructions
  using ( module InfinitySet )
open InfinitySet using ( #_; sucV )

open TruthAlgebra (hPropAlgebra (ℓ-suc ))
open hPropStructure 𝒮ʟ

module AbsL = FOL.Absoluteness.Single 𝒮ᵥ isL isL-trans
open AbsL renaming ( _⊨ᵐ_ to _⊨_ )

键,与要造出的东西

键是带元数标签的码,而那个封闭集持有的是键。解码所造出的,是一条公式,其码即该键的码分量,元数即该键另一个分量所点名的那个,而其诸常元取自那个字母表。

码是对该公式在层级中的像取的,那正是 mapFo 在那里做的事。它不是构造的一步:常量变换按定义与每个构造子交换,故字母表之上的一条公式连同它的像,其编码与模型之上的公式完全一样。

keyOf :   S  S
keyOf n x = prʟ (numeralL n) x

keyOf-fst : (n : ) (x : S)  fst (keyOf n x)  pr (# n) (fst x)
keyOf-fst n x = prʟ-fst (numeralL n) x  cong₂ pr (numeralL-fst n) refl

Coded : {K : Type } (f : K  V )    S  Type (ℓ-suc )
Coded {K} f n x =  Σ[ φ  Formula K n ] (VCode.⌜ mapFo f φ   fst x) ∥₁

那场递归

动机除码之外还对元数作量化,因为量词会抬升元数,而归纳必须自由地在一个更大的元数上回来。这正是元数在此处是一个自然数、而不是一个集合的全部理由:它是被带着走的,不是被下降进去的。载体则压根不被量化:它是环境的一位,在归纳开跑之前就已固定,而归纳从不问那里面装着什么。

字母表的两个参数出于同样的理由骑在归纳之外。六个框架里只有两个去看它们,即载荷里放着词项的那两个,而它们看的方式,是把那条假设径直递给词项解码。

module Decode {K : Type } (f : K  V )
              {m : } (C A : Fin m) (γ : S ^ m) (onto : Onto f A γ)
              (hcl :  γ  closedAt C ) (hsh :  γ  shapedAt C A ) where
  open Peel C A γ hcl hsh

  Wf :   S  Type (ℓ-suc )
  Wf n x =  keyOf n x ∈ˢ lookup C γ 

  recover : (n : ) (x : S)  Wf n x  Coded f n x
  recover n x = ∈-induction go (rank (fst x)) n x refl
    where
    P : V   Type (ℓ-suc )
    P r = (j : ) (z : S)  rank (fst z)  r  Wf j z  Coded f j z

    go : (r : V )  ((y : V )   y  r   P y)  P r
    go r IH j z qr wz = PT.rec squash₁ fill (peel (keyOf j z) wz)
      where
      D = fst (lookup C γ)

      rec : (i : ) (u : S)   rank (fst u)  rank (fst z) 
           Wf i u  Coded f i u
      rec i u lt wu = IH (rank (fst u))
        (subst  w   rank (fst u)  w ) qr lt) i u refl wu

      -- the arity numeral and the payload, read out of the key's shape
      split : (N : S) (p : V )  fst (keyOf j z)  pr (fst N) p
             (# j  fst N) × (fst z  p)
      split N p e = pr-inj (sym (keyOf-fst j z)  e)

      inD : (i : ) (N u : S)  # i  fst N   pr (fst N) (fst u)  D 
           Wf i u
      inD i N u qN h = subst  w   w  D )
        (cong₂ pr (sym qN) refl  sym (keyOf-fst i u)) h

      inD⁺ : (i : ) (N u : S)  # i  fst N
             pr (sucV (fst N)) (fst u)  D   Wf (suc i) u
      inD⁺ i N u qN h = subst  w   w  D )
        (cong₂ pr (cong sucV (sym qN)) refl  sym (keyOf-fst (suc i) u)) h

      -- the six frames. Each takes the constructor's coding equation rather
      -- than leaving the elaborator to find it: with the constructor a
      -- variable, nothing reduces, and the unification is the whole cost.
      -- Over the alphabet the equation is still refl at every call site,
      -- because relabelling commutes with every constructor definitionally.
      atom : (k : ) (op :  {i}  Term K i  Term K i  Formula K i)
            (∀ {i} (t u : Term K i)
               VCode.⌜ mapFo f (op t u) 
                 VCode.mkTag k (pr VCode.⌜ mapTm f t ⌝ᵗ VCode.⌜ mapTm f u ⌝ᵗ))
            BinWit k (bothTm A) γ (keyOf j z)  Coded f j z
      atom k op qop (N , (a , (b , (e , (ha , hb))))) =
        PT.rec squash₁
           { (t , qt)  PT.map
             { (u , qu)  op t u
               , ( qop t u
                  cong (VCode.mkTag k) (cong₂ pr qt qu)
                  sym qx ) })
            (isTmAt-decode f zero (suc (suc zero)) (suc (suc (suc (suc A))))
              (b  a  N  keyOf j z  γ) j (sym qN) onto hb) })
          (isTmAt-decode f (suc zero) (suc (suc zero)) (suc (suc (suc (suc A))))
            (b  a  N  keyOf j z  γ) j (sym qN) onto ha)
        where
        sp = split N (pr (# k) (pr (fst a) (fst b))) e
        qN = sp .fst
        qx = sp .snd

      binSame : (k : ) (op :  {i}  Formula K i  Formula K i  Formula K i)
               (∀ {i} (φ ψ : Formula K i)
                  VCode.⌜ mapFo f (op φ ψ) 
                    VCode.mkTag k (pr VCode.⌜ mapFo f φ  VCode.⌜ mapFo f ψ ))
               BinSame k (keyOf j z)  Coded f j z
      binSame k op qop (N , (a , (b , (e , (ha , hb))))) =
        PT.rec squash₁
           { (φ , )  PT.map
             { (ψ , )  op φ ψ
               , ( qop φ ψ
                  cong (VCode.mkTag k) (cong₂ pr  )
                  sym qx ) })
            (rec j b (subst  w   rank (fst b)  rank w ) (sym qx)
                       (rightPart (# k) (fst a) (fst b)))
                     (inD j N b qN hb)) })
          (rec j a (subst  w   rank (fst a)  rank w ) (sym qx)
                     (leftPart (# k) (fst a) (fst b)))
                   (inD j N a qN ha))
        where
        sp = split N (pr (# k) (pr (fst a) (fst b))) e
        qN = sp .fst
        qx = sp .snd

      unSame : (k : ) (op :  {i}  Formula K i  Formula K i)
              (∀ {i} (φ : Formula K i)
                 VCode.⌜ mapFo f (op φ)   VCode.mkTag k VCode.⌜ mapFo f φ )
              UnSame k (keyOf j z)  Coded f j z
      unSame k op qop (N , (a , (e , ha))) = PT.map
         { (φ , )  op φ
           , ( qop φ  cong (VCode.mkTag k)   sym qx ) })
        (rec j a (subst  w   rank (fst a)  rank w ) (sym qx)
                   (payload≺ (# k) (fst a)))
                 (inD j N a qN ha))
        where
        sp = split N (pr (# k) (fst a)) e
        qN = sp .fst
        qx = sp .snd

      konst : (k : ) (op :  {i}  Formula K i)
             (∀ i  VCode.⌜ mapFo f (op {i})   VCode.mkTag k (# 0))
             UnWit k zeroPay γ (keyOf j z)  Coded f j z
      konst k op qop (N , (a , (e , ha))) =  op
        , ( qop j  cong (VCode.mkTag k) (sym (ha  numeralL-fst 0))
           sym qx ) ∣₁
        where
        qx = split N (pr (# k) (fst a)) e .snd

      unSucc : (k : ) (op :  {i}  Formula K (suc i)  Formula K i)
              (∀ {i} (φ : Formula K (suc i))
                 VCode.⌜ mapFo f (op φ)   VCode.mkTag k VCode.⌜ mapFo f φ )
              UnSucc k (keyOf j z)  Coded f j z
      unSucc k op qop (N , (a , (e , ha))) = PT.map
         { (φ , )  op φ
           , ( qop φ  cong (VCode.mkTag k)   sym qx ) })
        (rec (suc j) a
          (subst  w   rank (fst a)  rank w ) (sym qx)
            (payload≺ (# k) (fst a)))
          (inD⁺ j N a qN ha))
        where
        sp = split N (pr (# k) (fst a)) e
        qN = sp .fst
        qx = sp .snd

      bnd : (k : ) (op :  {i}  Term K i  Formula K (suc i)  Formula K i)
           (∀ {i} (t : Term K i) (φ : Formula K (suc i))
              VCode.⌜ mapFo f (op t φ) 
                VCode.mkTag k (pr VCode.⌜ mapTm f t ⌝ᵗ VCode.⌜ mapFo f φ ))
           BinSucc k (keyOf j z)  Coded f j z
      bnd k op qop (N , (a , (b , (e , (ha , hb))))) =
        PT.rec squash₁
           { (t , qt)  PT.map
             { (φ , )  op t φ
               , ( qop t φ
                  cong (VCode.mkTag k) (cong₂ pr qt )
                  sym qx ) })
            (rec (suc j) b (subst  w   rank (fst b)  rank w ) (sym qx)
                             (rightPart (# k) (fst a) (fst b)))
                           (inD⁺ j N b qN hb)) })
          (isTmAt-decode f zero (suc zero) (suc (suc (suc A)))
            (a  N  keyOf j z  γ) j (sym qN) onto ha)
        where
        sp = split N (pr (# k) (pr (fst a) (fst b))) e
        qN = sp .fst
        qx = sp .snd

      fill : PeelWit (keyOf j z)  Coded f j z
      fill (inl x) = atom 0 _∈̇_  _ _  refl) x
      fill (inr (inl x)) = atom 1 _≐_  _ _  refl) x
      fill (inr (inr (inl x))) = binSame 2 _∧̇_  _ _  refl) x
      fill (inr (inr (inr (inl x)))) = binSame 3 _∨̇_  _ _  refl) x
      fill (inr (inr (inr (inr (inl x))))) = binSame 4 _⇒̇_  _ _  refl) x
      fill (inr (inr (inr (inr (inr (inl x)))))) = unSame 5 ¬̇_  _  refl) x
      fill (inr (inr (inr (inr (inr (inr (inl x))))))) = konst 6 ⊤̇  _  refl) x
      fill (inr (inr (inr (inr (inr (inr (inr (inl x)))))))) =
        konst 7 ⊥̇  _  refl) x
      fill (inr (inr (inr (inr (inr (inr (inr (inr (inl x))))))))) =
        unSucc 8 ∃̇_  _  refl) x
      fill (inr (inr (inr (inr (inr (inr (inr (inr (inr (inl x)))))))))) =
        unSucc 9 ∀̇_  _  refl) x
      fill (inr (inr (inr (inr (inr (inr (inr (inr (inr (inr (inl x))))))))))) =
        bnd 10 ∀̇∈  _ _  refl) x
      fill (inr (inr (inr (inr (inr (inr (inr (inr (inr (inr (inr x))))))))))) =
        bnd 11 ∃̇∈  _ _  refl) x