import Mathlib /- # Pset 2 ## 2.1 Prove the following lemmas in Lean. -/ lemma two_plus_two : 2 + 2 = 4 := by sorry lemma and_swap : p ∧ q → q ∧ p := by sorry lemma add_rearrange {a b c d : ℝ} : 0 ≤ a + b + c + d ↔ -b - c ≤ a + d := by sorry lemma three_not_even {x : ℤ} : 2 * x ≠ 3 := by sorry lemma linear_arithmetic {a b c d e f : ℝ} : 2 * a + b ≥ 1 → b ≥ 0 → c ≥ 0 → d ≥ 0 → e * f ≥ 0 → a ≥ 3 * c → c ≥ 6 * e * f → d - f * e * 5 ≥ 0 → a + b + 3 * c + d + 2 * e * f < 0 → False := by sorry lemma cross_multiply_field [Field α] {x y z w : α} : x / y = z / w → y ≠ 0 → w ≠ 0 → x * w = z * y := by sorry abbrev SolutionSet (y : ℝ) : Set (ℝ × ℝ × ℝ × ℝ × ℝ) := {(x₁, x₂, x₃, x₄, x₅) | (x₁ = 0 ∧ x₂ = 0 ∧ x₃ = 0 ∧ x₄ = 0 ∧ x₅ = 0) ∨ (x₁ = x₂ ∧ x₂ = x₃ ∧ x₃ = x₄ ∧ x₄ = x₅ ∧ y = 2) ∨ (y^2 + y - 1 = 0 ∧ ∃ s t, x₁ = s ∧ x₂ = t ∧ x₃ = y * t - s ∧ x₄ = -(y * t) - y * s ∧ x₅ = y * s - t)} lemma imo1963_p4 : (x₁, x₂, x₃, x₄, x₅) ∈ SolutionSet y ↔ (x₅ + x₂ = y * x₁ ∧ x₁ + x₃ = y * x₂ ∧ x₂ + x₄ = y * x₃ ∧ x₃ + x₅ = y * x₄ ∧ x₄ + x₁ = y * x₅) := by sorry /- ## 2.2 Prove the following lemmas. -/ lemma pow_two_larger : n ≤ 2 ^ n := by sorry lemma pow_two_larger' (h : 2 ≤ n) : (n - 2) * 2 ≤ 2 ^ (n - 1) := by sorry /- ## 2.3 Prove these lemmas about binary operations (taken from https://cjquines.com/files/binaryoperations.pdf). -/ lemma cjq1 (f : α → α → α) (hl : ∀ x, f l x = x) (hr : ∀ x, f x r = x) : l = r := by sorry lemma cjq2 [Nonempty α] (f : α → α → α) (h : ∀ x y, ∃ z, f x z = y ∧ ∀ z', f x z = f x z' → z = z') : ∃ g : α → α → α, ∀ x y, f x (g x y) = y ∧ g x (f x y) = y := by sorry lemma cjq3 (f g : α → α → α) (hid : ∀ x, f i x = x ∧ f x i = x ∧ g j x = x ∧ g x j = x) (h : ∀ x y z w, f (g x y) (g z w) = g (f x z) (f y w)) : f = g := by sorry /- ## 2.4 Write a recursive function that computes the index of least significant bit of a natural number `x`, i.e. the largest `k` such that `2 ^ k` divides `x`. Prove your that your function terminates and is correct. -/ def lsb (x : ℕ) (hx : 0 < x) : ℕ := sorry lemma lsb_div (x : ℕ) (hx : 0 < x) : 2 ^ lsb x hx ∣ x := by sorry lemma lsb_largest (x : ℕ) (hx : 0 < x) : ∀ k > lsb x hx, ¬2 ^ k ∣ x := by sorry /- ## 2.5 Create a `structure` called `Color` to represent RGB colors. Then write a function that parses a [P6 PPM image](https://en.wikipedia.org/wiki/Netpbm#PPM_example) and returns an `Except` type with either an `Array (Array Color)` or an error message string. Prove that all array accesses are in bounds. Then, run your function on the file `image.ppm` using `IO.FS.readBinFile`. -/ def parsePPM (bytes : ByteArray) := do sorry /- ## 2.6 Create a new file called `Quine.lean` and add it as a `[[lean_exe]]` in the `lakefile.toml` file. Then write a [quine](https://en.wikipedia.org/wiki/Quine_(computing)) in Lean and run it with `lake exe`. ## 2.7 Give an example of a functor that isn't an applicative and an applicative that isn't a monad. For each example, determine which law is violated and prove it in Lean. -/ /- ## 2.8 Another equivalent way to define monads is with a type class with a `fish` function of signature `(α → m β) → (β → m γ) → α → m γ`. Given this `fish` function, implement the other two equivalent formulations of monads. -/ def joinFromFish (m : Type u → Type u) (fish : {α β γ : Type u} → (α → m β) → (β → m γ) → α → m γ) : m (m α) → m α := sorry def bindFromFish (m : Type u → Type u) (fish : {α β γ : Type u} → (α → m β) → (β → m γ) → α → m γ) : m α → (α → m β) → m β := sorry /- ## 2.9 Implement applicative `seq` for a monad, first without using `do` notation, and then simplify your implementation using `do`. Finally, prove that your `seq` function satisfies the applicative laws. -/ namespace Monad variable [Monad m] [LawfulMonad m] def appSeq (fs : m (α → β)) (as : m α) : m β := sorry def appSeqDo (fs : m (α → β)) (as : m α) : m β := do sorry infixl:60 " <*>' " => fun x y ↦ appSeq x y lemma pure_seq (g : α → β) (x : m α) : pure g <*>' x = g <$> x := by sorry lemma seq_pure (g : m (α → β)) (x : α) : g <*>' pure x = (· x) <$> g := by sorry lemma seq_assoc (x : m α) (g : m (α → β)) (h : m (β → γ)) : h <*>' (g <*>' x) = (· ∘ ·) <$> h <*>' g <*>' x := by sorry end Monad /- ## 2.10 Show that the `Id'` type contructor below is an instance of `Monad` and `LawfulMonad`. -/ def Id' (type : Type u) := type