{-# OPTIONS --without-K --safe #-} module Lib where open import Data.Empty public open import Data.Unit using (⊤; tt) public open import Data.Sum using (_⊎_; inj₁; inj₂) public open import Data.Maybe using (Maybe; just; nothing) public open import Data.Nat using (ℕ; zero; suc; _+_; _∸_; _≤?_; _≤_; _<_) renaming (_⊔_ to max) public open import Data.Nat.Induction open import Data.Nat.Properties open import Data.Product using (Σ; ∃; ∃₂; _×_; _,_; -,_; proj₁; proj₂) public open import Data.List using (List; []; _∷_; _++_) public open import Data.List.Properties open import Data.List.Relation.Unary.Any using (here; there; _─_) public open import Data.List.Relation.Unary.Any.Properties open import Data.List.Relation.Unary.All using (All; []; _∷_) public open import Data.List.Membership.Propositional hiding (_─_; find) public open import Data.List.Relation.Binary.Sublist.Propositional using ([]; _∷_; _∷ʳ_; _⊆_; ⊆-refl; ⊆-trans) public open import Induction.WellFounded as Wf open import Relation.Nullary using (¬_; yes; no) public open import Relation.Binary using (Rel) open import Relation.Binary.PropositionalEquality using (_≡_; refl; sym; trans; cong; cong₂; subst; subst₂; module ≡-Reasoning) public import Data.Fin import Relation.Binary.Reasoning.Base.Triple as Triple module L = Data.List module All′ = Data.List.Relation.Unary.All module F = Data.Fin open _≤_ public pattern rhere = here refl pattern 1+ x = there x pattern 0d = rhere pattern 1d = 1+ 0d pattern 2d = 1+ 1d pattern 3d = 1+ 2d module _ {a} {A : Set a} where private variable b c : A l l′ l″ : List A ∈-⊆ : b ∈ l → l ⊆ l′ → b ∈ l′ ∈-⊆ b∈l (y ∷ʳ l⊆l′) = there (∈-⊆ b∈l l⊆l′) ∈-⊆ (here refl) (x ∷ l⊆l′) = here x ∈-⊆ (there b∈l) (x ∷ l⊆l′) = there (∈-⊆ b∈l l⊆l′) ∈-⊆-trans : ∀ (b∈l : b ∈ l) (l⊆l′ : l ⊆ l′) (l′⊆l″ : l′ ⊆ l″) → ∈-⊆ (∈-⊆ b∈l l⊆l′) l′⊆l″ ≡ ∈-⊆ b∈l (⊆-trans l⊆l′ l′⊆l″) ∈-⊆-trans b∈l (y ∷ʳ l⊆l′) (z ∷ʳ l′⊆l″) = cong there (∈-⊆-trans b∈l (y ∷ʳ l⊆l′) l′⊆l″) ∈-⊆-trans b∈l (y ∷ʳ l⊆l′) (x ∷ l′⊆l″) = cong there (∈-⊆-trans b∈l l⊆l′ l′⊆l″) ∈-⊆-trans b∈l (x ∷ l⊆l′) (y ∷ʳ l′⊆l″) = cong there (∈-⊆-trans b∈l (x ∷ l⊆l′) l′⊆l″) ∈-⊆-trans (here refl) (refl ∷ l⊆l′) (z ∷ l′⊆l″) = refl ∈-⊆-trans (there b∈l) (x ∷ l⊆l′) (z ∷ l′⊆l″) = cong there (∈-⊆-trans b∈l l⊆l′ l′⊆l″) ⊆-refl-trans : ∀ (l⊆l′ : l ⊆ l′) → ⊆-trans ⊆-refl l⊆l′ ≡ l⊆l′ ⊆-refl-trans [] = refl ⊆-refl-trans {[]} (y ∷ʳ l⊆l′) = cong (y ∷ʳ_) (⊆-refl-trans l⊆l′) ⊆-refl-trans {x ∷ l} (y ∷ʳ l⊆l′) = cong (y ∷ʳ_) (⊆-refl-trans l⊆l′) ⊆-refl-trans (x ∷ l⊆l′) = cong (x ∷_) (⊆-refl-trans l⊆l′) ⊆-trans-refl : ∀ (l⊆l′ : l ⊆ l′) → ⊆-trans l⊆l′ ⊆-refl ≡ l⊆l′ ⊆-trans-refl [] = refl ⊆-trans-refl (y ∷ʳ l⊆l′) = cong (y ∷ʳ_) (⊆-trans-refl l⊆l′) ⊆-trans-refl (refl ∷ l⊆l′) = cong (refl ∷_) (⊆-trans-refl l⊆l′) ⊆-trans-∷ʳ-refl : ∀ b (l⊆l′ : l ⊆ l′) → ⊆-trans l⊆l′ (b ∷ʳ ⊆-refl) ≡ b ∷ʳ l⊆l′ ⊆-trans-∷ʳ-refl b [] = refl ⊆-trans-∷ʳ-refl b (y ∷ʳ l⊆l′) = cong (λ l → b ∷ʳ (y ∷ʳ l)) (⊆-trans-refl l⊆l′) ⊆-trans-∷ʳ-refl b (refl ∷ l⊆l′) = cong (λ l → b ∷ʳ (refl ∷ l)) (⊆-trans-refl l⊆l′) ∈-⊆-refl : ∀ (b∈l : b ∈ l) → ∈-⊆ b∈l ⊆-refl ≡ b∈l ∈-⊆-refl {l = x ∷ l} (here refl) = refl ∈-⊆-refl {l = x ∷ l} (there b∈l) = cong there (∈-⊆-refl b∈l) infixr 5 _++ˡ_ _++ʳ_ infixl 5 _++ʳ′_ _++ˡ_ : ∀ l → l′ ⊆ l″ → l ++ l′ ⊆ l ++ l″ [] ++ˡ l′⊆l″ = l′⊆l″ (x ∷ l) ++ˡ l′⊆l″ = refl ∷ (l ++ˡ l′⊆l″) _++ʳ_ : ∀ l → l′ ⊆ l″ → l′ ⊆ l ++ l″ [] ++ʳ l′⊆l″ = l′⊆l″ (x ∷ l) ++ʳ l′⊆l″ = x ∷ʳ (l ++ʳ l′⊆l″) _++ʳ′_ : l′ ⊆ l″ → ∀ l → l′ ++ l ⊆ l″ ++ l [] ++ʳ′ l = ⊆-refl (x ∷ʳ l′⊆l″) ++ʳ′ l = x ∷ʳ (l′⊆l″ ++ʳ′ l) (eq ∷ l′⊆l″) ++ʳ′ l = eq ∷ (l′⊆l″ ++ʳ′ l) ⊆ʳ : ∀ (l l′ : List A) → l′ ⊆ l ++ l′ ⊆ʳ [] l′ = ⊆-refl ⊆ʳ (x ∷ l) l′ = x ∷ʳ ⊆ʳ l l′ ⊆-++ʳ : ∀ (l⊆l′ : l ⊆ l′) (l′⊆l″ : l′ ⊆ l″) l‴ → ⊆-trans l⊆l′ (l‴ ++ʳ l′⊆l″) ≡ l‴ ++ʳ ⊆-trans l⊆l′ l′⊆l″ ⊆-++ʳ l⊆l′ l′⊆l″ [] = refl ⊆-++ʳ [] l′⊆l″ (x ∷ l‴) = cong (x ∷ʳ_) (⊆-++ʳ [] l′⊆l″ l‴) ⊆-++ʳ (y ∷ʳ l⊆l′) l′⊆l″ (x ∷ l‴) = cong (x ∷ʳ_) (⊆-++ʳ (y ∷ʳ l⊆l′) l′⊆l″ l‴) ⊆-++ʳ (y ∷ l⊆l′) l′⊆l″ (x ∷ l‴) = cong (x ∷ʳ_) (⊆-++ʳ (y ∷ l⊆l′) l′⊆l″ l‴) ⊆-++ʳ′ : ∀ (l⊆l′ : l ⊆ l′) l″ → ⊆-trans l⊆l′ (l″ ++ʳ ⊆-refl) ≡ l″ ++ʳ l⊆l′ ⊆-++ʳ′ l⊆l′ l″ rewrite ⊆-++ʳ l⊆l′ ⊆-refl l″ = cong (l″ ++ʳ_) (⊆-trans-refl _) ⊆-++ʳ-++ˡ : ∀ (l⊆l′ : l ⊆ l′) (l′⊆l″ : l′ ⊆ l″) l‴ → ⊆-trans (l‴ ++ʳ l⊆l′) (l‴ ++ˡ l′⊆l″) ≡ l‴ ++ʳ ⊆-trans l⊆l′ l′⊆l″ ⊆-++ʳ-++ˡ l⊆l′ l′⊆l″ [] = refl ⊆-++ʳ-++ˡ l⊆l′ l′⊆l″ (x ∷ l‴) = cong (x ∷ʳ_) (⊆-++ʳ-++ˡ l⊆l′ l′⊆l″ l‴) ∈-⊆-++ : ∀ l‴ (b∈l : b ∈ l) (l⊆l′ : l ⊆ l′) → ∈-⊆ (++⁺ʳ l‴ b∈l) (l‴ ++ˡ l⊆l′) ≡ ++⁺ʳ l‴ (∈-⊆ b∈l l⊆l′) ∈-⊆-++ [] b∈l l⊆l′ = refl ∈-⊆-++ (c ∷ l‴) b∈l l⊆l′ = cong there (∈-⊆-++ l‴ b∈l l⊆l′) ++ˡ-assoc : ∀ l₁ l₂ {l₃ l₄ : List A} (l₃⊆l₄ : l₃ ⊆ l₄) → subst₂ _⊆_ (++-assoc l₁ l₂ l₃) (++-assoc l₁ l₂ l₄) ((l₁ ++ l₂) ++ˡ l₃⊆l₄) ≡ l₁ ++ˡ l₂ ++ˡ l₃⊆l₄ ++ˡ-assoc [] l₂ l₃⊆l₄ = refl ++ˡ-assoc (x ∷ l₁) l₂ {l₃} {l₄} l₃⊆l₄ with (l₁ ++ l₂) ++ l₃ | (l₁ ++ l₂) ++ l₄ | (l₁ ++ l₂) ++ˡ l₃⊆l₄ | ++-assoc l₁ l₂ l₃ | ++-assoc l₁ l₂ l₄ | ++ˡ-assoc l₁ l₂ l₃⊆l₄ ... | _ | _ | _ | refl | refl | rec = cong (refl ∷_) rec ++⁺ʳ-assoc : ∀ l₁ l₂ (b∈l : b ∈ l) → subst (b ∈_) (++-assoc l₁ l₂ l) (++⁺ʳ (l₁ ++ l₂) b∈l) ≡ ++⁺ʳ l₁ (++⁺ʳ l₂ b∈l) ++⁺ʳ-assoc [] l₂ b∈l = refl ++⁺ʳ-assoc {l = l} (x ∷ l₁) l₂ b∈l with (l₁ ++ l₂) ++ l | ++⁺ʳ (l₁ ++ l₂) b∈l | ++-assoc l₁ l₂ l | ++⁺ʳ-assoc l₁ l₂ b∈l ... | _ | _ | refl | rec = cong there rec find : List A → ℕ → Maybe A find [] n = nothing find (x ∷ l) zero = just x find (x ∷ l) (suc n) = find l n infix 2 _∶_∈_ data _∶_∈_ : ℕ → A → List A → Set a where here : ∀ {x} → 0 ∶ x ∈ x ∷ l there : ∀ {n x y l} → n ∶ x ∈ l → suc n ∶ x ∈ y ∷ l find⇒∈ : ∀ {n} → find l n ≡ just b → n ∶ b ∈ l find⇒∈ {[]} () find⇒∈ {x ∷ l} {_} {zero} refl = here find⇒∈ {x ∷ l} {_} {suc n} eq = there (find⇒∈ eq) length-∈ : ∀ {a} l → L.length l ∶ a ∈ l ++ a ∷ l′ length-∈ [] = here length-∈ (x ∷ l) = there (length-∈ l) split-∈ : ∀ {x a} → x ∶ a ∈ l → ∃₂ λ l′ l″ → l ≡ l′ ++ a ∷ l″ × x ≡ L.length l′ split-∈ here = [] , _ , refl , refl split-∈ (there a∈l) with split-∈ a∈l ... | l′ , l″ , eq , eql = _ ∷ l′ , l″ , cong (_ ∷_) eq , cong suc eql ∈-++ʳ : ∀ {x a} → x ∶ a ∈ l → x ∶ a ∈ l ++ l′ ∈-++ʳ here = here ∈-++ʳ (there a∈l) = there (∈-++ʳ a∈l) subst₃ : ∀ {a b c ℓ} {A : Set a} {B : Set b} {C : Set c} (P : A → B → C → Set ℓ) {x y z u v w} → x ≡ u → y ≡ v → z ≡ w → P x y z → P u v w subst₃ _ refl refl refl p = p cong₃ : ∀ {a b c d} {A : Set a} {B : Set b} {C : Set c} {D : Set d} (f : A → B → C → D) {x y u v w z} → x ≡ y → u ≡ v → w ≡ z → f x u w ≡ f y v z cong₃ f refl refl refl = refl ≤-diff : ∀ {m n} → m ≤ n → ℕ ≤-diff {_} {n} z≤n = n ≤-diff (s≤s m≤n) = ≤-diff m≤n ≤-diff-+ : ∀ {m n} (m≤n : m ≤ n) → m + ≤-diff m≤n ≡ n ≤-diff-+ z≤n = refl ≤-diff-+ (s≤s m≤n) = cong suc (≤-diff-+ m≤n) ap : ∀ {i j} {A : Set i} {B : A → Set j} {f g : (a : A) → B a} → f ≡ g → ∀ a → f a ≡ g a ap refl a = refl module Measure {a b ℓ} {A : Set a} {B : Set b} {_≺_ : Rel A ℓ} (≺-wf : WellFounded _≺_) (m : B → A) where open import Level using () renaming (zero to lzero) open Wf.Inverse-image {_<_ = _≺_} m using (wellFounded) open Wf.All (wellFounded ≺-wf) lzero using (wfRec) public module <-Measure = Measure <-wellFounded (λ x → x)