Mathlib.Algorithms.Monotone­Window­Deque

A rightmost-stable monotone deque for maxima over finite streams with nondecreasing contiguous windows, including invariant preservation, scan correctness, and amortized resource bounds.

Basic 9 core · 6 supporting This module gives the paper-independent input model for a monotone-window scan: a finite prefix of an ordered value function, bounded half-open windows, and a finite schedule whose two endpoints are nondecreasing. ★ left_le_of_get_lt

Finite streams and monotone contiguous window schedules

This module gives the paper-independent input model for a monotone-window scan: a finite prefix of an ordered value function, bounded half-open windows, and a finite schedule whose two endpoints are nondecreasing. It also relates predicate, list, and finset views of a window, including empty windows.

structure Stream reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A finite ordered stream of values in a type records its length and value at each natural-number index.

Definition (Lean source)
α :
Type*
length :
value :
ℕ → α
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Stream · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:17
structure Window reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A contiguous half-open window in a stream of given length has a left endpoint no larger than its right endpoint, which does not exceed the stream length.

Definition (Lean source)
n :
left :
right :
left_le_right :
left ≤ right
right_le_length :
right ≤ n
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:23
def ActiveAt reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A left endpoint, a right endpoint, and an index determine whether the index is active in the half-open interval.

Definition (Lean source)
left right i :
ActiveAt left right i :
Prop
clause 1
left ≤ i
clause 2
i < right
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.ActiveAt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:31
def Active reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A bounded window and an index determine whether the index is active in that window.

Definition (Lean source)
n :
w :
i :
Active w i :
Prop
ActiveAt w.left w.right i
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Active · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:35 · uses Window
def indices reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window

A bounded window determines its increasing list of active indices.

Definition (Lean source)
n :
w :
indices w :
List
range' w.left (w.right - w.left)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window.indices · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:39 · uses Window
def indexFinset reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window

A bounded window determines its finite set of active indices.

Definition (Lean source)
n :
w :
indexFinset w :
Finset
Ico w.left w.right
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window.indexFinset · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:43 · uses Window
structure Schedule reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A finite schedule for a stream of given length contains bounded windows with nondecreasing left and right endpoints.

Definition (Lean source)
n :
windows :
left_mono :
windows.Pairwise (fun a b => a.left ≤ b.left)
right_mono :
windows.Pairwise (fun a b => a.right ≤ b.right)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Schedule · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:79
def steps reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Schedule

A finite schedule determines its number of scheduled windows.

Definition (Lean source)
n :
schedule :
Schedule n
steps schedule :
schedule.windows.length
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Schedule.steps · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:86 · uses Schedule
theorem left_le_of_get_lt reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Schedule

A finite schedule, two valid schedule positions, and their strict order ensure that the earlier left endpoint is no larger.

Formal statement
n :
schedule :
Schedule n
i j :
hi :
i < schedule.steps
hj :
j < schedule.steps
hij :
i < j
(schedule.windows.get ⟨i, hi⟩).left ≤ (schedule.windows.get ⟨j, hj⟩).left
Proof (Lean source)
theorem Schedule.left_le_of_get_lt {n : ℕ} (schedule : Schedule n) {i j : ℕ} (hi : i < schedule.steps) (hj : j < schedule.steps) (hij : i < j) : (schedule.windows.get ⟨i, hi⟩).left ≤ (schedule.windows.get ⟨j, hj⟩).left := by exact schedule.left_mono.rel_get_of_lt hij
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Schedule.left_le_of_get_lt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:89 · uses Schedule , steps , Window
6 supporting declarations (lemmas, instances)
  • mem_indices_iff theorem — A bounded window has the same active indices in its list enumeration and in its active-window condition.
    n i :
    w :
    i ∈ w.indices ↔ Active w i
    Proof (Lean source)
    theorem Window.mem_indices_iff {n i : ℕ} (w : Window n) : i ∈ w.indices ↔ Active w i := by rw [Window.indices, List.mem_range'_1, Nat.add_sub_of_le w.left_le_right] rfl
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window.mem_indices_iff · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:46
  • mem_indexFinset_iff theorem — A bounded window has the same active indices in its finite-set enumeration and in its active-window condition.
    n i :
    w :
    i ∈ w.indexFinset ↔ Active w i
    Proof (Lean source)
    theorem Window.mem_indexFinset_iff {n i : ℕ} (w : Window n) : i ∈ w.indexFinset ↔ Active w i := by simp [Window.indexFinset, Active, ActiveAt]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window.mem_indexFinset_iff · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:52
  • card_indexFinset theorem — A bounded window has as many active indices as its width.
    n :
    w :
    w.indexFinset.card = w.right - w.left
    Proof (Lean source)
    theorem Window.card_indexFinset {n : ℕ} (w : Window n) : w.indexFinset.card = w.right - w.left := by simp [Window.indexFinset]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window.card_indexFinset · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:57
  • indices_eq_nil_iff theorem — A bounded window has an empty index list exactly when its two endpoints coincide.
    n :
    w :
    w.indices = [] ↔ w.left = w.right
    Proof (Lean source)
    theorem Window.indices_eq_nil_iff {n : ℕ} (w : Window n) : w.indices = [] ↔ w.left = w.right := by constructor · intro h have hlen : w.indices.length = 0 := by simp [h] rw [Window.indices, List.length_range'] at hlen exact Nat.le_antisymm w.left_le_right (Nat.sub_eq_zero_iff_le.mp hlen) · intro h simp [Window.indices, h]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window.indices_eq_nil_iff · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:62
  • indexFinset_nonempty_iff theorem — A bounded window has an active index exactly when its left endpoint is strictly below its right endpoint.
    n :
    w :
    w.indexFinset.Nonempty ↔ w.left < w.right
    Proof (Lean source)
    theorem Window.indexFinset_nonempty_iff {n : ℕ} (w : Window n) : w.indexFinset.Nonempty ↔ w.left < w.right := by simp [Window.indexFinset]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Window.indexFinset_nonempty_iff · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:73
  • right_le_of_get_lt theorem — A finite schedule, two valid schedule positions, and their strict order ensure that the earlier right endpoint is no larger.
    n :
    schedule :
    Schedule n
    i j :
    hi :
    i < schedule.steps
    hj :
    j < schedule.steps
    hij :
    i < j
    (schedule.windows.get ⟨i, hi⟩).right ≤ (schedule.windows.get ⟨j, hj⟩).right
    Proof (Lean source)
    theorem Schedule.right_le_of_get_lt {n : ℕ} (schedule : Schedule n) {i j : ℕ} (hi : i < schedule.steps) (hj : j < schedule.steps) (hij : i < j) : (schedule.windows.get ⟨i, hi⟩).right ≤ (schedule.windows.get ⟨j, hj⟩).right := by exact schedule.right_mono.rel_get_of_lt hij
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Schedule.right_le_of_get_lt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Basic.lean:96
Deque 12 core · 10 supporting This module defines the purely functional deque kernel. ★ mem_prunedBack_dominated

Monotone deque operations and invariant

This module defines the purely functional deque kernel. The deterministic tie policy is rightmost-stable: inserting a value deletes every suffix entry with value less than or equal to the new value. Consequently retained values are strictly decreasing from front to back.

abbrev Deque reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A deque is represented by its front-to-back list of natural-number indices. The type itself imposes no ordering or monotonicity; the monotone-deque invariant is carried separately by the validity predicates.

Definition (Lean source)
Deque :
Type
List
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Deque · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:16
def initialDeque reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

The initial deque is empty before any stream index enters.

Definition (Lean source)
initialDeque :
[]
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.initialDeque · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:21 · uses Deque
def expireFront reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A left endpoint and a deque determine the deque after front expiration.

Definition (Lean source)
left :
q :
expireFront left q :
q.dropWhile (fun i => decide (i < left))
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.expireFront · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:24 · uses Deque
def expiredFront reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A left endpoint and a deque determine the recorded front pops.

Definition (Lean source)
left :
q :
expiredFront left q :
List
q.takeWhile (fun i => decide (i < left))
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.expiredFront · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:28 · uses Deque
def pruneBack reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, a deque, and a new index determine the deque after rightmost-stable back pruning, which removes ties in favor of the newer index.

Definition (Lean source)
α :
Type u_1
shared
stream :
q :
i :
pruneBack stream q i :
q.rdropWhile (fun j => decide (stream.value j ≤ stream.value i))
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pruneBack · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:32 · uses Deque , Stream
def prunedBack reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, a deque, and a new index determine the recorded back pops.

Definition (Lean source)
α :
Type u_1
shared
stream :
q :
i :
prunedBack stream q i :
List
q.rtakeWhile (fun j => decide (stream.value j ≤ stream.value i))
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.prunedBack · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:37 · uses Deque , Stream
def push reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, a deque, and a new index determine the deque after one rightmost-stable insertion.

Definition (Lean source)
α :
Type u_1
shared
stream :
q :
i :
push stream q i :
pruneBack stream q i ++ [i]
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.push · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:42 · uses Deque , Stream
structure PushBatch reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A batch insertion records its final deque, every pushed index, and every index removed from the back while processing the batch.

Definition (Lean source)
state :
pushed :
List
backPopped :
List
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PushBatch · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:47
def pushAll reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream determines the recorded batch insertion from an initial deque and a list of entering indices.

Definition (Lean source)
α :
Type u_1
shared
stream :
pushAll stream :
DequeList ℕ → PushBatch
clause 1
| q, [] => { state := q, pushed := [], backPopped := [] }
clause 2
| q, i :: is
=> let removed := prunedBack stream q i let rest := pushAll stream (push stream q i) is { state := rest.state, pushed := i :: rest.pushed, backPopped := removed ++ rest.backPopped }
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pushAll · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:54 · uses Deque , PushBatch , Stream
structure ValidAt reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, two raw endpoints, and a deque satisfy the validity invariant when every retained index is active for the endpoints and within the stream, retained indices strictly increase from front to back, their stream values strictly decrease from front to back, and every active in-stream index that is not retained is dominated by a later retained index whose value is at least as large.

Definition (Lean source)
α :
Type u_1
shared
stream :
left right :
q :
active :
∀ i ∈ q, ActiveAt left right i ∧ i < stream.length
index_ordered :
q.Pairwise (· < ·)
value_decreasing :
q.Pairwise (fun i j => stream.value j < stream.value i)
dominates_omitted :
∀ i
if
ActiveAt left right i
and
i < stream.length
and
i ∉ q
then
∃ j ∈ q, i < j ∧ stream.value i ≤ stream.value j
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.ValidAt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:64 · uses Deque , Stream
def Valid reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, a bounded window, and a deque determine whether the deque is valid for that window.

Definition (Lean source)
α :
Type u_1
shared
stream :
w :
Window stream.length
q :
Valid stream w q :
Prop
ValidAt stream w.left w.right q
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Valid · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:76 · uses Deque , Stream , Window
theorem mem_prunedBack_dominated reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, all old indices being earlier than the new index, and an index recorded as a back pop ensure that the popped index is earlier and no larger in value than the new index.

Formal statement
α :
Type u_1
shared
stream :
q :
i j :
hindex :
∀ k ∈ q, k < i
hj :
j ∈ prunedBack stream q i
conclusion 1
j < i
conclusion 2
stream.value j ≤ stream.value i
Proof (Lean source)
theorem mem_prunedBack_dominated (stream : Stream α) {q : Deque} {i j : ℕ} (hindex : ∀ k ∈ q, k < i) (hj : j ∈ prunedBack stream q i) : j < i ∧ stream.value j ≤ stream.value i := by constructor · exact hindex j ((List.rtakeWhile_suffix _ _).mem hj) · have h := List.mem_rtakeWhile_imp hj simpa [prunedBack] using h
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.mem_prunedBack_dominated · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:161 · uses Deque , Stream , prunedBack
10 supporting declarations (lemmas, instances)
  • initialDeque_validAt theorem — A stream has an empty initial deque satisfying the zero-width invariant.
    α :
    Type u_1
    shared
    stream :
    Proof (Lean source)
    theorem initialDeque_validAt (stream : Stream α) : ValidAt stream 0 0 initialDeque := by refine ⟨?_, ?_, ?_, ?_⟩ · simp [initialDeque] · simp [initialDeque] · simp [initialDeque] · simp [initialDeque, ActiveAt]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.initialDeque_validAt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:81
  • expiredFront_append_expireFront theorem — A left endpoint and a deque have a reported front-pop prefix followed by the retained deque exactly equal to the original deque.
    left :
    q :
    expiredFront left q ++ expireFront left q = q
    Proof (Lean source)
    theorem expiredFront_append_expireFront (left : ℕ) (q : Deque) : expiredFront left q ++ expireFront left q = q := by exact List.takeWhile_append_dropWhile
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.expiredFront_append_expireFront · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:90
  • pruneBack_append_prunedBack theorem — A stream, a deque, and a new index have a retained prefix and reported back-pop suffix exactly equal to the original deque.
    α :
    Type u_1
    shared
    stream :
    q :
    i :
    pruneBack stream q i ++ prunedBack stream q i = q
    Proof (Lean source)
    theorem pruneBack_append_prunedBack (stream : Stream α) (q : Deque) (i : ℕ) : pruneBack stream q i ++ prunedBack stream q i = q := by exact List.rdropWhile_append_rtakeWhile
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pruneBack_append_prunedBack · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:96
  • pruneBack_prefix theorem — A stream, a deque, and a new index ensure that back pruning retains a prefix of the old deque.
    α :
    Type u_1
    shared
    stream :
    q :
    i :
    pruneBack stream q i <+: q
    Proof (Lean source)
    theorem pruneBack_prefix (stream : Stream α) (q : Deque) (i : ℕ) : pruneBack stream q i <+: q := by exact List.rdropWhile_prefix _ _
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pruneBack_prefix · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:102
  • pruneBack_index_ordered theorem — A stream, a new index, and strictly ordered old deque indices ensure that back pruning preserves strict index order.
    α :
    Type u_1
    shared
    stream :
    q :
    i :
    hq :
    q.Pairwise (· < ·)
    (pruneBack stream q i).Pairwise (· < ·)
    Proof (Lean source)
    theorem pruneBack_index_ordered (stream : Stream α) {q : Deque} {i : ℕ} (hq : q.Pairwise (· < ·)) : (pruneBack stream q i).Pairwise (· < ·) := by exact hq.sublist (pruneBack_prefix stream q i).sublist
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pruneBack_index_ordered · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:108
  • pruneBack_value_decreasing theorem — A stream, a new index, and strictly decreasing old deque values ensure that back pruning preserves strict value decrease.
    α :
    Type u_1
    shared
    stream :
    q :
    i :
    hq :
    q.Pairwise (fun j k => stream.value k < stream.value j)
    (pruneBack stream q i).Pairwise (fun j k => stream.value k < stream.value j)
    Proof (Lean source)
    theorem pruneBack_value_decreasing (stream : Stream α) {q : Deque} {i : ℕ} (hq : q.Pairwise (fun j k => stream.value k < stream.value j)) : (pruneBack stream q i).Pairwise (fun j k => stream.value k < stream.value j) := by exact hq.sublist (pruneBack_prefix stream q i).sublist
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pruneBack_value_decreasing · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:114
  • mem_push_iff theorem — A stream, a deque, a new index, and a queried index have the stated membership characterization after one push.
    α :
    Type u_1
    shared
    stream :
    q :
    i k :
    k ∈ push stream q i ↔ k ∈ pruneBack stream q i ∨ k = i
    Proof (Lean source)
    theorem mem_push_iff (stream : Stream α) (q : Deque) (i k : ℕ) : k ∈ push stream q i ↔ k ∈ pruneBack stream q i ∨ k = i := by simp [push]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.mem_push_iff · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:121
  • push_index_ordered theorem — A stream, strictly ordered old deque indices, and all old indices being earlier than the new one ensure that one push preserves strict index order.
    α :
    Type u_1
    shared
    stream :
    q :
    i :
    hq :
    q.Pairwise (· < ·)
    hi :
    ∀ j ∈ q, j < i
    (push stream q i).Pairwise (· < ·)
    Proof (Lean source)
    theorem push_index_ordered (stream : Stream α) {q : Deque} {i : ℕ} (hq : q.Pairwise (· < ·)) (hi : ∀ j ∈ q, j < i) : (push stream q i).Pairwise (· < ·) := by rw [push, List.pairwise_append] refine ⟨pruneBack_index_ordered stream hq, List.pairwise_singleton _ _, ?_⟩ intro j hj k hk simp only [List.mem_singleton] at hk subst k exact hi j ((pruneBack_prefix stream q i).mem hj)
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.push_index_ordered · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:127
  • push_value_decreasing theorem — A stream and strictly decreasing old deque values ensure that one rightmost-stable push leaves strictly decreasing values.
    α :
    Type u_1
    shared
    stream :
    q :
    i :
    hq :
    q.Pairwise (fun j k => stream.value k < stream.value j)
    (push stream q i).Pairwise (fun j k => stream.value k < stream.value j)
    Proof (Lean source)
    theorem push_value_decreasing (stream : Stream α) {q : Deque} {i : ℕ} (hq : q.Pairwise (fun j k => stream.value k < stream.value j)) : (push stream q i).Pairwise (fun j k => stream.value k < stream.value j) := by rw [push, List.pairwise_append] refine ⟨pruneBack_value_decreasing stream hq, List.pairwise_singleton _ _, ?_⟩ intro j hj k hk simp only [List.mem_singleton] at hk subst k let r := pruneBack stream q i have hr_ne : r ≠ [] := List.ne_nil_of_mem hj have hlast : stream.value i < stream.value (r.getLast hr_ne) := by have h := List.rdropWhile_last_not (fun j => decide (stream.value j ≤ stream.value i)) q hr_ne simpa [r, pruneBack] using h have hr : r.Pairwise (fun a b => stream.value b < stream.value a) := by exact pruneBack_value_decreasing stream (i := i) hq have hr_le : r.Pairwise (fun a b => stream.value b ≤ stream.value a) := by exact hr.imp (fun h => h.le) exact lt_of_lt_of_le hlast (hr_le.rel_getLast hj)
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.push_value_decreasing · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:139
  • nodup theorem — A valid raw-window deque has no duplicate indices.
    α :
    Type u_1
    shared
    left right :
    q :
    h :
    ValidAt stream left right q
    q.Nodup
    Proof (Lean source)
    theorem ValidAt.nodup {stream : Stream α} {left right : ℕ} {q : Deque} (h : ValidAt stream left right q) : q.Nodup := by exact h.index_ordered.nodup
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.ValidAt.nodup · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Deque.lean:172
Update 3 core · 7 supporting This module combines front expiration with batch insertion of the newly entered right-endpoint interval. ★ update_preserves

Window update and invariant preservation

This module combines front expiration with batch insertion of the newly entered right-endpoint interval. Its preservation results cover repeated endpoints, empty batches, empty windows, and windows that become empty.

structure StepTrace reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream has a step record containing its before and after deques and exact push, front-pop, and back-pop event lists.

Definition (Lean source)
α :
Type u_1
shared
stream :
oldRight :
window :
Window stream.length
before :
afterExpiration :
after :
pushed :
List
frontPopped :
List
backPopped :
List
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.StepTrace · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:15 · uses Stream
def update reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, the prior right endpoint, a new bounded window, and the prior deque determine the recorded monotone-deque update, expiring the front before inserting newly entered active indices.

Definition (Lean source)
α :
Type u_1
shared
stream :
oldRight :
window :
Window stream.length
q :
update stream oldRight window q :
StepTrace stream
expired :
expireFront window.left q
enteredLeft :
max oldRight window.left
entered :
range' enteredLeft (window.right - enteredLeft)
batch :
pushAll stream expired entered
{ oldRight := oldRight window := window before := q afterExpiration := expired after := batch.state pushed := batch.pushed frontPopped := expiredFront window.left q backPopped := batch.backPopped }
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.update · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:27 · uses Deque , StepTrace , Stream , Window
theorem update_preserves reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A valid old-window deque, a nondecreasing left endpoint, and a nondecreasing right endpoint ensure that one update produces a valid new-window deque.

Formal statement
α :
Type u_1
shared
oldWindow newWindow :
Window stream.length
q :
hq :
Valid stream oldWindow q
hleft :
oldWindow.left ≤ newWindow.left
hright :
oldWindow.right ≤ newWindow.right
Valid stream newWindow (update stream oldWindow.right newWindow q).after
Proof (Lean source)
theorem update_preserves {stream : Stream α} {oldWindow newWindow : Window stream.length} {q : Deque} (hq : Valid stream oldWindow q) (hleft : oldWindow.left ≤ newWindow.left) (hright : oldWindow.right ≤ newWindow.right) : Valid stream newWindow (update stream oldWindow.right newWindow q).after := by unfold Valid at hq ⊢ unfold update exact pushAll_interval_preserves (expireFront_preserves hq hleft) hright newWindow.right_le_length newWindow.left_le_right
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.update_preserves · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:241 · uses Deque , Stream , Valid , Window , update
7 supporting declarations (lemmas, instances)
  • update_pushed theorem — A stream, a prior right endpoint, a new window, and a prior deque have an update push log equal to the newly entered active interval.
    α :
    Type u_1
    shared
    stream :
    oldRight :
    window :
    Window stream.length
    q :
    (update stream oldRight window q).pushed
    = range' (max oldRight window.left) (window.right - max oldRight window.left)
    Proof (Lean source)
    theorem update_pushed (stream : Stream α) (oldRight : ℕ) (window : Window stream.length) (q : Deque) : (update stream oldRight window q).pushed = range' (max oldRight window.left) (window.right - max oldRight window.left) := by unfold update exact pushAll_pushed_eq _ _ _
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.update_pushed · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:82
  • expireFront_preserves theorem — A valid old raw-window deque and a nondecreasing new left endpoint ensure that front expiration preserves the full raw-window invariant, including an empty intermediate interval.
    α :
    Type u_1
    shared
    oldLeft oldRight newLeft :
    q :
    hq :
    ValidAt stream oldLeft oldRight q
    hleft :
    oldLeft ≤ newLeft
    ValidAt stream newLeft oldRight (expireFront newLeft q)
    Proof (Lean source)
    theorem expireFront_preserves {stream : Stream α} {oldLeft oldRight newLeft : ℕ} {q : Deque} (hq : ValidAt stream oldLeft oldRight q) (hleft : oldLeft ≤ newLeft) : ValidAt stream newLeft oldRight (expireFront newLeft q) := by by_cases hempty : oldRight < newLeft · have hexp : expireFront newLeft q = [] := by rw [expireFront, List.dropWhile_eq_nil_iff] intro i hi simp only [decide_eq_true_eq] exact lt_trans (hq.active i hi).1.2 hempty rw [hexp] refine ⟨by simp, by simp, by simp, ?_⟩ intro i hactive simp only [ActiveAt] at hactive exfalso omega · have hsub : (expireFront newLeft q).Sublist q := by exact List.dropWhile_sublist _ refine ⟨?_, hq.index_ordered.sublist hsub, hq.value_decreasing.sublist hsub, ?_⟩ · intro i hi have himem : i ∈ q ∧ newLeft ≤ i := by exact (mem_dropWhile_lt_iff newLeft hq.index_ordered i).mp hi have hiold := hq.active i himem.1 exact ⟨⟨himem.2, hiold.1.2⟩, hiold.2⟩ · intro i hi hbound hin have hiold : ActiveAt oldLeft oldRight i := ⟨le_trans hleft hi.1, hi.2⟩ have hiq : i ∉ q := by intro hiq apply hin exact (mem_dropWhile_lt_iff newLeft hq.index_ordered i).mpr ⟨hiq, hi.1⟩ obtain ⟨j, hjq, hij, hvalue⟩ := hq.dominates_omitted i hiold hbound hiq refine ⟨j, ?_, hij, hvalue⟩ exact (mem_dropWhile_lt_iff newLeft hq.index_ordered j).mpr ⟨hjq, le_trans hi.1 (le_of_lt hij)⟩
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.expireFront_preserves · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:91
  • to_max_right theorem — A valid raw-window deque remains valid when its right endpoint is enlarged to at least its left endpoint.
    α :
    Type u_1
    shared
    left right :
    q :
    hq :
    ValidAt stream left right q
    ValidAt stream left (max right left) q
    Proof (Lean source)
    theorem ValidAt.to_max_right {stream : Stream α} {left right : ℕ} {q : Deque} (hq : ValidAt stream left right q) : ValidAt stream left (max right left) q := by by_cases hempty : right < left · have hqnil : q = [] := by apply List.eq_nil_iff_forall_not_mem.mpr intro i hi have hactive := (hq.active i hi).1 simp only [ActiveAt] at hactive omega rw [hqnil] refine ⟨by simp, by simp, by simp, ?_⟩ intro i hactive simp only [ActiveAt] at hactive have hmax : max right left = left := max_eq_right (le_of_lt hempty) rw [hmax] at hactive omega · have hle : left ≤ right := Nat.le_of_not_gt hempty simpa [max_eq_left hle] using hq
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.ValidAt.to_max_right · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:130
  • push_succ_preserves theorem — A valid raw-window deque, a left endpoint no larger than the current right endpoint, and room for one more stream index ensure that pushing the right-boundary index preserves the invariant for the enlarged window.
    α :
    Type u_1
    shared
    left right :
    q :
    hq :
    ValidAt stream left right q
    hleft :
    left ≤ right
    hbound :
    right < stream.length
    ValidAt stream left (right + 1) (push stream q right)
    Proof (Lean source)
    theorem push_succ_preserves {stream : Stream α} {left right : ℕ} {q : Deque} (hq : ValidAt stream left right q) (hleft : left ≤ right) (hbound : right < stream.length) : ValidAt stream left (right + 1) (push stream q right) := by have hold_lt : ∀ j ∈ q, j < right := by intro j hj exact (hq.active j hj).1.2 have hright_mem : right ∈ push stream q right := by exact (mem_push_iff stream q right right).mpr (inr rfl) refine ⟨?_, push_index_ordered stream hq.index_ordered hold_lt, push_value_decreasing stream hq.value_decreasing, ?_⟩ · intro i hi rcases (mem_push_iff stream q right i).mp hi with hi | hiEq · have hiq : i ∈ q := (pruneBack_prefix stream q right).mem hi have hactive := hq.active i hiq exact ⟨⟨hactive.1.1, Nat.lt_succ_of_lt hactive.1.2⟩, hactive.2⟩ · subst i exact ⟨⟨hleft, Nat.lt_succ_self right⟩, hbound⟩ · intro i hi hifinite hin have hine : i ≠ right := by intro hiright apply hin simpa [hiright] using hright_mem have hiright : i < right := by simp only [ActiveAt] at hi omega have hiold : ActiveAt left right i := ⟨hi.1, hiright⟩ by_cases hiq : i ∈ q · have hipruned : i ∈ prunedBack stream q right := by have hiappend : i ∈ pruneBack stream q right ++ prunedBack stream q right := by rw [pruneBack_append_prunedBack] exact hiq rcases List.mem_append.mp hiappend with hiretained | hipruned · exact elim (hin ((mem_push_iff stream q right i).mpr (inl hiretained))) · exact hipruned have hidominated := mem_prunedBack_dominated stream hold_lt hipruned exact ⟨right, hright_mem, hidominated.1, hidominated.2⟩ · obtain ⟨j, hjq, hij, hvalue⟩ := hq.dominates_omitted i hiold hifinite hiq by_cases hjretained : j ∈ pruneBack stream q right · exact ⟨j, (mem_push_iff stream q right j).mpr (inl hjretained), hij, hvalue⟩ · have hjpruned : j ∈ prunedBack stream q right := by have hjappend : j ∈ pruneBack stream q right ++ prunedBack stream q right := by rw [pruneBack_append_prunedBack] exact hjq exact (List.mem_append.mp hjappend).resolve_left hjretained have hjdominated := mem_prunedBack_dominated stream hold_lt hjpruned exact ⟨right, hright_mem, lt_trans hij hjdominated.1, le_trans hvalue hjdominated.2⟩
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.push_succ_preserves · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:152
  • pushAll_range_preserves theorem — A valid raw-window deque, a left endpoint no larger than the range start, and a range ending within the stream ensure that pushing the whole consecutive range preserves the invariant.
    α :
    Type u_1
    shared
    left start count :
    q :
    hq :
    ValidAt stream left start q
    hleft :
    left ≤ start
    hbound :
    start + count ≤ stream.length
    ValidAt stream left (start + count) (pushAll stream q (range' start count)).state
    Proof (Lean source)
    theorem pushAll_range_preserves {stream : Stream α} {left start count : ℕ} {q : Deque} (hq : ValidAt stream left start q) (hleft : left ≤ start) (hbound : start + count ≤ stream.length) : ValidAt stream left (start + count) (pushAll stream q (range' start count)).state := by induction count generalizing start q with | zero => simpa [pushAll] | succ count ih => rw [List.range'_succ] simp only [pushAll] have hpush : ValidAt stream left (start + 1) (push stream q start) := push_succ_preserves hq hleft (by omega) have hrec := ih (start := start + 1) (q := push stream q start) hpush (by omega) (by omega) simpa only [Nat.add_assoc, Nat.add_comm, Nat.add_left_comm] using hrec
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pushAll_range_preserves · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:205
  • pushAll_interval_preserves theorem — A valid deque after front expiration, a nondecreasing right endpoint, a new endpoint within the stream, and a valid new raw interval ensure that inserting newly entered active indices restores the invariant.
    α :
    Type u_1
    shared
    left oldRight newRight :
    q :
    hq :
    ValidAt stream left oldRight q
    hright :
    oldRight ≤ newRight
    hbound :
    newRight ≤ stream.length
    hwindow :
    left ≤ newRight
    ValidAt stream left newRight (pushAll stream q (range' (max oldRight left) (newRight - max oldRight left))).state
    Proof (Lean source)
    theorem pushAll_interval_preserves {stream : Stream α} {left oldRight newRight : ℕ} {q : Deque} (hq : ValidAt stream left oldRight q) (hright : oldRight ≤ newRight) (hbound : newRight ≤ stream.length) (hwindow : left ≤ newRight) : ValidAt stream left newRight (pushAll stream q (range' (max oldRight left) (newRight - max oldRight left))).state := by have hright? : max oldRight left ≤ newRight := max_le hright hwindow have hq' : ValidAt stream left (max oldRight left) q := hq.to_max_right have hbatch := pushAll_range_preserves (start := max oldRight left) (count := newRight - max oldRight left) hq' (le_max_right oldRight left) (by simpa [Nat.add_sub_of_le hright?] using hbound) simpa [Nat.add_sub_of_le hright?] using hbatch
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.pushAll_interval_preserves · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:224
  • update_initial_preserves theorem — A stream and its first bounded window ensure that updating from the empty initial interval produces a valid deque.
    α :
    Type u_1
    shared
    stream :
    window :
    Window stream.length
    Valid stream window (update stream 0 window []).after
    Proof (Lean source)
    theorem update_initial_preserves (stream : Stream α) (window : Window stream.length) : Valid stream window (update stream 0 window []).after := by unfold Valid unfold update exact pushAll_interval_preserves (expireFront_preserves (initialDeque_validAt stream) (zero_le _)) (zero_le _) window.right_le_length window.left_le_right
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.update_initial_preserves · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Update.lean:257
Correctness 3 core · 3 supporting The invariant implies that the deque head is an active argmax. ★ head_value_eq_windowMax

Head and finite-window maximum correctness

The invariant implies that the deque head is an active argmax. This module exposes both the argmax witness formulation and equality with the maximum of the finite set of active values, so consumers never need to unfold the internal domination invariant.

def windowValues reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a bounded window determine the finite set of values observed in that window.

Definition (Lean source)
α :
Type u_1
shared
stream :
window :
Window stream.length
windowValues stream window :
window.indexFinset.image stream.value
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.windowValues · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Correctness.lean:16 · uses Stream , Window
def windowMax reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, a bounded window, and strictly ordered window endpoints determine the window maximum.

Definition (Lean source)
α :
Type u_1
shared
stream :
window :
Window stream.length
hne :
window.left < window.right
windowMax stream window hne :
α
(windowValues stream window).max' (windowValues_nonempty stream window hne)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.windowMax · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Correctness.lean:29 · uses Stream , Window
theorem head_value_eq_windowMax reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Valid

A valid bounded-window deque and a nonempty window ensure that its head is an active argmax whose value equals the finite-window maximum.

Formal statement
α :
Type u_1
shared
window :
Window stream.length
q :
hq :
Valid stream window q
hne :
window.left < window.right
∃ head tail,
q = head :: tail
Active window head
stream.value head = windowMax stream window hne
conclusion 1
i :
Active window i
stream.value i ≤ stream.value head
Proof (Lean source)
theorem Valid.head_value_eq_windowMax {stream : Stream α} {window : Window stream.length} {q : Deque} (hq : Valid stream window q) (hne : window.left < window.right) : ∃ head tail, q = head :: tailActive window head ∧ stream.value head = windowMax stream window hne ∧ ∀ i, Active window i → stream.value i ≤ stream.value head := by obtain ⟨head, tail, hqeq, hhead, hmax⟩ := hq.head_argmax hne refine ⟨head, tail, hqeq, hhead, ?_, hmax⟩ unfold windowMax symm apply (Finset.max'_eq_iff _ _ _).mpr constructor · rw [windowValues, mem_image] exact ⟨head, (Window.mem_indexFinset_iff window).mpr hhead, rfl⟩ · intro value hvalue rw [windowValues, mem_image] at hvalue obtain ⟨i, hi, rfl⟩ := hvalue exact hmax i ((Window.mem_indexFinset_iff window).mp hi)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Valid.head_value_eq_windowMax · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Correctness.lean:74 · uses Active , Deque , Stream , Valid , Window , windowMax
3 supporting declarations (lemmas, instances)
  • windowValues_nonempty theorem — A stream, a bounded window, and strictly ordered window endpoints ensure that the window's finite value set is nonempty.
    α :
    Type u_1
    shared
    stream :
    window :
    Window stream.length
    hne :
    window.left < window.right
    (windowValues stream window).Nonempty
    Proof (Lean source)
    theorem windowValues_nonempty (stream : Stream α) (window : Window stream.length) (hne : window.left < window.right) : (windowValues stream window).Nonempty := by refine ⟨stream.value window.left, ?_⟩ rw [windowValues, mem_image] exact ⟨window.left, (Window.mem_indexFinset_iff window).mpr ⟨le_rfl, hne⟩, rfl⟩
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.windowValues_nonempty · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Correctness.lean:21
  • head_argmax theorem — A valid raw-window deque, a nonempty raw interval, and a right endpoint within the stream ensure that the deque head is active and maximizes the stream value over that interval.
    α :
    Type u_1
    shared
    left right :
    q :
    hq :
    ValidAt stream left right q
    hne :
    left < right
    hbound :
    right ≤ stream.length
    ∃ head tail,
    q = head :: tail
    ActiveAt left right head
    head < stream.length
    conclusion 1
    i :
    ActiveAt left right i
    i < stream.length
    stream.value i ≤ stream.value head
    Proof (Lean source)
    theorem ValidAt.head_argmax {stream : Stream α} {left right : ℕ} {q : Deque} (hq : ValidAt stream left right q) (hne : left < right) (hbound : right ≤ stream.length) : ∃ head tail, q = head :: tailActiveAt left right head ∧ head < stream.length ∧ ∀ i, ActiveAt left right i → i < stream.length → stream.value i ≤ stream.value head := by have hq_ne : q ≠ [] := by intro hq_nil have hleft_bound : left < stream.length := lt_of_lt_of_le hne hbound obtain ⟨j, hj, -⟩ := hq.dominates_omitted left ⟨le_rfl, hne⟩ hleft_bound (by simp [hq_nil]) simp [hq_nil] at hj obtain ⟨head, tail, rfl⟩ := List.exists_cons_of_ne_nil hq_ne have hhead := hq.active head (by simp) refine ⟨head, tail, rfl, hhead.1, hhead.2, ?_⟩ intro i hi hibound have hmember_le : ∀ j ∈ head :: tail, stream.value j ≤ stream.value head := by intro j hj rcases List.mem_cons.mp hj with rfl | hj · exact le_rfl · exact (List.pairwise_cons.mp hq.value_decreasing).1 j hj |>.le by_cases hiq : i ∈ head :: tail · exact hmember_le i hiq · obtain ⟨j, hjq, -, hij⟩ := hq.dominates_omitted i hi hibound hiq exact le_trans hij (hmember_le j hjq)
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.ValidAt.head_argmax · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Correctness.lean:35
  • head_argmax theorem — A valid bounded-window deque and a nonempty window ensure that its head is an active argmax.
    α :
    Type u_1
    shared
    window :
    Window stream.length
    q :
    hq :
    Valid stream window q
    hne :
    window.left < window.right
    ∃ head tail,
    q = head :: tail
    Active window head
    conclusion 1
    i :
    Active window i
    stream.value i ≤ stream.value head
    Proof (Lean source)
    theorem Valid.head_argmax {stream : Stream α} {window : Window stream.length} {q : Deque} (hq : Valid stream window q) (hne : window.left < window.right) : ∃ head tail, q = head :: tailActive window head ∧ ∀ i, Active window i → stream.value i ≤ stream.value head := by obtain ⟨head, tail, hqeq, hhead, -, hmax⟩ := ValidAt.head_argmax hq hne window.right_le_length refine ⟨head, tail, hqeq, hhead, ?_⟩ intro i hi exact hmax i hi (lt_of_lt_of_le hi.2 window.right_le_length)
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.Valid.head_argmax · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Correctness.lean:62
Scan 3 core · 3 supporting This module runs the deque update over every scheduled window. ★ scan_head_value_eq_windowMax

Folding updates across a monotone window schedule

This module runs the deque update over every scheduled window. Its pointwise theorems return the valid state, active head argmax, and exact maximum value at any requested schedule position.

def scanFrom reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream determines the scan trace produced from a prior right endpoint, deque, and list of windows.

Definition (Lean source)
α :
Type u_1
shared
stream :
scanFrom stream :
ℕ → DequeList (Window stream.length) → List (StepTrace stream)
clause 1
| _, _, [] => []
clause 2
| oldRight, q, window :: windows
=> let step := update stream oldRight window q step :: scanFrom stream window.right step.after windows
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scanFrom · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Scan.lean:14 · uses Deque , StepTrace , Stream , Window
def scan reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a monotone window schedule determine the complete scan trace from the empty initial state.

Definition (Lean source)
α :
Type u_1
shared
stream :
schedule :
Schedule stream.length
scan stream schedule :
List (StepTrace stream)
scanFrom stream 0 initialDeque schedule.windows
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scan · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Scan.lean:23 · uses Schedule , StepTrace , Stream
theorem scan_head_value_eq_windowMax reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream, a monotone window schedule, a valid schedule position, and a nonempty window at that position ensure that the scan head is an active argmax whose value equals the finite-window maximum.

Formal statement
α :
Type u_1
shared
stream :
schedule :
Schedule stream.length
k :
hk :
k < schedule.steps
hne :
(schedule.windows.get ⟨k, hk⟩).left < (schedule.windows.get ⟨k, hk⟩).right
∃ step head tail,
(scan stream schedule)[k]? = some step
step.window = schedule.windows.get ⟨k, hk⟩
step.after = head :: tail
Active step.window head
stream.value head = windowMax stream (schedule.windows.get ⟨k, hk⟩) hne
conclusion 1
i :
Active step.window i
stream.value i ≤ stream.value head
Proof (Lean source)
theorem scan_head_value_eq_windowMax (stream : Stream α) (schedule : Schedule stream.length) {k : ℕ} (hk : k < schedule.steps) (hne : (schedule.windows.get ⟨k, hk⟩).left < (schedule.windows.get ⟨k, hk⟩).right) : ∃ step head tail, (scan stream schedule)[k]? = some step ∧ step.window = schedule.windows.get ⟨k, hk⟩ ∧ step.after = head :: tailActive step.window head ∧ stream.value head = windowMax stream (schedule.windows.get ⟨k, hk⟩) hne ∧ ∀ i, Active step.window i → stream.value i ≤ stream.value head := by obtain ⟨step, hstep, hwindow, hvalid⟩ := scan_valid_at stream schedule hk have hne_step : step.window.left < step.window.right := by simpa [hwindow] using hne obtain ⟨head, tail, hafter, hactive, hvalue, hmax⟩ := hvalid.head_value_eq_windowMax hne_step refine ⟨step, head, tail, hstep, hwindow, hafter, hactive, ?_, hmax⟩ simpa [hwindow] using hvalue
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scan_head_value_eq_windowMax · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Scan.lean:113 · uses Active , Deque , Schedule , steps , StepTrace , Stream , Window , scan , windowMax
3 supporting declarations (lemmas, instances)
  • length_scan theorem — A stream and a monotone window schedule ensure that the scan has exactly one trace step for each scheduled window.
    α :
    Type u_1
    shared
    stream :
    schedule :
    Schedule stream.length
    (scan stream schedule).length = schedule.steps
    Proof (Lean source)
    theorem length_scan (stream : Stream α) (schedule : Schedule stream.length) : (scan stream schedule).length = schedule.steps := by have hlength : ∀ (oldRight : ℕ) (q : Deque) (windows : List (Window stream.length)), (scanFrom stream oldRight q windows).length = windows.length := by intro oldRight q windows induction windows generalizing oldRight q with | nil => rfl | cons window windows ih => simp only [scanFrom, List.length_cons] rw [ih] exact hlength 0 initialDeque schedule.windows
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.length_scan · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Scan.lean:28
  • scan_valid_at theorem — A stream, a monotone window schedule, and a valid schedule position ensure that the corresponding scan step has a valid deque for its window.
    α :
    Type u_1
    shared
    stream :
    schedule :
    Schedule stream.length
    k :
    hk :
    k < schedule.steps
    ∃ step,
    conclusion 1
    (scan stream schedule)[k]? = some step
    conclusion 2
    step.window = schedule.windows.get ⟨k, hk⟩
    conclusion 3
    Valid stream step.window step.after
    Proof (Lean source)
    theorem scan_valid_at (stream : Stream α) (schedule : Schedule stream.length) {k : ℕ} (hk : k < schedule.steps) : ∃ step, (scan stream schedule)[k]? = some step ∧ step.window = schedule.windows.get ⟨k, hk⟩ ∧ Valid stream step.window step.after := by let emptyWindow : Window stream.length := { left := 0, right := 0, left_le_right := le_rfl, right_le_length := zero_le _ } have hinitial : Valid stream emptyWindow initialDeque := by exact initialDeque_validAt stream have hleft : (emptyWindow :: schedule.windows).Pairwise (fun a b => a.left ≤ b.left) := by rw [List.pairwise_cons] exact ⟨by simp [emptyWindow], schedule.left_mono⟩ have hright : (emptyWindow :: schedule.windows).Pairwise (fun a b => a.right ≤ b.right) := by rw [List.pairwise_cons] exact ⟨by simp [emptyWindow], schedule.right_mono⟩ simpa [scan, Schedule.steps, emptyWindow] using scanFrom_valid_at_of_valid stream hinitial schedule.windows hleft hright hk
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scan_valid_at · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Scan.lean:72
  • scan_head_argmax theorem — A stream, a monotone window schedule, a valid schedule position, and a nonempty window at that position ensure that the scan head is active and maximizes the stream value in that window.
    α :
    Type u_1
    shared
    stream :
    schedule :
    Schedule stream.length
    k :
    hk :
    k < schedule.steps
    hne :
    (schedule.windows.get ⟨k, hk⟩).left < (schedule.windows.get ⟨k, hk⟩).right
    ∃ step head tail,
    (scan stream schedule)[k]? = some step
    step.window = schedule.windows.get ⟨k, hk⟩
    step.after = head :: tail
    Active step.window head
    conclusion 1
    i :
    Active step.window i
    stream.value i ≤ stream.value head
    Proof (Lean source)
    theorem scan_head_argmax (stream : Stream α) (schedule : Schedule stream.length) {k : ℕ} (hk : k < schedule.steps) (hne : (schedule.windows.get ⟨k, hk⟩).left < (schedule.windows.get ⟨k, hk⟩).right) : ∃ step head tail, (scan stream schedule)[k]? = some step ∧ step.window = schedule.windows.get ⟨k, hk⟩ ∧ step.after = head :: tailActive step.window head ∧ ∀ i, Active step.window i → stream.value i ≤ stream.value head := by obtain ⟨step, hstep, hwindow, hvalid⟩ := scan_valid_at stream schedule hk have hne_step : step.window.left < step.window.right := by simpa [hwindow] using hne obtain ⟨head, tail, hafter, hactive, hmax⟩ := hvalid.head_argmax hne_step exact ⟨step, head, tail, hstep, hwindow, hafter, hactive, hmax⟩
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scan_head_argmax · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Scan.lean:95
Predicate­Schedule 10 core · 17 supporting This module turns entry and stay predicates on an arbitrary sparse list of raw keys into bounded half-open position windows. ★ active_schedule_iff

Compiling monotone raw-key predicates to position windows

This module turns entry and stay predicates on an arbitrary sparse list of raw keys into bounded half-open position windows. The hypotheses say exactly that entry sets are prefixes, stay sets are suffixes, entry can only expand along the step list, and stay can only shrink. No order or density assumption is imposed on the raw key type itself.

structure PredicateWindowSchedule reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A sparse raw-key list and an ordered step list determine a predicate window specification whose entry predicate, stay predicate, entry-prefix law, stay-suffix law, entry monotonicity across steps, and stay antitonicity across steps describe a monotone active window.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
steps :
List κ
entry :
κ → ι → Prop
stay :
κ → ι → Prop
entry_prefix :
∀ (s : κ) {i j : ℕ} (hi : i < keys.length) (hj : j < keys.length)
if
i ≤ j
and
entry s (keys.get ⟨j, hj⟩)
then
entry s (keys.get ⟨i, hi⟩)
stay_suffix :
∀ (s : κ) {i j : ℕ} (hi : i < keys.length) (hj : j < keys.length)
if
i ≤ j
and
stay s (keys.get ⟨i, hi⟩)
then
stay s (keys.get ⟨j, hj⟩)
entry_step_mono :
steps.Pairwise (fun s t => ∀ x ∈ keys, entry s x → entry t x)
stay_step_anti :
steps.Pairwise (fun s t => ∀ x ∈ keys, stay t x → stay s x)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:18
def entryTest reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule, a step, and a raw key determine the Boolean entry test used by the list operations. It decides the entry predicate classically, so it is a noncomputable specification rather than executable code.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
s :
κ
x :
ι
entryTest P s x :
by classical exact decide (P.entry s x)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.entryTest · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:37 · uses PredicateWindowSchedule
def expiredTest reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule, a step, and a raw key determine the Boolean test that the key has expired, true exactly when the key does not stay at that step. It decides the stay predicate classically, so it is noncomputable.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
s :
κ
x :
ι
expiredTest P s x :
by classical exact decide (¬ P.stay s x)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.expiredTest · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:44 · uses PredicateWindowSchedule
def entered reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a step determine the raw prefix that has entered by that step.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
s :
κ
entered P s :
List ι
by exact keys.takeWhile (P.entryTest s)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.entered · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:51 · uses PredicateWindowSchedule
def rightEndpoint reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a step determine the right position endpoint, namely the length of the entered raw-key prefix.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
s :
κ
rightEndpoint P s :
(P.entered s).length
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rightEndpoint · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:56 · uses PredicateWindowSchedule
def expiredPrefix reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a step determine the expired prefix of entered keys, namely the initial segment that no longer satisfies the stay predicate.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
s :
κ
expiredPrefix P s :
List ι
by exact (keys.take (P.rightEndpoint s)).takeWhile (P.expiredTest s)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.expiredPrefix · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:61 · uses PredicateWindowSchedule
def leftEndpoint reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a step determine the left position endpoint, namely the length of the expired prefix among entered keys.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
s :
κ
leftEndpoint P s :
(P.expiredPrefix s).length
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.leftEndpoint · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:66 · uses PredicateWindowSchedule
def windowAt reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a step determine a bounded half-open position window, including when the raw-key list or the active window is empty.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
s :
κ
windowAt P s :
Window keys.length
{ left := P.leftEndpoint s right := P.rightEndpoint s left_le_right := P.leftEndpoint_le_rightEndpoint s right_le_length := P.rightEndpoint_le_length s }
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.windowAt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:144 · uses PredicateWindowSchedule , Window
def schedule reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule compiles to the monotone bounded-window schedule over key positions.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
schedule P :
Schedule keys.length
by classical refine { windows := steps.map P.windowAt, left_mono := ?_, right_mono := ?_ } · rw [List.pairwise_map] exact (P.entry_step_mono.and P.stay_step_anti).imp (fun h => P.leftEndpoint_mono_of_predicates h.1 h.2) · rw [List.pairwise_map] exact P.entry_step_mono.imp (fun h => P.rightEndpoint_mono_of_entry h)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.schedule · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:336 · uses PredicateWindowSchedule , Schedule
theorem active_schedule_iff reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule, a valid step position, and an in-bounds key position characterize activity in the compiled scheduled window by the raw predicates.

Formal statement
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
shared
steps :
List κ
shared
P :
k i :
hk :
k < steps.length
hi :
i < keys.length
Active (P.schedule.windows.get ⟨k, by simpa [schedule, Schedule.steps] using hk⟩) i
↔ P.entry (steps.get ⟨k, hk⟩) (keys.get ⟨i, hi⟩) ∧
P.stay (steps.get ⟨k, hk⟩) (keys.get ⟨i, hi⟩)
Proof (Lean source)
theorem active_schedule_iff (P : PredicateWindowSchedule keys steps) {k i : ℕ} (hk : k < steps.length) (hi : i < keys.length) : Active (P.schedule.windows.get ⟨k, by simpa [schedule, Schedule.steps] using hk⟩) i ↔ P.entry (steps.get ⟨k, hk⟩) (keys.get ⟨i, hi⟩) ∧ P.stay (steps.get ⟨k, hk⟩) (keys.get ⟨i, hi⟩) := by rw [P.schedule_window_get hk] exact P.active_windowAt_iff (steps.get ⟨k, hk⟩) hi
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.active_schedule_iff · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:360 · uses Active , PredicateWindowSchedule , schedule , windowAt , Window
17 supporting declarations (lemmas, instances)
  • rightEndpoint_le_length theorem — A predicate schedule has every right endpoint bounded by the raw-key count.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s :
    κ
    P.rightEndpoint s ≤ keys.length
    Proof (Lean source)
    theorem rightEndpoint_le_length (P : PredicateWindowSchedule keys steps) (s : κ) : P.rightEndpoint s ≤ keys.length := by exact (List.takeWhile_prefix _).length_le
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rightEndpoint_le_length · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:129
  • leftEndpoint_le_rightEndpoint theorem — A predicate schedule has every left endpoint bounded by its right endpoint.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s :
    κ
    P.leftEndpoint s ≤ P.rightEndpoint s
    Proof (Lean source)
    theorem leftEndpoint_le_rightEndpoint (P : PredicateWindowSchedule keys steps) (s : κ) : P.leftEndpoint s ≤ P.rightEndpoint s := by change ((keys.take (P.rightEndpoint s)).takeWhile (P.expiredTest s)).length ≤ P.rightEndpoint s calc _ ≤ (keys.take (P.rightEndpoint s)).length := (List.takeWhile_prefix _).length_le _ = P.rightEndpoint s := by simp [List.length_take, Nat.min_eq_left (P.rightEndpoint_le_length s)]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.leftEndpoint_le_rightEndpoint · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:134
  • take_rightEndpoint_eq_entered theorem — A predicate schedule has its right prefix exactly equal to the takeWhile entry segment.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s :
    κ
    keys.take (P.rightEndpoint s) = P.entered s
    Proof (Lean source)
    theorem take_rightEndpoint_eq_entered (P : PredicateWindowSchedule keys steps) (s : κ) : keys.take (P.rightEndpoint s) = P.entered s := by change keys.take (keys.takeWhile (P.entryTest s)).length = keys.takeWhile (P.entryTest s) calc _ = (keys.takeWhile (P.entryTest s) ++ keys.dropWhile (P.entryTest s)).take (keys.takeWhile (P.entryTest s)).length := by rw [List.takeWhile_append_dropWhile] _ = _ := List.take_left
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.take_rightEndpoint_eq_entered · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:152
  • take_leftEndpoint_eq_expiredPrefix theorem — A predicate schedule has its left prefix exactly equal to the takeWhile segment of entered keys that fail the stay predicate.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s :
    κ
    (keys.take (P.rightEndpoint s)).take (P.leftEndpoint s) = P.expiredPrefix s
    Proof (Lean source)
    theorem take_leftEndpoint_eq_expiredPrefix (P : PredicateWindowSchedule keys steps) (s : κ) : (keys.take (P.rightEndpoint s)).take (P.leftEndpoint s) = P.expiredPrefix s := by change (keys.take (P.rightEndpoint s)).take (P.expiredPrefix s).length = P.expiredPrefix s rw [← List.takeWhile_append_dropWhile (p := P.expiredTest s) (l := keys.take (P.rightEndpoint s))] exact List.take_left
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.take_leftEndpoint_eq_expiredPrefix · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:163
  • drop_leftEndpoint_eq_dropWhile theorem — A predicate schedule has the keys between its endpoints exactly equal to dropping the non-staying prefix from the entered prefix.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s :
    κ
    (keys.take (P.rightEndpoint s)).drop (P.leftEndpoint s)
    = (keys.take (P.rightEndpoint s)).dropWhile (P.expiredTest s)
    Proof (Lean source)
    theorem drop_leftEndpoint_eq_dropWhile (P : PredicateWindowSchedule keys steps) (s : κ) : (keys.take (P.rightEndpoint s)).drop (P.leftEndpoint s) = (keys.take (P.rightEndpoint s)).dropWhile (P.expiredTest s) := by let l := keys.take (P.rightEndpoint s) change l.drop (l.takeWhile (P.expiredTest s)).length = l.dropWhile (P.expiredTest s) calc _ = (l.takeWhile (P.expiredTest s) ++ l.dropWhile (P.expiredTest s)).drop (l.takeWhile (P.expiredTest s)).length := by rw [List.takeWhile_append_dropWhile] _ = _ := List.drop_left
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.drop_leftEndpoint_eq_dropWhile · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:172
  • active_windowAt_iff theorem — A predicate schedule, a step, and an in-bounds position satisfy the exact equivalence between position activity and the raw entry-and-stay predicates.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s :
    κ
    i :
    hi :
    i < keys.length
    Active (P.windowAt s) i ↔ P.entry s (keys.get ⟨i, hi⟩) ∧ P.stay s (keys.get ⟨i, hi⟩)
    Proof (Lean source)
    theorem active_windowAt_iff (P : PredicateWindowSchedule keys steps) (s : κ) {i : ℕ} (hi : i < keys.length) : Active (P.windowAt s) i ↔ P.entry s (keys.get ⟨i, hi⟩) ∧ P.stay s (keys.get ⟨i, hi⟩) := by constructor · rintro ⟨hli, hir⟩ refine ⟨(P.lt_rightEndpoint_iff_entry s hi).mp hir, ?_⟩ by_contra hstay exact (Nat.not_lt_of_ge hli) ((P.lt_leftEndpoint_iff_not_stay s hir).mpr hstay) · rintro ⟨hentry, hstay⟩ have hir := (P.lt_rightEndpoint_iff_entry s hi).mpr hentry refine ⟨Nat.le_of_not_gt ?_, hir⟩ intro hil exact ((P.lt_leftEndpoint_iff_not_stay s hir).mp hil) hstay
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.active_windowAt_iff · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:223
  • rightEndpoint_mono_of_entry theorem — Predicate inclusion from an earlier step to a later step makes right endpoints nondecreasing.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s t :
    κ
    hentry :
    ∀ x ∈ keys
    if
    P.entry s x
    then
    P.entry t x
    P.rightEndpoint s ≤ P.rightEndpoint t
    Proof (Lean source)
    theorem rightEndpoint_mono_of_entry (P : PredicateWindowSchedule keys steps) {s t : κ} (hentry : ∀ x ∈ keys, P.entry s x → P.entry t x) : P.rightEndpoint s ≤ P.rightEndpoint t := by by_contra h have hlt : P.rightEndpoint t < P.rightEndpoint s := Nat.lt_of_not_ge h have hi : P.rightEndpoint t < keys.length := lt_of_lt_of_le hlt (P.rightEndpoint_le_length s) have hs := (P.lt_rightEndpoint_iff_entry s hi).mp hlt have ht := hentry _ (List.get_mem keys ⟨P.rightEndpoint t, hi⟩) hs exact (Nat.lt_irrefl _) ((P.lt_rightEndpoint_iff_entry t hi).mpr ht)
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rightEndpoint_mono_of_entry · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:240
  • leftEndpoint_mono_of_predicates theorem — Expanding entry and shrinking stay from one step to another make left endpoints nondecreasing.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s t :
    κ
    hentry :
    ∀ x ∈ keys
    if
    P.entry s x
    then
    P.entry t x
    hstay :
    ∀ x ∈ keys
    if
    P.stay t x
    then
    P.stay s x
    P.leftEndpoint s ≤ P.leftEndpoint t
    Proof (Lean source)
    theorem leftEndpoint_mono_of_predicates (P : PredicateWindowSchedule keys steps) {s t : κ} (hentry : ∀ x ∈ keys, P.entry s x → P.entry t x) (hstay : ∀ x ∈ keys, P.stay t x → P.stay s x) : P.leftEndpoint s ≤ P.leftEndpoint t := by by_contra h have hlt : P.leftEndpoint t < P.leftEndpoint s := Nat.lt_of_not_ge h have hright := P.rightEndpoint_mono_of_entry hentry have hirS : P.leftEndpoint t < P.rightEndpoint s := lt_of_lt_of_le hlt (P.leftEndpoint_le_rightEndpoint s) have hirT : P.leftEndpoint t < P.rightEndpoint t := lt_of_lt_of_le hirS hright have hi : P.leftEndpoint t < keys.length := lt_of_lt_of_le hirT (P.rightEndpoint_le_length t) have hnotStayS := (P.lt_leftEndpoint_iff_not_stay s hirS).mp hlt have hstayT : P.stay t (keys.get ⟨P.leftEndpoint t, hi⟩) := by by_contra hn exact (Nat.lt_irrefl _) ((P.lt_leftEndpoint_iff_not_stay t hirT).mpr hn) exact hnotStayS (hstay _ (List.get_mem keys ⟨P.leftEndpoint t, hi⟩) hstayT)
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.leftEndpoint_mono_of_predicates · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:253
  • newlyEntering_eq_drop_entered theorem — A predicate schedule, an earlier step, a later step, and entry inclusion have newly entered raw keys exactly equal to the later entered prefix after dropping the earlier right endpoint.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s t :
    κ
    hentry :
    ∀ x ∈ keys
    if
    P.entry s x
    then
    P.entry t x
    (keys.drop (P.rightEndpoint s)).takeWhile (P.entryTest t)
    = (P.entered t).drop (P.rightEndpoint s)
    Proof (Lean source)
    theorem newlyEntering_eq_drop_entered (P : PredicateWindowSchedule keys steps) (s t : κ) (hentry : ∀ x ∈ keys, P.entry s x → P.entry t x) : (keys.drop (P.rightEndpoint s)).takeWhile (P.entryTest t) = (P.entered t).drop (P.rightEndpoint s) := by exact takeWhile_drop_eq_drop_takeWhile (P.entryTest t) keys (P.rightEndpoint s) (P.rightEndpoint_mono_of_entry hentry)
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.newlyEntering_eq_drop_entered · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:274
  • rightEndpoint_eq_add_newlyEntering theorem — A predicate schedule, an earlier step, a later step, and entry inclusion have later right endpoint equal to the earlier endpoint plus the exact takeWhile entering-segment length.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s t :
    κ
    hentry :
    ∀ x ∈ keys
    if
    P.entry s x
    then
    P.entry t x
    P.rightEndpoint t
    = P.rightEndpoint s + ((keys.drop (P.rightEndpoint s)).takeWhile (P.entryTest t)).length
    Proof (Lean source)
    theorem rightEndpoint_eq_add_newlyEntering (P : PredicateWindowSchedule keys steps) (s t : κ) (hentry : ∀ x ∈ keys, P.entry s x → P.entry t x) : P.rightEndpoint t = P.rightEndpoint s + ((keys.drop (P.rightEndpoint s)).takeWhile (P.entryTest t)).length := by rw [P.newlyEntering_eq_drop_entered s t hentry, List.length_drop] exact (Nat.add_sub_of_le (P.rightEndpoint_mono_of_entry hentry)).symm
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rightEndpoint_eq_add_newlyEntering · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:284
  • newlyExpired_eq_takeWhile theorem — A predicate schedule, an earlier step, a later step, entry expansion, and stay shrinkage have the keys crossing the left endpoint exactly equal to the takeWhile non-staying segment.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s t :
    κ
    hentry :
    ∀ x ∈ keys
    if
    P.entry s x
    then
    P.entry t x
    hstay :
    ∀ x ∈ keys
    if
    P.stay t x
    then
    P.stay s x
    ((keys.take (P.rightEndpoint t)).drop (P.leftEndpoint s)).take (P.leftEndpoint t - P.leftEndpoint s)
    = ((keys.take (P.rightEndpoint t)).drop (P.leftEndpoint s)).takeWhile (P.expiredTest t)
    Proof (Lean source)
    theorem newlyExpired_eq_takeWhile (P : PredicateWindowSchedule keys steps) (s t : κ) (hentry : ∀ x ∈ keys, P.entry s x → P.entry t x) (hstay : ∀ x ∈ keys, P.stay t x → P.stay s x) : ((keys.take (P.rightEndpoint t)).drop (P.leftEndpoint s)).take (P.leftEndpoint t - P.leftEndpoint s) = ((keys.take (P.rightEndpoint t)).drop (P.leftEndpoint s)).takeWhile (P.expiredTest t) := by have hmono := P.leftEndpoint_mono_of_predicates hentry hstay let l := keys.take (P.rightEndpoint t) change (l.drop (P.leftEndpoint s)).take (P.leftEndpoint t - P.leftEndpoint s) = (l.drop (P.leftEndpoint s)).takeWhile (P.expiredTest t) calc _ = (l.take (P.leftEndpoint s + (P.leftEndpoint t - P.leftEndpoint s))).drop (P.leftEndpoint s) := List.take_drop _ = (l.take (P.leftEndpoint t)).drop (P.leftEndpoint s) := by rw [Nat.add_sub_of_le hmono] _ = (P.expiredPrefix t).drop (P.leftEndpoint s) := by rw [P.take_leftEndpoint_eq_expiredPrefix t] _ = _ := by symm exact takeWhile_drop_eq_drop_takeWhile (P.expiredTest t) l (P.leftEndpoint s) hmono
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.newlyExpired_eq_takeWhile · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:294
  • leftEndpoint_eq_add_newlyExpired theorem — A predicate schedule, an earlier step, a later step, entry expansion, and stay shrinkage have later left endpoint equal to the earlier endpoint plus the exact takeWhile expiration-segment length.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    s t :
    κ
    hentry :
    ∀ x ∈ keys
    if
    P.entry s x
    then
    P.entry t x
    hstay :
    ∀ x ∈ keys
    if
    P.stay t x
    then
    P.stay s x
    P.leftEndpoint t
    = P.leftEndpoint s
    + (((keys.take (P.rightEndpoint t)).drop (P.leftEndpoint s)).takeWhile (P.expiredTest t)).length
    Proof (Lean source)
    theorem leftEndpoint_eq_add_newlyExpired (P : PredicateWindowSchedule keys steps) (s t : κ) (hentry : ∀ x ∈ keys, P.entry s x → P.entry t x) (hstay : ∀ x ∈ keys, P.stay t x → P.stay s x) : P.leftEndpoint t = P.leftEndpoint s + (((keys.take (P.rightEndpoint t)).drop (P.leftEndpoint s)).takeWhile (P.expiredTest t)).length := by have hmono := P.leftEndpoint_mono_of_predicates hentry hstay have heq := congrArg length (P.newlyExpired_eq_takeWhile s t hentry hstay) have hbound := P.leftEndpoint_le_rightEndpoint t simp only [List.length_take, List.length_drop] at heq rw [Nat.min_eq_left (P.rightEndpoint_le_length t)] at heq rw [Nat.min_eq_left (Nat.sub_le_sub_right hbound (P.leftEndpoint s))] at heq omega
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.leftEndpoint_eq_add_newlyExpired · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:319
  • schedule_steps theorem — A predicate schedule compiles to one position window for each raw step.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    P.schedule.steps = steps.length
    Proof (Lean source)
    theorem schedule_steps (P : PredicateWindowSchedule keys steps) : P.schedule.steps = steps.length := by simp [schedule, Schedule.steps]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.schedule_steps · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:347
  • schedule_window_get theorem — A predicate schedule and a valid step-list position compile the window at that position to the endpoints of the corresponding raw step.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    k :
    hk :
    k < steps.length
    P.schedule.windows.get ⟨k, by simpa [schedule, Schedule.steps] using hk⟩
    = P.windowAt (steps.get ⟨k, hk⟩)
    Proof (Lean source)
    theorem schedule_window_get (P : PredicateWindowSchedule keys steps) {k : ℕ} (hk : k < steps.length) : P.schedule.windows.get ⟨k, by simpa [schedule, Schedule.steps] using hk⟩ = P.windowAt (steps.get ⟨k, hk⟩) := by simp [schedule, List.get_eq_getElem]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.schedule_window_get · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:352
  • rightEndpoint_le_of_step_lt theorem — A predicate schedule, two valid step positions, and their strict order ensure the earlier compiled right endpoint is no larger.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    i j :
    hi :
    i < steps.length
    hj :
    j < steps.length
    hij :
    i < j
    P.rightEndpoint (steps.get ⟨i, hi⟩) ≤ P.rightEndpoint (steps.get ⟨j, hj⟩)
    Proof (Lean source)
    theorem rightEndpoint_le_of_step_lt (P : PredicateWindowSchedule keys steps) {i j : ℕ} (hi : i < steps.length) (hj : j < steps.length) (hij : i < j) : P.rightEndpoint (steps.get ⟨i, hi⟩) ≤ P.rightEndpoint (steps.get ⟨j, hj⟩) := by apply P.rightEndpoint_mono_of_entry exact P.entry_step_mono.rel_get_of_lt hij
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rightEndpoint_le_of_step_lt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:371
  • leftEndpoint_le_of_step_lt theorem — A predicate schedule, two valid step positions, and their strict order ensure the earlier compiled left endpoint is no larger.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    i j :
    hi :
    i < steps.length
    hj :
    j < steps.length
    hij :
    i < j
    P.leftEndpoint (steps.get ⟨i, hi⟩) ≤ P.leftEndpoint (steps.get ⟨j, hj⟩)
    Proof (Lean source)
    theorem leftEndpoint_le_of_step_lt (P : PredicateWindowSchedule keys steps) {i j : ℕ} (hi : i < steps.length) (hj : j < steps.length) (hij : i < j) : P.leftEndpoint (steps.get ⟨i, hi⟩) ≤ P.leftEndpoint (steps.get ⟨j, hj⟩) := by apply P.leftEndpoint_mono_of_predicates · exact P.entry_step_mono.rel_get_of_lt hij · exact P.stay_step_anti.rel_get_of_lt hij
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.leftEndpoint_le_of_step_lt · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:379
  • windowAt_empty theorem — A predicate schedule over an empty raw-key list has both endpoints equal to zero at every step.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    List κ
    shared
    s :
    κ
    conclusion 1
    (P.windowAt s).left = 0
    conclusion 2
    (P.windowAt s).right = 0
    Proof (Lean source)
    theorem windowAt_empty (P : PredicateWindowSchedule ([] : List ι) steps) (s : κ) : (P.windowAt s).left = 0 ∧ (P.windowAt s).right = 0 := by simp [windowAt, leftEndpoint, rightEndpoint, expiredPrefix, entered]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.windowAt_empty · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateSchedule.lean:388
Accounting 7 core · 11 supporting Exact event lists make the amortized proof explicit. ★ scanCost_le

Trace accounting and linear resource bounds

Exact event lists make the amortized proof explicit. Each pushed stream index is unique, every pop is charged to a prior unique push, the final deque contains the unpopped pushes, and therefore all deque mutations are linear in stream length. Pointwise storage is bounded by window width.

def TracePushed reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a scan trace determine the aggregate push log.

Definition (Lean source)
α :
Type u_1
shared
stream :
trace :
List (StepTrace stream)
TracePushed stream trace :
List
trace.flatMap StepTrace.pushed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.TracePushed · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Accounting.lean:15 · uses StepTrace , Stream
def TraceFrontPopped reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a scan trace determine the aggregate front-pop log.

Definition (Lean source)
α :
Type u_1
shared
stream :
trace :
List (StepTrace stream)
TraceFrontPopped stream trace :
List
trace.flatMap StepTrace.frontPopped
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.TraceFrontPopped · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Accounting.lean:19 · uses StepTrace , Stream
def TraceBackPopped reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a scan trace determine the aggregate back-pop log.

Definition (Lean source)
α :
Type u_1
shared
stream :
trace :
List (StepTrace stream)
TraceBackPopped stream trace :
List
trace.flatMap StepTrace.backPopped
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.TraceBackPopped · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Accounting.lean:23 · uses StepTrace , Stream
def dequeOperations reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a scan trace determine the total number of deque mutations.

Definition (Lean source)
α :
Type u_1
shared
stream :
trace :
List (StepTrace stream)
dequeOperations stream trace :
(TracePushed stream trace).length
+ (TraceFrontPopped stream trace).length
+ (TraceBackPopped stream trace).length
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.dequeOperations · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Accounting.lean:27 · uses StepTrace , Stream
def scanCost reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a monotone window schedule determine the scan cost, including one bookkeeping unit per window.

Definition (Lean source)
α :
Type u_1
shared
stream :
schedule :
Schedule stream.length
scanCost stream schedule :
schedule.steps + dequeOperations stream (scan stream schedule)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scanCost · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Accounting.lean:33 · uses Schedule , Stream
def peakStored reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a scan trace determine the peak stored deque size.

Definition (Lean source)
α :
Type u_1
shared
stream :
trace :
List (StepTrace stream)
peakStored stream trace :
(trace.map (fun step => step.after.length)).foldl max 0
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.peakStored · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Accounting.lean:38 · uses StepTrace , Stream
theorem scanCost_le reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a monotone window schedule ensure that scan cost is at most twice stream length plus the number of scheduled windows.

Formal statement
α :
Type u_1
shared
stream :
schedule :
Schedule stream.length
scanCost stream schedule ≤ 2 * stream.length + schedule.steps
Proof (Lean source)
theorem scanCost_le (stream : Stream α) (schedule : Schedule stream.length) : scanCost stream schedule ≤ 2 * stream.length + schedule.steps := by have h := dequeOperations_le_two_mul_length stream schedule unfold scanCost omega
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scanCost_le · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Accounting.lean:311 · uses Schedule , steps , Stream , scanCost
11 supporting declarations (lemmas, instances)
Predicate­Raw­Scan 16 core · 4 supporting This module gives the raw-key view of a compiled predicate-window scan (a noncomputable specification, since entry and stay are arbitrary predicates decided classically). ★ scan_predicateSchedule_state_eq

Raw-key execution and representation equivalence

This module gives the raw-key view of a compiled predicate-window scan (a noncomputable specification, since entry and stay are arbitrary predicates decided classically). Pending keys advance by takeWhile on entry, expired material is removed by dropWhile on stay, and surviving new keys use the same rightmost-stable monotone back pruning as the position implementation. The main theorem identifies every mapped position-level trace with this raw-key trace.

def keyedStream reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key list, a raw-key score, and an out-of-bounds fallback score determine the total position stream used by the generic deque. The fallback is never observed at a valid position.

Definition (Lean source)
ι :
Type u_1
shared
α :
Type u_3
shared
keys :
List ι
score :
ι → α
fallback :
α
keyedStream keys score fallback :
{ length := keys.length value := fun i => (keys[i]?).map score |>.getD fallback }
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.keyedStream · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:20 · uses Stream
def positionsToKeys reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key list and a list of natural positions determine the raw keys obtained by safe lookup of every in-bounds position.

Definition (Lean source)
ι :
Type u_1
shared
keys :
List ι
positions :
List
positionsToKeys keys positions :
List ι
positions.filterMap (fun i => keys[i]?)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.positionsToKeys · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:27
def rawPruneBack reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw score, a raw deque, and a new key determine the deque prefix after deleting its suffix of scores no larger than the new score.

Definition (Lean source)
ι :
Type u_1
shared
α :
Type u_3
shared
score :
ι → α
q :
List ι
x :
ι
rawPruneBack score q x :
List ι
q.rdropWhile (fun y => decide (score y ≤ score x))
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPruneBack · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:32
def rawPrunedBack reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw score, a raw deque, and a new key determine the keys removed from the back by the deterministic rightmost-stable tie policy.

Definition (Lean source)
ι :
Type u_1
shared
α :
Type u_3
shared
score :
ι → α
q :
List ι
x :
ι
rawPrunedBack score q x :
List ι
q.rtakeWhile (fun y => decide (score y ≤ score x))
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPrunedBack · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:37
def rawPush reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw score, a raw deque, and a new key determine one rightmost-stable monotone push; equal old scores are removed in favor of the new key.

Definition (Lean source)
ι :
Type u_1
shared
α :
Type u_3
shared
score :
ι → α
q :
List ι
x :
ι
rawPush score q x :
List ι
rawPruneBack score q x ++ [x]
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPush · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:42
structure RawPushBatch reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key type determines a batch record with the final key deque, the pushed keys, and the keys removed from the back.

Definition (Lean source)
ι :
Type*
state :
List ι
pushed :
List ι
backPopped :
List ι
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.RawPushBatch · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:47
def rawPushAll reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw score, together with an initial raw deque and a list of input keys, determines the recorded batch of rightmost-stable pushes, given by leaving an empty input list unchanged and pushing the first key before recursing on the remainder.

Definition (Lean source)
ι :
Type u_1
shared
α :
Type u_3
shared
score :
ι → α
rawPushAll score :
List ι → List ι → RawPushBatch ι
clause 1
| q, [] => { state := q, pushed := [], backPopped := [] }
clause 2
| q, x :: xs
=> let removed := rawPrunedBack score q x let rest := rawPushAll score (rawPush score q x) xs { state := rest.state pushed := x :: rest.pushed backPopped := removed ++ rest.backPopped }
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPushAll · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:54 · uses RawPushBatch
structure RawState reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key type determines a predicate-scan state with the unentered suffix and the current raw-key deque.

Definition (Lean source)
ι :
Type*
pending :
List ι
deque :
List ι
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.RawState · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:80
structure RawDequeTrace reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key type determines a deque-update trace with the deque before updating, the deque after expiration, the final deque, the pushed keys, the front-popped keys, and the back-popped keys.

Definition (Lean source)
ι :
Type*
before :
List ι
afterExpiration :
List ι
after :
List ι
pushed :
List ι
frontPopped :
List ι
backPopped :
List ι
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.RawDequeTrace · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:86
structure RawStepTrace reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key type and a step type determine a predicate-scan step record that extends a deque update with the current step, the pending suffix before updating, the pending suffix afterward, and the complete entered prefix before expiration filtering.

Definition (Lean source)
ι κ :
Type*
extends :
step :
κ
beforePending :
List ι
pending :
List ι
advanced :
List ι
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.RawStepTrace · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:97
def dequeTrace reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.RawStepTrace

A raw predicate step trace determines its exact generic-shaped deque trace.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
trace :
dequeTrace trace :
trace.toRawDequeTrace
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.RawStepTrace.dequeTrace · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:107 · uses RawDequeTrace , RawStepTrace
def rawUpdate reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule, a raw score, a step, and a raw state determine the next recorded raw-key update. It advances entry by takeWhile, removes the non-staying prefixes by dropWhile, and pushes precisely the surviving new suffix.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
α :
Type u_3
shared
keys :
List ι
shared
steps :
List κ
shared
P :
score :
ι → α
s :
κ
state :
rawUpdate P score s state :
by let advanced := state.pending.takeWhile (P.entryTest s) let pending := state.pending.dropWhile (P.entryTest s) let afterExpiration := state.deque.dropWhile (P.expiredTest s) let frontPopped := state.deque.takeWhile (P.expiredTest s) let survivingNew := advanced.dropWhile (P.expiredTest s) let batch := rawPushAll score afterExpiration survivingNew exact { step := s beforePending := state.pending pending := pending advanced := advanced before := state.deque afterExpiration := afterExpiration after := batch.state pushed := batch.pushed frontPopped := frontPopped backPopped := batch.backPopped }
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rawUpdate · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:111 · uses PredicateWindowSchedule , RawState , RawStepTrace
def rawScanFrom reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a raw score determine the raw trace obtained by folding over a supplied suffix of steps from a supplied state.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
α :
Type u_3
shared
keys :
List ι
shared
steps :
List κ
shared
P :
score :
ι → α
rawScanFrom P score :
RawState ι → List κ → List (RawStepTrace ι κ)
clause 1
| _, [] => []
clause 2
| state, s :: ss
=> let trace := P.rawUpdate score s state trace :: P.rawScanFrom score { pending := trace.pending, deque := trace.after } ss
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rawScanFrom · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:135 · uses PredicateWindowSchedule , RawState , RawStepTrace
def rawScan reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a raw score determine the complete raw-key scan from all keys pending and an empty deque.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
α :
Type u_3
shared
keys :
List ι
shared
steps :
List κ
shared
P :
score :
ι → α
rawScan P score :
P.rawScanFrom score { pending := keys, deque := [] } steps
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rawScan · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:145 · uses PredicateWindowSchedule , RawStepTrace
def mapStepTrace reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key list maps one generic position-level step to the exact raw-key deque trace by safe lookup in every list-valued field.

Definition (Lean source)
ι :
Type u_1
shared
α :
Type u_3
shared
keys :
List ι
stream :
trace :
StepTrace stream
mapStepTrace keys trace :
{ before := positionsToKeys keys trace.before afterExpiration := positionsToKeys keys trace.afterExpiration after := positionsToKeys keys trace.after pushed := positionsToKeys keys trace.pushed frontPopped := positionsToKeys keys trace.frontPopped backPopped := positionsToKeys keys trace.backPopped }
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.mapStepTrace · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:166 · uses RawDequeTrace , StepTrace , Stream
theorem scan_predicateSchedule_state_eq reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A predicate schedule, a raw-key score, and a fallback score have the generic position scan mapped through raw-key lookup exactly equal to the corresponding raw-key predicate scan, including every deque state and push/pop log.

Formal statement
ι :
Type u_1
shared
κ :
Type u_2
shared
α :
Type u_3
shared
keys :
List ι
shared
steps :
List κ
shared
P :
score :
ι → α
fallback :
α
(scan (keyedStream keys score fallback) P.schedule).map (mapStepTrace keys)
= (P.rawScan score).map RawStepTrace.dequeTrace
Proof (Lean source)
theorem scan_predicateSchedule_state_eq [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) : (scan (keyedStream keys score fallback) P.schedule).map (mapStepTrace keys) = (P.rawScan score).map RawStepTrace.dequeTrace := by have hpair : steps.Pairwise (fun s t => P.rightEndpoint s ≤ P.rightEndpoint t) := P.entry_step_mono.imp (fun h => P.rightEndpoint_mono_of_entry h) have hbridge := scanFrom_bridge P score fallback steps hpair 0 [] (by simp) (by simp) change (scanFrom (keyedStream keys score fallback) 0 initialDeque (steps.map P.windowAt)).map (mapStepTrace keys) = (P.rawScanFrom score { pending := keys, deque := [] } steps).map RawStepTrace.dequeTrace simpa [initialDeque, positionsToKeys] using hbridge
4 supporting declarations (lemmas, instances)
  • rawPush_getLast?_eq theorem — One raw rightmost-stable push has the newly pushed key as its final element, including when all old entries tie with it.
    ι :
    Type u_1
    shared
    α :
    Type u_3
    shared
    score :
    ι → α
    q :
    List ι
    x :
    ι
    (rawPush score q x).getLast? = some x
    Proof (Lean source)
    theorem rawPush_getLast?_eq [LinearOrder α] (score : ι → α) (q : List ι) (x : ι) : (rawPush score q x).getLast? = some x := by simp [rawPush]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPush_getLast?_eq · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:67
  • rawPrunedBack_score_le theorem — A key removed by rightmost-stable back pruning has score no larger than the newly pushed key, so equal-score ties deterministically favor the newer occurrence.
    ι :
    Type u_1
    shared
    α :
    Type u_3
    shared
    score :
    ι → α
    q :
    List ι
    x y :
    ι
    hy :
    y ∈ rawPrunedBack score q x
    score y ≤ score x
    Proof (Lean source)
    theorem rawPrunedBack_score_le [LinearOrder α] (score : ι → α) (q : List ι) (x y : ι) (hy : y ∈ rawPrunedBack score q x) : score y ≤ score x := by have h := List.mem_rtakeWhile_imp hy simpa [rawPrunedBack] using h
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPrunedBack_score_le · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:73
  • length_rawScan theorem — A predicate schedule and a raw score produce one raw trace entry per step.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    score :
    ι → α
    (P.rawScan score).length = steps.length
    Proof (Lean source)
    theorem PredicateWindowSchedule.length_rawScan [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) : (P.rawScan score).length = steps.length := by have hlength : ∀ (state : RawState ι) (ss : List κ), (P.rawScanFrom score state ss).length = ss.length := by intro state ss induction ss generalizing state with | nil => rfl | cons s ss ih => simp only [rawScanFrom, List.length_cons] rw [ih] exact hlength { pending := keys, deque := [] } steps
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.length_rawScan · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:151
  • scan_predicateSchedule_after_eq theorem — A predicate schedule, a raw score, a valid step position, and a fallback score have the generic deque after that step mapped through key lookup equal to the raw predicate-scan deque.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    score :
    ι → α
    fallback :
    α
    k :
    hk :
    k < steps.length
    ∃ generic raw,
    conclusion 1
    (scan (keyedStream keys score fallback) P.schedule)[k]? = some generic
    conclusion 2
    (P.rawScan score)[k]? = some raw
    conclusion 3
    positionsToKeys keys generic.after = raw.after
    Proof (Lean source)
    theorem scan_predicateSchedule_after_eq [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) {k : ℕ} (hk : k < steps.length) : ∃ generic raw, (scan (keyedStream keys score fallback) P.schedule)[k]? = some generic ∧ (P.rawScan score)[k]? = some raw ∧ positionsToKeys keys generic.after = raw.after := by let genericTrace := scan (keyedStream keys score fallback) P.schedule let rawTrace := P.rawScan score have hGenericLength : genericTrace.length = steps.length := by rw [show genericTrace.length = P.schedule.steps by exact length_scan (keyedStream keys score fallback) P.schedule] exact P.schedule_steps have hRawLength : rawTrace.length = steps.length := by exact P.length_rawScan score have hgk : k < genericTrace.length := by simpa [hGenericLength] using hk have hrk : k < rawTrace.length := by simpa [hRawLength] using hk let generic := genericTrace.get ⟨k, hgk⟩ let raw := rawTrace.get ⟨k, hrk⟩ refine ⟨generic, raw, ?_, ?_, ?_⟩ · exact List.getElem?_eq_getElem hgk · exact List.getElem?_eq_getElem hrk · have heq := congrArg (fun xs => xs[k]?) (scan_predicateSchedule_state_eq P score fallback) change (genericTrace.map (mapStepTrace keys))[k]? = (rawTrace.map RawStepTrace.dequeTrace)[k]? at heq simp only [List.getElem?_map, List.getElem?_eq_getElem hgk, List.getElem?_eq_getElem hrk, Option.map_some, Option.some.injEq] at heq exact congrArg RawDequeTrace.after heq
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.scan_predicateSchedule_after_eq · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateRawScan.lean:735
Passes 4 core · 2 supporting This module packages a constant number of independent schedules over the same finite stream. ★ totalCost_le

Fixed finite families of monotone-window passes

This module packages a constant number of independent schedules over the same finite stream. It exports per-pass correctness and the sum of the linear per-pass cost bounds, which is the interface needed by algorithms that run a fixed collection of monotone scans.

structure FixedPasses reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A stream and a finite pass count have a family of monotone-window schedules, one for each pass.

Definition (Lean source)
α :
Type u_1
shared
stream :
passes :
schedule :
Fin passes → Schedule stream.length
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Passes.lean:18 · uses Stream
def totalCost reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses

A fixed family of passes determines the sum of its individual scan costs.

Definition (Lean source)
α :
Type u_1
shared
passes :
family :
FixedPasses stream passes
totalCost family :
∑ p, scanCost stream (family.schedule p)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses.totalCost · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Passes.lean:23 · uses FixedPasses , Stream
def totalSteps reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses

A fixed family of passes determines its total number of scheduled windows.

Definition (Lean source)
α :
Type u_1
shared
passes :
family :
FixedPasses stream passes
totalSteps family :
∑ p, (family.schedule p).steps
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses.totalSteps · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Passes.lean:28 · uses FixedPasses , Stream
theorem totalCost_le reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses

A fixed family of passes ensures that its total cost is at most twice the pass count times stream length plus its total scheduled-window count.

Formal statement
α :
Type u_1
shared
passes :
family :
FixedPasses stream passes
family.totalCost ≤ 2 * passes * stream.length + family.totalSteps
Proof (Lean source)
theorem FixedPasses.totalCost_le {stream : Stream α} {passes : ℕ} (family : FixedPasses stream passes) : family.totalCost ≤ 2 * passes * stream.length + family.totalSteps := by unfold FixedPasses.totalCost FixedPasses.totalSteps calc ∑ p, scanCost stream (family.schedule p) ≤ ∑ p, (2 * stream.length + (family.schedule p).steps) := by classical induction (Finset.univ : Finset (Fin passes)) using Finset.induction_on with | empty => simp | @insert p s hp ih => simp only [Finset.sum_insert hp] exact Nat.add_le_add (scanCost_le stream (family.schedule p)) ih _ = 2 * passes * stream.length + ∑ p, (family.schedule p).steps := by simp [Finset.sum_add_distrib, Nat.mul_comm, Nat.mul_left_comm]
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses.totalCost_le · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Passes.lean:50 · uses FixedPasses , totalCost , totalSteps , Stream
2 supporting declarations (lemmas, instances)
  • head_value_eq_windowMax theorem — A fixed family of passes, a selected pass, a valid position in that pass, and a nonempty window there ensure that the scan head is an active argmax with the finite-window maximum value.
    α :
    Type u_1
    shared
    passes :
    family :
    FixedPasses stream passes
    p :
    Fin passes
    k :
    hk :
    k < (family.schedule p).steps
    hne :
    ((family.schedule p).windows.get ⟨k, hk⟩).left < ((family.schedule p).windows.get ⟨k, hk⟩).right
    ∃ step head tail,
    (scan stream (family.schedule p))[k]? = some step
    step.window = (family.schedule p).windows.get ⟨k, hk⟩
    step.after = head :: tail
    Active step.window head
    stream.value head = windowMax stream ((family.schedule p).windows.get ⟨k, hk⟩) hne
    conclusion 1
    i :
    Active step.window i
    stream.value i ≤ stream.value head
    Proof (Lean source)
    theorem FixedPasses.head_value_eq_windowMax {stream : Stream α} {passes : ℕ} (family : FixedPasses stream passes) (p : Fin passes) {k : ℕ} (hk : k < (family.schedule p).steps) (hne : ((family.schedule p).windows.get ⟨k, hk⟩).left < ((family.schedule p).windows.get ⟨k, hk⟩).right) : ∃ step head tail, (scan stream (family.schedule p))[k]? = some step ∧ step.window = (family.schedule p).windows.get ⟨k, hk⟩ ∧ step.after = head :: tailActive step.window head ∧ stream.value head = windowMax stream ((family.schedule p).windows.get ⟨k, hk⟩) hne ∧ ∀ i, Active step.window i → stream.value i ≤ stream.value head := by exact scan_head_value_eq_windowMax stream (family.schedule p) hk hne
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses.head_value_eq_windowMax · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Passes.lean:33
  • memory_le_windowWidth theorem — A fixed family of passes, a selected pass, and a valid position in that pass ensure that the corresponding state stores no more than its window width.
    α :
    Type u_1
    shared
    passes :
    family :
    FixedPasses stream passes
    p :
    Fin passes
    k :
    hk :
    k < (family.schedule p).steps
    ∃ step,
    conclusion 1
    (scan stream (family.schedule p))[k]? = some step
    conclusion 2
    step.after.length
    ≤ ((family.schedule p).windows.get ⟨k, hk⟩).right
    - ((family.schedule p).windows.get ⟨k, hk⟩).left
    Proof (Lean source)
    theorem FixedPasses.memory_le_windowWidth {stream : Stream α} {passes : ℕ} (family : FixedPasses stream passes) (p : Fin passes) {k : ℕ} (hk : k < (family.schedule p).steps) : ∃ step, (scan stream (family.schedule p))[k]? = some step ∧ step.after.length ≤ ((family.schedule p).windows.get ⟨k, hk⟩).right - ((family.schedule p).windows.get ⟨k, hk⟩).left := by exact scan_memory_le_windowWidth stream (family.schedule p) hk
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.FixedPasses.memory_le_windowWidth · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/Passes.lean:68
Predicate­Accounting 9 core · 6 supporting This module transfers the generic monotone-window deque's head-argmax, amortized operation count, and peak-storage results to predicate scans on sparse raw keys. ★ rawScan_head_argmax

Correctness and resource bounds for compiled raw-key scans

This module transfers the generic monotone-window deque's head-argmax, amortized operation count, and peak-storage results to predicate scans on sparse raw keys. It also packages a fixed finite family of such scans, providing the constant-number-of-passes interface used by consumers.

def rawTracePushed reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw predicate-scan trace determines the aggregate list of pushed raw keys.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
trace :
rawTracePushed trace :
List ι
trace.flatMap (fun step => step.pushed)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawTracePushed · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:22 · uses RawStepTrace
def rawTraceFrontPopped reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw predicate-scan trace determines the aggregate list of front-popped raw keys.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
trace :
rawTraceFrontPopped trace :
List ι
trace.flatMap (fun step => step.frontPopped)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawTraceFrontPopped · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:26 · uses RawStepTrace
def rawTraceBackPopped reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw predicate-scan trace determines the aggregate list of back-popped raw keys.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
trace :
rawTraceBackPopped trace :
List ι
trace.flatMap (fun step => step.backPopped)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawTraceBackPopped · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:31 · uses RawStepTrace
def rawDequeOperations reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw predicate-scan trace determines its exact number of deque mutations.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
trace :
rawDequeOperations trace :
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawDequeOperations · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:36 · uses RawStepTrace
def rawScanCost reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule

A predicate schedule and a raw score determine the raw scan cost, including one bookkeeping unit per step.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
α :
Type u_3
shared
keys :
List ι
shared
steps :
List κ
shared
P :
score :
ι → α
rawScanCost P score :
steps.length + rawDequeOperations (P.rawScan score)
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicateWindowSchedule.rawScanCost · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:41 · uses PredicateWindowSchedule
def rawPeakStored reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw predicate-scan trace determines the largest raw deque length reached.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
trace :
rawPeakStored trace :
(trace.map (fun step => step.after.length)).foldl max 0
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPeakStored · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:47 · uses RawStepTrace
theorem rawScan_head_argmax reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A predicate schedule, a raw score, a fallback score, a valid step position, and a nonempty raw predicate window ensure the raw deque head is an active score maximizer, with equal maxima resolved at the greatest key position.

Formal statement
ι :
Type u_1
shared
κ :
Type u_2
shared
α :
Type u_3
shared
keys :
List ι
shared
steps :
List κ
shared
P :
score :
ι → α
fallback :
α
k :
hk :
k < steps.length
hne :
∃ i : Fin keys.length,
P.entry (steps.get ⟨k, hk⟩) (keys.get i) ∧ P.stay (steps.get ⟨k, hk⟩) (keys.get i)
∃ (trace : RawStepTrace ι κ) (head : ι) (tail : List ι) (headPos : Fin keys.length),
(P.rawScan score)[k]? = some trace
trace.step = steps.get ⟨k, hk⟩
trace.after = head :: tail
head = keys.get headPos
P.entry (steps.get ⟨k, hk⟩) head
P.stay (steps.get ⟨k, hk⟩) head
conclusion 1
i :
Fin keys.length
P.entry (steps.get ⟨k, hk⟩) (keys.get i)
P.stay (steps.get ⟨k, hk⟩) (keys.get i)
score (keys.get i) ≤ score head
conclusion 2
i :
Fin keys.length
P.entry (steps.get ⟨k, hk⟩) (keys.get i)
P.stay (steps.get ⟨k, hk⟩) (keys.get i)
score (keys.get i) = score head
i.1 ≤ headPos.1
Proof (Lean source)
theorem rawScan_head_argmax [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) {k : ℕ} (hk : k < steps.length) (hne : ∃ i : Fin keys.length, P.entry (steps.get ⟨k, hk⟩) (keys.get i) ∧ P.stay (steps.get ⟨k, hk⟩) (keys.get i)) : ∃ (trace : RawStepTrace ι κ) (head : ι) (tail : List ι) (headPos : Fin keys.length), (P.rawScan score)[k]? = some trace ∧ trace.step = steps.get ⟨k, hk⟩ ∧ trace.after = head :: tail ∧ head = keys.get headPos ∧ P.entry (steps.get ⟨k, hk⟩) head ∧ P.stay (steps.get ⟨k, hk⟩) head ∧ (∀ i : Fin keys.length, P.entry (steps.get ⟨k, hk⟩) (keys.get i) → P.stay (steps.get ⟨k, hk⟩) (keys.get i) → score (keys.get i) ≤ score head) ∧ (∀ i : Fin keys.length, P.entry (steps.get ⟨k, hk⟩) (keys.get i) → P.stay (steps.get ⟨k, hk⟩) (keys.get i) → score (keys.get i) = score head → i.1 ≤ headPos.1) := by let stream := keyedStream keys score fallback have hks : k < P.schedule.steps := by simpa [P.schedule_steps] using hk have hwindowNonempty : (P.schedule.windows.get ⟨k, hks⟩).left < (P.schedule.windows.get ⟨k, hks⟩).right := by obtain ⟨i, hentry, hstay⟩ := hne have hactive := (P.active_schedule_iff hk i.isLt).mpr ⟨hentry, hstay⟩ exact lt_of_le_of_lt hactive.1 hactive.2 obtain ⟨generic, headIndex, posTail, hgeneric, hwindow, hposAfter, hheadActive, hmax⟩ := scan_head_argmax stream P.schedule hks hwindowNonempty obtain ⟨validTrace, hvalidTrace, hvalidWindow, hvalid⟩ := scan_valid_at stream P.schedule hks have hvg : validTrace = generic := Option.some.inj (hvalidTrace.symm.trans hgeneric) subst validTrace rw [hwindow] at hvalid rw [hwindow] at hheadActive hmax obtain ⟨bridgeGeneric, raw, hbridgeGeneric, hraw, hmapAfter⟩ := scan_predicateSchedule_after_eq P score fallback hk have hbg : bridgeGeneric = generic := Option.some.inj (hbridgeGeneric.symm.trans hgeneric) subst bridgeGeneric have hheadBound : headIndex < keys.length := by exact lt_of_lt_of_le hheadActive.2 (P.schedule.windows.get ⟨k, hks⟩).right_le_length let headPos : Fin keys.length := ⟨headIndex, hheadBound⟩ let rawTail := positionsToKeys keys posTail have hrawAfter : raw.after = keys.get headPos :: rawTail := by rw [← hmapAfter, hposAfter] simp [positionsToKeys, headPos, rawTail, List.getElem?_eq_getElem hheadBound] obtain ⟨rawAt, hrawAt, hrawStep⟩ := rawScanFrom_get_step P score { pending := keys, deque := [] } steps hk have hrawEq : rawAt = raw := by exact Option.some.inj (hrawAt.symm.trans hraw) subst rawAt have hheadPred : P.entry (steps.get ⟨k, hk⟩) (keys.get headPos) ∧ P.stay (steps.get ⟨k, hk⟩) (keys.get headPos) := by exact (P.active_schedule_iff hk hheadBound).mp hheadActive have hstreamValue (i : Fin keys.length) : stream.value i.1 = score (keys.get i) := by simp [stream, keyedStream] have hretainedEqHead : ∀ j ∈ generic.after, stream.value j = stream.value headIndex → j = headIndex := by intro j hj heq rw [hposAfter] at hj rcases List.mem_cons.mp hj with rfl | hj · rfl · have hdec := hvalid.value_decreasing rw [hposAfter] at hdec have hlt := (List.pairwise_cons.mp hdec).1 j hj exfalso exact (ne_of_lt hlt) heq refine ⟨raw, keys.get headPos, rawTail, headPos, hraw, hrawStep, hrawAfter, rfl, hheadPred.1, hheadPred.2, ?_, ?_⟩ · intro i hentry hstay have hactive := (P.active_schedule_iff hk i.isLt).mpr ⟨hentry, hstay⟩ have hv := hmax i.1 hactive calc score (keys.get i) = stream.value i.1 := (hstreamValue i).symm _ ≤ stream.value headIndex := hv _ = score (keys.get headPos) := hstreamValue headPos · intro i hentry hstay heq have hactive := (P.active_schedule_iff hk i.isLt).mpr ⟨hentry, hstay⟩ have hvalueEq : stream.value i.1 = stream.value headIndex := by calc stream.value i.1 = score (keys.get i) := hstreamValue i _ = score (keys.get headPos) := heq _ = stream.value headIndex := (hstreamValue headPos).symm by_cases hiq : i.1 ∈ generic.after · have := hretainedEqHead i.1 hiq hvalueEq simpa [headPos] using Nat.le_of_eq this · obtain ⟨j, hjq, hij, hvalue⟩ := hvalid.dominates_omitted i.1 hactive i.isLt hiq have hjactive := (hvalid.active j hjq).1 have hjle := hmax j hjactive have hjEq : stream.value j = stream.value headIndex := by exact le_antisymm hjle (by simpa [hvalueEq] using hvalue) have hjHead := hretainedEqHead j hjq hjEq subst j simpa [headPos] using le_of_lt hij
structure PredicatePasses reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque

A raw-key list, a step list, and a finite pass count determine a pass family with one predicate-window schedule per pass.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
keys :
List ι
steps :
List κ
passes :
pass :
Fin passes → PredicateWindowSchedule keys steps
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicatePasses · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:451
def totalRawCost reviewed
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicatePasses

A fixed predicate-pass family and a raw score determine the sum of the raw costs of all passes.

Definition (Lean source)
ι :
Type u_1
shared
κ :
Type u_2
shared
α :
Type u_3
shared
keys :
List ι
shared
steps :
List κ
shared
passes :
family :
PredicatePasses keys steps passes
score :
ι → α
totalRawCost family score :
∑ p, (family.pass p).rawScanCost score
Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicatePasses.totalRawCost · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:456 · uses PredicatePasses
6 supporting declarations (lemmas, instances)
  • rawScanCost_eq_scanCost theorem — A predicate schedule, a raw score, and a fallback score have raw operation cost exactly equal to the generic compiled position-scan cost.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    score :
    ι → α
    fallback :
    α
    P.rawScanCost score = scanCost (keyedStream keys score fallback) P.schedule
    Proof (Lean source)
    theorem rawScanCost_eq_scanCost [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) : P.rawScanCost score = scanCost (keyedStream keys score fallback) P.schedule := by let stream := keyedStream keys score fallback let generic := scan stream P.schedule let raw := P.rawScan score have hmap : generic.map (mapStepTrace keys) = raw.map RawStepTrace.dequeTrace := scan_predicateSchedule_state_eq P score fallback have hfields : ∀ trace ∈ generic, (∀ i ∈ trace.pushed, i < keys.length) ∧ (∀ i ∈ trace.frontPopped, i < keys.length) ∧ (∀ i ∈ trace.backPopped, i < keys.length) := by intro trace htrace have h := scan_fields_bound stream P.schedule trace htrace exact ⟨h.2.2.2.1, h.2.2.2.2.1, h.2.2.2.2.2⟩ have hpushed := positionsToKeys_flatMap_length_eq keys generic StepTrace.pushed (fun trace htrace => (hfields trace htrace).1) have hfront := positionsToKeys_flatMap_length_eq keys generic StepTrace.frontPopped (fun trace htrace => (hfields trace htrace).2.1) have hback := positionsToKeys_flatMap_length_eq keys generic StepTrace.backPopped (fun trace htrace => (hfields trace htrace).2.2) have hoperations := congrArg (fun ts : List (RawDequeTrace ι) => (ts.flatMap RawDequeTrace.pushed).length + (ts.flatMap RawDequeTrace.frontPopped).length + (ts.flatMap RawDequeTrace.backPopped).length) hmap simp only [List.flatMap_map, mapStepTrace, RawStepTrace.dequeTrace] at hoperations rw [hpushed, hfront, hback] at hoperations have hop : dequeOperations stream generic = rawDequeOperations raw := by simpa [dequeOperations, TracePushed, TraceFrontPopped, TraceBackPopped, rawDequeOperations, rawTracePushed, rawTraceFrontPopped, rawTraceBackPopped] using hoperations unfold PredicateWindowSchedule.rawScanCost scanCost have hs : P.schedule.steps = steps.length := P.schedule_steps change steps.length + rawDequeOperations raw = P.schedule.steps + dequeOperations stream generic omega
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawScanCost_eq_scanCost · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:216
  • rawPeakStored_eq_peakStored theorem — A predicate schedule, a raw score, and a fallback score have raw peak storage exactly equal to generic compiled position-scan peak storage.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    score :
    ι → α
    fallback :
    α
    rawPeakStored (P.rawScan score)
    = peakStored (keyedStream keys score fallback) (scan (keyedStream keys score fallback) P.schedule)
    Proof (Lean source)
    theorem rawPeakStored_eq_peakStored [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) : rawPeakStored (P.rawScan score) = peakStored (keyedStream keys score fallback) (scan (keyedStream keys score fallback) P.schedule) := by let stream := keyedStream keys score fallback let generic := scan stream P.schedule let raw := P.rawScan score have hmap : generic.map (mapStepTrace keys) = raw.map RawStepTrace.dequeTrace := scan_predicateSchedule_state_eq P score fallback have hlength : ∀ trace ∈ generic, (positionsToKeys keys trace.after).length = trace.after.length := by intro trace htrace exact positionsToKeys_length_eq keys trace.after (scan_fields_bound stream P.schedule trace htrace).2.2.1 have hafter := congrArg (fun ts : List (RawDequeTrace ι) => (ts.map (fun trace => trace.after.length)).foldl max 0) hmap simp only [List.map_map] at hafter change (generic.map (fun trace => (positionsToKeys keys trace.after).length)).foldl max 0 = (raw.map (fun trace => trace.after.length)).foldl max 0 at hafter have hmapped : generic.map (fun trace => (positionsToKeys keys trace.after).length) = generic.map (fun trace => trace.after.length) := by apply List.map_congr_left intro trace htrace exact hlength trace htrace rw [hmapped] at hafter simpa [rawPeakStored, peakStored, generic, raw, stream] using hafter.symm
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPeakStored_eq_peakStored · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:256
  • rawScanCost_le theorem — A predicate schedule, a raw score, and a fallback score ensure raw scan cost is at most twice the number of sparse keys plus the number of steps.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    score :
    ι → α
    fallback :
    α
    P.rawScanCost score ≤ 2 * keys.length + steps.length
    Proof (Lean source)
    theorem rawScanCost_le [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) : P.rawScanCost score ≤ 2 * keys.length + steps.length := by rw [rawScanCost_eq_scanCost P score fallback] simpa [keyedStream, P.schedule_steps] using scanCost_le (keyedStream keys score fallback) P.schedule
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawScanCost_le · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:287
  • rawPeakStored_le_length theorem — A predicate schedule, a raw score, and a fallback score ensure raw peak deque storage is at most the number of sparse keys.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    score :
    ι → α
    fallback :
    α
    rawPeakStored (P.rawScan score) ≤ keys.length
    Proof (Lean source)
    theorem rawPeakStored_le_length [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) : rawPeakStored (P.rawScan score) ≤ keys.length := by rw [rawPeakStored_eq_peakStored P score fallback] simpa [keyedStream] using peakStored_le_length (keyedStream keys score fallback) P.schedule
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawPeakStored_le_length · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:296
  • rawScan_memory_le_windowWidth theorem — A predicate schedule, a raw score, a fallback score, and a valid step position ensure the raw deque stored there is no wider than its compiled window.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    P :
    score :
    ι → α
    fallback :
    α
    k :
    hk :
    k < steps.length
    trace,
    conclusion 1
    (P.rawScan score)[k]? = some trace
    conclusion 2
    trace.after.length
    ≤ P.rightEndpoint (steps.get ⟨k, hk⟩) - P.leftEndpoint (steps.get ⟨k, hk⟩)
    Proof (Lean source)
    theorem rawScan_memory_le_windowWidth [LinearOrder α] (P : PredicateWindowSchedule keys steps) (score : ι → α) (fallback : α) {k : ℕ} (hk : k < steps.length) : ∃ trace, (P.rawScan score)[k]? = some trace ∧ trace.after.length ≤ P.rightEndpoint (steps.get ⟨k, hk⟩) - P.leftEndpoint (steps.get ⟨k, hk⟩) := by have hks : k < P.schedule.steps := by simpa [P.schedule_steps] using hk obtain ⟨generic, raw, hgeneric, hraw, hafter⟩ := scan_predicateSchedule_after_eq P score fallback hk obtain ⟨found, hfound, hlen⟩ := scan_memory_le_windowWidth (keyedStream keys score fallback) P.schedule hks have hfoundEq : found = generic := by exact Option.some.inj (hfound.symm.trans hgeneric) subst found refine ⟨raw, hraw, ?_⟩ have hgenericMem : generic ∈ scan (keyedStream keys score fallback) P.schedule := by rcases List.getElem?_eq_some_iff.mp hgeneric with ⟨hkg, heq⟩ exact List.mem_iff_getElem.mpr ⟨k, hkg, heq⟩ have hbound := (scan_fields_bound (keyedStream keys score fallback) P.schedule generic hgenericMem).2.2.1 have hmapLength := positionsToKeys_length_eq keys generic.after hbound rw [← hafter, hmapLength] have hwindow := P.schedule_window_get hk have hget : P.schedule.windows.get ⟨k, hks⟩ = P.windowAt (steps.get ⟨k, hk⟩) := by convert hwindow using 1 calc generic.after.length ≤ (P.schedule.windows.get ⟨k, hks⟩).right - (P.schedule.windows.get ⟨k, hks⟩).left := hlen _ = P.rightEndpoint (steps.get ⟨k, hk⟩) - P.leftEndpoint (steps.get ⟨k, hk⟩) := by rw [hget] rfl
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.rawScan_memory_le_windowWidth · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:305
  • totalRawCost_le theorem — A fixed predicate-pass family, a raw score, and a fallback score ensure total raw cost is at most twice pass count times key count plus pass count times step count.
    ι :
    Type u_1
    shared
    κ :
    Type u_2
    shared
    α :
    Type u_3
    shared
    keys :
    List ι
    shared
    steps :
    List κ
    shared
    passes :
    family :
    PredicatePasses keys steps passes
    score :
    ι → α
    fallback :
    α
    family.totalRawCost score ≤ 2 * passes * keys.length + passes * steps.length
    Proof (Lean source)
    theorem PredicatePasses.totalRawCost_le [LinearOrder α] {passes : ℕ} (family : PredicatePasses keys steps passes) (score : ι → α) (fallback : α) : family.totalRawCost score ≤ 2 * passes * keys.length + passes * steps.length := by unfold PredicatePasses.totalRawCost calc ∑ p, (family.pass p).rawScanCost score ≤ ∑ _p : Fin passes, (2 * keys.length + steps.length) := by apply Finset.sum_le_sum intro p hp exact rawScanCost_le (family.pass p) score fallback _ = 2 * passes * keys.length + passes * steps.length := by simp [Nat.mul_add, Nat.mul_left_comm, Nat.mul_comm]
    Causalean.Mathlib.Algorithms.MonotoneWindowDeque.PredicatePasses.totalRawCost_le · Causalean/Mathlib/Algorithms/MonotoneWindowDeque/PredicateAccounting.lean:462