ltl-accumulator-verified/verification/Proofs/Consistency.lean

107 lines
4.4 KiB
Text
Raw Permalink Normal View History

/- S5 (stage 1) — infrastructure for consistency soundness (paper Theorem 3,
steps 1-2). The binding argument needs one non-obvious arithmetic fact and
two list-surgery facts, isolated and proven here before the main proof.
Arithmetic: when the pinned prefix of size n₀ spills past the left subtree
(k < n₀ ≤ n, k = kbelow n), the honest tree of `D₁.take n₀` splits at the
SAME point k. That is `kbelow n₀ = k`, and it holds because k is a power of
two with k < n₀ ≤ 2k, which pins kbelow uniquely. -/
import Proofs.Descent
namespace LTLAcc
/-- Two powers of two both lying in `(m/2, m]` (i.e. `2^a < m ≤ 2^(a+1)`)
have the same exponent. -/
theorem pow2_exp_unique {a j m : Nat}
(ha : 2^a < m) (ha2 : m ≤ 2^(a+1)) (hj : 2^j < m) (hj2 : m ≤ 2^(j+1)) :
a = j := by
rcases Nat.lt_trichotomy a j with h | h | h
· -- a < j ⇒ a+1 ≤ j ⇒ 2^(a+1) ≤ 2^j < m, contradicting m ≤ 2^(a+1)
have : a + 1 ≤ j := h
have hle : 2^(a+1) ≤ 2^j := Nat.pow_le_pow_right (by omega) this
omega
· exact h
· have : j + 1 ≤ a := h
have hle : 2^(j+1) ≤ 2^a := Nat.pow_le_pow_right (by omega) this
omega
/-- `kbelow` is pinned by its defining inequalities: a power of two `p`
with `p < m ≤ 2p` IS `kbelow m`. -/
theorem kbelow_eq_of_pow2_between {p m : Nat} (j : Nat) (hp : p = 2^j)
(h1 : p < m) (h2 : m ≤ 2 * p) : kbelow m = p := by
have hm2 : 2 ≤ m := by
have : 1 ≤ p := by rw [hp]; exact Nat.one_le_two_pow
omega
obtain ⟨a, ha⟩ := kbelow_pow2 m
have hlt := kbelow_lt m hm2
have hle := le_two_kbelow m hm2
-- kbelow m = 2^a with 2^a < m ≤ 2^(a+1); p = 2^j with 2^j < m ≤ 2^(j+1)
rw [ha] at hlt hle
have hj2 : m ≤ 2^(j+1) := by rw [Nat.pow_succ]; omega
have ha2 : m ≤ 2^(a+1) := by rw [Nat.pow_succ]; omega
have hja : 2^j < m := by omega
have : a = j := pow2_exp_unique hlt ha2 hja hj2
rw [ha, this, ← hp]
/-- The specialization used in the binding: with `k = kbelow n`, `2 ≤ n`,
and `k < n₀ ≤ n`, the prefix tree splits at the same `k`. -/
theorem kbelow_prefix_eq {n n₀ : Nat} (hn : 2 ≤ n)
(hk : k = kbelow n) (hlo : k < n₀) (hhi : n₀ ≤ n) :
kbelow n₀ = k := by
obtain ⟨j, hj⟩ := kbelow_pow2 n
rw [← hk] at hj
have hle := le_two_kbelow n hn
rw [← hk] at hle
exact kbelow_eq_of_pow2_between j hj hlo (by omega)
/-! ### list surgery -/
theorem take_take_le (l : List Bytes) (k n₀ : Nat) (h : k ≤ n₀) :
(l.take n₀).take k = l.take k := by
rw [List.take_take]; congr 1; omega
theorem take_drop_prefix (l : List Bytes) (k n₀ : Nat) :
(l.take n₀).drop k = (l.drop k).take (n₀ - k) := by
rw [List.drop_take]
/-! ### the consistency collision extractor (paper Theorem 3, steps 1-2) -/
/-- Walk the `ConsRec` fold in parallel with the honest size-`n` tree of
`D₁`. At each level the new-root component builds `hnode` of a left and
a right value; compare that argument pair against the honest node
`hnode (MTH (D₁.take k)) (MTH (D₁.drop k))`. Return `some` concrete
colliding preimage pair at the first mismatch (steps 1-2 of Theorem 3),
or `none` if the fold is genuine all the way down — in which case the
binding `x = MTH (D₁.take n₀)` holds (proven in stage 3). -/
noncomputable def extractConsNode (n₀ n : Nat) (C : List Hash) (b : Bool)
(r : Hash) (D₁ : List Bytes) : Option (List UInt8 × List UInt8) :=
if n₀ = n then none
else if n₀ > n n₀ = 0 n ≤ 1 then none
else
match C.getLast? with
| none => none
| some s =>
let k := kbelow n
if n₀ ≤ k then
let y' := ((ConsRec n₀ k C.dropLast b r).map Prod.snd).getD default
if y' = MTH (D₁.take k) ∧ s = MTH (D₁.drop k) then
extractConsNode n₀ k C.dropLast b r (D₁.take k)
else
some (0x01 :: (y'.val ++ s.val),
0x01 :: ((MTH (D₁.take k)).val ++ (MTH (D₁.drop k)).val))
else
let y' := ((ConsRec (n₀ - k) (n - k) C.dropLast false r).map Prod.snd).getD default
if s = MTH (D₁.take k) ∧ y' = MTH (D₁.drop k) then
extractConsNode (n₀ - k) (n - k) C.dropLast false r (D₁.drop k)
else
some (0x01 :: (s.val ++ y'.val),
0x01 :: ((MTH (D₁.take k)).val ++ (MTH (D₁.drop k)).val))
termination_by n
decreasing_by
· have h2 : 2 ≤ n := by omega
exact kbelow_lt n h2
· have := kbelow_pos n
omega
end LTLAcc