• No results found

computational aspects of elimination

Chapter 6 Pattern Matching for Dependent Types

6.2 interactive pattern matching in O LEG

6.2.1 computational aspects of elimination

Suppose a function can be given in terms of anotherÈ as follows:

‡ Y ^ ž D ^ ¥ JRÈ ^ „

What can we infer about the computational behaviour of from that of È ?

This is a very common situation. If È is an elimination rule and we construct by

eliminating some of its arguments withÈ , this is exactly the structure which will take.

If È has a reduction behaviour given by Y-reductions or a pattern matching function in

the Coquand style, we may be able to infer the corresponding behaviour for . For example, we have already seen how to construct 88(9@;A=?> from 88(§Šfg¨ in this way:

how does88(9@;4=?> reduce when it is fed constructor-headed numbers? It is not hard to

check that it inherits the appropriate behaviour from88:§pfg¨ :

88(9@;A=?> C {ø4{ù S ÿ ‡ {ø 88(9@;A=?> C {ø4{ù = G ÿ ‡ {ù G

Similarly, if we want to implement the pattern matching version of¤

f¥y= by means of 88:§pfg¨ , we need to be sure that the defining equations are intensionally recoverable.

In particular, we need to show that any recursive calls to88:§pfg¨ in the implementation

can be replaced by recursive calls to ¤

f¥y= convertible to them. We can achieve this

by a process of unfold/fold transformation on functional programs which respects the computational equality of OLEG.

Let us consider unfolding first.

SupposeÈ is given by a pattern matching program

È DsE­^ w D ^ … J ù È ^ „ d ‡

Ãd (over pattern variables

^ w D ^  d)

From the definition of , we can infer the lengthened equation ^ ž ÿ ‡ È ^ „ (any ^ ž D ^ ¥ ) For each^ „

d, there are two possibilities

Á ^ „ is at least as long as^ „ d Á ^ „ is shorter than^ „ d

In the former case, we may split ^

„ as ^ –x ^  C , so that ^  ^ „ d D ^ … . If ª is a substitution from ^ žyx ^ w to terms over ^ u D ^ ¸ which unifies ^ „ d and ^  , then we have ª ^ ž ÿ ‡ Èúª ™ ^ cx ^  C Ÿ  Èúª ^ „ d x ª ^  C ÿ ‡ ™ ªÃd Ÿ ª ^  C (over^ u D ^ ¸ )

In the latter case, it is ^

„ d which we split as ^ –x ^  C so that^ „ ^  D ^ û , where ^ û is a prefix of ^ … . Ifª is a unifying substitution, then we have

ª ^ ž ÿ ‡ Èúª ^ „  Èúª ^  and therefore ª ^ žyx ª ^  C ÿ ‡ Èúª ™ ^ cx ^  C Ÿ  Èvª ^ „ d ÿ ‡ ªjÃd

Note that we may not, in general, pad out the application of before the unification, because ^

ž

may not have functional type until the ^

ž

have been instantiated.

Folding is more straightforward. If we know that

^ ž ÿ ‡  where ^ ž

is the free pattern, and

]^ „ ÿ ‡ à “ ª 7” (over ^ w D ^  ) then ^ „ ÿ ‡ à “ ª ^ žp” (over^ w D ^  )

I have not explained where these substitutions ª come from,

6 but I do not have to:

unfolding and folding are a pair of techniques by which we can derive new intensional equations from old ones. I do not propose to use them to construct pattern matching programs, but rather to confirm their intensional status. For example, the program¤

f¥y=

may be written in pattern matching notation

¤ f¥y= S w w ¤ f¥y= = ž w ‡ = ™ ¤ f¥y= žÙwRŸ

This quite clearly falls within Coquand’s class of definable functions. We have already seen¤

f¥¦= defined somewhat less perspicuously in OLEG:

¤ f¥y= ‡ 88(§Šfg¨ ™ Y ž D 88ªJM88&ƒ«88 Ÿ ™ Y w D 88ªJ wRŸ ™ Y ž D 88ªJFY ¤ f¥y= ³ D 88&ƒ«88ªJ*Y w D 88ªJV= ™ ¤ f¥¦= ³ wRŸBŸ

We can check that the pattern matching equations hold intensionally for the OLEG

definition. First unfolding with respect to each Y-reduction of88(§pfg¨ :

¤ f¥y= S ‡ Y w D 88ªJ w ¤ f¥y= = ž ‡ Y w D 88ªJM= ™ 88(§pfg¨ J7JMJ žÙwRŸ

Folding with respect to the OLEG definition:

¤ f¥y= S ‡ Y w D 88ªJ w ¤ f¥y= = ž ‡ Y w D 88ªJM= ™ ¤ f¥y= žÙwRŸ Lengthening: ¤ f¥y= S w ‡ w ¤ f¥y= = ž w ‡ = ™ ¤ f¥y= žÙwRŸ

We have checked our implementation of the pattern matching program!

In fact, we can use lengthening, unfolding and folding to check all the dervived com- putation laws in this thesis, and we shall use them in particular to ensure the intensional validity of the pattern matching programs we shall shortly construct.

Of particular interest is the computational effect of case analysis followed by unifica- tion.

Suppose we face the goal

X íDE ^ ž D ^ … J ù where… d is some ZF[A\ ^ z , with the ^ z

in constructor form. Let

ZF[A\

^ u D ¸ œ 9@š›•œ ^ u D ZF[4\ ^ z œ Eliminatingž d by ZF[A\—˜[4?‚ yields, in general: † C ‡ Y ^ w D ZF[A\ E­^ ž D ^ … E^ Ž DŠ^ w ^ zjx1ž d ù .. . X œ DeE ^ u D ^ ¸ œ E­^ ž D ^ … Ey^ Ž DH^ z œ xF™ 9@š›œ ^ u~Ÿ ^ zyx1ž d ù .. . † ‡ Y ^ ž D ^ … Z][4\€([AB‚ C J7JMJ œtJ7JMJ ^ zyx1ž d ™ > ^ zRŸxF™ > ž d Ÿ

Now let us apply the unification algorithm to œ . Either there is no unifier, in which

case we have no need of a computational explanation, or there is a most general unifier

ª~œ . In this case, the new subgoal looks like

X C œ DVE^ w D ^  œ ª~œ ù

Furthermore, having found ª~œ , we may also unfold the definition of with respect to Z][4\€([AB‚

, discovering that for all ^

w ª~œ ^ ž ÿ ‡ œjª~œ ^ u·x ª~œ ^ žyxF™ >üª~œ ™ ^ zyxž d ŸBŸ ÿ ‡ C œ ^ w

The latter conversion holds by the computational properties of the proof term generated by the unification algorithm established in the previous chapter.

This shows us that case analysis with constructor form unification really does corre- spond intensionally to Coquand’s case-splitting step. We are now in a position to prove a crucial metatheorem.