Definitions bundle OAIQ037K043 of the split of OpenAI, The approximation threshold for metric k-median (result family 125)
DefinitionOAIQ037K043A definitions bundle of the split of OpenAI's proof of OAI.MetricKMedian.main_finite_work, carved from OpenAI's openai/math development (OpenAI, The approximation threshold for metric k-median (result family 125), OpenAI Math Release, September 24, 2026, result family 125, github.com/openai/math at commit adc7f12, Apache License 2.0) and ported to Lean 4.33.1 and Mathlib 0df444a. The declarations and their proofs are OpenAI's.
Contents. It holds 82 declarations of OpenAI's Lean: 41 definitions and 41 theorems. The definitions and types are OAI.MetricKMedian.Binary.ListFindIdx.loop, OAI.MetricKMedian.Binary.ListFindIdx.program, OAI.MetricKMedian.Binary.ListFold.linearLoop, OAI.MetricKMedian.Binary.ListSplit.loop, OAI.MetricKMedian.Binary.ListSplit.program, OAI.MetricKMedian.Binary.ListZip.loop, OAI.MetricKMedian.Binary.ListZip.program, OAI.MetricKMedian.Binary.PolyProgram.intLT, OAI.MetricKMedian.Binary.PolyProgram.intNeg, OAI.MetricKMedian.Binary.PolyProgram.intSub, OAI.MetricKMedian.Binary.PolyProgram.listAll, OAI.MetricKMedian.Binary.PolyProgram.listAppend, OAI.MetricKMedian.Binary.PolyProgram.listDrop, OAI.MetricKMedian.Binary.PolyProgram.listFilter, OAI.MetricKMedian.Binary.PolyProgram.listFilterWith, OAI.MetricKMedian.Binary.PolyProgram.listFindIdx, OAI.MetricKMedian.Binary.PolyProgram.listFoldLinear, OAI.MetricKMedian.Binary.PolyProgram.listGetD, OAI.MetricKMedian.Binary.PolyProgram.listIndices, OAI.MetricKMedian.Binary.PolyProgram.listLength, OAI.MetricKMedian.Binary.PolyProgram.listMap, OAI.MetricKMedian.Binary.PolyProgram.listSplitAt, OAI.MetricKMedian.Binary.PolyProgram.listZip, OAI.MetricKMedian.Binary.PolyProgram.mkRational, OAI.MetricKMedian.Binary.PolyProgram.natEQ, OAI.MetricKMedian.Binary.PolyProgram.natLE, OAI.MetricKMedian.Binary.PolyProgram.ratAdd, OAI.MetricKMedian.Binary.PolyProgram.ratDiv, OAI.MetricKMedian.Binary.PolyProgram.ratEQ, OAI.MetricKMedian.Binary.PolyProgram.ratInv, OAI.MetricKMedian.Binary.PolyProgram.ratLE, OAI.MetricKMedian.Binary.PolyProgram.ratLT, OAI.MetricKMedian.Binary.PolyProgram.ratMul, OAI.MetricKMedian.Binary.PolyProgram.ratNeg, OAI.MetricKMedian.Binary.PolyProgram.ratOfInt, OAI.MetricKMedian.Binary.PolyProgram.ratOfNat, OAI.MetricKMedian.Binary.PolyProgram.ratSub, OAI.MetricKMedian.IntegerLaw.BinaryCompression.el, OAI.MetricKMedian.LPBinary.Program.ratMax, OAI.MetricKMedian.LPBinary.Program.ratMin and 1 more.
Sources. They come from these modules of lean/OAI/Combinatorics/KMedian, in whole or in part: KMedian_Binary_BinaryAutomatic, KMedian_Binary_BinaryInteger, KMedian_Binary_BinaryListContext, KMedian_Binary_BinaryListFold, KMedian_Binary_BinaryListIndex, KMedian_Binary_BinaryListIndices, KMedian_Binary_BinaryListMap, KMedian_Binary_BinaryListSelection, KMedian_Binary_BinaryListZip, KMedian_Binary_BinaryLists, KMedian_Binary_BinaryPredicates, KMedian_Binary_BinaryRational, KMedian_Compression_CompressionListStep, KMedian_Optimization_LPListFacts, KMedian_Programs_DependentSparseProgram.
Imports. It imports the bundles OAIQ037K036, OAIQ037K037 and OAIQ037K038 of this split.
Imported by (directly, in this split): the bundles OAIQ037K048, OAIQ037K049 and OAIQ037K050.
import Mathlib
import Definitions.Def_OAIQ037K036
import Definitions.Def_OAIQ037K037
import Definitions.Def_OAIQ037K038
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryLists
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace PolyProgram
variable {α : Type} (ea : α → List Bool) (a0 : α)
noncomputable def listAppend : PolyProgram (encodePair (encodeList ea) (encodeList ea)) (encodeList ea) (fun x => x.1++x.2) :=
(((listReverse ea a0).thread (encodeList ea)).comp (ListReverse.loop ea a0)).congr _
(fun _ => by simp only [Function.comp_apply,ListReverse.result,List.reverse_reverse])
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryListFold
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace ListFold
variable {α β : Type} (ea : α → List Bool) (eb : β → List Bool) (a0 : α)
variable (op : β × α → β)
noncomputable def linearLoop (P : PolyProgram (encodePair eb ea) eb op) (C : ℕ)
(hop : ∀ b a, (eb (op (b,a))).length ≤ (eb b).length+C*(2*(ea a).length+1)) :
PolyProgram (enc ea eb) eb (result op) :=
loop ea eb a0 op P ((Polynomial.C C+1)*X) (fun as b pre suf he => by
have hh := linear_height ea eb op C hop pre b
have hp : (encodeList ea pre).length ≤ (encodeList ea as).length := by
rw [he,EncodedList.append,List.length_append]; omega
simp only [eval_mul,eval_add,eval_C,eval_one,eval_X,enc,encodePair_length]
nlinarith)
end ListFold
namespace PolyProgram
variable {α β : Type} {ea : α → List Bool} {eb : β → List Bool} {op : β × α → β}
noncomputable def listFoldLinear (P : PolyProgram (encodePair eb ea) eb op) (a0 : α) (C : ℕ)
(hop : ∀ b a, (eb (op (b,a))).length ≤ (eb b).length+C*(2*(ea a).length+1)) :
PolyProgram (encodePair (encodeList ea) eb) eb (fun x => x.1.foldl (fun b a => op (b,a)) x.2) :=
ListFold.linearLoop ea eb a0 op P C hop
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryListMap
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace PolyProgram
variable {α β : Type} {ea : α → List Bool} {eb : β → List Bool} {f : α → β}
noncomputable def listMap (P : PolyProgram ea eb f) (a0 : α) :
PolyProgram (encodeList ea) (encodeList eb) (List.map f) := by
let step : PolyProgram (encodePair (encodeList eb) ea) (encodeList eb) (fun x => f x.2::x.1) :=
(((P.second (encodeList eb)).comp (exchange (encodeList eb) eb)).comp (listCons eb)).congr _ (fun _ => rfl)
let fold := step.listFold a0 (X*(2*P.sizeBound+1)+X) (by
intro as bs pre suf he
simp only [ListAlgorithms.pushMap,EncodedList.append,List.length_append,EncodedList.reverse_length]
let L := (encodePair (encodeList ea) (encodeList eb) (as,bs)).length
have hpre : (encodeList ea pre).length ≤ (encodeList ea as).length := by
rw [he,EncodedList.append,List.length_append]; omega
have hlen : pre.length ≤ L := by
have hp := EncodedList.length_le ea pre
simp only [L,encodePair_length]; omega
have hbs : (encodeList eb bs).length ≤ L := by simp only [L,encodePair_length]; omega
have hh := EncodedList.length_bound eb (pre.map f) (P.sizeBound.eval L) (by
intro b hb
obtain ⟨a,ha,rfl⟩ := List.mem_map.mp hb
apply (P.length_bound a).trans
apply polynomial_eval_mono
have hmem := EncodedList.member_length ea pre a ha
simp only [L,encodePair_length]; omega)
simp only [List.length_map] at hh
simp only [eval_add,eval_mul,eval_X,eval_ofNat,eval_one]
change _ ≤ L*(2*P.sizeBound.eval L+1)+L
nlinarith)
let start := (identity (encodeList ea)).fanout (constant (encodeList ea) (encodeList eb) [])
exact ((start.comp fold).comp (listReverse eb (f a0))).congr _ (fun as => by
simp only [Function.comp_apply,id_eq,ListAlgorithms.pushMap,List.append_nil,List.reverse_reverse])
noncomputable def listFilter {p : α → Bool} (P : PolyProgram ea encodeBool p) (a0 : α) :
PolyProgram (encodeList ea) (encodeList ea) (List.filter p) := by
let first := fst (encodeList ea) ea
let test := (snd (encodeList ea) ea).comp P
let push := (exchange (encodeList ea) ea).comp (listCons ea)
let step : PolyProgram (encodePair (encodeList ea) ea) (encodeList ea) (fun x => if p x.2 then x.2::x.1 else x.1) :=
(ite test first push).congr _ (fun _ => rfl)
let fold := step.listFoldLinear a0 1 (by
intro bs a
simp only [one_mul]
split_ifs
· rw [EncodedList.cons_length]; omega
· omega)
exact ((((identity (encodeList ea)).fanout (constant (encodeList ea) (encodeList ea) [])).comp fold).comp (listReverse ea a0)).congr _
(fun as => by simp only [Function.comp_apply,id_eq,ListAlgorithms.pushFilter,List.append_nil,List.reverse_reverse])
noncomputable def listLength (ea : α → List Bool) (a0 : α) :
PolyProgram (encodeList ea) Nat.bits List.length := by
let step : PolyProgram (encodePair Nat.bits ea) Nat.bits (fun x : ℕ × α => x.1+1) :=
(((fst Nat.bits ea).fanout (constant (encodePair Nat.bits ea) Nat.bits 1)).comp natAdd).congr _ (fun _ => rfl)
let fold := step.listFoldLinear a0 2 (by
intro n a
have h := NatBinary.add_length n 1
have hone : (1:ℕ).bits.length=1 := rfl
rw [hone] at h
dsimp only
omega)
exact (((identity (encodeList ea)).fanout (constant (encodeList ea) Nat.bits 0)).comp fold).congr _
(fun as => by simpa only [Function.comp_apply,id_eq,Nat.zero_add] using ListAlgorithms.count as 0)
noncomputable def listAll {p : α → Bool} (P : PolyProgram ea encodeBool p) (a0 : α) :
PolyProgram (encodeList ea) encodeBool (fun as => as.all p) := by
let step := (P.second encodeBool).comp boolAnd
let fold := step.listFoldLinear a0 0 (by intro b a; simp only [encodeBool,List.length_singleton,zero_mul,add_zero,le_refl])
exact (((identity (encodeList ea)).fanout (constant (encodeList ea) encodeBool true)).comp fold).congr _
(fun as => by simpa only [Function.comp_apply,id_eq,Bool.true_and] using ListAlgorithms.all p as true)
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryListContext
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace PolyProgram
variable {α β γ : Type} {ea : α → List Bool} {eb : β → List Bool} {ec : γ → List Bool}
noncomputable def listFilterWith {p : γ × α → Bool}
(P : PolyProgram (encodePair ec ea) encodeBool p) (a0 : α) (c0 : γ) :
PolyProgram (encodePair ec (encodeList ea)) (encodeList ea) (fun x => x.2.filter (fun a => p (x.1,a))) := by
let attach := (identity (encodePair ec ea)).listMapWith a0 (c0,a0)
let filt := listFilter P (c0,a0)
let drop := (snd ec ea).listMap (c0,a0)
exact ((attach.comp filt).comp drop).congr _ (fun x => by
simp only [Function.comp_apply,id_eq,ListAlgorithms.filterMapPair])
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryListIndex
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace ListSplit
variable {α : Type} (ea : α → List Bool) (a0 : α)
noncomputable def program : PolyProgram (enc ea) (encodeLoop (enc ea) (out ea)) (body a0) := by
let ls := PolyProgram.fst (encodeList ea) (encodePair Nat.bits (encodeList ea))
let ns := PolyProgram.snd (encodeList ea) (encodePair Nat.bits (encodeList ea))
let n := ns.comp (PolyProgram.fst Nat.bits (encodeList ea))
let bs := ns.comp (PolyProgram.snd Nat.bits (encodeList ea))
let zero := (((ls.comp (PolyProgram.listIsEmpty ea)).fanout (n.comp PolyProgram.natZero)).comp PolyProgram.boolOr)
let done := (((bs.comp (PolyProgram.listReverse ea a0)).fanout ls).comp (PolyProgram.injectLeft (enc ea) (out ea)))
let pred := ((n.fanout (PolyProgram.constant (enc ea) Nat.bits 1)).comp PolyProgram.natSub)
let push := (((ls.comp (PolyProgram.listHead ea a0)).fanout bs).comp (PolyProgram.listCons ea))
let cont := (((ls.comp (PolyProgram.listTail ea a0)).fanout (pred.fanout push)).comp (PolyProgram.injectRight (enc ea) (out ea)))
exact (PolyProgram.ite zero cont done).congr _ (fun _ => rfl)
noncomputable def loop : PolyProgram (enc ea) (out ea) result :=
(program ea a0).loop result (X+1) X (fun x => by
obtain ⟨t,ht,hr⟩ := run ea a0 x.1 x.2.2 x.2.1 (enc ea x).length le_rfl
refine ⟨t,?_,?_⟩
· have hh := EncodedList.length_le ea x.1
simp only [eval_add,eval_X,eval_one,enc,encodePair_length]
omega
· simpa only [eval_X] using hr)
end ListSplit
namespace PolyProgram
variable {α : Type} (ea : α → List Bool) (a0 : α)
noncomputable def listSplitAt : PolyProgram (encodePair (encodeList ea) Nat.bits)
(encodePair (encodeList ea) (encodeList ea)) (fun x : List α × ℕ => (x.1.take x.2,x.1.drop x.2)) := by
let ls := fst (encodeList ea) Nat.bits
let n := snd (encodeList ea) Nat.bits
let start := ls.fanout (n.fanout (constant (encodePair (encodeList ea) Nat.bits) (encodeList ea) []))
exact (start.comp (ListSplit.loop ea a0)).congr _ (fun x => by simp only [Function.comp_apply,ListSplit.result,List.reverse_nil,List.nil_append])
noncomputable def listDrop : PolyProgram (encodePair (encodeList ea) Nat.bits)
(encodeList ea) (fun x : List α × ℕ => x.1.drop x.2) :=
((listSplitAt ea a0).comp (snd (encodeList ea) (encodeList ea))).congr _ (fun _ => rfl)
noncomputable def listGetD : PolyProgram (encodePair (encodeList ea) Nat.bits)
ea (fun x : List α × ℕ => x.1[x.2]?.getD a0) := by
exact ((listDrop ea a0).comp (listHead ea a0)).congr _ (fun x => by
simp only [Function.comp_apply,List.head?_drop])
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryInteger
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace PolyProgram
noncomputable def intNeg : PolyProgram Signed.encode Signed.encode Neg.neg :=
(((intSign.comp boolNot).fanout intAbs).comp intFromParts).congr _ (fun z => by
simp only [Function.comp_apply,Signed.value_neg,Signed.value_parts])
noncomputable def intSub : PolyProgram (encodePair Signed.encode Signed.encode) Signed.encode (fun x : ℤ × ℤ => x.1-x.2) :=
((intNeg.second Signed.encode).comp intAdd).congr _ (fun x => (sub_eq_add_neg x.1 x.2).symm)
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryRational
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace PolyProgram
noncomputable def intLT : PolyProgram (encodePair Signed.encode Signed.encode) encodeBool (fun x : ℤ × ℤ => decide (x.1 < x.2)) :=
(intSub.comp intSign).congr _ (fun _ => by simp only [Function.comp_apply,Signed.sign,sub_neg])
noncomputable def mkRational : PolyProgram (encodePair Signed.encode Nat.bits) Ratio.encode (fun x => mkRat x.1 x.2) := by
let pn := fst Signed.encode Nat.bits
let pd := snd Signed.encode Nat.bits
let pa := pn.comp intAbs
let pg := (pd.fanout pa).comp natGcd
let nm := (((pn.comp intSign).fanout ((pa.fanout pg).comp natDiv)).comp intFromParts)
let dm := (pd.fanout pg).comp natDiv
let normal := ite (pd.comp natZero) (nm.fanout dm)
(constant (encodePair Signed.encode Nat.bits) (encodePair Signed.encode Nat.bits) (0,1))
refine normal.recode id (fun _ => rfl) ?_
intro x
simp only [Function.comp_apply,id_eq,decide_eq_true_eq]
change encodePair Signed.encode Nat.bits (Ratio.normalized x)=Ratio.encode (mkRat x.1 x.2)
rw [Ratio.normalized_eq]
rfl
noncomputable def ratNeg : PolyProgram Ratio.encode Ratio.encode Neg.neg := by
refine (((ratNum.comp intNeg).fanout ratDen)).recode id (fun _ => rfl) ?_
intro q
simp only [Function.comp_apply,id_eq,Ratio.encode,Ratio.parts,Rat.num_neg_eq_neg_num,Rat.den_neg_eq_den]
noncomputable def ratOfInt : PolyProgram Signed.encode Ratio.encode Int.cast :=
(((identity Signed.encode).fanout (constant Signed.encode Nat.bits 1)).comp mkRational).congr _ (fun z => by simp [Rat.mkRat_eq_div])
noncomputable def ratOfNat : PolyProgram Nat.bits Ratio.encode Nat.cast :=
(intOfNat.comp ratOfInt).congr _ (fun n => by simp)
noncomputable def ratMul : PolyProgram (encodePair Ratio.encode Ratio.encode) Ratio.encode (fun x : ℚ × ℚ => x.1*x.2) := by
let px := fst Ratio.encode Ratio.encode
let py := snd Ratio.encode Ratio.encode
let pn := ((px.comp ratNum).fanout (py.comp ratNum)).comp intMul
let pd := ((px.comp ratDen).fanout (py.comp ratDen)).comp natMul
exact ((pn.fanout pd).comp mkRational).congr _ (fun x => (Rat.mul_def' x.1 x.2).symm)
noncomputable def ratAdd : PolyProgram (encodePair Ratio.encode Ratio.encode) Ratio.encode (fun x : ℚ × ℚ => x.1+x.2) := by
let px := fst Ratio.encode Ratio.encode
let py := snd Ratio.encode Ratio.encode
let pnx := ((px.comp ratNum).fanout ((py.comp ratDen).comp intOfNat)).comp intMul
let pny := ((py.comp ratNum).fanout ((px.comp ratDen).comp intOfNat)).comp intMul
let pn := (pnx.fanout pny).comp intAdd
let pd := ((px.comp ratDen).fanout (py.comp ratDen)).comp natMul
exact ((pn.fanout pd).comp mkRational).congr _ (fun x => (Rat.add_def' x.1 x.2).symm)
noncomputable def ratSub : PolyProgram (encodePair Ratio.encode Ratio.encode) Ratio.encode (fun x : ℚ × ℚ => x.1-x.2) :=
((ratNeg.second Ratio.encode).comp ratAdd).congr _ (fun x => (sub_eq_add_neg x.1 x.2).symm)
noncomputable def ratInv : PolyProgram Ratio.encode Ratio.encode Inv.inv :=
(((((ratNum.comp intSign).fanout ratDen).comp intFromParts).fanout (ratNum.comp intAbs)).comp mkRational).congr _ (fun q => (Ratio.inv_eq q).symm)
noncomputable def ratDiv : PolyProgram (encodePair Ratio.encode Ratio.encode) Ratio.encode (fun x : ℚ × ℚ => x.1/x.2) :=
((ratInv.second Ratio.encode).comp ratMul).congr _ (fun x => (div_eq_mul_inv x.1 x.2).symm)
noncomputable def ratLT : PolyProgram (encodePair Ratio.encode Ratio.encode) encodeBool (fun x : ℚ × ℚ => decide (x.1 < x.2)) := by
let px := fst Ratio.encode Ratio.encode
let py := snd Ratio.encode Ratio.encode
let lhs := ((px.comp ratNum).fanout ((py.comp ratDen).comp intOfNat)).comp intMul
let rhs := ((py.comp ratNum).fanout ((px.comp ratDen).comp intOfNat)).comp intMul
refine ((lhs.fanout rhs).comp intLT).congr _ ?_
intro x
simp only [Function.comp_apply]
simp only [← Rat.lt_iff]
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryListIndices
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace PolyProgram
variable {α : Type} (ea : α → List Bool) (a0 : α)
noncomputable def listIndices : PolyProgram (encodeList ea) (encodeList Nat.bits) (fun xs : List α => List.range xs.length) := by
let eb := encodePair Nat.bits (encodeList Nat.bits)
let acc := fst eb ea
let n := acc.comp (fst Nat.bits (encodeList Nat.bits))
let bs := acc.comp (snd Nat.bits (encodeList Nat.bits))
let inc := (n.fanout (constant (encodePair eb ea) Nat.bits 1)).comp natAdd
let push := (n.fanout bs).comp (listCons Nat.bits)
let step : PolyProgram (encodePair eb ea) eb ListAlgorithms.indexStep :=
(inc.fanout push).congr _ (fun _ => rfl)
let fold := step.listFold a0 (10*(X+1)^2) (by
intro xs x pre suf he
simpa only [eval_mul,eval_ofNat,eval_pow,eval_add,eval_X,eval_one] using ListAlgorithms.index_partial_size ea xs x pre suf he)
let start := (identity (encodeList ea)).fanout (constant (encodeList ea) eb (0,[]))
exact ((((start.comp fold).comp (snd Nat.bits (encodeList Nat.bits))).comp (listReverse Nat.bits 0))).congr _ (fun xs => by
simp only [Function.comp_apply,id_eq,ListAlgorithms.pushIndices,List.append_nil,List.reverse_reverse,← List.range_eq_range'])
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryListZip
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace ListZip
variable {α β : Type} (ea : α → List Bool) (eb : β → List Bool) (a0 : α) (b0 : β)
noncomputable def program : PolyProgram (enc ea eb) (encodeLoop (enc ea eb) (encodeList (encodePair ea eb))) (body a0 b0) := by
let pair := PolyProgram.fst (encodePair (encodeList ea) (encodeList eb)) (encodeList (encodePair ea eb))
let as := pair.comp (PolyProgram.fst (encodeList ea) (encodeList eb))
let bs := pair.comp (PolyProgram.snd (encodeList ea) (encodeList eb))
let cs := PolyProgram.snd (encodePair (encodeList ea) (encodeList eb)) (encodeList (encodePair ea eb))
let test := (((as.comp (PolyProgram.listIsEmpty ea)).fanout (bs.comp (PolyProgram.listIsEmpty eb))).comp PolyProgram.boolOr)
let done := ((cs.comp (PolyProgram.listReverse (encodePair ea eb) (a0,b0))).comp (PolyProgram.injectLeft (enc ea eb) (encodeList (encodePair ea eb))))
let heads := (as.comp (PolyProgram.listHead ea a0)).fanout (bs.comp (PolyProgram.listHead eb b0))
let tails := (as.comp (PolyProgram.listTail ea a0)).fanout (bs.comp (PolyProgram.listTail eb b0))
let push := ((heads.fanout cs).comp (PolyProgram.listCons (encodePair ea eb)))
let cont := ((tails.fanout push).comp (PolyProgram.injectRight (enc ea eb) (encodeList (encodePair ea eb))))
exact (PolyProgram.ite test cont done).congr _ (fun _ => rfl)
noncomputable def loop : PolyProgram (enc ea eb) (encodeList (encodePair ea eb)) result :=
(program ea eb a0 b0).loop result (X+1) X (fun x => by
obtain ⟨t,ht,hr⟩ := run ea eb a0 b0 x.1.1 x.1.2 x.2 (enc ea eb x).length le_rfl
refine ⟨t,?_,?_⟩
· have hh := EncodedList.length_le ea x.1.1
simp only [eval_add,eval_X,eval_one,enc,encodePair_length]
omega
· simpa only [eval_X] using hr)
end ListZip
namespace PolyProgram
variable {α β γ : Type} (ea : α → List Bool) (eb : β → List Bool) (a0 : α) (b0 : β)
noncomputable def listZip : PolyProgram (encodePair (encodeList ea) (encodeList eb))
(encodeList (encodePair ea eb)) (fun x : List α × List β => x.1.zip x.2) := by
let start := (identity (encodePair (encodeList ea) (encodeList eb))).fanout
(constant (encodePair (encodeList ea) (encodeList eb)) (encodeList (encodePair ea eb)) [])
exact (start.comp (ListZip.loop ea eb a0 b0)).congr _ (fun _ => by simp only [Function.comp_apply,id_eq,ListZip.result,List.reverse_nil,List.nil_append])
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryListSelection
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary
open Function Polynomial
namespace ListFindIdx
variable {α : Type} (ea : α → List Bool) (a0 : α) (p : α → Bool)
noncomputable def program (P : PolyProgram ea encodeBool p) :
PolyProgram (enc ea) (encodeLoop (enc ea) Nat.bits) (body a0 p) := by
let ls := PolyProgram.fst (encodeList ea) Nat.bits
let n := PolyProgram.snd (encodeList ea) Nat.bits
let hd := (ls.comp (PolyProgram.listHead ea a0)).comp P
let test := ((ls.comp (PolyProgram.listIsEmpty ea)).fanout hd).comp PolyProgram.boolOr
let done := n.comp (PolyProgram.injectLeft (enc ea) Nat.bits)
let inc := (n.fanout (PolyProgram.constant (enc ea) Nat.bits 1)).comp PolyProgram.natAdd
let cont := (((ls.comp (PolyProgram.listTail ea a0)).fanout inc).comp (PolyProgram.injectRight (enc ea) Nat.bits))
exact (PolyProgram.ite test cont done).congr _ (fun _ => rfl)
noncomputable def loop (P : PolyProgram ea encodeBool p) : PolyProgram (enc ea) Nat.bits (result p) :=
(program ea a0 p P).loop (result p) (X+1) X (fun x => by
obtain ⟨t,ht,hr⟩ := run ea a0 p x.1 x.2 (enc ea x).length le_rfl
refine ⟨t,?_,?_⟩
· have hh := EncodedList.length_le ea x.1
simp only [eval_add,eval_X,eval_one,enc,encodePair_length]
omega
· simpa only [eval_X] using hr)
end ListFindIdx
namespace PolyProgram
variable {α : Type} {ea : α → List Bool}
noncomputable def listFindIdx {p : α → Bool} (P : PolyProgram ea encodeBool p) (a0 : α) :
PolyProgram (encodeList ea) Nat.bits (List.findIdx p) :=
((((identity (encodeList ea)).fanout (constant (encodeList ea) Nat.bits 0)).comp
(ListFindIdx.loop ea a0 p P))).congr _ (fun _ => by simp only [Function.comp_apply,id_eq,ListFindIdx.result,Nat.zero_add])
end PolyProgram
end MetricKMedian.Binary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryPredicates
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary.PolyProgram
noncomputable def natLE : PolyProgram (encodePair Nat.bits Nat.bits) encodeBool (fun x : ℕ × ℕ => decide (x.1≤x.2)) :=
(((exchange Nat.bits Nat.bits).comp natLT).comp boolNot).congr _ (fun x => by
by_cases h : x.1≤x.2
· simp [Function.comp_def,h,not_lt.mpr h]
· simp [Function.comp_def,h,lt_of_not_ge h])
noncomputable def natEQ : PolyProgram (encodePair Nat.bits Nat.bits) encodeBool (fun x : ℕ × ℕ => decide (x.1=x.2)) :=
((natLE.fanout ((exchange Nat.bits Nat.bits).comp natLE)).comp boolAnd).congr _ (fun x => by
by_cases h₁ : x.1≤x.2 <;> by_cases h₂ : x.2≤x.1 <;> simp [Function.comp_apply,Prod.swap,h₁,h₂,le_antisymm_iff])
noncomputable def ratEQ : PolyProgram (encodePair Ratio.encode Ratio.encode) encodeBool (fun x : ℚ × ℚ => decide (x.1=x.2)) :=
(ratSub.comp ratZero).congr _ (fun q => by simp only [Function.comp_apply,sub_eq_zero])
noncomputable def ratLE : PolyProgram (encodePair Ratio.encode Ratio.encode) encodeBool (fun x : ℚ × ℚ => decide (x.1≤x.2)) :=
(((exchange Ratio.encode Ratio.encode).comp ratLT).comp boolNot).congr _ (fun x => by
by_cases h : x.1≤x.2
· simp [Function.comp_def,h,not_lt.mpr h]
· simp [Function.comp_def,h,lt_of_not_ge h])
end MetricKMedian.Binary.PolyProgram
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Optimization_LPListFacts
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.LPBinary
open Finset
namespace Program
open Binary Binary.PolyProgram
noncomputable def ratMax : PolyProgram (encodePair Ratio.encode Ratio.encode) Ratio.encode (fun x : ℚ × ℚ => max x.1 x.2) :=
(ite ratLE (fst Ratio.encode Ratio.encode) (snd Ratio.encode Ratio.encode)).congr _ (fun x => by
by_cases h : x.1≤x.2
· simp [h]
· simp [h,max_eq_left (le_of_not_ge h)])
noncomputable def ratMin : PolyProgram (encodePair Ratio.encode Ratio.encode) Ratio.encode (fun x : ℚ × ℚ => min x.1 x.2) :=
(ite ratLE (snd Ratio.encode Ratio.encode) (fst Ratio.encode Ratio.encode)).congr _ (fun x => by
by_cases h : x.1≤x.2
· simp [h]
· simp [h,min_eq_right (le_of_not_ge h)])
end Program
end MetricKMedian.LPBinary
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Binary_BinaryAutomatic
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.Binary.Automatic
open PolyProgram Function
namespace Poly
variable {α β γ : Type} [Coding α] [Coding β] [Coding γ]
@[fun_prop] theorem rat_add : Poly (fun x : ℚ × ℚ => x.1+x.2) := ⟨ratAdd⟩
@[fun_prop] theorem rat_sub : Poly (fun x : ℚ × ℚ => x.1-x.2) := ⟨ratSub⟩
@[fun_prop] theorem rat_mul : Poly (fun x : ℚ × ℚ => x.1*x.2) := ⟨ratMul⟩
@[fun_prop] theorem rat_div : Poly (fun x : ℚ × ℚ => x.1/x.2) := ⟨ratDiv⟩
@[fun_prop] theorem rat_lt : Poly (fun x : ℚ × ℚ => decide (x.1<x.2)) := ⟨ratLT⟩
@[fun_prop] theorem rat_le : Poly (fun x : ℚ × ℚ => decide (x.1≤x.2)) := ⟨ratLE⟩
@[fun_prop] theorem rat_eq : Poly (fun x : ℚ × ℚ => decide (x.1=x.2)) := ⟨ratEQ⟩
@[fun_prop] theorem rat_min : Poly (fun x : ℚ × ℚ => min x.1 x.2) := ⟨LPBinary.Program.ratMin⟩
@[fun_prop] theorem rat_max : Poly (fun x : ℚ × ℚ => max x.1 x.2) := ⟨LPBinary.Program.ratMax⟩
@[fun_prop] theorem nat_add : Poly (fun x : ℕ × ℕ => x.1+x.2) := ⟨natAdd⟩
@[fun_prop] theorem nat_sub : Poly (fun x : ℕ × ℕ => x.1-x.2) := ⟨natSub⟩
@[fun_prop] theorem nat_mul : Poly (fun x : ℕ × ℕ => x.1*x.2) := ⟨natMul⟩
@[fun_prop] theorem nat_lt : Poly (fun x : ℕ × ℕ => decide (x.1<x.2)) := ⟨natLT⟩
@[fun_prop] theorem nat_le : Poly (fun x : ℕ × ℕ => decide (x.1≤x.2)) := ⟨natLE⟩
@[fun_prop] theorem nat_eq : Poly (fun x : ℕ × ℕ => decide (x.1=x.2)) := ⟨natEQ⟩
@[fun_prop] theorem bool_and : Poly (fun x : Bool × Bool => x.1 && x.2) := ⟨boolAnd⟩
@[fun_prop] theorem bool_or : Poly (fun x : Bool × Bool => x.1 || x.2) := ⟨boolOr⟩
@[fun_prop] theorem rat_neg : Poly (fun x : ℚ => -x) := ⟨ratNeg⟩
@[fun_prop] theorem bool_not : Poly (fun x : Bool => !x) := ⟨boolNot⟩
@[fun_prop] theorem rat_ofNat : Poly (fun x : ℕ => (x:ℚ)) := ⟨ratOfNat⟩
@[fun_prop] theorem rat_ofInt : Poly (fun x : ℤ => (x:ℚ)) := ⟨ratOfInt⟩
@[fun_prop] theorem list_length [Inhabited α] : Poly (List.length : List α → ℕ) := ⟨listLength enc default⟩
@[fun_prop] theorem list_indices [Inhabited α] : Poly (fun xs : List α => List.range xs.length) := ⟨listIndices enc default⟩
@[fun_prop] theorem list_getD (a0 : α) : Poly (fun x : List α × ℕ => x.1[x.2]?.getD a0) := ⟨listGetD enc a0⟩
@[fun_prop] theorem list_head (a0 : α) : Poly (fun xs : List α => xs.head?.getD a0) := ⟨listHead enc a0⟩
@[fun_prop] theorem list_tail [Inhabited α] : Poly (List.tail : List α → List α) := ⟨listTail enc default⟩
@[fun_prop] theorem list_empty : Poly (List.isEmpty : List α → Bool) := ⟨listIsEmpty enc⟩
@[fun_prop] theorem list_append [Inhabited α] : Poly (fun x : List α × List α => x.1++x.2) := ⟨listAppend enc default⟩
@[fun_prop] theorem list_cons : Poly (fun x : α × List α => x.1::x.2) := ⟨listCons enc⟩
@[fun_prop] theorem list_zip [Inhabited α] [Inhabited β] : Poly (fun x : List α × List β => x.1.zip x.2) := ⟨listZip enc enc default default⟩
@[fun_prop] theorem list_filter [Inhabited α] [Inhabited β] {f : α → β → Bool} {as : α → List β}
(hf : Poly (fun x : α × β => f x.1 x.2)) (ha : Poly as) :
Poly (fun x => (as x).filter (f x)) :=
⟨((PolyProgram.identity enc).fanout ha.program).comp (hf.program.listFilterWith default default)⟩
@[fun_prop] theorem list_findIdx [Inhabited β] {f : α → β → Bool} {as : α → List β}
(hf : Poly (fun x : α × β => f x.1 x.2)) (ha : Poly as) :
Poly (fun x => (as x).findIdx (f x)) := by
let tests := ((PolyProgram.identity enc).fanout ha.program).comp (hf.program.listMapWith default false)
exact ⟨(tests.comp (listFindIdx (PolyProgram.identity encodeBool) false)).congr _ (fun _ => by
simp only [Function.comp_def,List.findIdx_map,id_eq])⟩
@[fun_prop] theorem list_getD_comp (a0 : β) {xs : α → List β} {i : α → ℕ}
(hx : Poly xs) (hi : Poly i) : Poly (fun x => (xs x)[i x]?.getD a0) :=
comp (list_getD a0) (pair hx hi)
@[fun_prop] theorem list_head_comp (a0 : β) {xs : α → List β}
(hx : Poly xs) : Poly (fun x => (xs x).head?.getD a0) := comp (list_head a0) hx
@[fun_prop] theorem rat_lt_comp {f g : α → ℚ} (hf : Poly f) (hg : Poly g) : Poly (fun x => decide (f x<g x)) := comp rat_lt (pair hf hg)
@[fun_prop] theorem rat_le_comp {f g : α → ℚ} (hf : Poly f) (hg : Poly g) : Poly (fun x => decide (f x≤g x)) := comp rat_le (pair hf hg)
@[fun_prop] theorem rat_eq_comp {f g : α → ℚ} (hf : Poly f) (hg : Poly g) : Poly (fun x => decide (f x=g x)) := comp rat_eq (pair hf hg)
@[fun_prop] theorem nat_lt_comp {f g : α → ℕ} (hf : Poly f) (hg : Poly g) : Poly (fun x => decide (f x<g x)) := comp nat_lt (pair hf hg)
@[fun_prop] theorem nat_le_comp {f g : α → ℕ} (hf : Poly f) (hg : Poly g) : Poly (fun x => decide (f x≤g x)) := comp nat_le (pair hf hg)
@[fun_prop] theorem nat_eq_comp {f g : α → ℕ} (hf : Poly f) (hg : Poly g) : Poly (fun x => decide (f x=g x)) := comp nat_eq (pair hf hg)
@[fun_prop] theorem ite_prop {p : α → Prop} [DecidablePred p] {f g : α → β}
(hp : Poly (fun x => decide (p x))) (hf : Poly f) (hg : Poly g) :
Poly (fun x => if p x then f x else g x) := by
exact ⟨(PolyProgram.ite hp.program hg.program hf.program).congr _ (fun _ => by simp only [decide_eq_true_eq])⟩
end Poly
end MetricKMedian.Binary.Automatic
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Compression_CompressionListStep
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.IntegerLaw.BinaryCompression
open Binary Binary.PolyProgram Function Finset
abbrev el := ListPivot.el
end MetricKMedian.IntegerLaw.BinaryCompression
end
end OAI
end
section
-- module Solutions.OAIQ037_KM.KMedian_Programs_DependentSparseProgram
set_option linter.all false
set_option linter.unusedVariables false
set_option linter.unusedTactic false
set_option linter.unreachableTactic false
namespace OAI
section
namespace MetricKMedian.SparseIntegerLaw.DependentProgram
open Binary Binary.PolyProgram Function BinarySparse
variable {C A : Type} (T : C → Type)
variable {T} (ec : C → List Bool) (ea : A → List Bool) (view : ∀ c, T c → A)
def Bundle.encode (x : Bundle T) : List Bool := encodePair ec (ed ea) (x.raw view)
end MetricKMedian.SparseIntegerLaw.DependentProgram
end
end OAI
end