In Agda, I can make the following definition, and Agda believes that the recursion terminates. Notice that the arguments “swap places” in the recursive call, so neither of the arguments individually gets obviously smaller.
open import Data.List
ripple : ∀ {a} {A : Set a} → List A → List A → List A
ripple [] ys = ys
ripple (x ∷ xs) ys = x ∷ ripple ys xs
I am interested in how other proof assistants deal with this recursion pattern. I have tried calquing this definition into Coq using Fixpoint
, but predictably it can't find a decreasing argument. Answers to this question should establish that ripple
terminates (either because all functions in the language terminate, or because an explicit termination proof is given), and preferably be as idiomatic and lightweight as possible.
I think I first heard of this exercise, in some form or another, from Conor McBride.