Imports
/-
Copyright (c) 2026 Terence Rokop. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Terence Rokop
-/
module
public import Geb.Prototypes.Computability.BitTree.Scanner
public import Mathlib.Data.W.Basicset_option doc.verso trueBinary trees with bitstrings at the leaves
The W-type of the polynomial X ↦ List Bool + X × X has a direct binary
encoding. A fork is 1, a leaf starts with 0, each payload bit
b is escaped as 1b, and 0 terminates the payload.
Main definitions
-
Treeis the W-type, with constructorsleafandfork. -
encodeserializes a tree. -
validBoolscans a word once, retaining a mode and a pending-tree count.
Main statements
-
validBool_iffcharacterizes acceptance by existence of an encoded tree. -
encode_injectivestates uniqueness of the encoded tree. -
length_encodecounts the bits in the representation.
Tags
binary tree, bitstring, encoding, recognizer, W-type
@[expose] public sectionnamespace Geb.BitTreeNode shapes: a labelled leaf or a binary fork.
abbrev Shape := Option (List Bool)Leaves have no children; forks have two children indexed by booleans.
def Arity : Shape → Type
| some _ => Empty
| none => Bool
The initial algebra of X ↦ List Bool + X × X.
abbrev Tree := WType ArityA leaf carrying a bitstring.
def leaf (s : List Bool) : Tree := WType.mk (some s) Empty.elimA binary fork, with the left child indexed by false.
The two-constructor induction principle of the underlying W-type.
theorem tree_ind {P : Tree → Prop} (hl : ∀ s, P (leaf s))
(hf : ∀ l r, P l → P r → P (fork l r)) : ∀ t, P t :=
WType.rec fun a f ih ↦ P:Tree → Prophl:∀ (s : List Bool), P (leaf s)hf:∀ (l r : Tree), P l → P r → P (fork l r)a:Shapef:Arity a → WType Arityih:∀ (a : Arity a), P (f a)⊢ P (WType.mk a f)
cases a with
P:Tree → Prophl:∀ (s : List Bool), P (leaf s)hf:∀ (l r : Tree), P l → P r → P (fork l r)s:List Boolf:Arity (some s) → WType Arityih:∀ (a : Arity (some s)), P (f a)⊢ P (WType.mk (some s) f)
P:Tree → Prophl:∀ (s : List Bool), P (leaf s)hf:∀ (l r : Tree), P l → P r → P (fork l r)s:List Boolf:Arity (some s) → WType Arityih:∀ (a : Arity (some s)), P (f a)h:f = Empty.elim⊢ P (WType.mk (some s) f)
P:Tree → Prophl:∀ (s : List Bool), P (leaf s)hf:∀ (l r : Tree), P l → P r → P (fork l r)s:List Boolih:∀ (a : Arity (some s)), P (Empty.elim a)⊢ P (WType.mk (some s) Empty.elim)
All goals completed! 🐙
P:Tree → Prophl:∀ (s : List Bool), P (leaf s)hf:∀ (l r : Tree), P l → P r → P (fork l r)f:Arity none → WType Arityih:∀ (a : Arity none), P (f a)⊢ P (WType.mk none f)
none P:Tree → Prophl:∀ (s : List Bool), P (leaf s)hf:∀ (l r : Tree), P l → P r → P (fork l r)f:Arity none → WType Arityih:∀ (a : Arity none), P (f a)h:(fun b ↦ if b = true then f true else f false) = f⊢ P (WType.mk none f)
exact h ▸ hf (f false) (f true) (ih false) (ih true) All goals completed! 🐙Escape payload bits and terminate the string.
def encodeString (s : List Bool) : List Bool := s.foldr (fun b w ↦ true :: b :: w) [false]@[simp] theorem encodeString_nil : encodeString [] = [false] := rfl@[simp] theorem encodeString_cons (b : Bool) (s : List Bool) :
encodeString (b :: s) = true :: b :: encodeString s := rflPreorder encoding with a mode-dependent code for leaves and their payloads.
def encode : Tree → List Bool := WType.elim (List Bool) fun x ↦
match x with
| ⟨some s, _⟩ => false :: encodeString s
| ⟨none, f⟩ => true :: (f false ++ f true)@[simp] theorem encode_leaf (s : List Bool) : encode (leaf s) = false :: encodeString s := rfl@[simp] theorem encode_fork (l r : Tree) :
encode (fork l r) = true :: (encode l ++ encode r) := rflScanning an escaped string completes one pending tree.
theorem foldl_encodeString (s : List Bool) (n : Nat) :
(encodeString s).foldl step (.string, n) = finish n :=
List.rec rfl (fun b s ih ↦ by s✝:List Booln:ℕb:Bools:List Boolih:List.foldl step (Mode.string, n) (encodeString s) = finish n⊢ List.foldl step (Mode.string, n) (encodeString (b :: s)) = finish n simpa [encodeString, step] using ih All goals completed! 🐙) sScanning one encoded tree completes exactly one pending tree.
theorem foldl_encode (t : Tree) : ∀ n, 0 < n →
(encode t).foldl step (.tree, n) = finish n :=
tree_ind (P := fun t ↦ ∀ n, 0 < n → (encode t).foldl step (.tree, n) = finish n)
(fun s n _ ↦ by t:Trees:List Booln:ℕx✝:0 < n⊢ List.foldl step (Mode.tree, n) (encode (leaf s)) = finish n simpa [step] using foldl_encodeString s n All goals completed! 🐙)
(fun l r ihl ihr n hn ↦ by t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ List.foldl step (Mode.tree, n) (encode (fork l r)) = finish n
simp only [encode_fork, List.foldl_cons, step, List.foldl_append, ↓reduceIte] t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ List.foldl step (List.foldl step (Mode.tree, n + 1) (encode l)) (encode r) = finish n
rw [ihl (n + 1) (by t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ 0 < n + 1 omega All goals completed! 🐙)] t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ List.foldl step (finish (n + 1)) (encode r) = finish n
have h : finish (n + 1) = (.tree, n) := by t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ List.foldl step (Mode.tree, n) (encode (fork l r)) = finish n
rw [finish, t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ (if n + 1 = 1 then (Mode.done, 0) else (Mode.tree, n + 1 - 1)) = (Mode.tree, n) ite_eq_right (show n + 1 ≠ 1 by t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ List.foldl step (Mode.tree, n) (encode (fork l r)) = finish n omega All goals completed! 🐙)] t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < n⊢ (Mode.tree, n + 1 - 1) = (Mode.tree, n)
rfl t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < nh:finish (n + 1) = (Mode.tree, n)⊢ List.foldl step (finish (n + 1)) (encode r) = finish n
rw [h, t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < nh:finish (n + 1) = (Mode.tree, n)⊢ List.foldl step (Mode.tree, n) (encode r) = finish n ihr n hn t:Treel:Treer:Treeihl:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode l) = finish nihr:∀ (n : ℕ), 0 < n → List.foldl step (Mode.tree, n) (encode r) = finish nn:ℕhn:0 < nh:finish (n + 1) = (Mode.tree, n)⊢ finish n = finish n] All goals completed! 🐙) tEvery encoded tree is accepted.
@[simp] theorem validBool_encode (t : Tree) : validBool (encode t) = true := by t:Tree⊢ validBool (encode t) = true
simp [validBool, scan, foldl_encode t 1 (by omega), finish] All goals completed! 🐙An escaped string can be cancelled from a prefix without losing its boundary.
theorem encodeString_append_injective (s : List Bool) : ∀ t u v,
encodeString s ++ u = encodeString t ++ v → s = t ∧ u = v :=
List.rec
(fun t u v h ↦ by s:List Boolt:List Boolu:List Boolv:List Boolh:encodeString [] ++ u = encodeString t ++ v⊢ [] = t ∧ u = v
cases t with
| nil => nil s:List Boolu:List Boolv:List Boolh:encodeString [] ++ u = encodeString [] ++ v⊢ [] = [] ∧ u = v exact ⟨rfl, (List.cons.inj h).2⟩ All goals completed! 🐙
| cons _ _ => cons s:List Boolu:List Boolv:List Boolhead✝:Booltail✝:List Boolh:encodeString [] ++ u = encodeString (head✝ :: tail✝) ++ v⊢ [] = head✝ :: tail✝ ∧ u = v simp at h All goals completed! 🐙)
(fun b s ih t u v h ↦ by s✝:List Boolb:Bools:List Boolih:∀ (t u v : List Bool), encodeString s ++ u = encodeString t ++ v → s = t ∧ u = vt:List Boolu:List Boolv:List Boolh:encodeString (b :: s) ++ u = encodeString t ++ v⊢ b :: s = t ∧ u = v
cases t with
| nil => nil s✝:List Boolb:Bools:List Boolih:∀ (t u v : List Bool), encodeString s ++ u = encodeString t ++ v → s = t ∧ u = vu:List Boolv:List Boolh:encodeString (b :: s) ++ u = encodeString [] ++ v⊢ b :: s = [] ∧ u = v simp at h All goals completed! 🐙
| cons c t => cons s✝:List Boolb:Bools:List Boolih:∀ (t u v : List Bool), encodeString s ++ u = encodeString t ++ v → s = t ∧ u = vu:List Boolv:List Boolc:Boolt:List Boolh:encodeString (b :: s) ++ u = encodeString (c :: t) ++ v⊢ b :: s = c :: t ∧ u = v
obtain ⟨hbc, hrest⟩ := List.cons.inj (List.cons.inj h).2 cons s✝:List Boolb:Bools:List Boolih:∀ (t u v : List Bool), encodeString s ++ u = encodeString t ++ v → s = t ∧ u = vu:List Boolv:List Boolc:Boolt:List Boolh:encodeString (b :: s) ++ u = encodeString (c :: t) ++ vhbc:b = chrest:(List.foldr (fun b w ↦ true :: b :: w) [false] s).append u = (List.foldr (fun b w ↦ true :: b :: w) [false] t).append v⊢ b :: s = c :: t ∧ u = v
obtain ⟨hst, huv⟩ := ih t u v hrest cons s✝:List Boolb:Bools:List Boolih:∀ (t u v : List Bool), encodeString s ++ u = encodeString t ++ v → s = t ∧ u = vu:List Boolv:List Boolc:Boolt:List Boolh:encodeString (b :: s) ++ u = encodeString (c :: t) ++ vhbc:b = chrest:(List.foldr (fun b w ↦ true :: b :: w) [false] s).append u = (List.foldr (fun b w ↦ true :: b :: w) [false] t).append vhst:s = thuv:u = v⊢ b :: s = c :: t ∧ u = v
exact ⟨by s✝:List Boolb:Bools:List Boolih:∀ (t u v : List Bool), encodeString s ++ u = encodeString t ++ v → s = t ∧ u = vu:List Boolv:List Boolc:Boolt:List Boolh:encodeString (b :: s) ++ u = encodeString (c :: t) ++ vhbc:b = chrest:(List.foldr (fun b w ↦ true :: b :: w) [false] s).append u = (List.foldr (fun b w ↦ true :: b :: w) [false] t).append vhst:s = thuv:u = v⊢ b :: s = c :: t simp [hbc, hst] All goals completed! 🐙, huv⟩) sAn encoded tree determines both its value and its boundary in a longer word.
theorem encode_append_injective (t : Tree) : ∀ t' u v,
encode t ++ u = encode t' ++ v → t = t' ∧ u = v :=
tree_ind
(P := fun t ↦ ∀ t' u v, encode t ++ u = encode t' ++ v → t = t' ∧ u = v)
(fun s t' ↦ tree_ind
(P := fun t' ↦ ∀ u v, encode (leaf s) ++ u = encode t' ++ v →
leaf s = t' ∧ u = v)
(fun s' u v h ↦ by t:Trees:List Boolt':Trees':List Boolu:List Boolv:List Boolh:encode (leaf s) ++ u = encode (leaf s') ++ v⊢ leaf s = leaf s' ∧ u = v
obtain ⟨hs, huv⟩ := encodeString_append_injective s s' u v (List.cons.inj h).2 t:Trees:List Boolt':Trees':List Boolu:List Boolv:List Boolh:encode (leaf s) ++ u = encode (leaf s') ++ vhs:s = s'huv:u = v⊢ leaf s = leaf s' ∧ u = v
exact ⟨congrArg leaf hs, huv⟩ All goals completed! 🐙)
(fun _ _ _ _ u v h ↦ by t:Trees:List Boolt':Treex✝³:Treex✝²:Treex✝¹:∀ (u v : List Bool), encode (leaf s) ++ u = encode x✝³ ++ v → leaf s = x✝³ ∧ u = vx✝:∀ (u v : List Bool), encode (leaf s) ++ u = encode x✝² ++ v → leaf s = x✝² ∧ u = vu:List Boolv:List Boolh:encode (leaf s) ++ u = encode (fork x✝³ x✝²) ++ v⊢ leaf s = fork x✝³ x✝² ∧ u = v simp at h All goals completed! 🐙) t')
(fun l r ihl ihr t' ↦ tree_ind
(P := fun t' ↦ ∀ u v, encode (fork l r) ++ u = encode t' ++ v →
fork l r = t' ∧ u = v)
(fun _ u v h ↦ by t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treex✝:List Boolu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (leaf x✝) ++ v⊢ fork l r = leaf x✝ ∧ u = v simp at h All goals completed! 🐙)
(fun l' r' _ _ u v h ↦ by t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ v⊢ fork l r = fork l' r' ∧ u = v
have he : encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v) := by
have he' := congrArg List.tail h t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe':(encode (fork l r) ++ u).tail = (encode (fork l' r') ++ v).tail⊢ encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)
change (encode l ++ encode r) ++ u = (encode l' ++ encode r') ++ v at he' t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe':encode l ++ encode r ++ u = encode l' ++ encode r' ++ v⊢ encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)
simpa only [List.append_assoc] using he' t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe:encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)⊢ fork l r = fork l' r' ∧ u = v
obtain ⟨hl, hr⟩ := ihl l' (encode r ++ u) (encode r' ++ v) he t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe:encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)hl:l = l'hr:encode r ++ u = encode r' ++ v⊢ fork l r = fork l' r' ∧ u = v
obtain ⟨hr', huv⟩ := ihr r' u v hr t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe:encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)hl:l = l'hr:encode r ++ u = encode r' ++ vhr':r = r'huv:u = v⊢ fork l r = fork l' r' ∧ u = v
exact ⟨by t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe:encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)hl:l = l'hr:encode r ++ u = encode r' ++ vhr':r = r'huv:u = v⊢ fork l r = fork l' r' rw [hl, t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe:encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)hl:l = l'hr:encode r ++ u = encode r' ++ vhr':r = r'huv:u = v⊢ fork l' r = fork l' r' hr' t:Treel:Treer:Treeihl:∀ (t' : Tree) (u v : List Bool), encode l ++ u = encode t' ++ v → l = t' ∧ u = vihr:∀ (t' : Tree) (u v : List Bool), encode r ++ u = encode t' ++ v → r = t' ∧ u = vt':Treel':Treer':Treex✝¹:∀ (u v : List Bool), encode (fork l r) ++ u = encode l' ++ v → fork l r = l' ∧ u = vx✝:∀ (u v : List Bool), encode (fork l r) ++ u = encode r' ++ v → fork l r = r' ∧ u = vu:List Boolv:List Boolh:encode (fork l r) ++ u = encode (fork l' r') ++ vhe:encode l ++ (encode r ++ u) = encode l' ++ (encode r' ++ v)hl:l = l'hr:encode r ++ u = encode r' ++ vhr':r = r'huv:u = v⊢ fork l' r' = fork l' r'] All goals completed! 🐙, huv⟩) t') tThe direct binary encoding is injective.
theorem encode_injective : Function.Injective encode := fun t t' h ↦
(encode_append_injective t t' [] [] (by t:Treet':Treeh:encode t = encode t'⊢ encode t ++ [] = encode t' ++ [] simpa using h All goals completed! 🐙)).1Forest encoding is the concatenation of its component encodings.
The grammar of the remaining suffix in each scanner mode.
def Completion (s : State) (w : List Bool) : Prop :=
match s.1 with
| .tree => ∃ ts, ts.length = s.2 ∧ w = encodeForest ts
| .string => ∃ bs ts, ts.length + 1 = s.2 ∧ w = encodeString bs ++ encodeForest ts
| .bit => ∃ b bs ts, ts.length + 1 = s.2 ∧
w = b :: (encodeString bs ++ encodeForest ts)
| .done => w = []
| .dead => FalseA successful scan supplies a grammatical decomposition of its whole suffix.
theorem completion_of_accept (w : List Bool) : ∀ s, Active s →
(w.foldl step s).1 = .done → Completion s w :=
List.rec
(fun s _ h ↦ by w:List Bools:Statex✝:Active sh:(List.foldl step s []).1 = Mode.done⊢ Completion s [] rcases s with ⟨m, n⟩ w:List Boolm:Moden:ℕx✝:Active (m, n)h:(List.foldl step (m, n) []).1 = Mode.done⊢ Completion (m, n) []; cases m tree w:List Booln:ℕx✝:Active (Mode.tree, n)h:(List.foldl step (Mode.tree, n) []).1 = Mode.done⊢ Completion (Mode.tree, n) []string w:List Booln:ℕx✝:Active (Mode.string, n)h:(List.foldl step (Mode.string, n) []).1 = Mode.done⊢ Completion (Mode.string, n) []bit w:List Booln:ℕx✝:Active (Mode.bit, n)h:(List.foldl step (Mode.bit, n) []).1 = Mode.done⊢ Completion (Mode.bit, n) []done w:List Booln:ℕx✝:Active (Mode.done, n)h:(List.foldl step (Mode.done, n) []).1 = Mode.done⊢ Completion (Mode.done, n) []dead w:List Booln:ℕx✝:Active (Mode.dead, n)h:(List.foldl step (Mode.dead, n) []).1 = Mode.done⊢ Completion (Mode.dead, n) [] <;> tree w:List Booln:ℕx✝:Active (Mode.tree, n)h:(List.foldl step (Mode.tree, n) []).1 = Mode.done⊢ Completion (Mode.tree, n) []string w:List Booln:ℕx✝:Active (Mode.string, n)h:(List.foldl step (Mode.string, n) []).1 = Mode.done⊢ Completion (Mode.string, n) []bit w:List Booln:ℕx✝:Active (Mode.bit, n)h:(List.foldl step (Mode.bit, n) []).1 = Mode.done⊢ Completion (Mode.bit, n) []done w:List Booln:ℕx✝:Active (Mode.done, n)h:(List.foldl step (Mode.done, n) []).1 = Mode.done⊢ Completion (Mode.done, n) []dead w:List Booln:ℕx✝:Active (Mode.dead, n)h:(List.foldl step (Mode.dead, n) []).1 = Mode.done⊢ Completion (Mode.dead, n) [] simp_all [Completion] All goals completed! 🐙)
(fun b w ih s hs ha ↦ by w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s ws:Statehs:Active sha:(List.foldl step s (b :: w)).1 = Mode.done⊢ Completion s (b :: w)
have hc := ih (step s b) (active_step s b hs) ha w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s ws:Statehs:Active sha:(List.foldl step s (b :: w)).1 = Mode.donehc:Completion (step s b) w⊢ Completion s (b :: w)
rcases s with ⟨m, n⟩ w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wm:Moden:ℕhs:Active (m, n)ha:(List.foldl step (m, n) (b :: w)).1 = Mode.donehc:Completion (step (m, n) b) w⊢ Completion (m, n) (b :: w)
cases m with
| tree => tree w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)ha:(List.foldl step (Mode.tree, n) (b :: w)).1 = Mode.donehc:Completion (step (Mode.tree, n) b) w⊢ Completion (Mode.tree, n) (b :: w)
have hn : 0 < n := hs (Or.inl rfl) tree w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)ha:(List.foldl step (Mode.tree, n) (b :: w)).1 = Mode.donehc:Completion (step (Mode.tree, n) b) whn:0 < n⊢ Completion (Mode.tree, n) (b :: w)
cases b with
| false => tree.false w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.tree, n) false) w⊢ Completion (Mode.tree, n) (false :: w)
obtain ⟨bs, ts, ht, hw⟩ := hc tree.false w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (false :: w)).1 = Mode.donebs:List Boolts:List Treeht:ts.length + 1 = (step (Mode.tree, n) false).2hw:w = encodeString bs ++ encodeForest ts⊢ Completion (Mode.tree, n) (false :: w)
exact ⟨leaf bs :: ts, ht, by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (false :: w)).1 = Mode.donebs:List Boolts:List Treeht:ts.length + 1 = (step (Mode.tree, n) false).2hw:w = encodeString bs ++ encodeForest ts⊢ false :: w = encodeForest (leaf bs :: ts) simp [encodeForest, hw] All goals completed! 🐙⟩
| true => tree.true w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donehc:Completion (step (Mode.tree, n) true) w⊢ Completion (Mode.tree, n) (true :: w)
change ∃ ts, ts.length = n + 1 ∧ w = encodeForest ts at hc tree.true w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donehc:∃ ts, ts.length = n + 1 ∧ w = encodeForest ts⊢ Completion (Mode.tree, n) (true :: w)
obtain ⟨ts, ht, hw⟩ := hc tree.true w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donets:List Treeht:ts.length = n + 1hw:w = encodeForest ts⊢ Completion (Mode.tree, n) (true :: w)
cases ts with
| nil => tree.true.nil w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.doneht:[].length = n + 1hw:w = encodeForest []⊢ Completion (Mode.tree, n) (true :: w)
exfalso tree.true.nil w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.doneht:[].length = n + 1hw:w = encodeForest []⊢ False
change 0 = n + 1 at ht tree.true.nil w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donehw:w = encodeForest []ht:0 = n + 1⊢ False
omega All goals completed! 🐙
| cons l ts => tree.true.cons w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donel:Treets:List Treeht:(l :: ts).length = n + 1hw:w = encodeForest (l :: ts)⊢ Completion (Mode.tree, n) (true :: w)
cases ts with
| nil => tree.true.cons.nil w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donel:Treeht:[l].length = n + 1hw:w = encodeForest [l]⊢ Completion (Mode.tree, n) (true :: w)
exfalso tree.true.cons.nil w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donel:Treeht:[l].length = n + 1hw:w = encodeForest [l]⊢ False
change 1 = n + 1 at ht tree.true.cons.nil w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donel:Treehw:w = encodeForest [l]ht:1 = n + 1⊢ False
omega All goals completed! 🐙
| cons r ts => tree.true.cons.cons w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donel:Treer:Treets:List Treeht:(l :: r :: ts).length = n + 1hw:w = encodeForest (l :: r :: ts)⊢ Completion (Mode.tree, n) (true :: w)
refine ⟨fork l r :: ts, by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donel:Treer:Treets:List Treeht:(l :: r :: ts).length = n + 1hw:w = encodeForest (l :: r :: ts)⊢ (fork l r :: ts).length = (Mode.tree, n).2 simp only [List.length_cons] at ht ⊢ w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.tree, n)hn:0 < nha:(List.foldl step (Mode.tree, n) (true :: w)).1 = Mode.donel:Treer:Treets:List Treeht:ts.length + 1 + 1 = n + 1hw:w = encodeForest (l :: r :: ts)⊢ ts.length + 1 = n; omega All goals completed! 🐙, ?_⟩
simp [encodeForest, hw, List.append_assoc] All goals completed! 🐙
| string => string w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (b :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) b) w⊢ Completion (Mode.string, n) (b :: w)
cases b with
| false => string.false w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) w⊢ Completion (Mode.string, n) (false :: w)
by_cases hn : n = 1 pos w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:n = 1⊢ Completion (Mode.string, n) (false :: w)neg w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:¬n = 1⊢ Completion (Mode.string, n) (false :: w)
· pos w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:n = 1⊢ Completion (Mode.string, n) (false :: w) have hw : w = [] := by w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s ws:Statehs:Active sha:(List.foldl step s (b :: w)).1 = Mode.done⊢ Completion s (b :: w) simpa [step, finish, hn, Completion] using hc pos w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:n = 1hw:w = []⊢ Completion (Mode.string, n) (false :: w)
exact ⟨[], [], by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:n = 1hw:w = []⊢ [].length + 1 = (Mode.string, n).2 simpa using hn.symm All goals completed! 🐙, by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:n = 1hw:w = []⊢ false :: w = encodeString [] ++ encodeForest [] simp [hw, encodeForest] All goals completed! 🐙⟩
· neg w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:¬n = 1⊢ Completion (Mode.string, n) (false :: w) obtain ⟨ts, ht, hw⟩ : ∃ ts, ts.length = n - 1 ∧ w = encodeForest ts := by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:¬n = 1⊢ ∃ ts, ts.length = n - 1 ∧ w = encodeForest ts
simpa [step, finish, hn, Completion] using hc neg w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:¬n = 1ts:List Treeht:ts.length = n - 1hw:w = encodeForest ts⊢ Completion (Mode.string, n) (false :: w)
have hp := hs (Or.inr (Or.inl rfl)) neg w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:¬n = 1ts:List Treeht:ts.length = n - 1hw:w = encodeForest tshp:0 < (Mode.string, n).2⊢ Completion (Mode.string, n) (false :: w)
exact ⟨[], ts, by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:¬n = 1ts:List Treeht:ts.length = n - 1hw:w = encodeForest tshp:0 < (Mode.string, n).2⊢ ts.length + 1 = (Mode.string, n).2 omega All goals completed! 🐙, by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (false :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) false) whn:¬n = 1ts:List Treeht:ts.length = n - 1hw:w = encodeForest tshp:0 < (Mode.string, n).2⊢ false :: w = encodeString [] ++ encodeForest ts simp [hw] All goals completed! 🐙⟩
| true => string.true w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (true :: w)).1 = Mode.donehc:Completion (step (Mode.string, n) true) w⊢ Completion (Mode.string, n) (true :: w)
obtain ⟨c, bs, ts, ht, hw⟩ := hc string.true w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (true :: w)).1 = Mode.donec:Boolbs:List Boolts:List Treeht:ts.length + 1 = (step (Mode.string, n) true).2hw:w = c :: (encodeString bs ++ encodeForest ts)⊢ Completion (Mode.string, n) (true :: w)
exact ⟨c :: bs, ts, ht, by w✝:List Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.string, n)ha:(List.foldl step (Mode.string, n) (true :: w)).1 = Mode.donec:Boolbs:List Boolts:List Treeht:ts.length + 1 = (step (Mode.string, n) true).2hw:w = c :: (encodeString bs ++ encodeForest ts)⊢ true :: w = encodeString (c :: bs) ++ encodeForest ts simp [hw] All goals completed! 🐙⟩
| bit => bit w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.bit, n)ha:(List.foldl step (Mode.bit, n) (b :: w)).1 = Mode.donehc:Completion (step (Mode.bit, n) b) w⊢ Completion (Mode.bit, n) (b :: w)
obtain ⟨bs, ts, ht, hw⟩ := hc bit w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.bit, n)ha:(List.foldl step (Mode.bit, n) (b :: w)).1 = Mode.donebs:List Boolts:List Treeht:ts.length + 1 = (step (Mode.bit, n) b).2hw:w = encodeString bs ++ encodeForest ts⊢ Completion (Mode.bit, n) (b :: w)
exact ⟨b, bs, ts, ht, by w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.bit, n)ha:(List.foldl step (Mode.bit, n) (b :: w)).1 = Mode.donebs:List Boolts:List Treeht:ts.length + 1 = (step (Mode.bit, n) b).2hw:w = encodeString bs ++ encodeForest ts⊢ b :: w = b :: (encodeString bs ++ encodeForest ts) simp [hw] All goals completed! 🐙⟩
| done => done w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.done, n)ha:(List.foldl step (Mode.done, n) (b :: w)).1 = Mode.donehc:Completion (step (Mode.done, n) b) w⊢ Completion (Mode.done, n) (b :: w) exact False.elim hc All goals completed! 🐙
| dead => dead w✝:List Boolb:Boolw:List Boolih:∀ (s : State), Active s → (List.foldl step s w).1 = Mode.done → Completion s wn:ℕhs:Active (Mode.dead, n)ha:(List.foldl step (Mode.dead, n) (b :: w)).1 = Mode.donehc:Completion (step (Mode.dead, n) b) w⊢ Completion (Mode.dead, n) (b :: w) exact False.elim hc All goals completed! 🐙) wAcceptance is equivalent to being the encoding of a binary tree of bitstrings.
theorem validBool_iff (w : List Bool) : validBool w = true ↔ ∃ t, encode t = w := by w:List Bool⊢ validBool w = true ↔ ∃ t, encode t = w
constructor mp w:List Bool⊢ validBool w = true → ∃ t, encode t = wmpr w:List Bool⊢ (∃ t, encode t = w) → validBool w = true
· mp w:List Bool⊢ validBool w = true → ∃ t, encode t = w intro h mp w:List Boolh:validBool w = true⊢ ∃ t, encode t = w
have hc := completion_of_accept w (.tree, 1) (by w:List Boolh:validBool w = true⊢ Active (Mode.tree, 1) simp [Active] All goals completed! 🐙)
(of_decide_eq_true h) mp w:List Boolh:validBool w = truehc:Completion (Mode.tree, 1) w⊢ ∃ t, encode t = w
obtain ⟨ts, ht, hw⟩ := hc mp w:List Boolh:validBool w = truets:List Treeht:ts.length = (Mode.tree, 1).2hw:w = encodeForest ts⊢ ∃ t, encode t = w
cases ts with
| nil => mp.nil w:List Boolh:validBool w = trueht:[].length = (Mode.tree, 1).2hw:w = encodeForest []⊢ ∃ t, encode t = w simp at ht All goals completed! 🐙
| cons t ts => mp.cons w:List Boolh:validBool w = truet:Treets:List Treeht:(t :: ts).length = (Mode.tree, 1).2hw:w = encodeForest (t :: ts)⊢ ∃ t, encode t = w
have he : ts = [] := List.eq_nil_of_length_eq_zero (by w:List Boolh:validBool w = truet:Treets:List Treeht:(t :: ts).length = (Mode.tree, 1).2hw:w = encodeForest (t :: ts)⊢ ts.length = 0 change ts.length + 1 = 1 at ht w:List Boolh:validBool w = truet:Treets:List Treehw:w = encodeForest (t :: ts)ht:ts.length + 1 = 1⊢ ts.length = 0; omega All goals completed! 🐙) mp.cons w:List Boolh:validBool w = truet:Treets:List Treeht:(t :: ts).length = (Mode.tree, 1).2hw:w = encodeForest (t :: ts)he:ts = []⊢ ∃ t, encode t = w
subst ts mp.cons w:List Boolh:validBool w = truet:Treeht:[t].length = (Mode.tree, 1).2hw:w = encodeForest [t]⊢ ∃ t, encode t = w
exact ⟨t, by w:List Boolh:validBool w = truet:Treeht:[t].length = (Mode.tree, 1).2hw:w = encodeForest [t]⊢ encode t = w simpa [encodeForest] using hw.symm All goals completed! 🐙⟩
· mpr w:List Bool⊢ (∃ t, encode t = w) → validBool w = true rintro ⟨t, rfl⟩ mpr t:Tree⊢ validBool (encode t) = true
exact validBool_encode t All goals completed! 🐙Every accepted word represents exactly one tree.
theorem validBool_iff_existsUnique (w : List Bool) :
validBool w = true ↔ ∃! t, encode t = w := by w:List Bool⊢ validBool w = true ↔ ∃! t, encode t = w
rw [validBool_iff w:List Bool⊢ (∃ t, encode t = w) ↔ ∃! t, encode t = w] w:List Bool⊢ (∃ t, encode t = w) ↔ ∃! t, encode t = w
constructor mp w:List Bool⊢ (∃ t, encode t = w) → ∃! t, encode t = wmpr w:List Bool⊢ (∃! t, encode t = w) → ∃ t, encode t = w
· mp w:List Bool⊢ (∃ t, encode t = w) → ∃! t, encode t = w rintro ⟨t, ht⟩ mp w:List Boolt:Treeht:encode t = w⊢ ∃! t, encode t = w
exact ⟨t, ht, fun t' ht' ↦ encode_injective (ht'.trans ht.symm)⟩ All goals completed! 🐙
· mpr w:List Bool⊢ (∃! t, encode t = w) → ∃ t, encode t = w rintro ⟨t, ht, _⟩ mpr w:List Boolt:Treeht:encode t = wright✝:∀ (y : Tree), (fun t ↦ encode t = w) y → y = t⊢ ∃ t, encode t = w
exact ⟨t, ht⟩ All goals completed! 🐙The number of forks, leaves, and payload bits, respectively.
def counts : Tree → Nat × Nat × Nat := WType.elim (Nat × Nat × Nat) fun x ↦
match x with
| ⟨some s, _⟩ => (0, 1, s.length)
| ⟨none, f⟩ => (1 + (f false).1 + (f true).1,
(f false).2.1 + (f true).2.1, (f false).2.2 + (f true).2.2)@[simp] theorem counts_leaf (s : List Bool) : counts (leaf s) = (0, 1, s.length) := rfl@[simp] theorem counts_fork (l r : Tree) :
counts (fork l r) = ((counts l).1 + (counts r).1 + 1,
(counts l).2.1 + (counts r).2.1, (counts l).2.2 + (counts r).2.2) := by l:Treer:Tree⊢ counts (fork l r) = ((counts l).1 + (counts r).1 + 1, (counts l).2.1 + (counts r).2.1, (counts l).2.2 + (counts r).2.2)
change (1 + (counts l).1 + (counts r).1, _, _) = _ l:Treer:Tree⊢ (1 + (counts l).1 + (counts r).1,
((fun b ↦
WType.elim (ℕ × ℕ × ℕ)
(fun x ↦
match x with
| ⟨some s, snd⟩ => (0, 1, s.length)
| ⟨none, f⟩ =>
(1 + (f false).1 + (f true).1, (f false).2.1 + (f true).2.1, (f false).2.2 + (f true).2.2))
((fun b ↦ if b = true then r else l) b))
false).2.1 +
((fun b ↦
WType.elim (ℕ × ℕ × ℕ)
(fun x ↦
match x with
| ⟨some s, snd⟩ => (0, 1, s.length)
| ⟨none, f⟩ =>
(1 + (f false).1 + (f true).1, (f false).2.1 + (f true).2.1, (f false).2.2 + (f true).2.2))
((fun b ↦ if b = true then r else l) b))
true).2.1,
((fun b ↦
WType.elim (ℕ × ℕ × ℕ)
(fun x ↦
match x with
| ⟨some s, snd⟩ => (0, 1, s.length)
| ⟨none, f⟩ =>
(1 + (f false).1 + (f true).1, (f false).2.1 + (f true).2.1, (f false).2.2 + (f true).2.2))
((fun b ↦ if b = true then r else l) b))
false).2.2 +
((fun b ↦
WType.elim (ℕ × ℕ × ℕ)
(fun x ↦
match x with
| ⟨some s, snd⟩ => (0, 1, s.length)
| ⟨none, f⟩ =>
(1 + (f false).1 + (f true).1, (f false).2.1 + (f true).2.1, (f false).2.2 + (f true).2.2))
((fun b ↦ if b = true then r else l) b))
true).2.2) =
((counts l).1 + (counts r).1 + 1, (counts l).2.1 + (counts r).2.1, (counts l).2.2 + (counts r).2.2)
congr 1 e_fst l:Treer:Tree⊢ 1 + (counts l).1 + (counts r).1 = (counts l).1 + (counts r).1 + 1
omega All goals completed! 🐙A full binary tree has one more leaf than fork.
theorem leaves_eq_forks_add_one (t : Tree) : (counts t).2.1 = (counts t).1 + 1 :=
tree_ind (P := fun t ↦ (counts t).2.1 = (counts t).1 + 1)
(fun s ↦ rfl) (fun l r ihl ihr ↦ by t:Treel:Treer:Treeihl:(counts l).2.1 = (counts l).1 + 1ihr:(counts r).2.1 = (counts r).1 + 1⊢ (counts (fork l r)).2.1 = (counts (fork l r)).1 + 1 simp only [counts_fork] t:Treel:Treer:Treeihl:(counts l).2.1 = (counts l).1 + 1ihr:(counts r).2.1 = (counts r).1 + 1⊢ (counts l).2.1 + (counts r).2.1 = (counts l).1 + (counts r).1 + 1 + 1; omega All goals completed! 🐙) tEscaping uses two bits per payload bit and one terminator.
@[simp] theorem length_encodeString (s : List Bool) :
(encodeString s).length = 2 * s.length + 1 :=
List.rec rfl (fun b s ih ↦ by s✝:List Boolb:Bools:List Boolih:(encodeString s).length = 2 * s.length + 1⊢ (encodeString (b :: s)).length = 2 * (b :: s).length + 1 simp only [encodeString_cons, List.length_cons] s✝:List Boolb:Bools:List Boolih:(encodeString s).length = 2 * s.length + 1⊢ (encodeString s).length + 1 + 1 = 2 * (s.length + 1) + 1; omega All goals completed! 🐙) sThe encoding uses one bit per fork, two per leaf, and two per payload bit.
theorem length_encode (t : Tree) :
(encode t).length = (counts t).1 + 2 * (counts t).2.1 + 2 * (counts t).2.2 :=
tree_ind (P := fun t ↦ (encode t).length =
(counts t).1 + 2 * (counts t).2.1 + 2 * (counts t).2.2)
(fun s ↦ by t:Trees:List Bool⊢ (encode (leaf s)).length = (counts (leaf s)).1 + 2 * (counts (leaf s)).2.1 + 2 * (counts (leaf s)).2.2
change (false :: encodeString s).length = 0 + 2 * 1 + 2 * s.length t:Trees:List Bool⊢ (false :: encodeString s).length = 0 + 2 * 1 + 2 * s.length
simp t:Trees:List Bool⊢ 2 * s.length + 1 + 1 = 2 + 2 * s.length; omega All goals completed! 🐙)
(fun l r ihl ihr ↦ by t:Treel:Treer:Treeihl:(encode l).length = (counts l).1 + 2 * (counts l).2.1 + 2 * (counts l).2.2ihr:(encode r).length = (counts r).1 + 2 * (counts r).2.1 + 2 * (counts r).2.2⊢ (encode (fork l r)).length = (counts (fork l r)).1 + 2 * (counts (fork l r)).2.1 + 2 * (counts (fork l r)).2.2
simp only [encode_fork, List.length_cons, List.length_append] t:Treel:Treer:Treeihl:(encode l).length = (counts l).1 + 2 * (counts l).2.1 + 2 * (counts l).2.2ihr:(encode r).length = (counts r).1 + 2 * (counts r).2.1 + 2 * (counts r).2.2⊢ (encode l).length + (encode r).length + 1 =
(counts (fork l r)).1 + 2 * (counts (fork l r)).2.1 + 2 * (counts (fork l r)).2.2
change _ = (1 + (counts l).1 + (counts r).1) +
2 * ((counts l).2.1 + (counts r).2.1) +
2 * ((counts l).2.2 + (counts r).2.2) t:Treel:Treer:Treeihl:(encode l).length = (counts l).1 + 2 * (counts l).2.1 + 2 * (counts l).2.2ihr:(encode r).length = (counts r).1 + 2 * (counts r).2.1 + 2 * (counts r).2.2⊢ (encode l).length + (encode r).length + 1 =
1 + (counts l).1 + (counts r).1 + 2 * ((counts l).2.1 + (counts r).2.1) + 2 * ((counts l).2.2 + (counts r).2.2)
omega All goals completed! 🐙) tCounting leaves through the full-binary-tree identity eliminates one parameter.
theorem length_encode_forks (t : Tree) :
(encode t).length = 3 * (counts t).1 + 2 + 2 * (counts t).2.2 := by t:Tree⊢ (encode t).length = 3 * (counts t).1 + 2 + 2 * (counts t).2.2
rw [length_encode, t:Tree⊢ (counts t).1 + 2 * (counts t).2.1 + 2 * (counts t).2.2 = 3 * (counts t).1 + 2 + 2 * (counts t).2.2 leaves_eq_forks_add_one t:Tree⊢ (counts t).1 + 2 * ((counts t).1 + 1) + 2 * (counts t).2.2 = 3 * (counts t).1 + 2 + 2 * (counts t).2.2] t:Tree⊢ (counts t).1 + 2 * ((counts t).1 + 1) + 2 * (counts t).2.2 = 3 * (counts t).1 + 2 + 2 * (counts t).2.2
omega All goals completed! 🐙end Geb.BitTree