Relatively Complete Verification of Higher-Order Programs
72K - views

Relatively Complete Verification of Higher-Order Programs

(via Automated Refinement Type Inference). Tachio. Terauchi. Nagoya University. TexPoint fonts used in EMF. . Read the TexPoint manual before you delete this box.: . A. A. A. A. A. A. A. A. A. Verifying higher-order functional programs.

Download Presentation

Relatively Complete Verification of Higher-Order Programs




Download Presentation - The PPT/PDF document "Relatively Complete Verification of High..." is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.



Presentation on theme: "Relatively Complete Verification of Higher-Order Programs"— Presentation transcript:

Slide1

Relatively Complete Verification of Higher-Order Programs (via Automated Refinement Type Inference)

Tachio TerauchiNagoya University

TexPoint fonts used in EMF.

Read the TexPoint manual before you delete this box.:

A

A

A

A

A

A

A

A

A

Slide2

Verifying higher-order functional programs

let rec F x c = c x inand G x y = assert x+1 ¸ y; F (y+1) (G y) inand Main w = F (w+1) (G w)

Show : 8w:int. Main w is assertion safe

Refinement types approach:

F : x:int -> c

:(

{

u|u

¸

x} -> *) -> *

G : x:int -> y:{u|x+1

¸

y} -> *

Main: w:int -> *

Slide3

Much recent work on automated inference

Liquid types [Rondon, Kawaguchi, Jhala PLDI’08]Dependent type inference with interpolants [Unno, Kobayashi PPDP’09]Dependent types from counterexamples [Terauchi POPL’10]Predicate abstraction and CEGAR for higher-order model checking [Kobayashi, Sato, Unno PLDI’11]HMC: Verifying functional programs using abstract interpreters [Jhala, Majumdar, Rybalchenko CAV’11]“?” [Jagannathan 2011]Leverages advances in first-order program verification: predicate abstraction, interpolation, CEGAR, SMT solvers, Test generation, etc.“Model Checkers” for higher-order programs

Incomplete

Slide4

Completeness and Incompleteness

Def: Refinement type system is

sound

iff

If a program is

typable

then it is safe.

Def: Refinement type system is

complete

iff

A program is

typable

iff

it is safe.

Existing refinement type systems are sound, but incomplete

D

ifferent from incompleteness of inference algorithms

Slide5

Relative Completeness

Higher-order program verification is

undecidable

Because

it contains 1

st

-order program verification

Complete verification for 1

st

-ord programs

E.g., Hoare logic

Relative to expressive 1

st

-ord theory like PA

Allow arbitrary PA formulas as refinement predicates? i.e., { u |

µ

}

µ

2

PA

Sufficient for ord-1 programs

Not for general higher-order programs

Slide6

Refinement types incompleteness in detail

Problem:

H

igher-order functions

A typical relative completeness proof of Hoare logic

wpre

(x = e,

µ

) =

µ

[x/e]

wpre

(s

1

;s

2

,

µ

) =

wpre

(s

1

,wpre(s

2

,

µ

)) , …

Show the logic (PA) can express

wpre

(…)

Then, s is safe

iff

wpre

(

s,true

) = true.

What’s

wpre

(f x,

µ

) where f :

int

-> * and x :

int

?

Or

wpre

(g f,

µ

) with g : (

int

-> *) -> * and f : (

int

-> *)?

Slide7

Weakest pre. of higher-order terms

Ideally:

wpre

(f x, true) = “f x runs safe”

Ex. F

f

x = f x

F : f

:(

int

->*)->x:{ u :

int

| “f u runs safe” }->*

But, ref. pred. inference becomes higher-order program verification!

To prevent circularity, we only allow 1

st

-ord formulas

I don’t have relative completeness for all

higer

-order programs yet

I will show: How to get relative completeness for a class that haven’t been covered previously

Slide8

Closure Boudedness

Def:

Size of a closure

is the number of base-type values captured in the closure

Def: A program is

closure-bounded

if its evaluation only generates closures of bounded size

Def:

Closure pattern

is a closure with base-type values abstracted

E.g., F (G

®

)

®

represent infinite number of closures F (G 0) 0, F (G 0) 1, F (G 1) -1, …

In lambda,

¸

x.(y (

¸

z.z

®

)

®

), etc.

Lemma: Closure-bounded

iff

finite # of patterns

Slide9

Contribution

Relative completeness for closure-bounded programsHigh-level Idea : Environment Passing

F c f = c f G x k = k x H x y = assert x · y; F (G y+1) (H y)Main w = F (G w+1) (H w)

Parametrize

type of F with G

®, H ®

F : 8a1.8a2.c:(({u|µ1}->*)->*)->f:({u|µ2} ->*) ->*

Intersection types to handle different contexts(this example needs none)

Show: 8w:int. Main w as safe

Slide10

Details

Naïve Approach :

Symbolically evaluate

the program for n steps and record

closure patterns seen

Build

type shapes

from the patterns

Check if

typable

restricted to the type shapes

If not

typable

,

increase n and repeat

(In parallel) check for

unsafety

Slide11

Symbolic Eval => Closure Patterns

Patterns A := F | ® | F AEx. Evaluate from M with w : intPatterns: F (G ®) ®, …

F c x = c x

G x y = assert x+1

·

y ; F (G y) (y+1)

M w = F (G w) (w+1)

Slide12

Patterns => Type shapes

Types t := * | x:t -> t | {u|µ} | 8x.t | [A].t Æ [A].tType shapes = N £ types with µ erased E.g., (3, f:{u|_}->*)ord(A) = order of simple type of A A => (v,t’) inductively on the order of AEx. A = F : Seen patterns: F (G ®) ®, F (H ® ®) ®, …ty(F) = (0, [(G ®), ®].8a1.t1->®.s->* Æ [(H ® ®), ®].8a18a2.t2->®.s->*)ty(®) = (0,s), ty(G ®) = (1,t1), ty(H ® ®) = (2, t2), …

Slide13

Checking typability

Shapes & patterns => derivation structureFor each F, have patterns A1, …, An for its argsMake type derivation per F, AiEx. Patterns : F (G ®) (K ®) ® for F c f x = c f xTrack concrete patterns: c: G a1, f: K a2, x: x, …, up to base-type parameter variablesAt function applicationsLook up ty(...) for matching abstract patternsInstantiate with captured base-type variablesUse “top” type to handle unmatched shapesInfer satisfying assignment for µ’sIf none found, fail

Slide14

Summary of naïve approach

Symbolically evaluate

the program for n steps and record

closure patterns seen

Build

type shapes

from the patterns

Check if

typable

restricted to the type shapes

If not

typable

,

increase n and repeat

(In parallel) check for

unsafety

Thm

: This is rel. comp. for closure-bounded programs

Pf. Like that of Hoare logic. “Thread” weakest precondition through the type derivation.

Cor

: 1

st

-order program verification can be “lifted” to closure-bounded higher-order program verification

Slide15

Naïve approach

Relatively complete but not very clever

Patterns sufficient but not always necessary

Fails for non-closure-bounded programs

Better approach:

Try type inference w/o patterns

If type inference fails, then infer patterns

Repeat with the added patterns

Also, just add candidate

8

x.t, e[e’] and have type inf. alg. figure out the rest (i.e., rid patterns from type inference)

Slide16

Check typability w/o patterns

Leverage existing algorithms

Liquid types [

Rondon

, Kawaguchi,

Jhala

PLDI’08]

Dependent type inference with

interpolants

[

Unno

, Kobayashi PPDP’09]

Dependent types from counterexamples [Terauchi POPL’10]

Predicate abstraction and CEGAR for higher-order model checking [Kobayashi, Sato,

Unno

PLDI’11]

HMC: Verifying functional programs using abstract interpreters [

Jhala

,

Majumdar

,

Rybalchenko

CAV’11]

Slide17

Use the symbolic evaluation as in naïveOr use counterexample from type inference[Terauchi POPL’10][Kobayashi, Sato, Unno PLDI’11]Unwound program slice without recursionInfer patterns that occur in slice via flow analysis

If inference fails, infer patterns

Slide18

Check typability with the added patterns

Like the naïve approach,

b

ut

Instead of using the patterns

i.e.,

c :

G w

, …, and

[(G

®

),

®

].

8

x.t1->

®

.s->*, …, etc.

Use the built type shapes minus the patterns

c :

8

x.{u | _} -> *, …

And how to instantiate them

Let backend type inference alg. resolve type matching (as well as

µ

inference)

Implement as program translation

Slide19

Program Translation

Universal types 8x.t modeled by x:int -> tInstantiations e[e’] modeled by e e’

F c f = c f G x k = k x H x y = assert x · y main w = F (G w) (H w)

F a1 a2 c f = c f G x k = k x H x y = assert x · y main w = F w (G w) w (H w)

ty(F) = (nil,8a1.8a2.c:(({u|_}->*)->*)->f:({u|_} ->*) ->*)ty(G ®) = ([w],…)ty(H ®) = ([w],…)

Multiple trans. when ty(…) has intersection types(none needed for this example)

Slide20

Summary of translation approach

Try type inference w/o patterns

If type inference fails, then infer patterns

Repeat with the added patterns

Uses off-the-shelf refinement type inference algorithms

Complete relative to

Underlying refinement type inference

And pattern

generation

Incomplete in practice (obviously)

Slide21

Preliminary Experimental Results

Depcegar [Terauchi POPL’10]

Slide22

Conclusions

Relatively complete verification framework for higher-order programs

Based on refinement types

Good for “model checking” like automation

Frees the backend theorem

prover

/decision

prover

from directly reasoning about higher-order functions

High-level : Environment passing

Theory : Rel. comp. for closure-bounded programs

Practice: Iterative translation