-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
import Std.Tactic.Do
import Mathlib
namespace Paradox
-- https://leanprover.zulipchat.com/#narrow/channel/236446-Type-theory/topic/Paradoxes.20and.20Type.20Universes/with/538016579
axiom Bad : Type
axiom bad : (α : Type) × α ↪ Bad
noncomputable def k (P : Bad → Prop) : Bad :=
bad ⟨Bad → Prop, P⟩
def Q (b : Bad) : Prop :=
∃ P, k P = b ∧ ¬P b
theorem k_injective : k.Injective :=
fun _ _ hab => eq_of_heq
(Sigma.mk.inj (bad.injective hab)).2
theorem down (h : Q (k Q)) : ¬Q (k Q) :=
h.elim fun _ hP =>
(congrArg Not (congrFun (k_injective hP.1) (k Q))).mp hP.2
theorem up (h : ¬Q (k Q)) : Q (k Q) :=
⟨Q, rfl, h⟩
theorem false : False :=
down (up fun h => down h h) (up fun h => down h h)
-- 'false' depends on axioms: [Bad, bad]
#print axioms Paradox.false
end Paradox
inductive Fmt where
| Arg : Fmt → Fmt
| Nat : Fmt → Fmt
| Char : Char → Fmt → Fmt
| End
def toFmt : List Char → Fmt
| '*' :: xs => .Arg <| toFmt xs
| '#' :: xs => .Nat <| toFmt xs
| x :: xs => .Char x <| toFmt xs
| [] => .End
def FormatType : Fmt → Type 1
| .Arg fmt => {α : Type} → [ToString α] → α → FormatType fmt
| .Nat fmt => Nat → FormatType fmt
| .Char _ fmt => FormatType fmt
| .End => PLift String
def format (fmt : String) : FormatType <| toFmt fmt.toList :=
let rec formatAux (acc : String) : (fmt : Fmt) → FormatType fmt
| .Arg fmt => fun x ↦ formatAux (acc ++ toString x) fmt
| .Nat fmt => fun x ↦ formatAux (acc ++ "#" ++ toString x) fmt
| .Char c fmt => formatAux (acc.push c) fmt
| .End => .up acc
formatAux "" <| toFmt fmt.toList
#eval format "Hello * # * *" (-1) 1 [42, 69] "Meow" |>.down
-- TODO: prove binary search
def Array.binarySearch (A : Array ℕ) (x : ℕ) := Id.run do
let n := A.size
let mut l : Fin (n + 1) := 0
let mut r : Fin (n + 1) := ⟨n, by grind⟩
while h : l < r do
let m : Fin (n + 1) := ⟨(l.val + r.val) / 2, by grind⟩
if A[m]'(by grind) < x then
l := m + 1
else
r := m
return l
open Std.Do in
lemma binarySearchCorrect (A : Array ℕ) (hA : A.Pairwise (· ≤ ·)) : ∀ i (hi : i < A.binarySearch x), A[i] < x := by
sorry