agdanon-termination

How to choose the design for a well-founded inductive type?


While studying well-foundedness, I wanted to see how different designs behave. For example, for a type:

data _<_ (x : Nat) : Nat -> Set where
   <-b : x < (suc x)
   <-s : (y : Nat) -> x < y -> x < (suc y)

well-foundedness is easy to demonstrate. But if a similar type is defined differently:

data _<_ : Nat -> Nat -> Set where
   z-< : (m : Nat) -> zero < (suc m)
   s<s : (m n : Nat) -> m < n -> (suc m) < (suc n)

It is obvious that in both cases the descending chain is not infinite, but in the second case well-foundedness is not easy to demonstrate: it is not easy to show (y -> y < x -> Acc y) exists for a given x.

Are there some principles that help choose the designs like the first in preference to the designs like the second?


It's not impossibly hard to prove well-foundedness of the second definition, it just requires extra theorems. Here, relying on decidability of _==_ for Nat, we can construct new _<_ for the case (suc y) != x, and can rewrite the target types to use the solution to the problem known to decrease in size as the solution for suc y.

-- trying to express well-foundedness is tricky, because of how x < y is defined:
-- since both x and y decrease in the inductive step case, need special effort to
-- prove when the induction stops - when no more constructors are available
<-Well-founded : Well-founded Nat _<_
<-Well-founded x = acc (aux x) where
   aux : (x y : Nat) -> y < x -> Acc _<_ y
   aux zero    y       ()
   aux x       zero    z-<           = acc \_ ()
   aux (suc x) (suc y) (s<s y<x) with is-eq? (suc y) x
   ...                   | no  sy!=x = aux x (suc y) (neq y<x sy!=x)
   ...                   | yes sy==x rewrite sy==x = <-Well-founded x

Solution

  • The first definition is "canonical" in a sense, while the second one is not. In Agda, every inductive type has a subterm relation which is well-founded and transitive, although not necessarily total, decidable or proof-irrelevant. For W-types, it's the following:

    open import Data.Product
    open import Data.Sum
    open import Relation.Binary.PropositionalEquality
    
    data W (S : Set)(P : S → Set) : Set where
      lim : ∀ s → (P s → W S P) → W S P
    
    _<_ : ∀ {S P} → W S P → W S P → Set
    a < lim s f = ∃ λ p → a ≡ f p ⊎ a < f p
    

    If we define Nat as a W-type, then the generic _<_ is the same as the first definition. The first definition establishes a subterm relation even if we have no idea about the constructors of Nat. The second definition is only a subterm relation because we know that zero is reachable from every suc n. If we added an extra zero' : Nat constructor, then this would not be the case anymore.