Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
186 commits
Select commit Hold shift + click to select a range
7c47d30
initial commit
tannerduve Dec 5, 2025
c0c3426
fix up docs
tannerduve Dec 5, 2025
a5389ab
docs
tannerduve Dec 5, 2025
a32b00d
fix up
tannerduve Dec 5, 2025
927e4e8
Merge branch 'main' into query-complexity-freeM
tannerduve Dec 5, 2025
c8d3206
effects fix
tannerduve Dec 5, 2025
9c3c26c
Add TimeM time/cost monad
tannerduve Dec 5, 2025
2136afe
Add TimeM time/cost monad
tannerduve Dec 5, 2025
f5397b0
rename
tannerduve Dec 5, 2025
9e6fcd4
update cslib.lean
tannerduve Dec 5, 2025
9381b9a
Test PR to PR ability with doc comment
Shreyas4991 Dec 6, 2025
aeed9a7
Yet to fix monad instance issue in timeProg function
Shreyas4991 Dec 6, 2025
b8c9a1e
Remove unnecessary instance
Shreyas4991 Dec 6, 2025
9f1ba8a
monadLift instance needed
Shreyas4991 Dec 6, 2025
80c704d
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Jan 8, 2026
c1fb032
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Jan 13, 2026
5e1eb09
Need to restart
Shreyas4991 Jan 20, 2026
ba95a81
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Jan 20, 2026
aaf1d87
Revert to FreeM, but use extra type param
Shreyas4991 Jan 21, 2026
3267a70
Some progress on the example
Shreyas4991 Jan 21, 2026
48755f0
Dangers of using only pure ops
Shreyas4991 Jan 21, 2026
da183e1
experiments
Shreyas4991 Jan 22, 2026
29a5908
Simple example
Shreyas4991 Jan 22, 2026
65d820d
Simple example
Shreyas4991 Jan 22, 2026
6c2835f
Developing array sort example
Shreyas4991 Jan 22, 2026
0684bdd
Developing array sort example
Shreyas4991 Jan 22, 2026
b8c18b0
Vectors
Shreyas4991 Jan 22, 2026
f859a41
Vectors
Shreyas4991 Jan 22, 2026
912890d
Made coercions work. Added custom cost structures
Shreyas4991 Jan 22, 2026
734747c
Comment out mergesort.lean for now
Shreyas4991 Jan 22, 2026
e77ef9b
Comment out mergesort.lean for now
Shreyas4991 Jan 22, 2026
e831672
Comment out mergesort.lean for now
Shreyas4991 Jan 22, 2026
68bdf55
Comment out mergesort.lean for now
Shreyas4991 Jan 22, 2026
93dae2c
Try removing #evals to check build
Shreyas4991 Jan 22, 2026
9ef8f16
remove #evals
Shreyas4991 Jan 22, 2026
b7a95d5
Model is a structure now
Shreyas4991 Jan 23, 2026
8973608
Remove redundant TimeM interpretation in the beginning. The TimeM sec…
Shreyas4991 Jan 23, 2026
e4407cc
Cslib.Init imports
Shreyas4991 Jan 23, 2026
c59aa5d
Set up linear search example. Only theorem statements. Proofs come later
Shreyas4991 Jan 23, 2026
903f5e4
extra space removed
Shreyas4991 Jan 23, 2026
b8e89df
Let's tail-recursive linear search. It is still monadic
Shreyas4991 Jan 23, 2026
d7fa83e
Author and license stuff
Shreyas4991 Jan 23, 2026
c1061d3
Another attempt at proofs
Shreyas4991 Jan 24, 2026
2535336
Let's count pure oerations as well
Shreyas4991 Jan 24, 2026
fb185b9
Let's count pure oerations as well
Shreyas4991 Jan 24, 2026
3bf4db0
Add missing public annotation to import in CSLib
Shreyas4991 Jan 24, 2026
5ca8828
Address some review comments
Shreyas4991 Jan 24, 2026
22a5af4
List linear search proofs were simpler
Shreyas4991 Jan 25, 2026
7ef2750
Try Vector proofs by list induction
Shreyas4991 Jan 25, 2026
72a74c7
Split the files
Shreyas4991 Jan 25, 2026
c2529f7
Add copyright header
Shreyas4991 Jan 25, 2026
db100ea
Improve docs
Shreyas4991 Jan 25, 2026
6462145
Circuit complexitygit add *!
Shreyas4991 Jan 26, 2026
5acdf88
add copyright comment to CircuitProgs.lean
Shreyas4991 Jan 26, 2026
2888f3d
Circuits with automatic IDs
Shreyas4991 Jan 28, 2026
7532c85
Eric's suggestion
Shreyas4991 Jan 28, 2026
36abc2f
Done
Shreyas4991 Feb 3, 2026
72d96fc
Circuits works
Shreyas4991 Feb 3, 2026
d472ff5
Circuits works
Shreyas4991 Feb 3, 2026
c965ec7
Update MergeSort.lean
Shreyas4991 Feb 5, 2026
0a8316d
Organise:
Shreyas4991 Feb 14, 2026
a644c1c
Move the old Algorithms Folder to AlgorithmsTheory
Shreyas4991 Feb 14, 2026
e99f82c
Fix stuff
Shreyas4991 Feb 16, 2026
4d0b7a1
AddCommSemigroup is the right Cost structure
Shreyas4991 Feb 17, 2026
86b608c
AddCommSemigroup
Shreyas4991 Feb 17, 2026
83ae820
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Feb 17, 2026
cba2fba
pull main branch
Shreyas4991 Feb 17, 2026
ea0f6bb
Sorry out proofs for now
Shreyas4991 Feb 17, 2026
b4de3d5
The proof of insertOrd_complexity_upper_bound is AI slop. But it sugg…
Shreyas4991 Feb 17, 2026
16466dc
The proof of insertOrd_complexity_upper_bound is AI slop. But it sugg…
Shreyas4991 Feb 17, 2026
12bc143
Extract nice lemmas
Shreyas4991 Feb 17, 2026
a9814ba
Extract nice lemmas
Shreyas4991 Feb 17, 2026
1d231c7
Insertion Sort done
Shreyas4991 Feb 18, 2026
03bdd09
Remove #checks
Shreyas4991 Feb 18, 2026
f530a75
Clean up merge sort
Shreyas4991 Feb 18, 2026
9ff1ebc
Clean up merge sort
Shreyas4991 Feb 18, 2026
a36cf06
More work to be done
Shreyas4991 Feb 18, 2026
fbb8f30
More work to be done
Shreyas4991 Feb 18, 2026
1e67a97
Simplify this PR. Use AddCommMonoid for now
Shreyas4991 Feb 20, 2026
790bf06
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Feb 20, 2026
048738e
Toolchain update
Shreyas4991 Feb 20, 2026
ceca5eb
Remove graph files
Shreyas4991 Feb 20, 2026
77d5132
remove extraneous TimeM.lean
Shreyas4991 Feb 20, 2026
efe79bf
Restore the OG TimeM under Lean subfolder
Shreyas4991 Feb 20, 2026
c6ed278
Remove changes in Free/Effects.lean
Shreyas4991 Feb 20, 2026
d6076ff
Check toplevel file
Shreyas4991 Feb 20, 2026
e4fc337
Changes to import paths of TimeM
Shreyas4991 Feb 20, 2026
f9ab544
Only mergeSort_complexity remains
Shreyas4991 Feb 20, 2026
764749a
Build okay
Shreyas4991 Feb 20, 2026
04582c1
Done
Shreyas4991 Feb 20, 2026
1598685
Lint passes locally
Shreyas4991 Feb 20, 2026
cc27876
Ran lake exe mk_all --module
Shreyas4991 Feb 20, 2026
1b44e04
Remove Dead Code
Shreyas4991 Feb 20, 2026
9a3b3e0
Fix docstring of mergeNaive
Shreyas4991 Feb 20, 2026
af3a8d1
Use the ML definition-by-match-expression formal for defining evalQue…
Shreyas4991 Feb 20, 2026
85bf956
Fix Indent in Prog
Shreyas4991 Feb 20, 2026
a1731e6
Fix line breaks
Shreyas4991 Feb 20, 2026
7293c63
Fix line breaks
Shreyas4991 Feb 20, 2026
8c1a33a
Fix line breaks
Shreyas4991 Feb 20, 2026
a32bb22
OrderedInsert fixed
Shreyas4991 Feb 21, 2026
9cecfae
All ready
Shreyas4991 Feb 21, 2026
5db32aa
All ready
Shreyas4991 Feb 21, 2026
6808a44
Take the example suggestion. But this kinda defeats the point of that…
Shreyas4991 Feb 21, 2026
0443b0f
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Feb 21, 2026
d9f105a
Some indentation rule fixes
Shreyas4991 Feb 22, 2026
de4be8d
Round one
Shreyas4991 Feb 22, 2026
cd56656
nlinarith not needed. linarith is enough
Shreyas4991 Feb 22, 2026
523bd8c
insertOrd_complexity_upper_bound has a shorter proof
Shreyas4991 Feb 22, 2026
5a165cc
use simp only's
Shreyas4991 Feb 22, 2026
fcf4b3c
Golf some mergeSort proofs with grind
Shreyas4991 Feb 23, 2026
29a8d96
Golf some mergeSort proofs with grind
Shreyas4991 Feb 23, 2026
26b2f15
fix naming in test files
Shreyas4991 Feb 23, 2026
ac25d60
Fix names
Shreyas4991 Feb 23, 2026
fc281c6
Linebreak
Shreyas4991 Feb 23, 2026
a1733b9
acsSortOps
Shreyas4991 Feb 23, 2026
5a6137a
Instances improved. API lemmas for sortOps moved to sortops file
Shreyas4991 Feb 23, 2026
8eefce5
remove Id.run and pure and bind from simp lemma sets
Shreyas4991 Feb 23, 2026
e62cc44
Fix docblame error
Shreyas4991 Feb 23, 2026
6b88832
TimeM abbrev added. Prog.time untouched
Shreyas4991 Feb 23, 2026
63680f1
One sorry remains
Shreyas4991 Feb 23, 2026
174e86b
Apparently induction syntax is better
Shreyas4991 Feb 23, 2026
e13c74b
sorry free again
Shreyas4991 Feb 23, 2026
8144aac
sorry free again
Shreyas4991 Feb 23, 2026
43373c6
sorry free again
Shreyas4991 Feb 23, 2026
fd4f8bd
sorry free again
Shreyas4991 Feb 23, 2026
d2f8a2f
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Feb 23, 2026
7f2ca28
docstring
Shreyas4991 Feb 23, 2026
7e57d15
Docstring
Shreyas4991 Feb 23, 2026
ac70600
Some review fixes
Shreyas4991 Feb 23, 2026
0011bde
Other review fixes
Shreyas4991 Feb 23, 2026
afa3b0b
Other review fixes
Shreyas4991 Feb 23, 2026
e0d71ba
Manual inlines
Shreyas4991 Feb 23, 2026
7f939eb
rfls
Shreyas4991 Feb 23, 2026
9be8cb6
rfls
Shreyas4991 Feb 23, 2026
03a11f9
rfls
Shreyas4991 Feb 23, 2026
e833073
remove some instance names
Shreyas4991 Feb 23, 2026
b14e423
fix
Shreyas4991 Feb 24, 2026
ec83b8c
correctness as a single theorem
Shreyas4991 Feb 24, 2026
f869355
correctness as a single theorem
Shreyas4991 Feb 24, 2026
9420e1d
fewer intros in insertOrd
Shreyas4991 Feb 24, 2026
b793973
Unname instances
Shreyas4991 Feb 24, 2026
971e825
Removed (m := Id) in favour of Id.run)
Shreyas4991 Feb 24, 2026
eca91b3
Using Equiv instance for SortOpsCost with Nat pair
Shreyas4991 Feb 24, 2026
d67d698
Simplify Prog.bind_pure and Prog.pure_bind
Shreyas4991 Feb 24, 2026
fa6980f
BEq can be better that decidableEq for equality
Shreyas4991 Feb 24, 2026
d1faebb
BEq can be better that decidableEq for equality
Shreyas4991 Feb 24, 2026
786dbb3
simps
Shreyas4991 Feb 24, 2026
193f4e8
simps
Shreyas4991 Feb 24, 2026
66d24fa
simps
Shreyas4991 Feb 24, 2026
77646e8
Remove mergeNaive
Shreyas4991 Feb 24, 2026
16e08b3
Fix instruction docs
Shreyas4991 Feb 24, 2026
b70c432
made mergeSortNaive private
Shreyas4991 Feb 24, 2026
0f93390
fix doc typo
Shreyas4991 Feb 24, 2026
22e6bfa
naming
Shreyas4991 Feb 24, 2026
7a4a6a4
Fix induction proofs and add missing pures
eric-wieser Feb 24, 2026
41d5380
substantially golf proofs
eric-wieser Feb 24, 2026
2d4cb11
Merge branch 'main' of github.com:leanprover/cslib into query-complex…
Shreyas4991 Feb 24, 2026
f80426f
golf
eric-wieser Feb 24, 2026
d8c9c60
more golf
eric-wieser Feb 24, 2026
c617b92
more
eric-wieser Feb 24, 2026
99b39c3
mergeSortNaive_Perm
Shreyas4991 Feb 24, 2026
24a396b
mergeSort_Perm
Shreyas4991 Feb 24, 2026
df89dcf
mergeSort_Perm
Shreyas4991 Feb 24, 2026
0ea351b
golf further
eric-wieser Feb 24, 2026
b96744d
generalize to total partial orders, to allow stability claims
eric-wieser Feb 24, 2026
93b9135
fix whitespace, use notation
eric-wieser Feb 24, 2026
c19709e
whitespace and docstrings
eric-wieser Feb 25, 2026
013464c
. in docstrings
eric-wieser Feb 25, 2026
d701068
generalize theorems
eric-wieser Feb 25, 2026
ac2b2b0
Deduplicate proofs
eric-wieser Feb 25, 2026
3917fea
Use SortOpsNat with only cmpLE for mergeSort
Shreyas4991 Feb 25, 2026
ae1cbca
Use SortOpsCmp with only cmpLE for mergeSort
Shreyas4991 Feb 25, 2026
597f4de
Fix line lengths in linear search
Shreyas4991 Feb 25, 2026
f1e1496
insertOrd module docstring
Shreyas4991 Feb 25, 2026
2bcedcb
insertionSort module docstring
Shreyas4991 Feb 25, 2026
e245e21
mergeSort module docstring
Shreyas4991 Feb 25, 2026
e7e24cb
mergeSort module docstring
Shreyas4991 Feb 25, 2026
3ce1856
linear search docstring
Shreyas4991 Feb 25, 2026
cb28606
linear search docstring
Shreyas4991 Feb 25, 2026
34ac82c
Fix comments
Shreyas4991 Feb 25, 2026
ab68694
fix style in tests
eric-wieser Feb 25, 2026
022eea9
Universe generalizations
eric-wieser Feb 25, 2026
79d8dea
deduplicate example code
eric-wieser Feb 25, 2026
163c589
style tweaks and typo
eric-wieser Feb 25, 2026
929cf67
further deduplicate tests
eric-wieser Feb 25, 2026
4b08676
simp in examples
eric-wieser Feb 25, 2026
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
11 changes: 9 additions & 2 deletions Cslib.lean
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
module -- shake: keep-all

public import Cslib.Algorithms.Lean.MergeSort.MergeSort
public import Cslib.Algorithms.Lean.TimeM
public import Cslib.AlgorithmsTheory.Algorithms.ListInsertionSort
public import Cslib.AlgorithmsTheory.Algorithms.ListLinearSearch
public import Cslib.AlgorithmsTheory.Algorithms.ListOrderedInsert
public import Cslib.AlgorithmsTheory.Algorithms.MergeSort
public import Cslib.AlgorithmsTheory.Lean.MergeSort.MergeSort
public import Cslib.AlgorithmsTheory.Lean.TimeM
public import Cslib.AlgorithmsTheory.Models.ListComparisonSearch
public import Cslib.AlgorithmsTheory.Models.ListComparisonSort
public import Cslib.AlgorithmsTheory.QueryModel
public import Cslib.Computability.Automata.Acceptors.Acceptor
public import Cslib.Computability.Automata.Acceptors.OmegaAcceptor
public import Cslib.Computability.Automata.DA.Basic
Expand Down
100 changes: 100 additions & 0 deletions Cslib/AlgorithmsTheory/Algorithms/ListInsertionSort.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/-
Copyright (c) 2026 Shreyas Srinivas. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Shreyas Srinivas, Eric Wieser
-/
module

public import Cslib.AlgorithmsTheory.QueryModel
public import Cslib.AlgorithmsTheory.Algorithms.ListOrderedInsert
public import Mathlib

@[expose] public section

/-!
# Insertion sort in a list

In this file we state and prove the correctness and complexity of insertion sort in lists under
the `SortOps` model. This insertionSort evaluates identically to the upstream version of
`List.insertionSort`
--

## Main Definitions

- `insertionSort` : Insertion sort algorithm in the `SortOps` query model

## Main results

- `insertionSort_eval`: `insertionSort` evaluates identically to `List.insertionSort`.
- `insertionSort_permutation` : `insertionSort` outputs a permutation of the input list.
- `insertionSort_sorted` : `insertionSort` outputs a sorted list.
- `insertionSort_complexity` : `insertionSort` takes at most n * (n + 1) comparisons and
(n + 1) * (n + 2) list head-insertions.
-/

namespace Cslib

namespace Algorithms

open Prog

/-- The insertionSort algorithms on lists with the `SortOps` query. -/
def insertionSort (l : List α) : Prog (SortOps α) (List α) :=
match l with
| [] => return []
| x :: xs => do
let rest ← insertionSort xs
insertOrd x rest

@[simp]
theorem insertionSort_eval (l : List α) (le : α → α → Prop) [DecidableRel le] :
(insertionSort l).eval (sortModel le) = l.insertionSort le := by
induction l with simp_all [insertionSort]

theorem insertionSort_permutation (l : List α) (le : α → α → Prop) [DecidableRel le] :
((insertionSort l).eval (sortModel le)).Perm l := by
simp [insertionSort_eval, List.perm_insertionSort]

theorem insertionSort_sorted
(l : List α) (le : α → α → Prop) [DecidableRel le] [Std.Total le] [IsTrans α le] :
((insertionSort l).eval (sortModel le)).Pairwise le := by
simpa using List.pairwise_insertionSort _ _

lemma insertionSort_length (l : List α) (le : α → α → Prop) [DecidableRel le] :
((insertionSort l).eval (sortModel le)).length = l.length := by
simp

lemma insertionSort_time_compares (head : α) (tail : List α) (le : α → α → Prop) [DecidableRel le] :
((insertionSort (head :: tail)).time (sortModel le)).compares =
((insertionSort tail).time (sortModel le)).compares +
((insertOrd head (tail.insertionSort le)).time (sortModel le)).compares := by
simp [insertionSort]

lemma insertionSort_time_inserts (head : α) (tail : List α) (le : α → α → Prop) [DecidableRel le] :
((insertionSort (head :: tail)).time (sortModel le)).inserts =
((insertionSort tail).time (sortModel le)).inserts +
((insertOrd head (tail.insertionSort le)).time (sortModel le)).inserts := by
simp [insertionSort]

theorem insertionSort_complexity (l : List α) (le : α → α → Prop) [DecidableRel le] :
((insertionSort l).time (sortModel le))
≤ ⟨l.length * (l.length + 1), (l.length + 1) * (l.length + 2)⟩ := by
induction l with
| nil =>
simp [insertionSort]
| cons head tail ih =>
have h := insertOrd_complexity_upper_bound (tail.insertionSort le) head le
simp_all only [List.length_cons, List.length_insertionSort]
obtain ⟨ih₁,ih₂⟩ := ih
obtain ⟨h₁,h₂⟩ := h
refine ⟨?_, ?_⟩
· clear h₂
rw [insertionSort_time_compares]
nlinarith [ih₁, h₁]
· clear h₁
rw [insertionSort_time_inserts]
nlinarith [ih₂, h₂]

end Algorithms

end Cslib
83 changes: 83 additions & 0 deletions Cslib/AlgorithmsTheory/Algorithms/ListLinearSearch.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/-
Copyright (c) 2026 Shreyas Srinivas. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Shreyas Srinivas, Eric Wieser
-/

module

public import Cslib.AlgorithmsTheory.QueryModel
public import Cslib.AlgorithmsTheory.Models.ListComparisonSearch
public import Mathlib

@[expose] public section

/-!
# Linear search in a list

In this file we state and prove the correctness and complexity of linear search in lists under
the `ListSearch` model.
--

## Main Definitions

- `listLinearSearch` : Linear search algorithm in the `ListSearch` query model

## Main results

- `listLinearSearch_eval`: `insertOrd` evaluates identically to `List.contains`.
- `listLinearSearchM_time_complexity_upper_bound` : `linearSearch` takes at most `n`
comparison operations
- `listLinearSearchM_time_complexity_lower_bound` : There exist lists on which `linearSearch` needs
`n` comparisons
-/
namespace Cslib

namespace Algorithms

open Prog

open ListSearch in
/-- Linear Search in Lists on top of the `ListSearch` query model. -/
def listLinearSearch (l : List α) (x : α) : Prog (ListSearch α) Bool := do
match l with
| [] => return false
| l :: ls =>
let cmp : Bool ← compare (l :: ls) x
if cmp then
return true
else
listLinearSearch ls x

@[simp, grind =]
lemma listLinearSearch_eval [BEq α] (l : List α) (x : α) :
(listLinearSearch l x).eval ListSearch.natCost = l.contains x := by
fun_induction l.elem x with simp_all [listLinearSearch]

lemma listLinearSearchM_correct_true [BEq α] [LawfulBEq α] (l : List α)
{x : α} (x_mem_l : x ∈ l) : (listLinearSearch l x).eval ListSearch.natCost = true := by
simp [x_mem_l]

lemma listLinearSearchM_correct_false [BEq α] [LawfulBEq α] (l : List α)
{x : α} (x_mem_l : x ∉ l) : (listLinearSearch l x).eval ListSearch.natCost = false := by
simp [x_mem_l]

lemma listLinearSearchM_time_complexity_upper_bound [BEq α] (l : List α) (x : α) :
(listLinearSearch l x).time ListSearch.natCost ≤ l.length := by
fun_induction l.elem x with
| case1 => simp [listLinearSearch]
| case2 => simp_all [listLinearSearch]
| case3 =>
simp_all [listLinearSearch]
grind

-- This statement is wrong
lemma listLinearSearchM_time_complexity_lower_bound [DecidableEq α] [Nonempty α] :
∃ l : List α, ∃ x : α, (listLinearSearch l x).time ListSearch.natCost = l.length := by
inhabit α
refine ⟨[], default, ?_⟩
simp_all [ListSearch.natCost, listLinearSearch]
Comment on lines +74 to +79
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Shreyas4991, flagging for you that the statement is vacuous as written

Copy link
Contributor Author

@Shreyas4991 Shreyas4991 Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a lemma that says linear search has worst case inputs. Maybe it ought to say it has worst case inputs for every list length n > 0, and input x.

The idea is of course that a non trivial type has two distinct values x and y. So for any n + 1, create [y,y,...,y, x] or [y,y,...y]

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this needs to quantify over all possible list lengths


end Algorithms

end Cslib
96 changes: 96 additions & 0 deletions Cslib/AlgorithmsTheory/Algorithms/ListOrderedInsert.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/-
Copyright (c) 2026 Shreyas Srinivas. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Shreyas Srinivas, Eric Wieser
-/

module

public import Cslib.AlgorithmsTheory.QueryModel
public import Cslib.AlgorithmsTheory.Models.ListComparisonSort
public import Mathlib

@[expose] public section

/-!
# Ordered insertion in a list

In this file we state and prove the correctness and complexity of ordered insertions in lists under
the `SortOps` model. This ordered insert is later used in `insertionSort` mirroring the structure
in upstream libraries for the pure lean code versions of these declarations.

--

## Main Definitions

- `insertOrd` : ordered insert algorithm in the `SortOps` query model

## Main results

- `insertOrd_eval`: `insertOrd` evaluates identically to `List.orderedInsert`.
- `insertOrd_complexity_upper_bound` : Shows that `insertOrd` takes at most `n` comparisons,
and `n + 1` list head-insertion operations.
- `insertOrd_sorted` : Applying `insertOrd` to a sorted list yields a sorted list.
-/

namespace Cslib
namespace Algorithms

open Prog

open SortOps

/--
Performs ordered insertion of `x` into a list `l` in the `SortOps` query model.
If `l` is sorted, then `x` is inserted into `l` such that the resultant list is also sorted.
-/
def insertOrd (x : α) (l : List α) : Prog (SortOps α) (List α) := do
match l with
| [] => insertHead x l
| a :: as =>
if (← cmpLE x a : Bool) then
insertHead x (a :: as)
else
let res ← insertOrd x as
insertHead a res

@[simp]
lemma insertOrd_eval (x : α) (l : List α) (le : α → α → Prop) [DecidableRel le] :
(insertOrd x l).eval (sortModel le) = l.orderedInsert le x := by
induction l with
| nil =>
simp [insertOrd, sortModel]
| cons head tail ih =>
by_cases h_head : le x head
· simp [insertOrd, h_head]
· simp [insertOrd, h_head, ih]

-- to upstream
@[simp]
lemma _root_.List.length_orderedInsert (x : α) (l : List α) [DecidableRel r] :
(l.orderedInsert r x).length = l.length + 1 := by
induction l <;> grind

theorem insertOrd_complexity_upper_bound
(l : List α) (x : α) (le : α → α → Prop) [DecidableRel le] :
(insertOrd x l).time (sortModel le) ≤ ⟨l.length, l.length + 1⟩ := by
induction l with
| nil =>
simp [insertOrd, sortModel]
| cons head tail ih =>
obtain ⟨ih_compares, ih_inserts⟩ := ih
rw [insertOrd]
by_cases h_head : le x head
· simp [h_head]
· simp [h_head]
grind

lemma insertOrd_sorted
(l : List α) (x : α) (le : α → α → Prop) [DecidableRel le] [Std.Total le] [IsTrans _ le] :
l.Pairwise le → ((insertOrd x l).eval (sortModel le)).Pairwise le := by
rw [insertOrd_eval]
exact List.Pairwise.orderedInsert _ _

end Algorithms

end Cslib
Loading