{-# OPTIONS --type-in-type
#-}
open import NeilPrelude
open import Nat
open import List
module Recursion where
listrec : {A : Set} → {P : List A → Set} → P [] → ({a : A} → {as : List A} → P as → P (a ∷ as)) → Π (List A) P
listrec base step [] = base
listrec {_} {P} base step (_ ∷ as) = step (listrec {_} {P} base step as)
listrec' : {A : Set} → {P : List A → Set} → P [] → ((a : A) → (as : List A) → P as → P (a ∷ as)) → Π (List A) P
listrec' base step = listrec base (λ {a} {as} → step a as)
natrec : {P : ℕ → Set} → P O → ({m : ℕ} → P m → P (S m)) → Π ℕ P
natrec base step O = base
natrec {P} base step (S n) = step (natrec {P} base step n)
natrec2 : {P : ℕ → ℕ → Set} → ((n : ℕ) → P O n) → ((m : ℕ) → P m O) → ({m n : ℕ} → P m n → P (S m) n → P m (S n) → P (S m) (S n)) → (m n : ℕ) → P m n
natrec2 baseL baseR step O n = baseL n
natrec2 baseL baseR step m O = baseR m
natrec2 {P} baseL baseR step (S m) (S n) = step (natrec2 {P} baseL baseR step m n)
(natrec2 {P} baseL baseR step (S m) n)
(natrec2 {P} baseL baseR step m (S n))
natrec2simpl : {P : ℕ → ℕ → Set} → ((n : ℕ) → P O n) → ((m : ℕ) → P m O) → ({m n : ℕ} → P m n → P (S m) (S n)) → (m n : ℕ) → P m n
natrec2simpl baseL baseR step O n = baseL n
natrec2simpl baseL baseR step m O = baseR m
natrec2simpl {P} baseL baseR step (S m) (S n) = step (natrec2simpl {P} baseL baseR step m n)
CRec : (ℕ → Set) → ℕ → Set
CRec P O = True
CRec P (S n) = P n × CRec P n
mutual
comrec : {P : ℕ → Set} → ((m : ℕ) → CRec P m → P m) → Π ℕ P
comrec step n = step n (covrec step n)
covrec : {P : ℕ → Set} → ((m : ℕ) → CRec P m → P m) → Π ℕ (CRec P)
covrec step O = _
covrec step (S n) = comrec step n , covrec step n
CReclist : {A : Set} → (List A → Set) → List A → Set
CReclist P [] = True
CReclist P (_ ∷ as) = P as × CReclist P as
mutual
comreclist : {A : Set} → {P : List A → Set} → ((bs : List A) → CReclist P bs → P bs) → Π (List A) P
comreclist step as = step as (covreclist step as)
covreclist : {A : Set} → {P : List A → Set} → ((bs : List A) → CReclist P bs → P bs) → Π (List A) (CReclist P)
covreclist step [] = _
covreclist step (_ ∷ as) = comreclist step as , covreclist step as
data W (A : Set) (B : A → Set) : Set where
sup : (a : A) → (B a → W A B) → W A B
wrec : {A : Set} → {B : A → Set} → (P : W A B → Set) → ((a : A) → (f : B a → W A B) → ((b : B a) → P (f b)) → P (sup a f)) → Π (W A B) P
wrec P step (sup a f) = step a f (λ b → wrec P step (f b))
initialW : {A : Set} → {B : A → Set} → Σ A (Not ∘ B) → W A B
initialW (a , nb) = sup a (absurd ∘ nb)
terminatingW : {A : Set} → {B : A → Set} → W A B → Not (Π A B)
terminatingW (sup a fw) fb = terminatingW (fw (fb a)) fb
data Acc (A : Set) (_≺_ : A → A → Set) (a : A) : Set where
acc : ((y : A) → y ≺ a → Acc A _≺_ y) → Acc A _≺_ a
mutual
wfrec : {A : Set} → {_≺_ : A → A → Set} → {P : A → Set} → (a : A) → ((y : A) → Acc A _≺_ y → ((z : A) → z ≺ y → P z) → P y) → Acc A _≺_ a → P a
wfrec a step Aa = step a Aa (wfrec' step Aa)
wfrec' : {A : Set} → {_≺_ : A → A → Set} → {P : A → Set} → {a : A} → ((y : A) → Acc A _≺_ y → ((z : A) → z ≺ y → P z) → P y) → Acc A _≺_ a → (z : A) → z ≺ a → P z
wfrec' step (acc f) z za = wfrec z step (f z za)
acc-init : {A : Set} → {_≺_ : A → A → Set} → {a : A} → ((y : A) → Not (y ≺ a)) → Acc A _≺_ a
acc-init f = acc (λ y → absurd ∘ f y)