module _ where open import nat open import eq open import sum open import bool open import list open import bool-thms open import nat-thms {- Be aware that you can define helper functions (aka lemmas). Often, it is easier to prove some specific lemma on its own and then use it in a larger proof. This is very handy even when the main proof is only two or three lines, in fact. -} {- We did right distributive in class; state and prove that multiplication also distributes on the left, eg, for any three numbers, x, y, and z: z * (x + y) ≡ z * x + z * y -} {- We started commutivity of multiplication in class. Finish it here. Note that the proof is in the IAL; feel free to look, but give it a try on your own first. The idea of the proof is similar to that of +. You case split and then, in each case need a helper lemma. One that says what happens when you multiply by zero on the right and one that says how you call "peel off one succ", roughly speaking. (Don't just call the existing proof!) -} *commutes : ∀ n m -> n * m ≡ m * n *commutes n m = {!!} -- This predicate determines if a number is a multiple of three or not m3 : ℕ -> 𝔹 m3 zero = tt m3 (suc zero) = ff m3 (suc (suc zero)) = ff m3 (suc (suc (suc n))) = m3 n {- prove that the sum of two multiples of three is also a multiple of three -} summ3 : ∀ n m -> m3 n ≡ tt -> m3 m ≡ tt -> m3 (n + m) ≡ tt summ3 = {!!} {- prove that the product of a multiple of three and any other number is also a multiple of three -} multm3 : ∀ n m -> m3 n ≡ tt -> m3 (n * m) ≡ tt multm3 = {!!} {- consider this alternative definition of greater than: -} _≥2_ : nat -> nat -> bool zero ≥2 zero = tt zero ≥2 (suc m) = ff (suc n) ≥2 zero = tt (suc n) ≥2 (suc m) = n ≥2 m {- prove that it is the same as the definition in the ial, i.e. prove these two results: -} ≥2->≥ : ∀ n m -> n ≥2 m ≡ tt -> n ≥ m ≡ tt ≥2->≥ = {!!} ≥->≥2 : ∀ n m -> n ≥ m ≡ tt -> n ≥2 m ≡ tt ≥->≥2 = {!!} {- Prove that reversing a list doesn't change it's length, using this definition of rev. Note that you'll really need to prove something about `rh` (reverse helper) and then the main theorem will just be a simple use of the theorem about rh, just like reverse is a simple use of rh. Beware when you do induction on that proof about rh. There is more than one way to use induction (ie more than one way to make the recursive call) and the "obvious" one (well, at least, the one I tried first!) is the wrong one. Note: there is a proof of this in the ial so you can look there if you get stuck; do the proof for these definitions, however -} rh : ∀ {l} {A : Set l} -> 𝕃 A -> 𝕃 A -> 𝕃 A rh [] l2 = l2 rh (x :: l1) l2 = rh l1 (x :: l2) rev : ∀ {l} -> {A : Set l} -> 𝕃 A -> 𝕃 A rev l = rh l [] revtest : rev (1 :: 2 :: 3 :: []) ≡ 3 :: 2 :: 1 :: [] revtest = refl length-reverse : ∀ {l} {A : Set l} (l : 𝕃 A) -> length l ≡ length (rev l) length-reverse = {!!}