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.Mathlib.Computability.BellantoniCook.Basic
public import Geb.Mathlib.Data.PFunctor.Slice.Decidable
public import Geb.Mathlib.Data.Tree.Ranked.BinaryA tree recognizer in the Bellantoni-Cook class
Three expressions of B deciding whether a bitstring is the preorder spelling
of a binary tree, and their correctness against the Valid predicate of the
encoding. Composed with RankedAlphabet.valid_iff_exists_spell,
isTreeSem_eq_singleton_iff_exists_spell states that an expression of B
accepts exactly the spellings of binRanked's terms. BellantoniCook.BC
reformulates [BellantoniCook1992]'s class; by [HeraudNowak2011] Theorems 1 and
2, which relate B to Cobham's class in both directions, composed with
Cobham's theorem identifying Cobham's class with the polynomial-time
functions, B coincides with the polynomial-time functions. That composition
is used and not proved here, so the membership test lies in that class
without a separate complexity argument.
The recognizer is a single right-to-left scan rather than a recursive descent. A descent would parse the second subtree from a remainder the first call computes, which sits in safe position, and recursion on a safe argument is what the class forbids.
Main definitions
BellantoniCook.zeroAtRaw, BellantoniCook.oneAtRaw — the empty
bitstring and the one-bit string [true] at an arbitrary arity.
BellantoniCook.falseAtRaw — the one-bit string [false] at an
arbitrary arity.
BellantoniCook.comb — the stack depth and the underflow verdict in a
single value, of arity (1, 0).
BellantoniCook.eqOne — whether a bitstring has length one, of arity
(0, 1).
BellantoniCook.isTree — the recognizer, of arity (1, 0).
BellantoniCook.combSem, BellantoniCook.eqOneSem and
BellantoniCook.isTreeSem — the meaning of each of the three at its
arity, over which every statement of the module is stated.
Main statements
BellantoniCook.combSem_eq — the scan computes
RankedAlphabet.Binary.depth in unary, offset by one, while
RankedAlphabet.Binary.ok holds, and [false] once it has failed.
BellantoniCook.eqOneSem_eq — eqOne accepts exactly the bitstrings
of length one.
BellantoniCook.isTreeSem_eq_singleton_iff_valid — isTree accepts
exactly the words binRanked's scan accepts.
BellantoniCook.isTreeSem_eq_singleton_iff_exists_spell —
equivalently, exactly the spellings of binRanked's terms.
BellantoniCook.isTreeSem_eq_ite — the recognizer as the indicator of
binRanked's scan.
Implementation notes
The scan carries the stack depth and the underflow verdict in one
recursive value, told apart by its head. While no node bit has been read
below depth two the value is the depth in unary offset by one, so its
head is true; once one has been, the value is [false], which the node
step reproduces, that value's two predecessors being empty. Each bit is
read once.
Each unfolding lemma is stated per constructor with the recursive value
exposed on the right. Sem is a function type, so evalRec recurses at
a function motive and every eliminator in the chain sits there;
eliminators at function motives reduce only when their scrutinee is a
constructor, so a symbolic-bit or fold-shaped statement is not
definitional.
Every unfolding lemma closes by rfl across the module boundary, and so
depends on the @[expose] attributes Basic.lean carries on Direction,
rc, q, sig, compChildren, BC, evalRec, evalValue, evalStep and
BC.eval. Removing any of them leaves those lemmas stuck; the failure is
silent at the language server and appears at lake build.
combSem, eqOneSem and isTreeSem name each meaning at its arity, so
that the arity pair is reduced and rewriting under it type-checks. A
meaning taken through the Sigma projection instead has a type headed by
that projection rather than by an arrow, and rw under it fails as not
type-correct at implicit transparency.
References
[BellantoniCook1992]
[HeraudNowak2011]
Tags
Bellantoni-Cook, polytime, implicit computational complexity, safe recursion, binary tree, preorder, recognizer
namespace BellantoniCookopen RankedAlphabet.Binarypublic sectionThe empty bitstring at an arbitrary arity.
@[expose] def zeroAtRaw (n s : ℕ) : sig.toPFunctor.W :=
WType.mk (.comp n s 0 0)
(compChildren (WType.mk .zero Fin.elim0) Fin.elim0 Fin.elim0)
The one-bit string [true] at an arbitrary arity.
@[expose] def oneAtRaw (n s : ℕ) : sig.toPFunctor.W :=
WType.mk (.comp n s 0 1)
(compChildren (WType.mk (.succ true) Fin.elim0) Fin.elim0 ![zeroAtRaw n s])
The one-bit string [false] at an arbitrary arity.
@[expose] def falseAtRaw (n s : ℕ) : sig.toPFunctor.W :=
WType.mk (.comp n s 0 1)
(compChildren (WType.mk (.succ false) Fin.elim0) Fin.elim0 ![zeroAtRaw n s])
Prepend true to the recursive value.
@[expose] def incRaw : sig.toPFunctor.W :=
WType.mk (.comp 1 1 0 1)
(compChildren (WType.mk (.succ true) Fin.elim0) Fin.elim0
![WType.mk (.proj 1 1 1) Fin.elim0])Drop the low bit of the recursive value.
@[expose] def decRaw : sig.toPFunctor.W :=
WType.mk (.comp 1 1 0 1)
(compChildren (WType.mk .pred Fin.elim0) Fin.elim0
![WType.mk (.proj 1 1 1) Fin.elim0])The guard of the node step: the recursive value with two bits dropped. It is empty exactly when the value is the failure flag, whose two predecessors truncate to the empty bitstring, or a depth below two.
@[expose] def predPredRaw : sig.toPFunctor.W :=
WType.mk (.comp 1 1 0 1)
(compChildren (WType.mk .pred Fin.elim0) Fin.elim0 ![decRaw])
The leaf step: push a level onto a live value, whose head is true,
and return the failure flag on a value that is empty or has head
false.
@[expose] def combFalseStepRaw : sig.toPFunctor.W :=
WType.mk (.comp 1 1 0 4)
(compChildren (WType.mk .cond Fin.elim0) Fin.elim0
![WType.mk (.proj 1 1 1) Fin.elim0, falseAtRaw 1 1, incRaw,
falseAtRaw 1 1])The node step: pop a level when at least two remain, and return the failure flag otherwise. An existing failure propagates, its guard being empty.
@[expose] def combTrueStepRaw : sig.toPFunctor.W :=
WType.mk (.comp 1 1 0 4)
(compChildren (WType.mk .cond Fin.elim0) Fin.elim0
![predPredRaw, falseAtRaw 1 1, decRaw, decRaw])
The raw tree of the scan. The base is [true], the empty bitstring
having depth zero and satisfying RankedAlphabet.Binary.ok.
@[expose] def combRaw : sig.toPFunctor.W :=
WType.mk (.safeRec 0 0) ![oneAtRaw 0 0, combFalseStepRaw, combTrueStepRaw]
The stack depth and the underflow verdict of a bitstring in one
value: the depth in unary, offset by one so that a live value is
non-empty with head true, and [false] once a node bit has been read
below depth two.
The inner conditional of eqOne: whether the predecessor of the
argument is empty. The even branch is unreachable only under this
module's own use, where the argument is always a unary numeral; the
expression and its characterization are stated for an arbitrary
bitstring, over which the branch is reached.
@[expose] def eqOneInnerRaw : sig.toPFunctor.W :=
WType.mk (.comp 0 1 0 4)
(compChildren (WType.mk .cond Fin.elim0) Fin.elim0
![WType.mk (.comp 0 1 0 1)
(compChildren (WType.mk .pred Fin.elim0) Fin.elim0
![WType.mk (.proj 0 1 0) Fin.elim0]),
oneAtRaw 0 1, zeroAtRaw 0 1, zeroAtRaw 0 1])The raw tree of the one-test: empty is not one, and otherwise the argument is one exactly when its predecessor is empty.
@[expose] def eqOneRaw : sig.toPFunctor.W :=
WType.mk (.comp 0 1 0 4)
(compChildren (WType.mk .cond Fin.elim0) Fin.elim0
![WType.mk (.proj 0 1 0) Fin.elim0, zeroAtRaw 0 1, eqOneInnerRaw,
eqOneInnerRaw])
Whether a bitstring has length one, returning [true] or [].
The raw tree of the recognizer: the scan's predecessor has length one.
@[expose] def isTreeRaw : sig.toPFunctor.W :=
WType.mk (.comp 1 0 0 1)
(compChildren eqOneRaw Fin.elim0
![WType.mk (.comp 1 0 0 1)
(compChildren (WType.mk .pred Fin.elim0) Fin.elim0 ![combRaw])])
The recognizer: whether a bitstring is the preorder spelling of a
binary tree. The output is [true] or [], so correctness is an
equation rather than a disequation.
comb at its declared arity. Elaborating this is the assertion that
BC.arity comb is (1, 0).
eqOne at its declared arity.
isTree at its declared arity.
The scan's meaning at its arity, ascribed so that the arity pair is reduced and rewriting under it type-checks.
The one-test's meaning at its arity, ascribed likewise.
The recognizer's meaning at its arity, ascribed likewise.
@[expose] def isTreeSem :
(Fin 1 → List Bool) → (Fin 0 → List Bool) → List Bool := (BC.eval isTree).2The scan's value on the empty bitstring: depth zero, offset by one.
theorem combSem_nil : combSem ![[]] ![] = [true] := rflA leaf bit pushes a level onto a live value, and is absorbed by a failure.
theorem combSem_cons_false (v : List Bool) :
combSem ![false :: v] ![] =
(match combSem ![v] ![] with
| [] => [false]
| true :: _ => true :: combSem ![v] ![]
| false :: _ => [false]) := rflA node bit pops a level when at least two remain, and fails otherwise. The guard is the value with two bits dropped, so a failure, whose two predecessors are empty, propagates.
theorem combSem_cons_true (v : List Bool) :
combSem ![true :: v] ![] =
(match (combSem ![v] ![]).tail.tail with
| [] => [false]
| true :: _ => (combSem ![v] ![]).tail
| false :: _ => (combSem ![v] ![]).tail) := rfl
The scan computes the stack depth in unary, offset by one, while
RankedAlphabet.Binary.ok holds, and the absorbing value [false] once it
has failed.
theorem combSem_eq (w : List Bool) :
combSem ![w] ![] =
if ok w then List.replicate (depth w + 1) true
else [false] := w:List Bool⊢ combSem ![w] ![] = if ok w = true then List.replicate (depth w + 1) true else [false]
w:List Bool⊢ ∀ (head : Bool) (tail : List Bool),
(combSem ![tail] ![] = if ok tail = true then List.replicate (depth tail + 1) true else [false]) →
combSem ![head :: tail] ![] =
if ok (head :: tail) = true then List.replicate (depth (head :: tail) + 1) true else [false]
w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]⊢ combSem ![b :: v] ![] = if ok (b :: v) = true then List.replicate (depth (b :: v) + 1) true else [false]
w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = false⊢ combSem ![b :: v] ![] = if ok (b :: v) = true then List.replicate (depth (b :: v) + 1) true else [false]w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = true⊢ combSem ![b :: v] ![] = if ok (b :: v) = true then List.replicate (depth (b :: v) + 1) true else [false]
w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = false⊢ combSem ![b :: v] ![] = if ok (b :: v) = true then List.replicate (depth (b :: v) + 1) true else [false] false w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ combSem ![b :: v] ![] = if ok (b :: v) = true then List.replicate (depth (b :: v) + 1) true else [false]
cases b false.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ combSem ![false :: v] ![] = if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false]false.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ combSem ![true :: v] ![] = if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false]
· false.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ combSem ![false :: v] ![] = if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false] rw [combSem_cons_false, false.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match combSem ![v] ![] with
| [] => [false]
| true :: tail => true :: combSem ![v] ![]
| false :: tail => [false]) =
if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false] hv, false.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false] with
| [] => [false]
| true :: tail => [true, false]
| false :: tail => [false]) =
if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false] ok_cons_false, false.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false] with
| [] => [false]
| true :: tail => [true, false]
| false :: tail => [false]) =
if ok v = true then List.replicate (depth (false :: v) + 1) true else [false] hok false.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false] with
| [] => [false]
| true :: tail => [true, false]
| false :: tail => [false]) =
if false = true then List.replicate (depth (false :: v) + 1) true else [false]] false.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false] with
| [] => [false]
| true :: tail => [true, false]
| false :: tail => [false]) =
if false = true then List.replicate (depth (false :: v) + 1) true else [false]; rfl All goals completed! 🐙
· false.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ combSem ![true :: v] ![] = if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false] rw [combSem_cons_true, false.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match (combSem ![v] ![]).tail.tail with
| [] => [false]
| true :: tail => (combSem ![v] ![]).tail
| false :: tail => (combSem ![v] ![]).tail) =
if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false] hv, false.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false].tail.tail with
| [] => [false]
| true :: tail => [false].tail
| false :: tail => [false].tail) =
if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false] ok_cons_true, false.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false].tail.tail with
| [] => [false]
| true :: tail => [false].tail
| false :: tail => [false].tail) =
if (ok v && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false] hok false.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false].tail.tail with
| [] => [false]
| true :: tail => [false].tail
| false :: tail => [false].tail) =
if (false && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]] false.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = falsehv:combSem ![v] ![] = [false]⊢ (match [false].tail.tail with
| [] => [false]
| true :: tail => [false].tail
| false :: tail => [false].tail) =
if (false && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]; rfl All goals completed! 🐙
· true w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = true⊢ combSem ![b :: v] ![] = if ok (b :: v) = true then List.replicate (depth (b :: v) + 1) true else [false] have hv : combSem ![v] ![] = List.replicate (depth v + 1) true := by w:List Bool⊢ combSem ![w] ![] = if ok w = true then List.replicate (depth w + 1) true else [false]
rw [ih, w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = true⊢ (if ok v = true then List.replicate (depth v + 1) true else [false]) = List.replicate (depth v + 1) true hok w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = true⊢ (if true = true then List.replicate (depth v + 1) true else [false]) = List.replicate (depth v + 1) true] w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = true⊢ (if true = true then List.replicate (depth v + 1) true else [false]) = List.replicate (depth v + 1) true; rfl true w:List Boolb:Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ combSem ![b :: v] ![] = if ok (b :: v) = true then List.replicate (depth (b :: v) + 1) true else [false]
cases b true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ combSem ![false :: v] ![] = if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false]true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ combSem ![true :: v] ![] = if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false]
· true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ combSem ![false :: v] ![] = if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false] rw [combSem_cons_false, true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match combSem ![v] ![] with
| [] => [false]
| true :: tail => true :: combSem ![v] ![]
| false :: tail => [false]) =
if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false] hv, true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match List.replicate (depth v + 1) true with
| [] => [false]
| true :: tail => true :: List.replicate (depth v + 1) true
| false :: tail => [false]) =
if ok (false :: v) = true then List.replicate (depth (false :: v) + 1) true else [false] ok_cons_false, true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match List.replicate (depth v + 1) true with
| [] => [false]
| true :: tail => true :: List.replicate (depth v + 1) true
| false :: tail => [false]) =
if ok v = true then List.replicate (depth (false :: v) + 1) true else [false] hok, true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match List.replicate (depth v + 1) true with
| [] => [false]
| true :: tail => true :: List.replicate (depth v + 1) true
| false :: tail => [false]) =
if true = true then List.replicate (depth (false :: v) + 1) true else [false]
depth_cons_false_of_ok v hok true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match List.replicate (depth v + 1) true with
| [] => [false]
| true :: tail => true :: List.replicate (depth v + 1) true
| false :: tail => [false]) =
if true = true then List.replicate (depth v + 1 + 1) true else [false]] true.false w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match List.replicate (depth v + 1) true with
| [] => [false]
| true :: tail => true :: List.replicate (depth v + 1) true
| false :: tail => [false]) =
if true = true then List.replicate (depth v + 1 + 1) true else [false]
rfl All goals completed! 🐙
· true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ combSem ![true :: v] ![] = if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false] rw [combSem_cons_true, true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match (combSem ![v] ![]).tail.tail with
| [] => [false]
| true :: tail => (combSem ![v] ![]).tail
| false :: tail => (combSem ![v] ![]).tail) =
if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false] hv, true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if ok (true :: v) = true then List.replicate (depth (true :: v) + 1) true else [false] ok_cons_true, true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (ok v && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false] hok true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]] true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) true⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]
-- the guard's two predecessors reduce only on a numeral of at least
-- that size, so the depth is split into constructor forms; the
-- conditional depth lemma applies only in the third case, the first
-- two closing on the failed branch
have hsplit : ∀ d : ℕ, d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2 := fun d ↦
match d with
| 0 => Or.inl rfl
| 1 => Or.inr (Or.inl rfl)
| (m + 2) => Or.inr (Or.inr ⟨m, rfl⟩) true.true w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]
obtain (h0 | h1 | ⟨m, hm⟩) := hsplit (depth v) true.true.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h0:depth v = 0⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]true.true.inr.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h1:depth v = 1⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]true.true.inr.inr w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2m:ℕhm:depth v = m + 2⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false]
· true.true.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h0:depth v = 0⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false] rw [h0 true.true.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h0:depth v = 0⊢ (match (List.replicate (0 + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (0 + 1) true).tail
| false :: tail => (List.replicate (0 + 1) true).tail) =
if (true && decide (2 ≤ 0)) = true then List.replicate (depth (true :: v) + 1) true else [false]] true.true.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h0:depth v = 0⊢ (match (List.replicate (0 + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (0 + 1) true).tail
| false :: tail => (List.replicate (0 + 1) true).tail) =
if (true && decide (2 ≤ 0)) = true then List.replicate (depth (true :: v) + 1) true else [false]; rfl All goals completed! 🐙
· true.true.inr.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h1:depth v = 1⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false] rw [h1 true.true.inr.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h1:depth v = 1⊢ (match (List.replicate (1 + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (1 + 1) true).tail
| false :: tail => (List.replicate (1 + 1) true).tail) =
if (true && decide (2 ≤ 1)) = true then List.replicate (depth (true :: v) + 1) true else [false]] true.true.inr.inl w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2h1:depth v = 1⊢ (match (List.replicate (1 + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (1 + 1) true).tail
| false :: tail => (List.replicate (1 + 1) true).tail) =
if (true && decide (2 ≤ 1)) = true then List.replicate (depth (true :: v) + 1) true else [false]; rfl All goals completed! 🐙
· true.true.inr.inr w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2m:ℕhm:depth v = m + 2⊢ (match (List.replicate (depth v + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (depth v + 1) true).tail
| false :: tail => (List.replicate (depth v + 1) true).tail) =
if (true && decide (2 ≤ depth v)) = true then List.replicate (depth (true :: v) + 1) true else [false] rw [depth_cons_true_of_ok_of_two_le_depth v hok (by w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2m:ℕhm:depth v = m + 2⊢ 2 ≤ depth v omega All goals completed! 🐙), hm true.true.inr.inr w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2m:ℕhm:depth v = m + 2⊢ (match (List.replicate (m + 2 + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (m + 2 + 1) true).tail
| false :: tail => (List.replicate (m + 2 + 1) true).tail) =
if (true && decide (2 ≤ m + 2)) = true then List.replicate (m + 2 - 1 + 1) true else [false]] true.true.inr.inr w:List Boolv:List Boolih:combSem ![v] ![] = if ok v = true then List.replicate (depth v + 1) true else [false]hok:ok v = truehv:combSem ![v] ![] = List.replicate (depth v + 1) truehsplit:∀ (d : ℕ), d = 0 ∨ d = 1 ∨ ∃ m, d = m + 2m:ℕhm:depth v = m + 2⊢ (match (List.replicate (m + 2 + 1) true).tail.tail with
| [] => [false]
| true :: tail => (List.replicate (m + 2 + 1) true).tail
| false :: tail => (List.replicate (m + 2 + 1) true).tail) =
if (true && decide (2 ≤ m + 2)) = true then List.replicate (m + 2 - 1 + 1) true else [false]; rfl All goals completed! 🐙The one-test at an arbitrary environment is the test at the canonical one.
theorem eqOneSem_env (f : Fin 0 → List Bool) (g : Fin 1 → List Bool) :
eqOneSem f g = eqOneSem ![] ![g 0] := by f:Fin 0 → List Boolg:Fin 1 → List Bool⊢ eqOneSem f g = eqOneSem ![] ![g 0]
have hf : f = ![] := Subsingleton.elim _ _ f:Fin 0 → List Boolg:Fin 1 → List Boolhf:f = ![]⊢ eqOneSem f g = eqOneSem ![] ![g 0]
have hg : g = ![g 0] := funext fun i ↦ match i with | ⟨0, _⟩ => rfl f:Fin 0 → List Boolg:Fin 1 → List Boolhf:f = ![]hg:g = ![g 0]⊢ eqOneSem f g = eqOneSem ![] ![g 0]
conv_lhs => rw [hf, hg] f:Fin 0 → List Boolg:Fin 1 → List Boolhf:f = ![]hg:g = ![g 0]| eqOneSem ![] ![g 0]The one-test accepts exactly the bitstrings of length one. It is not a recursion, so its three cases are decided by matching.
theorem eqOneSem_eq (u : List Bool) :
eqOneSem ![] ![u] = if u.length = 1 then [true] else [] := by u:List Bool⊢ eqOneSem ![] ![u] = if u.length = 1 then [true] else []
match u with
| [] => u:List Bool⊢ eqOneSem ![] ![[]] = if [].length = 1 then [true] else [] rfl All goals completed! 🐙
| [b] => u:List Boolb:Bool⊢ eqOneSem ![] ![[b]] = if [b].length = 1 then [true] else [] cases b false u:List Bool⊢ eqOneSem ![] ![[false]] = if [false].length = 1 then [true] else []true u:List Bool⊢ eqOneSem ![] ![[true]] = if [true].length = 1 then [true] else [] <;> false u:List Bool⊢ eqOneSem ![] ![[false]] = if [false].length = 1 then [true] else []true u:List Bool⊢ eqOneSem ![] ![[true]] = if [true].length = 1 then [true] else [] rfl All goals completed! 🐙
| b :: c :: v => u:List Boolb:Boolc:Boolv:List Bool⊢ eqOneSem ![] ![b :: c :: v] = if (b :: c :: v).length = 1 then [true] else []
cases b false u:List Boolc:Boolv:List Bool⊢ eqOneSem ![] ![false :: c :: v] = if (false :: c :: v).length = 1 then [true] else []true u:List Boolc:Boolv:List Bool⊢ eqOneSem ![] ![true :: c :: v] = if (true :: c :: v).length = 1 then [true] else [] <;> false u:List Boolc:Boolv:List Bool⊢ eqOneSem ![] ![false :: c :: v] = if (false :: c :: v).length = 1 then [true] else []true u:List Boolc:Boolv:List Bool⊢ eqOneSem ![] ![true :: c :: v] = if (true :: c :: v).length = 1 then [true] else [] cases c true.false u:List Boolv:List Bool⊢ eqOneSem ![] ![true :: false :: v] = if (true :: false :: v).length = 1 then [true] else []true.true u:List Boolv:List Bool⊢ eqOneSem ![] ![true :: true :: v] = if (true :: true :: v).length = 1 then [true] else [] <;> false.false u:List Boolv:List Bool⊢ eqOneSem ![] ![false :: false :: v] = if (false :: false :: v).length = 1 then [true] else []false.true u:List Boolv:List Bool⊢ eqOneSem ![] ![false :: true :: v] = if (false :: true :: v).length = 1 then [true] else []true.false u:List Boolv:List Bool⊢ eqOneSem ![] ![true :: false :: v] = if (true :: false :: v).length = 1 then [true] else []true.true u:List Boolv:List Bool⊢ eqOneSem ![] ![true :: true :: v] = if (true :: true :: v).length = 1 then [true] else []
(change ([] : List Bool) = _ true.true u:List Boolv:List Bool⊢ [] = if (true :: true :: v).length = 1 then [true] else []
rw [ite_eq_right (by u:List Boolv:List Bool⊢ ¬(true :: true :: v).length = 1 simp only [List.length_cons] u:List Boolv:List Bool⊢ ¬v.length + 1 + 1 = 1; omega All goals completed! 🐙)] All goals completed! 🐙)
One step of the recognizer: the one-test on the scan's predecessor.
The scan's value is [false] on failure, whose predecessor is empty, and
otherwise the depth in unary offset by one, whose predecessor has length
the depth.
theorem isTreeSem_apply (w : List Bool) :
isTreeSem ![w] ![] =
eqOneSem (fun _ ↦ []) (fun _ ↦ (combSem ![w] ![]).tail) := rfl
The recognizer accepts exactly the words binRanked's scan accepts.
theorem isTreeSem_eq_singleton_iff_valid (w : List Bool) :
isTreeSem ![w] ![] = [true] ↔ binRanked.Valid w := by w:List Bool⊢ isTreeSem ![w] ![] = [true] ↔ binRanked.Valid w
rw [isTreeSem_apply, w:List Bool⊢ (eqOneSem (fun x ↦ []) fun x ↦ (combSem ![w] ![]).tail) = [true] ↔ binRanked.Valid w eqOneSem_env w:List Bool⊢ eqOneSem ![] ![(combSem ![w] ![]).tail] = [true] ↔ binRanked.Valid w] w:List Bool⊢ eqOneSem ![] ![(combSem ![w] ![]).tail] = [true] ↔ binRanked.Valid w
simp only [eqOneSem_eq, combSem_eq] w:List Bool⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) = [true] ↔
binRanked.Valid w
by_cases h : ok w = true pos w:List Boolh:ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) = [true] ↔
binRanked.Valid wneg w:List Boolh:¬ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) = [true] ↔
binRanked.Valid w
· pos w:List Boolh:ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) = [true] ↔
binRanked.Valid w rw [ite_eq_left h pos w:List Boolh:ok w = true⊢ (if (List.replicate (depth w + 1) true).tail.length = 1 then [true] else []) = [true] ↔ binRanked.Valid w] pos w:List Boolh:ok w = true⊢ (if (List.replicate (depth w + 1) true).tail.length = 1 then [true] else []) = [true] ↔ binRanked.Valid w
simp only [List.tail_replicate, List.length_replicate, Nat.add_sub_cancel] pos w:List Boolh:ok w = true⊢ (if depth w = 1 then [true] else []) = [true] ↔ binRanked.Valid w
by_cases hd : depth w = 1 pos w:List Boolh:ok w = truehd:depth w = 1⊢ (if depth w = 1 then [true] else []) = [true] ↔ binRanked.Valid wneg w:List Boolh:ok w = truehd:¬depth w = 1⊢ (if depth w = 1 then [true] else []) = [true] ↔ binRanked.Valid w
· pos w:List Boolh:ok w = truehd:depth w = 1⊢ (if depth w = 1 then [true] else []) = [true] ↔ binRanked.Valid w rw [ite_eq_left hd pos w:List Boolh:ok w = truehd:depth w = 1⊢ [true] = [true] ↔ binRanked.Valid w] pos w:List Boolh:ok w = truehd:depth w = 1⊢ [true] = [true] ↔ binRanked.Valid w
exact ⟨fun _ ↦ (valid_iff_ok_and_depth_eq_one w).mpr ⟨h, hd⟩, fun _ ↦ rfl⟩ All goals completed! 🐙
· neg w:List Boolh:ok w = truehd:¬depth w = 1⊢ (if depth w = 1 then [true] else []) = [true] ↔ binRanked.Valid w rw [ite_eq_right hd neg w:List Boolh:ok w = truehd:¬depth w = 1⊢ [] = [true] ↔ binRanked.Valid w] neg w:List Boolh:ok w = truehd:¬depth w = 1⊢ [] = [true] ↔ binRanked.Valid w
refine ⟨fun hw ↦ absurd hw (by w:List Boolh:ok w = truehd:¬depth w = 1hw:[] = [true]⊢ ¬[] = [true] nofun All goals completed! 🐙), ?_⟩
rintro hv neg w:List Boolh:ok w = truehd:¬depth w = 1hv:binRanked.Valid w⊢ [] = [true]
exact absurd ((valid_iff_ok_and_depth_eq_one w).mp hv).2 hd All goals completed! 🐙
· neg w:List Boolh:¬ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) = [true] ↔
binRanked.Valid w rw [ite_eq_right h, neg w:List Boolh:¬ok w = true⊢ (if [false].tail.length = 1 then [true] else []) = [true] ↔ binRanked.Valid w ite_eq_right (by w:List Boolh:¬ok w = true⊢ ¬[false].tail.length = 1 decide All goals completed! 🐙 : ¬ ([false] : List Bool).tail.length = 1)] neg w:List Boolh:¬ok w = true⊢ [] = [true] ↔ binRanked.Valid w
refine ⟨fun hw ↦ absurd hw (by w:List Boolh:¬ok w = truehw:[] = [true]⊢ ¬[] = [true] nofun All goals completed! 🐙), ?_⟩
rintro hv neg w:List Boolh:¬ok w = truehv:binRanked.Valid w⊢ [] = [true]
exact absurd ((valid_iff_ok_and_depth_eq_one w).mp hv).1 h All goals completed! 🐙
The recognizer accepts exactly the preorder spellings of binRanked's
terms.
theorem isTreeSem_eq_singleton_iff_exists_spell (w : List Bool) :
isTreeSem ![w] ![] = [true] ↔ ∃ t, binRanked.spell t = w :=
(isTreeSem_eq_singleton_iff_valid w).trans (binRanked.valid_iff_exists_spell w)
The recognizer is the indicator of binRanked's scan: [true] on a
spelling and [] on anything else. isTreeSem_eq_singleton_iff_valid pins
the value only where it accepts.
theorem isTreeSem_eq_ite (w : List Bool) :
isTreeSem ![w] ![] = if binRanked.Valid w then [true] else [] := by w:List Bool⊢ isTreeSem ![w] ![] = if binRanked.Valid w then [true] else []
rw [isTreeSem_apply, w:List Bool⊢ (eqOneSem (fun x ↦ []) fun x ↦ (combSem ![w] ![]).tail) = if binRanked.Valid w then [true] else [] eqOneSem_env, w:List Bool⊢ eqOneSem ![] ![(combSem ![w] ![]).tail] = if binRanked.Valid w then [true] else [] eqOneSem_eq, w:List Bool⊢ (if (combSem ![w] ![]).tail.length = 1 then [true] else []) = if binRanked.Valid w then [true] else [] combSem_eq w:List Bool⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) =
if binRanked.Valid w then [true] else []] w:List Bool⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) =
if binRanked.Valid w then [true] else []
by_cases h : ok w = true pos w:List Boolh:ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) =
if binRanked.Valid w then [true] else []neg w:List Boolh:¬ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) =
if binRanked.Valid w then [true] else []
· pos w:List Boolh:ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) =
if binRanked.Valid w then [true] else [] rw [ite_eq_left h pos w:List Boolh:ok w = true⊢ (if (List.replicate (depth w + 1) true).tail.length = 1 then [true] else []) = if binRanked.Valid w then [true] else []] pos w:List Boolh:ok w = true⊢ (if (List.replicate (depth w + 1) true).tail.length = 1 then [true] else []) = if binRanked.Valid w then [true] else []
simp only [List.tail_replicate, List.length_replicate, Nat.add_sub_cancel] pos w:List Boolh:ok w = true⊢ (if depth w = 1 then [true] else []) = if binRanked.Valid w then [true] else []
by_cases hd : depth w = 1 pos w:List Boolh:ok w = truehd:depth w = 1⊢ (if depth w = 1 then [true] else []) = if binRanked.Valid w then [true] else []neg w:List Boolh:ok w = truehd:¬depth w = 1⊢ (if depth w = 1 then [true] else []) = if binRanked.Valid w then [true] else []
· pos w:List Boolh:ok w = truehd:depth w = 1⊢ (if depth w = 1 then [true] else []) = if binRanked.Valid w then [true] else [] rw [ite_eq_left hd, pos w:List Boolh:ok w = truehd:depth w = 1⊢ [true] = if binRanked.Valid w then [true] else [] ite_eq_left ((valid_iff_ok_and_depth_eq_one w).mpr ⟨h, hd⟩) pos w:List Boolh:ok w = truehd:depth w = 1⊢ [true] = [true]] All goals completed! 🐙
· neg w:List Boolh:ok w = truehd:¬depth w = 1⊢ (if depth w = 1 then [true] else []) = if binRanked.Valid w then [true] else [] rw [ite_eq_right hd, neg w:List Boolh:ok w = truehd:¬depth w = 1⊢ [] = if binRanked.Valid w then [true] else []
ite_eq_right fun hv ↦ hd ((valid_iff_ok_and_depth_eq_one w).mp hv).2 neg w:List Boolh:ok w = truehd:¬depth w = 1⊢ [] = []] All goals completed! 🐙
· neg w:List Boolh:¬ok w = true⊢ (if (if ok w = true then List.replicate (depth w + 1) true else [false]).tail.length = 1 then [true] else []) =
if binRanked.Valid w then [true] else [] rw [ite_eq_right h, neg w:List Boolh:¬ok w = true⊢ (if [false].tail.length = 1 then [true] else []) = if binRanked.Valid w then [true] else [] ite_eq_right (by w:List Boolh:¬ok w = true⊢ ¬[false].tail.length = 1 decide All goals completed! 🐙 : ¬ ([false] : List Bool).tail.length = 1),
ite_eq_right fun hv ↦ h ((valid_iff_ok_and_depth_eq_one w).mp hv).1 neg w:List Boolh:¬ok w = true⊢ [] = []] All goals completed! 🐙endend BellantoniCook