module _ where open import list open import nat open import eq open import bool {- prove that if the maximum and the minimum of two numbers are the same, the numbers themselves must also be the same minmax≡ : ∀ n m -> min n m ≡ max n m -> n ≡ m HINT: consider all four cases of `n` and `m` as either `zero` or `(suc n)`. Three will either be impossible or trivial. For the last one, look in nat-thms.agda to see if you find some useful rewrites. You may need to do a case split on n < m (which is interesting, as you are trying to prove that it never happens) -} minmax≡ : ∀ n m -> min n m ≡ max n m -> n ≡ m minmax≡ = {!!} {- Prove that if there is a `ff` in a list, i.e., if you know this: list-member _iff_ ff l ≡ tt for an arbitrary (l : 𝕃 𝔹), then list-and of that list is ff, i.e.: list-and l ≡ ff The definition of list-member is in list.agda. -} falsemeansfalse : ∀ (l : 𝕃 𝔹) -> list-member _iff_ ff l ≡ tt -> list-and l ≡ ff falsemeansfalse = {!!} {- Prove a similar result for list-or, namely that if there is a tt in the input list, then list-or returns tt. -} truemeanstrue : ∀ (l : 𝕃 𝔹) -> list-member _iff_ tt l ≡ tt -> list-or l ≡ tt truemeanstrue = {!!} {- prove that reversing a list twice returns the same list, i.e. rev2x : ∀{ℓ}{A : Set ℓ} → (l : 𝕃 A) -> reverse (reverse l) ≡ l HINT: prove two lemmas, one that says what happens when reverse-helper's first argument end with the list element `x` and one that says what happens when the second argument ends with the list element `x`. Here is the statement for the first one of those: rh-firstarg : ∀{ℓ}{A : Set ℓ} → (x : A) -> (l m : 𝕃 A) -> reverse-helper (l ++ (x :: [])) m ≡ (reverse-helper l m) ++ (x :: []) These will be useful for finishing the inductive case in rev2x. -} rev2x : ∀{ℓ}{A : Set ℓ} → (l : 𝕃 A) -> reverse (reverse l) ≡ l rev2x l = {!!} {- In the IAL you'll find the theorem map-compose : ∀ {ℓ ℓ' ℓ''} {A : Set ℓ} {B : Set ℓ'}{C : Set ℓ''} → (f : B → C) (g : A → B) (l : 𝕃 A) → map f (map g l) ≡ map (f ∘ g) l where (f ∘ g) means the composition of f and g. That is, this function takes an input, calls `g` on it, and then calls `f` on the result of calling `g` and then returns that. In racket notation, the composition of f and g can be written like this: (define (f-compose-g x) (f (g x))) This theorem is false in "regular" programming languages. Give a counter example in running racket code. Put the counterexample in your agda submission file in a comment. -} {- Prove that filtering before reversing and filtering after reversing yield the same result. Hint: you'll need a theorem about reverse-helper and its relationship to filter. Note that the definition of reverse-helper is slightly different than the definition we did in class. (Not in an important way.) -} filter-rev : ∀ {ℓ} {A : Set ℓ} (p : A → 𝔹) (l : 𝕃 A) → filter p (reverse l) ≡ reverse (filter p l) filter-rev p l = {!!} {- This theorem is also false in a regular programming language; as with the previous exercise, come with a counterexample using Racket and include it in your agda submission in a comment. -}