feat(Query): query complexity framework with sorting examples#401
feat(Query): query complexity framework with sorting examples#401kim-em wants to merge 3 commits intoleanprover:mainfrom
Conversation
dc724df to
8371c12
Compare
| /- | ||
| Copyright (c) 2026 Lean FRO, LLC. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Sorrachai Yingchareonthawornchai, Kim Morrison, Sebastian Graf, Shreyas Srinivas |
There was a problem hiding this comment.
Sorrachai is not an author on this file, only on the TimeM files. Further on all prog files I am first author
8371c12 to
dbb9e41
Compare
Add a framework for proving upper and lower bounds on query complexity of comparison-based algorithms, using `Prog` (free monad over query types) with oracle-parametric evaluation and structural query counting. Results: - Insertion sort: correctness + O(n²) upper bound - Merge sort: correctness + n·⌈log₂ n⌉ upper bound - Lower bound: any correct comparison sort on an infinite type needs ≥ ⌈log₂(n!)⌉ queries (via adversarial pigeonhole on QueryTree depth) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dbb9e41 to
9acdbbd
Compare
Add `Prog.cost`, a weighted generalization of `Prog.queriesOn` where each query type can have a different cost. Demonstrate this with complex multiplication: naive (4 muls + 2 adds) vs Gauss's trick (3 muls + 5 adds), proving correctness, exact parametric costs, and the crossover condition. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| Authors: Kim Morrison | ||
| -/ | ||
| module | ||
|
|
There was a problem hiding this comment.
This is the Arith Prog from my CslibTests files?
Shreyas4991
left a comment
There was a problem hiding this comment.
Thus arith query is similar to mine in the the CslibTests folder
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shreyas4991
left a comment
There was a problem hiding this comment.
A non-comprehensive comparison with previous PR and authorship issues that arise therein.
| namespace Cslib.Query | ||
|
|
||
| /-- Insert `x` into a sorted list using comparison queries. -/ | ||
| @[expose] def orderedInsert (x : α) : List α → Prog (LEQuery α) (List α) |
There was a problem hiding this comment.
This is identical to the Prog version upto query type.
|
|
||
| -- ## Query count proofs | ||
|
|
||
| theorem orderedInsert_queriesOn_le (oracle : {ι : Type} → LEQuery α ι → ι) |
There was a problem hiding this comment.
You oracle is just my Model.evalQuery. Likewise for time.
| toQTOracle (fromQTOracle f) = f := rfl | ||
|
|
||
| /-- Convert a `Prog (LEQuery α)` program to a `QueryTree (α × α) Bool` decision tree. -/ | ||
| @[expose] def Prog.toQueryTree : Prog (LEQuery α) β → QueryTree (α × α) Bool β |
There was a problem hiding this comment.
This is essentially traceSort from cslib#372
| /- | ||
| Copyright (c) 2026 Lean FRO, LLC. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Sorrachai Yingchareonthawornchai, Kim Morrison |
There was a problem hiding this comment.
The authorship claims on this go to an equal extent for me and Sorrachai. We both use a different recursive structure and I provide the Prog version of his code. Since the recursion structure is different here (and more akin to the upstream version), potentially neither of us are co-authors or both of us are.
| @@ -0,0 +1,107 @@ | |||
| /- | |||
| Copyright (c) 2026 Lean FRO, LLC. All rights reserved. | |||
| Released under Apache 2.0 license as described in the file LICENSE. | |||
There was a problem hiding this comment.
I published a similar proof of model wide lower bound a few hours before cslib#376 got there.
| /-- Evaluate a program by answering each query using `oracle`. -/ | ||
| @[expose] def eval (oracle : {ι : Type} → Q ι → ι) : Prog Q α → α | ||
| | .pure a => a | ||
| | .liftBind op cont => eval oracle (cont (oracle op)) |
There was a problem hiding this comment.
I claim that pattern matching on the free monad is exploiting an implementation detail, and that everything should really go through the universal property, FreeM.liftM. (this is what #372 does)
This PR implements Sebastian Graf's unified approach to query complexity (discussed in the CSLib Algorithm frameworks thread), combining the strengths of #372 (explicit
Prog/FreeMquery types) and #376 (monad-parametric approach).Programs are
Prog Q α(free monad over query typeQ), and the oracle is supplied after the program produces its query plan — giving anti-cheating guarantees for both upper and lower bounds. No WP/Hoare triple machinery is needed: correctness is just equations aboutProg.eval oracle, and cost is just equations aboutProg.queriesOn oracle.This provides an alternative to the
TimeM-based cost analysis already in the repo: here query counting is structural (derived from theProgtree) rather than annotation-based.New files
Query/Prog.leanProgtype,eval,queriesOn, simp lemmasQuery/Bounds.leanUpperBoundandLowerBounddefinitionsQuery/QueryTree.leanQuery/Sort/LEQuery.leanQuery/Sort/IsSort.leanIsSortcorrectness specificationQuery/Sort/Insertion/{Defs,Lemmas}.leanQuery/Sort/Merge/{Defs,Lemmas}.leanQuery/Sort/QueryTree.leanProg-to-QueryTreebridge + pigeonhole depth lemmaQuery/Sort/LowerBound.leanResults
IsSortinstanceIsSortinstanceIsSorton an infinite type makes ≥ ⌈log₂(n!)⌉ queries. The proof constructs n! distinct total orders via permutations of embedded elements, shows they force distinct sorted outputs, then applies an adversarial pigeonhole argument onQueryTreedepth.🤖 Prepared with Claude Code