• No results found

Chapter 6 Pattern Matching for Dependent Types

6.3 recognising programs

6.4.2 more exotic recursion

While it is sufficient to facilitate functions which are only recursive on one argument position, it is nonetheless convenient to allow more complex structures to be built into a single function, rather than forcing the programmer to break them up. The traditional example is Ackermann’s function:

;Ak D 88&ƒ«88$ƒ 88 ;Ak SÙG ‡ = G ;AkÞ= Œ S ‡ ;4k Œ = S ;AkÞ= Œ = G ‡ ;Ak Œ ™ ;AkÙ= Œ€G Ÿ

The recursion in this function is lexicographic in the sense that either the first argument decreases structurally, or else it stays the same, but the second argument decreases. It can be split into a pair of Coquand-accepted primitive recursive functionals as follows:

;Ak ¯ D ™ 88 ƒ 88 Ÿ ƒ«88$ƒ 88 ;Ak ¯ ÂMŒÍ S ‡ Â7Œ[Í = S ;Ak ¯ ÂMŒÍ = G ‡ Â7Œ[Í ™ ;Ak ¯ ÂMŒÍ G Ÿ ;Ak D 88&ƒ«88$ƒ 88 ;Ak S ‡ = ;AkÞ= Œ ‡ ;Ak ¯ ™ ;Ak Œ Ÿ

What has happened here? For a start, the main ;Ak function has been ’d into a

functional. This enables the =

Œ

case to be delegated to the auxiliary function;Ak ¯

This receives as an argument the function;Ak , available by structural recursion—it

is thus free to apply this function, as well as making its own guarded calls.8

Would not all but the most die-hard of origami programmers9prefer to write the lex-

icographic version? In fact, we already have the tools to construct it interactively— suppose we have reached the following stage:

X Ê k DEpŒ GÉD 88KJMLMNPORQ XR‘ [Aoo DEpŒ GÉD 88KJ ™ Ê k Œ€G Ÿ ƒ 88 X Ç ‚ýÆÇÇ ä DEpŒ GÉD 88KJM88 ƒ Ê k Œ€G † ;Ak ® ‡ Y ‘Ž?Œ„ D ÏÏ Y G D 88 = G XM;Ak ¯ DE‹Œ D 88 E  Ž?Œ„ D ™ EHGÅD 88ªJ Ê k Œ—G ŸsÐޙ 88 Ê ¥¦Ë J7JMJ Œ Ÿ EŠG D 88 Ê kº= Œ€G † ;Ak ‡ 88 © g˺J7JMJ The ŽBŒ}„

argument gives us access to guarded recursion on the first argument. We may now add guarded recursion on the second (for the same first argument) by eliminating

G with88 © gË , fixing Œ and‘Ž?Œ„ : XM;Ak ¯ DVEpŒ D 88 E ‘Ž?Œ„ D ™ EHGÉD 88ªJ Ê k Œ€G ŸsÐ(™ 88 Ê ¥yË J7J7J Œ Ÿ EHG D 88 E ‘Ž?Œ„ C D 88 Ê ¥yË ™ Ê kº= Œ Ÿ G Ê kÞ= Œ—G Case splitting onG now gives us

8We would not need to pass

!" #%$ explicitly through the recursion if we could define&(')+*$ locally

to the successor case of&,'-) .

XM;Ak D}EpŒ D 88 E ‘Ž?Œ„ D ™ EHGÅD 88ªJ Ê k Œ G Ÿ]Ð:™ 88 Ê ¥yË J7J7J Œ Ÿ E ‘Ž?Œ„'C D ÏÏ Ê kÞ= Œ&S XM;Ak ¯¯ D}EpŒ D 88 E ‘Ž?Œ„ D ™ EHGÅD 88ªJ Ê k Œ G Ÿ]Ð:™ 88 Ê ¥yË J7J7J Œ Ÿ EHG D 88 E ‘Ž?Œ„'C D ™ Ê kÞ= Œ€G ŸsÐ(™ 88 Ê ¥yË ™ Ê kÙ= Œ Ÿ G Ÿ Ê kÞ= Œ = G For the ;4k ¯®

case, we may project the appropriate component of ŽBŒ}„

. Looking at

;Ak ¯¯

in more detail, the nested right-hand side translates by‘ [Aoo and ǂýÆÇ Ç ä to XM;Ak ¯¯ D Y Œ D 88 Y ‘Ž?Œ„ D ™ EHGÅD 88ªJ Ê k Œ—G ŸsÐޙ 88 Ê ¥¦Ë J7JMJ Œ Ÿ Y G D 88 Y ‘Ž?Œ„ C D ™ Ê kÞ= Œ€G ŸsÐ:™ 88 Ê ¥¦Ë ™ Ê kÙ= Œ Ÿ G Ÿ X ‘Ž?ŒK D Ê kÙ= Œ€G X ‘Ž?ŒRM D Ê k Œ ™ ‘ [Aoo  Ž?ŒK‘Ÿ Ç ‚ýÆÇ Ç ä ™ ‘ [4oo ‘Ž?ŒVMŸ  Ž?ŒK is solved from ŽBŒ}„ C and‘Ž?ŒRM is solved from Ž?Œ„

. The definition is complete.

We can build quite complex structures with multiple eliminations by guarded recursion—more even than lexicographic recursion on a number of argument posi- tions. For example, we may define a function on lists of trees which at each recursion replaces the head tree by its subtrees—some steps may make the list longer, but the decomposition of the head tree guarantees termination.

The question of how to extend the class of recognisable pattern matching programs into this more exotic territory is an important and interesting one. Much attention has already been paid to the simply typed case, for example, in Manoury and Simonot’s ‘ProPre’ [MS94] system. Further, Cristina Cornes has equipped COQwith a substantial

package translating equational programs with relatively interesting recursive structure into constructor guarded fixpoint expressions [Cor97].

Further investigation is beyond the scope of this thesis. However, I shall nonetheless write such equational programs in the following chapter, since they are shorter and clearer than their expanded versions where each recursion has its own subfunction. When I do so, I shall always be careful to point out the justification, imagining that we are deriving the function interactively.