• Keine Ergebnisse gefunden

Quantification Procedures for Second-Order ProceduresProcedures

By Lemma 2.59 (p. 44), (3.9) is equivalent to evalP(p(z)) =true

for all (j, iπ0)∈Occ@Ah(cons) and all z∈Itm(qj, iπ0). (3.10) The conjunction of (3.6) and (3.10) is equivalent to

evalP(p(z)) =true for allz∈Itmτ(x, h) (3.11) by definition ofItmτ(x, h), which proves (1).

2. Ifπ =, then (2) is trivially satisfied.

Ifπ =iπ0, thenevalP(ALLτ(x, π)) =true iff evalP forall.str0i(λy:τi.ALLτi(y, π0), x)

=true (3.12)

by definition ofALL. By (1), this is equivalent to

evalP(ALLτi(z, π0)) =true for allz∈Itmτ(x, i). (3.13) Sincez<T x, we can apply (20): (3.13) is equivalent to evalP(p(z0)) = true for all z ∈ Itmτ(x, i) and all z0 ∈ Itmτi(z, π0). By Lemma 2.59, this is equivalent to evalP(p(z)) = true for all z ∈ Itmτ(x, iπ0) as desired.

3.2 Quantification Procedures for Second-Order

procedure [infixl,10]−(x, y:N) :N<=

if ?0(x) then 0 else if ?0(y)

thenx

else (x)−(y) end

end

procedure [infixl,20]/(x, y:N) :N<=

assume?+(y);

if y > x then 0

else +((x−y)/ y) end

Figure 3.3: Procedures for subtraction and division of natural numbers Using procedurefoldr (Figure 1.4 on p. 7), we can write this as

foldr(/,1, k) . (3.14)

Since procedure “/” may only be applied to pairs (x, y) withy=/0, we might like to know whether the items of listk are of such a form that the context requirement of procedure “/” is satisfied when evaluating (3.14). So which pairs (x, y) of values will “/” be applied to during the evaluation of (3.14)?

Let us do an example:

evalP foldr(/,1,33 :: 12 :: 24 :: 6 ::ε)

=evalP 33/(12/(24/(6/1)))

= 11

In this example, procedure “/” is applied to (6,1), (24,6), (12,4), and (33,3).

The first component of these pairs of values is determined by the items in list k, while the second component is determined by (i) the items in k, (ii) procedure “/”, and (iii) the order thatfoldr applies “/” to the list items.

In the following, we describe the synthesis of a procedure procedure forall.foldr(p: @A×@B→bool,

f: @A×@B →@B, x: @B, k:list[@A]) :bool

that checks ifp(a, b) is satisfied for all (a, b) thatf is applied to when eval-uating foldr(f, x, k). We use this procedure to automatically synthesize a

so-calledcontext hypothesis for (3.14) that ensures that the context require-ment of procedure “/” is satisfied (see Section 3.5):

forall.foldr(λx, y:N.?+(y), /, 1, k) (3.15) 3.2.1 Uniform Synthesis of forall.proc

For the sake of readability, we first define quantification procedures for second-order procedures with one first-order parameter and an (optional) second formal parameter. We generalize this definition afterwards.

Definition 3.6 (Quantification procedures for second-order procedures).

For each second-order procedure

procedure proc(f:τ1×. . .×τm →τf, x:τx) :τproc <=

assumecproc; Bproc

the quantification procedure forall.proc forproc is defined by procedure forall.proc(p:τ1×. . .×τm→bool ,

f:τ1×. . .×τm →τf, x:τx) :bool <=

ALLf(cproc)∧if{cproc,ALLf(Bproc),true}

where

ALLf(v) :=true

ALLf(f(t1, . . . , tm)) :=p(t1, . . . , tm)∧ALLf(t1)∧. . .∧ALLf(tm) ALLf(g(t1, . . . , tn)) :=ALLf(t1)∧. . .∧ALLf(tn)

ALLf(h(λ~y. t, t0)) :=forall.h(λ~y.ALLf(t), λ~y. t, t0)∧ALLf(t0) ALLf(if{t1, t2, t3}) :=ALLf(t1)∧if{t1,ALLf(t2),ALLf(t3)}

ALLf(case{t1;t2, . . ., tn}) :=ALLf(t1)∧case{t1;ALLf(t2), . . .,ALLf(tn)}

ALLf(let{y:= t1; t0}) :=ALLf(t1)∧let{y:= t1; ALLf(t0)}

for any variable v, any first-order function g /∈ Σ(P)cond, g 6= f, and any second-order procedure h (including proc).

Example 3.7. Figure 3.4 shows the resulting quantification procedures for the second-order procedures in Figure 1.3 (p. 6).

• Proceduresforall.map and forall.filter check ifp(x) is satisfied for all items xof listk.

• Procedureforall.every checks ifp0(ei) is satisfied for all itemse1, . . ., eν

of listk =e1::. . . ::en::ε, where ν ∈ {1, . . . , n} is the smallest index such that p(eν) is not satisfied (because every does not call p(eν+1), . . . , p(en) in this case). If no suchν exists, thenν :=n. ♦

procedure forall.map(p: @A→bool, f: @A→@B,

k:list[@A]) :bool <=

if ?ε(k) then true

else if p(hd(k))

then forall.map(p, f,tl(k)) else false

end end

procedure forall.every(p0, p: @A→bool, k:list[@A]) :bool <=

if ?ε(k) then true

else if p0(hd(k)) then if p(hd(k))

then forall.every(p0, p,tl(k)) else true

end else false end

end

procedure forall.filter(p0, p: @A→bool, k:list[@A]) :bool <=

if ?ε(k) then true

else if p0(hd(k))

then forall.filter(p0, p,tl(k)) else false

end end

Figure 3.4: Automatically synthesized quantification procedures for proce-duresmap,every, and filter, cf. Figure 1.3 (p. 6)

procedure forall.foldl(p: @A×@B →bool, f: @A×@B →@A,

x: @A, k:list[@B]) :bool <=

if ?ε(k) then true

else if p(x,hd(k))

then forall.foldl(p, f, f(x,hd(k)),tl(k)) else false

end end

procedure forall.foldr(p: @A×@B→bool, f: @A×@B →@B,

x: @B, k:list[@A]) :bool <=

if ?ε(k) then true

else if p(hd(k), foldr(f, x,tl(k))) then forall.foldr(p, f, x,tl(k)) else false

end end

procedure forall.rev itlist(p: @A×@B →bool, f: @A×@B →@B,

x: @B, k:list[@A]) :bool <=

if ?ε(k) then true

else if p(hd(k), x)

then forall.rev itlist(p, f, f(hd(k), x),tl(k)) else false

end end

Figure 3.5: Automatically synthesized quantification procedures for thefold procedures of Figure 1.4 (p. 7)

Example 3.8. Figure 3.5 shows the resulting quantification procedures for the second-order procedures in Figure 1.4 (p. 7). ♦ Definition 3.6 is generalized to second-order procedures of arbitrary arity as follows: Letproc be a second-order procedure that is defined by

procedure proc(x11, . . . , xnn) :τproc <=

assumecproc;Bproc .

For eachi∈ {1, . . . , n} such that τi is a function type τi10 ×. . .×τm0 → τm+10 , quantification procedure

procedure forall.proci(p:τ10 ×. . .×τm0 →bool, x11, . . . , xnn) :bool <=

ALLxi(cproc)∧if{cproc,ALLxi(Bproc),true}

is defined as in Definition 3.6. The straightforward generalization of the definition ofALLf h(λ~y. t, t0)

to arbitrary numbers of first-order arguments λ~y1. t1, . . . , λ~yk. tk and arguments t01, . . . , t0n of base types is:

ALLxi h(λ~y1. t1, . . . , λ~yk. tk, t01, . . . , t0n) :=

k

^

ν=1

forall.hν λ~yν.ALLxi(tν), λ~y1. t1, . . . , λ~yk. tk, t01, . . . , t0n

∧ALLxi(t01)∧. . .∧ALLxi(t0n) 3.2.2 Properties of forall.proc

In this section we show that procedure forall.proc computes the expected result. We expect that forall.proc(p,f,x) yields true iff p(~q) yieldstrue for all~q withproc(f,x)Bf f(~q).

However, we need to phrase our expectation more precisely. For instance, consider the procedure callmap(hd,(0 ::ε) ::ε). We have:

1. map(hd,(0 ::ε) ::ε)Bhd hd((0 ::ε) ::ε) 2. map(hd,(0 ::ε) ::ε)Bhd hd(0 ::ε)

We get two calls of hd, although list (0 ::ε) ::ε contains just one element (0 ::ε). In fact, procedureforall.map only checksp(0 ::ε), which corresponds to the second call ofhd. This second call ofhd stems from the instantiation of parameter f with hd, whereas the first call of hd occurs already in the body ofmap.

Therefore the following lemma demands thatf be afresh function. This means that f is a λ-expression f = λ~y. g(~y) such that function symbol g neither occurs in the body ofproc nor in the bodies of the proceduresproc0 withproc >+uses proc0. Alternatively, one can imagine f as uniquely labeled (e. g., asf) so that in the example above we can tell the calls of hd apart:

1. map(hd,(0 ::ε) ::ε)7hd hd((0 ::ε) ::ε), because hd 6=hd 2. map(hd,(0 ::ε) ::ε)Bhd hd(0 ::ε)

Lemma 3.9. Let P be a terminating program. Then for all second-order procedures proc ∈Σ(P)as in Definition 3.6, all grounding type substitutions θ∈ GndSubstΩ(P)1, . . . , τm, τf, τx), all values x∈V(P)θ(τx), and all fresh functions p∈V(P)θ(τ1×...×τm→bool) and f∈V(P)θ(τ1×...×τm→τf):

1. evalP(forall.proc(p,f,x))∈ {true,false}

2. forall.proc(p,f,x)Bf f(q1, . . . , qm) =⇒ proc(f,x)Bf f(q1, . . . , qm) 3. forall.proc(p,f,x)Bpp(q1, . . . , qm) =⇒ proc(f,x)Bf f(q1, . . . , qm) 4. evalP(forall.proc(p,f,x)) =true ⇐⇒

evalP(p(q1, . . . , qm)) =true for all q1, . . . , qm∈V(P) with proc(f,x)Bf f(q1, . . . , qm)

Proof. The idea is to show the claims via a proof by contradiction (which actually is an inductive proof). Suppose that there were a >uses-minimal procedure proc and some θproc-minimal values (f,x) such that one of the claims was violated for some p.

Claims (1)–(3) hold because of the following invariant of ALLf (to be proved by structural induction on termt): If the resulting termt0:=ALLf(t) contains a function callϕ(t1, . . . , tn) under call contextC0, then at least one of the following holds:

(i) tcontains a function callϕ(t1, . . . , tn) under some call contextC⊆C0. (ii) ϕ(t1, . . . , tn) =p(t1, . . . , tm) andtcontains a function callf(t1, . . . , tm)

under some call contextC ⊆C0.

(iii) ϕ(t1, . . . , tn) =forall.h(t1, t2, t3) andtcontains a function callh(t2, t3) under some call contextC ⊆C0.

This invariant entails (1) termination offorall.proc (becauseforall.proc con-tains no more recursive calls thanproc by (i) and (iii)) as well as claims (2) (by (i) and (iii)) and (3) of the lemma (by (ii) and (iii)). Claim (4) cannot be violated either because of the following invariant of ALLf (again to be proved by structural induction on termt):

evalP(ALLf(t)[p/p, f /f, x/x]) =true ⇐⇒

evalP(p(q1, . . . , qm)) =true for all q1, . . . , qm∈V(P) withf(q1, . . . , qm)∈Callsf(t[p/p, f /f, x/x])

Thus there cannot exist minimalproc,f, andxthat violate the claims, which proves the lemma.

Checking properties of function calls. The construction ALLf(t) of Definition 3.6 checks if some predicate p holds for all f-calls. We can gen-eralize this construction in a straightforward way to arbitrary many func-tions f1, . . . , fm to check that each call fj(q1, . . . , qnj) satisfies a certain predicatepfj(q1, . . . , qnj).

LetP be a terminating L-program and lett∈ T(Σ(P),V) be a normal-ized term of a base type. Furthermore, let

• V0⊆ Vf(t) be the set of all term variables of base types in t,

• V1⊆ Vf(t) be the set of all first-order term variables in t,

• Σ1 ⊆Σ(t)\Σ(P)cond be the set of all first-order function symbols in t different fromif and case, and

• Σ2 ⊆Σ(t) be the set of all second-order function symbols in t.

For each function typeτ =τ1×. . .×τn→τn+1 ∈Types(Ω(P),W) and each f ∈ V1∪Σ1 ∪Σ2 with f:τ, let pf : τ1×. . .×τn → bool be a fresh term variable.

We define a term Chk(t) ∈ T(Σ(P),V ∪ {pf | f ∈ V1∪Σ1∪Σ2})bool that checks if pf is satisfied for each call of f in t by case analysis over the form of term t. In the following definition, x ∈ V0 is a term variable, f ∈ V1 ∪Σ1 is a first-order function or term variable, and h ∈ Σ2 is a second-order procedure:

Chk(x) :=true

Chk(f(t1, . . . , tn)) :=pf(t1, . . . , tn)∧Chk(t1)∧. . .∧Chk(tn) Chk(h(λ~y. t1, t2)) :=ph(λ~y. t1, t2)∧Chk(t2)∧

forall.h(λ~y.Chk(t1), λ~y. t1, t2) Chk(if{t1, t2, t3}) :=Chk(t1)∧if{t1,Chk(t2),Chk(t3)}

Chk(case{t1;t2, . . . , tn}) :=Chk(t1)∧case{t1;Chk(t2), . . . ,Chk(tn)}

Chk(let{x:= t1; t0}) :=Chk(t1)∧let{y:= t1; Chk(t0)}

This construction appears in various guises for different purposes. For instance, in Section 3.5 we use it to generate so-called context hypotheses that ensure that for each function callf(q1, . . . , qn) in a termt, the context requirementcf[q1, . . . , qn] of f is satisfied.