[Agda] list for termination counter

Sergei Meshveliani mechvel at botik.ru
Tue Aug 23 19:51:25 CEST 2016


I see now. Thank you.

------
Sergei


On Tue, 2016-08-23 at 13:59 +0200, G. Allais wrote:
> Hi Sergei,
> 
> The issue comes from the pattern-matching lambda: it is quite often
> the case that it hides a termination argument from Agda. Using an
> equivalent `with` clause solves the issue:
> 
> ---------------------------------------------------------------
> add : Op₂ R
> add (r [])       g            =  g
> add f            (r [])       =  f
> add (r (m ∷ ms)) (r (n ∷ ns)) with m ≤? n
> ... | yes _ = let (r hMems) = add (r (m ∷ ms)) (r ns)
>                in  r (n ∷ hMems)
> ... | no _  = let (r hMems) = add (r ms) (r (n ∷ ns))
>                in  r (m ∷ hMems)
> ---------------------------------------------------------------
> 
> Alternatively you can lift the recursive calls outside of the pattern
> matching lambda (if your target language is lazy, the complexity should
> be the same):
> 
> ---------------------------------------------------------------
> add' : Op₂ R
> add' (r [])       g            =  g
> add' f            (r [])       =  f
> add' (r (m ∷ ms)) (r (n ∷ ns)) =
>    let yesIH = add' (r ms) (r (n ∷ ns))
>        noIH  = add' (r ms) (r (n ∷ ns))
>    in case
>          m ≤? n
>      of \
>      { (yes _) → let (r hMems) = yesIH
>                  in  r (n ∷ hMems)
> 
>      ; (no _)  → let (r hMems) = noIH
>                  in  r (m ∷ hMems)
>      }	
> ---------------------------------------------------------------
> 
> Cheers,
> 
> On 22/08/16 14:48, Sergei Meshveliani wrote:
> > Can somebody explain, please,
> > what may be a simple way to prove termination in the following example?
> >
> >
> > ---------------------------------------------------------------
> > open import Function                   using (case_of_)
> > open import Algebra.FunctionProperties using (Op₂)
> > open import Relation.Nullary using (yes; no)
> > open import Relation.Binary  using (DecTotalOrder)
> > open import Relation.Binary.PropositionalEquality as PE using(_≡_)
> > open import Data.Nat  using (ℕ; decTotalOrder)
> > open import Data.List using (List; []; _∷_)
> >
> > open DecTotalOrder decTotalOrder using (_≤?_)
> >
> > record R : Set where
> >                constructor r
> >                field  members : List ℕ
> >
> > add : Op₂ R
> >
> > add (r [])       g            =  g
> > add f            (r [])       =  f
> > add (r (m ∷ ms)) (r (n ∷ ns)) =
> >     case
> >         m ≤? n
> >     of \
> >     { (yes _) → let (r hMems) = add (r (m ∷ ms)) (r ns)
> >                 in  r (n ∷ hMems)
> >
> >     ; (no _)  → let (r hMems) = add (r ms) (r (n ∷ ns))
> >                 in  r (m ∷ hMems)
> >     }
> > --------------------------------------------------------------------
> >
> > This is something similar to merging of ordered lists.
> > Agda does not see termination. I think, this is due to that the lists
> > are kept under the constructor r.
> > So, I extract the two lists and use them as counters for termination:
> >
> > -------------------------------------------------------------------
> > add f g =  aux f g (R.members f) (R.members g) PE.refl PE.refl
> >   where
> >   aux : (f g : R) → (ms ns : List ℕ) → ms ≡ R.members f →
> >                                        ns ≡ R.members g → R
> >
> >   aux (r .[]) g        [] _  PE.refl _       =  g
> >   aux f       (r .[])  _  [] _       PE.refl =  f
> >
> >   aux (r .(m ∷ ms)) (r .(n ∷ ns)) (m ∷ ms) (n ∷ ns) PE.refl PE.refl =
> >     case
> >         m ≤? n
> >     of \
> >     { (yes _) → let (r hMems) = aux (r (m ∷ ms)) (r ns) (m ∷ ms) ns
> >                                                         PE.refl PE.refl
> >                 in  r (n ∷ hMems)
> >
> >     ; (no _)  → let (r hMems) = aux (r ms) (r (n ∷ ns)) ms (n ∷ ns)
> >                                                         PE.refl PE.refl
> >                 in  r (m ∷ hMems)
> >     }
> > ------------------------------------------------------------------------
> >
> > The 'yes' pattern calls aux with  ns  -- which list expression is
> > syntactically smaller than   n ∷ ns.
> > The 'no' pattern calls aux with  ms  -- which list expression is
> > syntactically smaller than   m ∷ ms.
> >
> > But Agda still reports : "Termination checking failed".
> >
> > Why?
> > How to fix?
> > What is a simple way to prove termination in this example?
> >
> > Thanks,
> >
> > ------
> > Sergei
> >
> >
> >
> >
> >
> > _______________________________________________
> > Agda mailing list
> > Agda at lists.chalmers.se
> > https://lists.chalmers.se/mailman/listinfo/agda
> >
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda
> 




More information about the Agda mailing list