Satisfaction over the whole code set

上一章那个实例以 slot B φ 为索引,即一条公式及其诸子公式的诸键。下游没有任何东西用得上它。消费方到场时手里握着的是一个,而不是该码所出自的那条公式:内部可定义幂集在某阶段处元数一的诸码上取值,而良序要比较的两个码并非任何共同公式的子码。以一条公式的槽为索引,就是一条公式一张表,而「这张表在这个码处说什么」在有人拿出「该码是其子码」的某条公式之前,根本没有答案。

作答的那个定义域是某阶段处的码集,而上一个目标已经把它造好。AllCodes 持有载体之上诸公式在每个元数处的诸键,而那恰是消费方到场时手里握着的东西。

整个码集的封闭性不是打发图对索引集之要求的那个东西,而这件事值得说出来,因为那条定理正是上一个目标为之登记的。图把自己的表与索引集都作存在绑定,故 funct 只欠「某个装着该成员的合格集合」,而最小的那个就是该成员自己那条公式的槽,其封闭性由造出它的那一章给出。它在任何地方都不被消费,故此后已予撤除。

这次更换的代价就是本章的全部内容,而它几乎为零;理由值得在一切之前说明。那个图把自己的表存在绑定。故 funct 在一个成员处不必拿出一张覆盖整个定义域的表;它只需拿出「某张封闭、全的、满足诸子句的、装着该成员的表」,而最小的这样一张,就是该成员自己那条公式的子公式槽,而它已由前面四章造好并认证。这场递归换掉它的定义域,其余一概不变:TableSlotSoundUnique 逐条陈述原封不动,而按公式索引的那个实例继续在这一个旁边有效。

此处确有一件全新的东西,而它压根与递归无关。码集的诸成员是在层级的编码里、在该阶段自己的字母表之上取的键;而这场递归所说的一切,是在模型的编码里、在模型的语言之上取的键。两者是同一套构造落在两个字母表上,而没有任何定理把它们接上。

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

open import Base.Prelude
open import Base.Truth
open import Base.Classical using ( LEM )

module L.Coding.Uniform { : Level} (lem : LEM (ℓ-suc )) where

open import FOL.ZFStructure using ( module hPropStructure )
open import FOL.Syntax using ( Formula )
open import FOL.Manipulation.Relabelling using ( mapFo; mapFo-comp; ⊨-map )
import FOL.Absoluteness
open import V.Hierarchy {} using ( 𝒮ᵥ )
open import V.Coding {} using ( pr; module VCode )
open import L.Constructible {} using ( 𝒮ʟ; isL; isL-trans )
open import L.Definability {} using ( module DefOf )
open import L.Axioms.Numerals {} using ( numeralL; numeralL-fst )
open import L.Coding.Model {}
  using ( module LCode; prʟ-fst; codeBridge; domAt; domAt-intro; domAt-out )
open import L.Coding.EnvSet {} lem using ( envS )
open import L.Coding.Sat {} lem using ( Sat )
open import L.Coding.Bridge {} lem
  using ( intoL; asConst; Sat-spec; defSet-Sat ) renaming ( graph to envGraph )
open import L.Coding.Table {} lem
  using ( keyʟ; slot; satTable; total; inSlot; entry-in )
open import L.Coding.Slot {} lem using ( slotClosed )
open import L.Coding.Sound {} lem using ( soundness )
open import L.Coding.Unique {} lem using ( module Good )
open import L.Coding.Graph {} lem using ( satGraph; graph-in; graph-out )
open import L.Coding.CodeSet {} lem
  using ( keyS; AllCodes; AllCodes-out; key∈AllCodes )
open import L.Recursion {} lem using ( Recursion; mereFunct; module Of )

open import Cubical.Data.Sigma using ( Σ≡Prop )
import Cubical.HITs.PropositionalTruncation as PT
open PT using ( ∣_∣₁ )
open import Cubical.HITs.CumulativeHierarchy.Base using ( _∈_; setIsSet )
open import Cubical.HITs.CumulativeHierarchy.Properties using ( ⟪_⟫; ⟪_⟫↪ )
open import Cubical.HITs.CumulativeHierarchy.Constructions
  using ( module InfinitySet )
open InfinitySet using ( #_ )

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

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

点名一个成员

三行,而它们是本章唯一的一次性能决定。想要某条特定公式处的取值的消费方,必须为「取值所在的那个成员」点名,而显而易见的名字就是那个键本身;可是那样点名展开不了,因为键会展成「数码与码之对」,而那个构造随后就坐进了递归的定义域里、也坐进了一个满足关系里面。

于是那个名字在它被造出之处封印。封印之后,它是 L 的一个元素,类型可以提它而不必展开,而消费方所需的两条事实随之出来:它落在定义域中,且它是「造它时所用的那条公式」的键。下面的一切都陈述在变元成员上、并经一条等式抵达它的键,故需要被打开的只有这个封印,而没有任何东西打开它。

module _ (A : S) where
  opaque
    keyIn :  {n}  Formula  fst A  n  S
    keyIn ψ = keyS A ψ

    keyIn≡ :  {n} (ψ : Formula  fst A  n)  fst (keyIn ψ)  fst (keyS A ψ)
    keyIn≡ ψ = refl

    keyIn∈ :  {n} (ψ : Formula  fst A  n)   keyIn ψ ∈ˢ AllCodes A 
    keyIn∈ ψ = key∈AllCodes A ψ

两套编码的会合

层级编码里的一个键,是元数数码与「沿字母表的嵌入重标之后那条公式的码」之对;模型编码里的一个键,是 L 的数码与「在 L 里取的码」之对。codeBridge 把这两个码等同起来,一构造子一子句。它写在模型那一章,此后一直没有消费方,因为它当初就是为这条陈述而写的。

它供不出的是那次重标。集合那边的公式在字母表 A 之上,递归这边的公式在 L 之上,故两侧经过的是两个不同的映射,而它们的复合必须被认出为一个映射。那是重标的函子性,它归属于重标被定义之处,而如今就在那里;于是整座桥是四次改写,没有归纳。

通往模型的那个映射也不在此处造。它就是桥那一章自己的 asConst,即字母表的嵌入接上类包含;而取它、而非取一个与它相等的映射,正是使最后一节能够径直引用那条适足性、无须任何翻译步骤的原因。

这座桥只取字母表,别无其他。诸环境所落之上的那个集合在它里面从未出现,故它比下面那场递归少一个参数;而后面某一章若需要两套编码在「握在一位上的载体」处相符,便可以直接用它,无须供上一个它并不拥有的第二载体。

module _ (A : S) where
  keyBridge :  {n} (ψ : Formula  fst A  n)
             fst (keyS A ψ)  fst (keyʟ (mapFo (asConst A) ψ))
  keyBridge {n} ψ =
      cong (pr (# n))
        ( cong  χ  VCode.⌜ χ ) (sym (mapFo-comp (asConst A) fst ψ))
         sym (codeBridge (mapFo (asConst A) ψ)) )
     cong  w  pr w (fst LCode.⌜ mapFo (asConst A) ψ ))
        (sym (numeralL-fst n))
     sym (prʟ-fst (numeralL n) LCode.⌜ mapFo (asConst A) ψ )

module _ (A B : S) where
  private
    toS :  {n}  Formula  fst A  n  Formula S n
    toS = mapFo (asConst A)

两半,落在那个码所命名的公式上

两半都是前几章的,只是施于「该成员是其键的那条公式」而非某条周遭公式,而这次更换使存在性更短。按公式索引的那个实例得把一条子公式的条目沿「它自己的子树到周遭表的包含」搬过去;此处被还原出来的那条公式就是其表正被递出的那条公式,故 entry-in 直接适用,那次搬运消失了。

唯一性压根察觉不到这次更换,而理由是结构性的。Pinned 谈的是「图所产出的索引集与表」,那是调用方环境里的被绑定变元,从不谈递归的定义域。定义域既不出现在它里面,也不出现在十二条子句里,故更换递归的索引,够不着唯一性。

此处只把全性那条假设写出来,而它的环境也一并写出。若交给推断,图那三个存在绑定的槽位什么也决定不了,会剩下六个元变元;把环境点名只花一行,而那正是「能否被展开求解」的分水岭。

    Ci Ti : Fin 5
    Ci = suc (suc zero)
    Ti = suc zero

    hdom :  {n} (φ : Formula S n) (x y : S)
           (B  satTable B φ  slot B φ  y  x  [])  domAt Ti Ci 
    hdom φ x y = domAt-intro Ti Ci (B  satTable B φ  slot B φ  y  x  [])
       z   h  PT.rec (snd (fst z  fst (slot B φ)))
                 { (w , hw)  inSlot B φ (fst z) (fst w) hw }) h)
           ,  h  total B φ (fst z) h))

    exists :  {n} (φ : Formula S n) (x : S)  fst x  fst (keyʟ φ)
             (Sat B φ  x  [])  satGraph B 
    exists φ x k = graph-in B x (Sat B φ)
       slot B φ , (satTable B φ , (B , (refl
      , ( slotClosed B φ (Sat B φ  x  [])
      , ( hdom φ x (Sat B φ)
      , ( subst  w   pr w (fst (Sat B φ))  fst (satTable B φ) ) (sym k)
            (entry-in B φ)
      , soundness B φ (Sat B φ  x  []) )))))) ∣₁

    unique :  {n} (φ : Formula S n) (x : S)  fst x  fst (keyʟ φ)
            (y : S)   (y  x  [])  satGraph B   y  Sat B φ
    unique φ x k y hy = Σ≡Prop  v  snd (isL v))
      (PT.rec (setIsSet (fst y) (fst (Sat B φ)))
         { (C , (T , (b , (eb , (hc , (hd , (ha , h12))))))) 
          Good.pinned (b  T  C  y  x  []) Ci Ti zero hc hd h12 φ x y k
              (domAt-out Ti Ci (b  T  C  y  x  []) hd x y ha) ha
           cong  w  fst (Sat w φ)) (Σ≡Prop  v  snd (isL v)) eb) })
        (graph-out B x y hy))

那个实例

定义域是该阶段处的码集,图是两章之前的那一个,而 functmereFunct 交付,因为「仅仅存在的唯一解」就是可缩解。一个成员以「字母表之上某条公式的键」这种仅仅存在的形式到场,那座桥把它的等式变成一条关于模型之键的等式,而上面两半就施于那个键。

两个载体是彼此独立的参数,且保持如此。A 是诸码的常元所取自的字母表;B 是诸环境所落之上的集合;递归里没有任何东西把它们联系起来,而为一个用不上的关系向递归收费,等于陈述一条更弱的定理。它们在下一节、且只在那里被钉在一起,因为那才是满足关系获得含义的地方。

  satRec : Recursion
  Recursion.dom satRec = AllCodes A
  Recursion.graph satRec = satGraph B
  Recursion.funct satRec x x∈ = mereFunct (satGraph B) x
    (PT.map
       { (n , ψ , q)  Sat B (toS ψ)
         , ( exists (toS ψ) x (q  keyBridge A ψ)
           , unique (toS ψ) x (q  keyBridge A ψ) ) })
      (AllCodes-out A x x∈))

  module Table = Of satRec

那个取值是什么

一场与任何东西都不相连的递归什么也没定义,故那个取值陈述两遍。

先对着递归自己的构造,而那是唯一性反过来花掉:在「是某条公式之键」的那个成员处,取值就是元语言递归在那条公式处造出的那个集合,因为存在性那一半把那个集合作为一个解拿了出来,而递归的取值是唯一的解。这就是消费方要从这张表里取出任何东西所需的读式,因为那个值函数来自一次可缩性,自身不化简出任何东西。

那个成员是变元,而它的键经一条等式抵达;这是一次测量,不是口味。若径直陈述在那个键上,值函数的实参就是一个具体的码构造,也就把那个构造塞进了「值据以定义的那个图的满足关系」里;在变元上花四秒的那条陈述,写在键上跑过了六分钟并被放弃,而把它写成变元版本的推论时同样如此,这说明代价在陈述里、不在证明里。唯一性那一章在它的第一个情形上记下了这条规矩,而它在此处原样成立。

两个方向都什么也没有失去。手里握着一个成员的消费方,握着的就是一个成员,外加它的键等式;而想把那个成员点名的消费方,可经那个封印过的名字把方便的形式拿回来,且分文不花,因为类型在那里所提的东西不会展开。

  val-at :  {n} (ψ : Formula  fst A  n) (x : S) (x∈ :  x ∈ˢ AllCodes A )
          fst x  fst (keyS A ψ)
          Table.val x x∈  Sat B (toS ψ)
  val-at ψ x x∈ q =
    Table.val-uniq x x∈ (Sat B (toS ψ)) (exists (toS ψ) x (q  keyBridge A ψ))

  val-key :  {n} (ψ : Formula  fst A  n)
           Table.val (keyIn A ψ) (keyIn∈ A ψ)  Sat B (toS ψ)
  val-key ψ = val-at ψ (keyIn A ψ) (keyIn∈ A ψ) (keyIn≡ A ψ)

再对着满足关系,而那是这个目标存在的理由。桥那一章证过:元语言那个取值的成员,就是在世界 (B, ∈) 中满足该公式的一个环境;把它与上面那条读式复合,同一句话便落到这场递归所产出的表上。在元数一处它特化为可定义幂集所指的那个可定义子集,故在「是某条公式之键」的那个成员处读出的那张表,就是该公式的可定义子集,而那正是内部层级将据以读出 Def 的陈述。

两个载体在此会合,因为此处是它们非会合不可的地方。常元皆为载体成员的公式,内层世界读得了;点名了 L 的任意元素的公式则不然,而桥那一章对自己就是这么说的。故下面两条定理陈述在同一个载体上,而那本来也是消费方想要的实例化:某阶段处的诸码,在同一个阶段之上被满足。

module _ (A : S) where
  module DA = DefOf (fst A)
  open DA using ( _⊨ᵐ_ )

  val-sat :  {n} (ψ : Formula  fst A  n)
            (x : S) (x∈ :  x ∈ˢ AllCodes A )  fst x  fst (keyS A ψ)
           (δ : DA.SM ^ n) (z : S)  fst z  envGraph A δ
           (z ∈ˢ Table.val A A x x∈)  (δ ⊨ᵐ ψ)
  val-sat ψ x x∈ q δ z qz =
      cong (z ∈ˢ_)
        (val-at A A ψ x x∈ q  cong (Sat A) (sym (mapFo-comp DA.ι (intoL A) ψ)))
     Sat-spec A (mapFo DA.ι ψ) δ z qz
     ⊨-map (hPropAlgebra (ℓ-suc )) DA.𝒮M DA.ι id ψ δ

  val-defSet : (ψ : Formula  fst A  1) (m :  fst A )
               (x : S) (x∈ :  x ∈ˢ AllCodes A )  fst x  fst (keyS A ψ)
              ( fst A ⟫↪ m  DA.defSet ψ)
              (envS A  _  m) ∈ˢ Table.val A A x x∈)
  val-defSet ψ m x x∈ q = defSet-Sat A ψ m
     cong (envS A  _  m) ∈ˢ_) (sym (val-at A A ψ x x∈ q))

小结

satRec 是作为已内化递归的满足关系,跑在某阶段处的诸码之上,而非跑在一条公式的诸子公式之上,而 Table 是它产出的那张表。val-at 在一个以键的形式给出的成员处读出取值,而 val-key 是同一条读式落在「一条公式自己的键」那个封印过的名字上;val-sat 说那个取值就是载体之上的满足关系;而 val-defSet 把两者花在元数一处的可定义幂集上,那正是内部层级所消费的形式。

底下没有任何东西被重新索引,也没有任何东西被削弱。本目标登记在案的风险是:定义域或它的良构谓词会在某个不能取作槽位之处、把载体当作常元来要;那将把槽、表、全性与隶属重新索引在「载体与键」之对上,并为两半的十二个情形各记一笔搬运。它没有引爆,而直接的证据是:slotsatTabletotalinSlotslotClosedsoundnessGood.pinned 在上面全都是按它们既有的类型施用的。码载体压根到不了那个图:它在码集自己的谓词里被绑定、被钉住,而出来的是 L 的一个元素,而定义域无非就是这个。

使这一切便宜的是图里的那个存在量词,而这值得当作一项设计事实、而非一次偶然留存下来。一个把自己的表存在量化的图,允许一个取值由任意一张合格的表来担保,故实例可以在每个索引处用「够得着它的最小的表」作答。倘若那个图把自己的表点了名,定义域与表就得一起长大,而前面每一章都要动。

唯一没被预料到的代价落在诸陈述里、不落在诸证明里,而它就是本章的那次测量。在一个写开了的键处读出的取值,无论证明写多长都展开不了,因为那个键的构造落进了一个满足关系里面;在变元成员上花四秒的那条读式,写在键上跑过了六分钟,而把它写成变元版本的推论时同样如此。修好它的有两件事,恰是登记在案的两条规矩、一条一件:每条读式都把成员取作变元、并经一条等式抵达它的键;而消费方本会写下的那个名字,在它被造出之处封印。前者是唯一性那一章的规矩,此番出现在一个压根没有在作归纳证明的地方;后者是「关于出现在目标里的构造」的那条规矩,此番出现在一个只是一条等式的目标上。