\import Arith.Nat \import Logic \import Logic.Meta \import Order.StrictOrder \import Paths \func id {A : \Type} => \lam (x : A) => x \func -o {A B C : \Type} (f : A -> B) => \lam (g : B -> C) x => g (f x) \func o- {A B C : \Type} (g : B -> C) => \lam (f : A -> B) x => g (f x) \func \infixr 8 o {A B C : \Type} (g : B -> C) (f : A -> B) => \lam x => g (f x) \func iterl {A : \Type} (f : A -> A) (n : Nat) (a : A) : A \elim n | 0 => a | suc n => iterl f n (f a) \func iterr {A : \Type} (f : A -> A) (n : Nat) (a : A) : A \elim n | 0 => a | suc n => f (iterr f n a) \func iterr-ind {A : \Type} {P : A -> \Type} {f : A -> A} {a0 : A} (p0 : P a0) (s : \Pi {a : A} -> P a -> P (f a)) (n : Nat) : P (iterr f n a0) \elim n | 0 => p0 | suc n => s (iterr-ind p0 s n) \func iterr-index-ind {A : \Type} {P : Nat -> A -> \Type} {f : A -> A} {a0 : A} (p0 : P 0 a0) (s : \Pi {n : Nat} {a : A} -> P n a -> P (suc n) (f a)) (n : Nat) : P n (iterr f n a0) \elim n | 0 => p0 | suc n => s (iterr-index-ind p0 s n) \func isInj {A B : \Set} (f : A -> B) => \Pi {a a' : A} -> f a = f a' -> a = a' \lemma iterr_inj {A : \Set} (f : A -> A) (inj : isInj f) (a : A) (n m : Nat) (p : n < m) (q : iterr f n a = iterr f m a) : a = iterr f (suc (pred (m -' n))) a \elim n, m, p | 0, suc m, NatSemiring.zero<suc => q | suc n, suc m, NatSemiring.suc<suc p => iterr_inj f inj a n m p (inj q) \func isSurj {A B : \Type} (f : A -> B) => \Pi (y : B) -> ∃ (x : A) (f x = y) \where { \lemma comp {A B C : \Type} {f : A -> B} (fs : isSurj f) {g : B -> C} (gs : isSurj g) : isSurj (g o f) => \lam z => \have | (inP (y,gy=z)) => gs z | (inP (x,fx=y)) => fs y \in inP (x, pmap g fx=y *> gy=z) } \func assuming {A B : \Type} (f : (A -> B) -> B) (g : A -> B) => f g \type Image {A B : \Type} (f : A -> B) => \Sigma (b : B) (∃ (a : A) (f a = b)) \meta flip f a b => f b a