Agda-2.3.2.2: test/succeed/TerminationArgumentSwapping.agda
module TerminationArgumentSwapping where
-- subtyping simple types
data Bool : Set where
true : Bool
false : Bool
_&&_ : Bool -> Bool -> Bool
true && a = a
false && a = false
data Ty : Set where
bot : Ty
top : Ty
arr : Ty -> Ty -> Ty
subty : Ty -> Ty -> Bool
subty bot _ = true
subty _ top = true
subty (arr a b) (arr a' b') = subty a' a && subty b b'
subty _ _ = false
-- maximum with happy swapping
data Nat : Set where
zero : Nat
succ : Nat -> Nat
-- Maximum of 3 numbers
max3 : Nat -> Nat -> Nat -> Nat
max3 zero zero z = z
max3 zero y zero = y
max3 x zero zero = x
max3 (succ x) (succ y) zero = succ (max3 x y zero)
max3 (succ x) zero (succ z) = succ (max3 x z zero)
max3 zero (succ y) (succ z) = succ (max3 y z zero)
max3 (succ x) (succ y) (succ z) = succ (max3 z x y)
-- can also be done with sized types
-- max3 : Nat^i -> Nat^i -> Nat^i -> Nat^i
-- swapping with higher-order datatypes
data Ord : Set where
ozero : Ord
olim : (Nat -> Ord) -> Ord
foo : Ord -> (Nat -> Ord) -> Ord
foo ozero g = ozero
foo (olim f) g = olim (\n -> foo (g n) f)