------------------------------------------------------------------------ -- The Agda standard library -- -- An abstraction of various forms of recursion/induction ------------------------------------------------------------------------ -- The idea underlying Induction.* comes from Epigram 1, see Section 4 -- of "The view from the left" by McBride and McKinna. -- Note: The types in this module can perhaps be easier to understand -- if they are normalised. Note also that Agda can do the -- normalisation for you. {-# OPTIONS --cubical-compatible --safe #-} module Induction where open import Level open import Relation.Unary open import Relation.Unary.PredicateTransformer using (PT) private variable a ℓ ℓ₁ ℓ₂ : Level A : Set a Q : Pred A ℓ Rec : PT A A ℓ₁ ℓ₂ ------------------------------------------------------------------------ -- A RecStruct describes the allowed structure of recursion. The -- examples in Data.Nat.Induction should explain what this is all -- about. RecStruct : Set a → (ℓ₁ ℓ₂ : Level) → Set _ RecStruct A = PT A A -- A recursor builder constructs an instance of a recursion structure -- for a given input. RecursorBuilder : RecStruct A ℓ₁ ℓ₂ → Set _ RecursorBuilder Rec = ∀ P → Rec P ⊆′ P → Universal (Rec P) -- A recursor can be used to actually compute/prove something useful. Recursor : RecStruct A ℓ₁ ℓ₂ → Set _ Recursor Rec = ∀ P → Rec P ⊆′ P → Universal P -- And recursors can be constructed from recursor builders. build : RecursorBuilder Rec → Recursor Rec build builder P f x = f x (builder P f x) -- We can repeat the exercise above for subsets of the type we are -- recursing over. SubsetRecursorBuilder : Pred A ℓ → RecStruct A ℓ₁ ℓ₂ → Set _ SubsetRecursorBuilder Q Rec = ∀ P → Rec P ⊆′ P → Q ⊆′ Rec P SubsetRecursor : Pred A ℓ → RecStruct A ℓ₁ ℓ₂ → Set _ SubsetRecursor Q Rec = ∀ P → Rec P ⊆′ P → Q ⊆′ P subsetBuild : SubsetRecursorBuilder Q Rec → SubsetRecursor Q Rec subsetBuild builder P f x q = f x (builder P f x q)