Skip to content
Merged
Changes from 4 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
e7c3a35
push code
wkrozowski Oct 14, 2025
4b4aba5
stash work
wkrozowski Oct 14, 2025
fb6192e
push intermediate work
wkrozowski Oct 14, 2025
02b00a4
push intermediate work
wkrozowski Oct 15, 2025
7d1fc8e
First slice iterator correct
wkrozowski Oct 16, 2025
8767892
further verification work
wkrozowski Oct 16, 2025
71fecdd
progress
wkrozowski Oct 16, 2025
e957481
end of day push
wkrozowski Oct 16, 2025
05ba72e
left open iterator work
wkrozowski Oct 17, 2025
41780f7
Rcc slice
wkrozowski Oct 17, 2025
9f131d4
some golfing
wkrozowski Oct 17, 2025
87b9017
Add rxo iterator
wkrozowski Oct 17, 2025
c0e9549
Add Raw iterators
wkrozowski Oct 20, 2025
3c3bed7
minor changes
wkrozowski Oct 20, 2025
e6821e0
Add productiveness relation
wkrozowski Oct 20, 2025
e14d54c
Add `DTreeMap` iterators
wkrozowski Oct 20, 2025
83c2127
Add productiveness relation for the ordinary zipper
wkrozowski Oct 20, 2025
fe870d6
fix
wkrozowski Oct 20, 2025
a573195
Further refactor
wkrozowski Oct 21, 2025
0e59f32
Add rco
wkrozowski Oct 21, 2025
8618bca
add roc
wkrozowski Oct 21, 2025
e8e797b
Add rci
wkrozowski Oct 21, 2025
76f4f44
Add roi
wkrozowski Oct 21, 2025
c56bab2
Rii slice now works
wkrozowski Oct 21, 2025
f51bed2
module system issues
wkrozowski Oct 21, 2025
1568a15
see if it buiilds
wkrozowski Oct 21, 2025
72f6450
and slices for raw dtreemaps and their correctenss lemmas
wkrozowski Oct 21, 2025
fa7fcb8
chore: add imports to `Raw.lean`
wkrozowski Oct 21, 2025
5c3750d
Add 'DTreeMap' slices
wkrozowski Oct 21, 2025
9ef6ac3
some imports editing
wkrozowski Oct 21, 2025
351c2c1
dirty fix
wkrozowski Oct 21, 2025
123dcb1
Fix some imports
wkrozowski Oct 22, 2025
fcce3fa
Add imports to Raw
wkrozowski Oct 22, 2025
166f413
chore: rewrite map lemma
wkrozowski Oct 27, 2025
619cf51
minor cleanup
wkrozowski Oct 27, 2025
06ce30a
Rename correctness lemmas names
wkrozowski Oct 27, 2025
80727b5
Add simp lemmas to non-raw slice instances
wkrozowski Oct 27, 2025
bd4afe1
chore: refactor
wkrozowski Oct 27, 2025
b0cf25d
chore: rearrange files a bit
wkrozowski Oct 27, 2025
9278457
chore: further refactor
wkrozowski Oct 27, 2025
816e158
chore: remove productiveness instances
wkrozowski Oct 27, 2025
3e439f7
chore : fix user facing instances
wkrozowski Oct 27, 2025
b41c25e
chore: add comments
wkrozowski Oct 27, 2025
a7b5efc
chore: further renaming
wkrozowski Oct 27, 2025
c4dc8c7
Fix imports
wkrozowski Oct 28, 2025
465b91f
Add TreeMap iterators
wkrozowski Oct 28, 2025
f32d394
fix imports
wkrozowski Oct 28, 2025
8a91d04
push
wkrozowski Oct 28, 2025
298b7eb
chore: refactor
wkrozowski Oct 30, 2025
b9e7575
chore: refactor
wkrozowski Oct 30, 2025
008adc4
chore: refactor
wkrozowski Oct 30, 2025
f19e38b
Yet another const iterator is done
wkrozowski Oct 30, 2025
5d29dd6
chore: get const rco iterator working
wkrozowski Oct 30, 2025
0da49e9
TreeMap Raw slices are done
wkrozowski Oct 30, 2025
265ece2
chore TreeMap slices are done
wkrozowski Oct 30, 2025
a0e9f7c
chore: slices are done for treemaps
wkrozowski Oct 30, 2025
da87f95
TreeSet iterators
wkrozowski Oct 30, 2025
ddd85ef
feat: add `TreeSet` slices
wkrozowski Oct 30, 2025
9986361
chore: add iterator tests
wkrozowski Oct 30, 2025
8731535
Add slice unit tests
wkrozowski Oct 30, 2025
5f791c9
chore: address Markus' comments
wkrozowski Oct 31, 2025
6f3f00f
Fix some minor issues
wkrozowski Nov 10, 2025
d586985
Fix WF impliciteness
wkrozowski Nov 10, 2025
980a18b
Update src/Std/Data/TreeSet/Iterator.lean
wkrozowski Nov 11, 2025
95f5d36
Merge branch 'master' into wojciech/treemap_iterators
wkrozowski Nov 11, 2025
af9c7ed
chore: merge with master
wkrozowski Nov 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
332 changes: 332 additions & 0 deletions src/Std/Data/DTreeMap/Slice.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Wojciech Rozowski
-/
module

prelude
public import Init.Data.Iterators.Basic
public import Init.Data.Iterators.Consumers
public import Std.Data.Iterators.Lemmas.Producers.Slice
public import Init.Data.Slice
public import Init.Data.Range.Polymorphic.Basic
public import Std.Data.DTreeMap

namespace Std.DTreeMap
open Std.Iterators

public def Internal.Impl.treeSize : Internal.Impl α β → Nat
| .leaf => 0
| .inner _ _ _ l r => 1 + l.treeSize + treeSize r

section MapIterator
public inductive Zipper (α : Type u) (β : α → Type v) where
| done
| cons (k : α) (v : β k) (tree : Internal.Impl α β) (next : Zipper α β)

variable {α : Type u} {β : α → Type v}

public def Zipper.toList : Zipper α β → List ((a : α) × β a)
| .done => []
| .cons k v tree next => ⟨k,v⟩ :: tree.toList ++ next.toList

public def Zipper.keys : Zipper α β → List α
| .done => []
| .cons k _ tree next => k :: tree.keys ++ next.keys

def Zipper.size : Zipper α β → Nat
| .done => 0
| .cons _ _ tree next => 1 + tree.treeSize + next.size

public def Zipper.WF [Ord α] : Zipper α β → Prop
| .done => True
| .cons k _ tree next => tree.keys.all (fun key => (compare key k).isLE) ∧ next.keys.all (fun key => (compare key k).isLE)

public def Zipper.prependMap : Internal.Impl α β → Zipper α β → Zipper α β
| .leaf, it => it
| .inner _ k v l r, it => prependMap l (.cons k v r it)

theorem prependMap_WF_inv [Ord α] [TransOrd α] {t : Internal.Impl α β} {wf : Internal.Impl.WF t} {z : Zipper α β} {z_wf : Zipper.WF z} : Zipper.WF (Zipper.prependMap t z) := by
induction t generalizing z
case leaf =>
simp [Zipper.prependMap]
exact z_wf
case inner _ k v l r l_ih r_ih =>
simp [Zipper.prependMap]
apply l_ih
. sorry
. constructor
sorry
sorry

public theorem Zipper.prependMap_to_list (t : Internal.Impl α β) (it : Zipper α β) : (Zipper.prependMap t it).toList = t.toList ++ it.toList := by
induction t generalizing it
case leaf =>
simp [prependMap, Internal.Impl.toList_eq_toListModel]
case inner _ k v l r l_ih r_ih =>
simp only [Zipper.prependMap]
specialize l_ih (Zipper.cons k v r it)
rw [l_ih]
simp [toList, Internal.Impl.toList_eq_toListModel]

theorem Zipper.prependMap_size (t : Internal.Impl α β) (it : Zipper α β) : (Zipper.prependMap t it).size = t.treeSize + it.size := by
fun_induction Zipper.prependMap
case case1 =>
simp only [Internal.Impl.treeSize, Nat.zero_add]
case case2 size k v l r it ih =>
simp only [ih, Zipper.size, Internal.Impl.treeSize, ← Nat.add_assoc, Nat.add_comm]

end MapIterator

section Rxc

public structure RxcIterator (α : Type u) (β : α → Type v) (cmp : α → α → Ordering) where
iter : Zipper α β
upper : α

variable {α : Type u} {β : α → Type v}

public def RxcIterator.inBounds {cmp : α → α → Ordering} (it : RxcIterator α β cmp) (k : α) : Bool :=
(cmp k it.upper).isLE

public def RxcIterator.step {cmp : α → α → Ordering} : RxcIterator α β cmp → IterStep (IterM (α := RxcIterator α β cmp) Id ((a : α) × β a)) ((a : α) × β a)
| ⟨.done, _⟩ => .done
| ⟨.cons k v t it, upper⟩ =>
if (cmp k upper).isLE then
.yield ⟨it.prependMap t, upper⟩ ⟨k, v⟩
else
.done

public instance : Iterator (RxcIterator α β cmp) Id ((a : α) × β a) where
IsPlausibleStep it step := it.internalState.step = step
step it := ⟨it.internalState.step, rfl⟩

public instance : IteratorCollect (RxcIterator α β cmp) Id Id := .defaultImplementation

public instance : IteratorCollectPartial (RxcIterator α β cmp) Id Id := .defaultImplementation

def instFinitenessRelation : FinitenessRelation (RxcIterator α β cmp) Id where
rel t' t := t'.internalState.iter.size < t.internalState.iter.size
wf := by
apply InvImage.wf
exact Nat.lt_wfRel.wf
subrelation {it it'} h := by
obtain ⟨w, h, h'⟩ := h
simp only [IterM.IsPlausibleStep, Iterator.IsPlausibleStep] at h'
cases w
case skip it'' =>
cases h
simp only [RxcIterator.step] at h'
split at h'
any_goals contradiction
. split at h'
all_goals contradiction
case done =>
cases h
case yield it'' out =>
cases h
simp [RxcIterator.step] at h'
split at h'
case h_1 =>
contradiction
case h_2 h2 =>
split at h'
case isFalse =>
contradiction
case isTrue heq =>
simp at h'
simp only [h2, ← h'.1, Zipper.prependMap_size, Zipper.size, Nat.add_lt_add_iff_right,
Nat.lt_add_left_iff_pos, Nat.lt_add_one]

@[no_expose]
public instance instFinite : Finite (RxcIterator α β cmp) Id :=
.of_finitenessRelation instFinitenessRelation

public theorem toList_lemma {it : Iter (α := RxcIterator α β cmp) ((a : α) × β a)} : it.toList = it.internalState.iter.toList.filter (fun e => (cmp e.fst bound).isLE) := by
unfold Iter.toList
simp [Iter.toIterM]
unfold Iter.internalState
simp [instIteratorCollectRxcIteratorIdSigma]
sorry

public theorem step_rxcIterator_eq_match {cmp : α → α → Ordering} {it : IterM (α := RxcIterator α β cmp) Id ((a : α) × β a)} :
it.step = ⟨match it.internalState with
| { iter := Zipper.done, upper := _ } => IterStep.done
| { iter := Zipper.cons k v t it, upper := upper } =>
if (cmp k upper).isLE = true then
IterStep.yield { internalState := { iter := Zipper.prependMap t it, upper := upper } } ⟨k, v⟩
else IterStep.done,
(by simp only [IterM.IsPlausibleStep, Iterator.IsPlausibleStep, RxcIterator.step]; split; all_goals (rename_i heq; simp only [heq]))⟩ := by
simp [IterM.step, Iterator.step, RxcIterator.step]
ext
congr 1

public structure RicSliceData (α : Type u) (β : α → Type v) (cmp : α → α → Ordering := by exact compare) where
treeMap : DTreeMap.Raw α β cmp
range : Ric α

public abbrev RicSlice α β cmp := Slice (RicSliceData α β cmp)

public instance : Ric.Sliceable (DTreeMap.Raw α β cmp) α (RicSlice α β cmp) where
mkSlice carrier range := ⟨carrier, range⟩

@[always_inline]
public def RicSlice.Internal.iterM (s : RicSlice α β cmp) : IterM (α := RxcIterator α β cmp) Id ((a : α) × β a) :=
⟨⟨Zipper.done.prependMap s.1.treeMap.inner, s.1.range.upper⟩⟩

public instance {s : RicSlice α β cmp} : ToIterator s Id ((a : α) × β a) where
State := RxcIterator α β cmp
iterMInternal := RicSlice.Internal.iterM s

def test : DTreeMap.Raw Nat (fun _ => Nat) compare := .ofList [⟨0, 0⟩, ⟨1, 1⟩, ⟨100, 3⟩, ⟨101, 4⟩]

-- RxcIterator α β cmp
public theorem step_iter_ricSlice_eq_match {α β} {cmp : α → α → Ordering} {t : DTreeMap.Raw α β cmp} {a b : α} :
t[*...=b].iter.step = ⟨match ({ iter := Zipper.prependMap t.inner Zipper.done, upper := b } : RxcIterator α β cmp) with
| { iter := Zipper.done, upper := upper } => IterStep.done
| { iter := Zipper.cons k v t it, upper := upper } =>
if (cmp k upper).isLE = true then
IterStep.yield { internalState := { iter := Zipper.prependMap t it, upper := upper } } ⟨k, v⟩
else IterStep.done, (sorry)⟩ := by
rw [Slice.iter_eq_toIteratorIter]
simp only [Ric.Sliceable.mkSlice, instSliceableRawRicSlice, RicSlice.Internal.iterM, ToIterator.iter_eq, IterM.toIter, Iter.step]
rw [step_rxcIterator_eq_match]
simp only [Iter.toIterM]
simp only [IterM.Step.toPure, IterStep.mapIterator, Id.run]
congr
split
case h_1 =>
rename_i heq
split at heq
any_goals contradiction
. rename_i heq2
simp at heq2
split at heq
. simp at heq
rename_i heq3
simp [heq3, ← heq.1, heq.2, IterM.toIter]
. contradiction
case h_2 =>
rename_i heq
split at heq
any_goals contradiction
. rename_i heq
split at heq
. contradiction
. contradiction
case h_3 =>
rename_i heq
split at heq
any_goals trivial
split at heq
. contradiction
. rename_i heq2
simp [heq2]

public theorem toList_rocSlice_eq_filter_toList {α β} {cmp : α → α → Ordering}
{t : DTreeMap.Raw α β cmp} (h : t.WF) {bound : α} :
t[*...=bound].toList = t.toList.filter (fun e => (cmp e.fst bound).isLE) := by
simp only [Slice.toList_eq_toList_iter]
rw [Iter.toList_eq_match_step]
rw [step_iter_ricSlice_eq_match]
split
case h_1 x it' out heq =>
split at heq
any_goals contradiction
rename_i x' k v t it upper heq2
simp at heq2
split at heq
any_goals contradiction
simp at heq
rename_i isLE
rename_i t'
have ⟨heq₁, heq₂⟩ := heq
rw [← heq₂]
have := @Zipper.prependMap_to_list α β t'.inner .done
rw [heq2.1] at this
simp [Zipper.toList] at this
rw [← heq₁]
have toList_lemma := @toList_lemma α β cmp bound { internalState := { iter := Zipper.prependMap t it, upper := upper } }
simp at toList_lemma
rw [toList_lemma]
simp only [Raw.toList]
rw [← this]
simp only [List.filter, isLE, heq2.2]
congr
simp [Zipper.prependMap_to_list]
case h_2 =>
rename_i heq
split at heq
any_goals contradiction
. split at heq
any_goals contradiction
case h_3 x heq =>
split at heq
case h_1 it upper heq2 =>
simp at heq2
unfold Zipper.prependMap at heq2
split at heq2
. rename_i eq_empty
simp only [Raw.toList]
rw [eq_empty]
rw [Internal.Impl.toList_eq_toListModel]
simp only [Internal.Impl.toListModel_leaf, List.filter_nil]
. rename_i t₁ t₂ _ k v l r heq3
replace heq2 := heq2.1
sorry
case h_2 x' k v t it upper heq2 =>
split at heq
. contradiction
. rename_i t' notLE
simp at heq2
have ⟨heq2₁, heq2₂⟩ := heq2
clear heq2
have prependMap_to_List := @Zipper.prependMap_to_list α β t'.inner Zipper.done
simp [heq2₁, Zipper.toList] at prependMap_to_List
simp only [Raw.toList]
rw [← prependMap_to_List]
simp only [List.filter]
rw [← heq2₂] at notLE
simp only [notLE]

sorry
exact bound

































#eval test[*...=1].toList


end Rxc
end Std.DTreeMap
Loading