[Agda] Recursive definitions over lists
Guillaume Allais
gallais at cs.ru.nl
Tue Jun 25 10:58:03 CEST 2019
Hi Phil,
First of all the code-free answer: AllTree is accepted because Agda recorded
internally that `All`'s first argument was only ever used in a strictly
positive manner. It is therefore legal to take the fixpoint of that definition.
Regarding the definition of mapTree, the problem is the level of indirection
introduced by `map`: it is not obvious for Agda that the partially applied
recursive call `mapTree f` will only ever be used on subterms.
As you have observed, inlining `map` is a possible solution to remove this
level of indirection. Another one is to start using sized types so that the
notion of being a subterm becomes a type-level one.
Cf. this recent discussion on the mailing list:
https://lists.chalmers.se/pipermail/agda/2019/011209.html
and in particular this message with code for a similar sized inductive type:
https://lists.chalmers.se/pipermail/agda/2019/011212.html
Cheers,
--
gallais
On 24/06/2019 22:05, Philip Wadler wrote:
> Consider the following code.
>
> \begin{code}
> module Tree where
>
> open import Data.List using (List; []; _∷_; map)
> open import Data.List.All using (All; []; _∷_)
>
> data Tree (A : Set) : Set where
> node : List (Tree A) → Tree A
>
> mapTree : ∀ {A B : Set} → (A → B) → Tree A → Tree B
> mapTree f (node ts) = node (map (mapTree f) ts)
>
> mapTree′ : ∀ {A B : Set} → (A → B) → Tree A → Tree B
> mapForest′ : ∀ {A B : Set} → (A → B) → List (Tree A) → List (Tree B)
>
> mapTree′ f (node ts) = node (mapForest′ f ts)
> mapForest′ f [] = []
> mapForest′ f (t ∷ ts) = mapTree′ f t ∷ mapForest′ f ts
>
> data AllTree {A : Set} (P : A → Set) : Tree A → Set where
> node : ∀ {ts : List (Tree A)}
> → All (AllTree P) ts
> -------------------
> → AllTree P (node ts)
> \end{code}
>
> Agda complains that the first definition of mapTree may not terminate.
>
> Termination checking failed for the following functions:
> mapTree
> Problematic calls:
> mapTree f
> (at /Users/wadler/Desktop/Tree.lagda:11,38-45)
>
> I guess this is because it is not quite clever enough to figure out that in
> the definition of (mapTree (node ts)) that the recursive invocation
> (mapTree f) is in fact always applied to a substructure of ts.
>
> One way to get Agda to accept the definition is to rewrite it as two
> mutually recursive functions, one of which expands the definition of map.
> Is this the recommend way to solve the problem, or is there a better
> alternative?
>
> I'm surprised to note that Agda does not make a similar complaint about the
> definition of AllTree. Why not?
>
> Cheers, -- P
>
> . \ Philip Wadler, Professor of Theoretical Computer Science,
> . /\ School of Informatics, University of Edinburgh
> . / \ and Senior Research Fellow, IOHK
> . http://homepages.inf.ed.ac.uk/wadler/
>
>
> The University of Edinburgh is a charitable body, registered in
> Scotland, with registration number SC005336.
>
>
> _______________________________________________
> Agda mailing list
> Agda at lists.chalmers.se
> https://lists.chalmers.se/mailman/listinfo/agda
>
More information about the Agda
mailing list