How to Make Ad Hoc Proof Automation Less Ad Hoc Georges Gonthier 1 - - PowerPoint PPT Presentation

how to make ad hoc proof automation less ad hoc
SMART_READER_LITE
LIVE PREVIEW

How to Make Ad Hoc Proof Automation Less Ad Hoc Georges Gonthier 1 - - PowerPoint PPT Presentation

How to Make Ad Hoc Proof Automation Less Ad Hoc Georges Gonthier 1 Beta Ziliani 2 Aleks Nanevski 3 Derek Dreyer 2 1 Microsoft Research Cambridge 2 Max Planck Institute for Software Systems (MPI-SWS) 3 IMDEA Software Institute, Madrid ICFP 2011,


slide-1
SLIDE 1

How to Make Ad Hoc Proof Automation Less Ad Hoc

Georges Gonthier1 Beta Ziliani2 Aleks Nanevski3 Derek Dreyer2

1Microsoft Research Cambridge 2Max Planck Institute for Software Systems (MPI-SWS) 3IMDEA Software Institute, Madrid

ICFP 2011, Tokyo

slide-2
SLIDE 2

Why proof automation at ICFP?

Ad hoc polymorphism ≈ Overloading terms Ad hoc proof automation ≈ Overloading lemmas “How to make ad hoc polymorphism less ad hoc” Haskell type classes (Wadler & Blott ’89) “How to make ad hoc proof automation less ad hoc” Canonical structures: A generalization of type classes that’s already present in Coq

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-3
SLIDE 3

Motivating example from program verification

Lemma noalias: If pointers x1 and x2 appear in disjoint heaps, they do not alias. In formal syntax: noalias : ∀h : heap. ∀x1 x2 : ptr. ∀v1 : A1. ∀v2 : A2. def ( x1 → v1 ⊎ x2 → v2 ⊎ h ) → x1 != x2

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-4
SLIDE 4

Motivating example from program verification

Lemma noalias: If pointers x1 and x2 appear in disjoint heaps, they do not alias. In formal syntax: noalias : ∀h : heap. ∀x1 x2 : ptr. ∀v1 : A1. ∀v2 : A2. def ( x1 → v1 ⊎ x2 → v2 ⊎ h ) → x1 != x2 singleton heaps

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-5
SLIDE 5

Motivating example from program verification

Lemma noalias: If pointers x1 and x2 appear in disjoint heaps, they do not alias. In formal syntax: noalias : ∀h : heap. ∀x1 x2 : ptr. ∀v1 : A1. ∀v2 : A2. def ( x1 → v1 ⊎ x2 → v2 ⊎ h ) → x1 != x2 disjoint union (undefined if heaps overlap)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-6
SLIDE 6

Motivating example from program verification

Lemma noalias: If pointers x1 and x2 appear in disjoint heaps, they do not alias. In formal syntax: noalias : ∀h : heap. ∀x1 x2 : ptr. ∀v1 : A1. ∀v2 : A2. def ( x1 → v1 ⊎ x2 → v2 ⊎ h ) → x1 != x2 test for definedness/disjointness

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-7
SLIDE 7

Motivating example from program verification

Lemma noalias: If pointers x1 and x2 appear in disjoint heaps, they do not alias. In formal syntax: noalias : ∀h : heap. ∀x1 x2 : ptr. ∀v1 : A1. ∀v2 : A2. def ( x1 → v1 ⊎ x2 → v2 ⊎ h ) → x1 != x2 no alias

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-8
SLIDE 8

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (h1 ⊎ (y1 → w1 ⊎ y2 → w2) ⊎ (h2 ⊎ y3 → w3)) (y1 != y2) && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-9
SLIDE 9

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (h1 ⊎ (y1 → w1 ⊎ y2 → w2) ⊎ (h2 ⊎ y3 → w3)) (y1 != y2) && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-10
SLIDE 10

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (h1 ⊎ (y1 → w1 ⊎ y2 → w2) ⊎ (h2 ⊎ y3 → w3)) (y1 != y2) && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-11
SLIDE 11

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (h1 ⊎ (y1 → w1 ⊎ y2 → w2) ⊎ (h2 ⊎ y3 → w3)) (y1 != y2) && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-12
SLIDE 12

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y1 → w1 ⊎ y2 → w2 ⊎ (h1 ⊎ (h2 ⊎ y3 → w3))) (y1 != y2) && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-13
SLIDE 13

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y1 → w1 ⊎ y2 → w2 ⊎ (h1 ⊎ (h2 ⊎ y3 → w3))) true && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-14
SLIDE 14

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y1 → w1 ⊎ y2 → w2 ⊎ (h1 ⊎ (h2 ⊎ y3 → w3))) true && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-15
SLIDE 15

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y1 → w1 ⊎ y2 → w2 ⊎ (h1 ⊎ (h2 ⊎ y3 → w3))) true && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-16
SLIDE 16

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y2 → w2 ⊎ y3 → w3 ⊎ (y1 → w1 ⊎ h1 ⊎ h2)) true && (y2 != y3) && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-17
SLIDE 17

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y2 → w2 ⊎ y3 → w3 ⊎ (y1 → w1 ⊎ h1 ⊎ h2)) true && true && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-18
SLIDE 18

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y2 → w2 ⊎ y3 → w3 ⊎ (y1 → w1 ⊎ h1 ⊎ h2)) true && true && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-19
SLIDE 19

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y2 → w2 ⊎ y3 → w3 ⊎ (y1 → w1 ⊎ h1 ⊎ h2)) true && true && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-20
SLIDE 20

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y3 → w3 ⊎ y1 → w1 ⊎ (y2 → w2 ⊎ h1 ⊎ h2)) true && true && (y3 != y1)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-21
SLIDE 21

Using noalias requires a lot of “glue proof”

noalias : ∀ h x1 x2 v1 v2. def (x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 D : def (y3 → w3 ⊎ y1 → w1 ⊎ (y2 → w2 ⊎ h1 ⊎ h2)) true && true && true

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-22
SLIDE 22

Glue proof, formally (in Coq)

rewrite −!unA −!(unCA (y2 → ) −!(unCA (y1 → )) unA in D. rewrite (noalias D). rewrite −!unA − (unC (y3 → )) −!(unCA (y3 → )) in D. rewrite −!(unCA (y2 → )) unA in D. rewrite (noalias D). rewrite −!unA −!(unCA (y1 → )) −!(unCA (y3 → )) unA in D. rewrite (noalias D).

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-23
SLIDE 23

Glue proof, formally (in Coq)

rewrite −!unA −!(unCA (y2 → ) −!(unCA (y1 → )) unA in D. rewrite (noalias D). rewrite −!unA − (unC (y3 → )) −!(unCA (y3 → )) in D. rewrite −!(unCA (y2 → )) unA in D. rewrite (noalias D). rewrite −!unA −!(unCA (y1 → )) −!(unCA (y3 → )) unA in D. rewrite (noalias D).

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-24
SLIDE 24

Automation as it is today

Write custom tactic: For each xi != xj in the goal: rearrange hypothesis, to bring xi and xj to the front apply the noalias lemma repeat

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-25
SLIDE 25

Automation as it is today

Write custom tactic: For each xi != xj in the goal: rearrange hypothesis, to bring xi and xj to the front apply the noalias lemma repeat However, custom tactics have several limitations Can be untyped or weakly specified Automation as a second class citizen

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-26
SLIDE 26

What we want: automated lemmas!

We really want an automated version of the noalias lemma: noaliasA : ∀ . . .??? . . . x1 != x2 where ??? asks type inference to construct glue proof. Why? Strongly-typed custom automation! Composable, modular custom automation!

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-27
SLIDE 27

Using and composing automated lemmas

(y1 != y2) && (y2 != y3) && (y3 != y1)

slide-28
SLIDE 28

Using and composing automated lemmas

(y1 != y2) && (y2 != y3) && (y3 != y1) ↓ true && true && true by performing rewrite !(noaliasA D)

slide-29
SLIDE 29

Using and composing automated lemmas

(y1 != y2) && (y2 != y3) && (y3 != y1) ↓ true && true && true by performing

rewrite ! (noaliasA D)

slide-30
SLIDE 30

Using and composing automated lemmas

(y1 != y2) && (y2 != y3) && (y3 != y1) ↓ true && true && true by performing

rewrite ! (noaliasA D)

multiple times

slide-31
SLIDE 31

Using and composing automated lemmas

(y1 == y2) && (y2 != y3) && (y3 != y1) ↓ true && true && true by performing rewrite !(noaliasA D)

slide-32
SLIDE 32

Using and composing automated lemmas

(y1 == y2) && (y2 != y3) && (y3 != y1) ↓ false && (y2 != y3) && (y3 != y1) = false by performing rewrite !(noaliasA D)

slide-33
SLIDE 33

Using and composing automated lemmas

(y1 == y2) && (y2 != y3) && (y3 != y1) ↓ false && (y2 != y3) && (y3 != y1) = false by performing

rewrite (negate (noaliasA D))

where negate : ∀b : bool. !b = true → b = false

slide-34
SLIDE 34

How? Lemma automation by overloading

Curry-Howard correspondence! Overloading: infer code for a function based on arguments Lemma overloading: infer proof for a lemma based on arguments

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-35
SLIDE 35

Our Main Contributions

Idea: proof automation through lemma overloading Realizing this idea by Coq’s canonical structures: A generalization of Haskell type classes Instances pattern-match terms as well as types “Design patterns” for controlling Coq type inference Several interesting examples from HTT See the paper for details!

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-36
SLIDE 36

Our Main Contributions

Idea: proof automation through lemma overloading Realizing this idea by Coq’s canonical structures: A generalization of Haskell type classes Instances pattern-match terms as well as types “Design patterns” for controlling Coq type inference Several interesting examples from HTT See the paper for details!

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-37
SLIDE 37

Haskell overloading: equality type class

class Eq a where (==) :: a → a → Bool instance Eq Bool where (==) = λx y. (x && y) | | (!x && !y) instance (Eq a, Eq b) ⇒ Eq (a × b) where (==) = λx y. (fst x == fst y) && (snd x == snd y)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-38
SLIDE 38

Haskell overloading: equality type class

class Eq a where (==) :: a → a → Bool instance Eq Bool where (==) = eq bool instance (f1 : Eq a, f2 : Eq b) ⇒ Eq (a × b) where (==) = eq pair f1 f2

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-39
SLIDE 39

Haskell overloading: equality type class

Example: (x, true) == (false, y) class Eq a where (==) :: a → a → Bool instance Eq Bool where (==) = eq bool instance (f1 : Eq a, f2 : Eq b) ⇒ Eq (a × b) where (==) = eq pair f1 f2

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-40
SLIDE 40

Haskell overloading: equality type class

Example: (x, true) ==

  • eq pair eq bool eq bool

(false, y) class Eq a where (==) :: a → a → Bool instance Eq Bool where (==) = eq bool instance (f1 : Eq a, f2 : Eq b) ⇒ Eq (a × b) where (==) = eq pair f1 f2

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-41
SLIDE 41

Coq overloading: equality type class

Coq structure: just a dependent record type structure name

  • Eq

:= constructor mkEq { fields

  • sort : Type;

( == ) : sort → sort → bool; }

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-42
SLIDE 42

Coq overloading: equality type class

Coq structure: just a dependent record type structure name

  • Eq

:= constructor mkEq { fields

  • sort : Type;

( == ) : sort → sort → bool; }

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-43
SLIDE 43

Coq overloading: equality type class

Coq structure: just a dependent record type structure name

  • Eq

:= constructor mkEq { fields

  • sort : Type;

( == ) : sort → sort → bool; } Creates projectors for each field, e.g.: sort : Eq → Type ( == ) : ∀e : Eq. sort e → sort e → bool

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-44
SLIDE 44

Canonical instances

Instances defined as in Haskell canonical bool inst := mkEq sort

  • bool

( == ) eq bool canonical pair inst (A B : Eq) := mkEq (sort A × sort B)

  • sort

(eq pair A B)

  • ( == )
  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-45
SLIDE 45

Example of instance inference

(x, true) == (false, y)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-46
SLIDE 46

Example of instance inference

(x, true) == (false, y) Remember ( == ) : ∀ e : Eq . sort e → sort e → bool

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-47
SLIDE 47

Example of instance inference

(x, true) == (false, y) Remember ( == ) : ∀ e : Eq . sort e → sort e → bool implicit parameter

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-48
SLIDE 48

Example of instance inference

(x, true) == (false, y) Remember ( == ) : ∀ e : Eq . sort e → sort e → bool Coq finds an instance of e : Eq that unifies sort e with (bool × bool)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-49
SLIDE 49

Example of instance inference

(x, true) == (false, y) Remember ( == ) : ∀ e : Eq . sort e → sort e → bool Coq finds an instance of e : Eq that unifies sort e with (bool × bool) ↓ e = pair inst bool inst bool inst

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-50
SLIDE 50

Adding a proof

We add the proof that ( == ) is equivalent to Coq’s ( = ) structure name

  • Eq

:= constructor mkEq { fields

  • sort : Type;

( == ) : sort → sort → bool; proof : ∀x y : sort. x == y ↔ x = y}

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-51
SLIDE 51

Adding a proof

We add the proof that ( == ) is equivalent to Coq’s ( = ) structure name

  • Eq

:= constructor mkEq { fields

  • sort : Type;

( == ) : sort → sort → bool; proof : ∀x y : sort. x == y ↔ x = y} Now instances also compute the proof: canonical bool inst := mkEq bool eq bool pf bool canonical pair inst (A B : Eq) := mkEq (sort A × sort B) (eq pair A B) (pf pair A B)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-52
SLIDE 52

Lemma overloading

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-53
SLIDE 53

Overloading a simple lemma

Goal: Prove x is in the domain of · · · ⊎ (· · · ⊎ x → v ⊎ · · · ) ⊎ · · ·

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-54
SLIDE 54

Overloading a simple lemma

Goal: Prove x is in the domain of · · · ⊎ (· · · ⊎ x → v ⊎ · · · ) ⊎ · · · Na¨ ıve lemma: indom : ∀x : ptr. ∀v : A. ∀h : heap. x ∈ dom (x → v ⊎ h)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-55
SLIDE 55

Overloading a simple lemma

Goal: Prove x is in the domain of · · · ⊎ (· · · ⊎ x → v ⊎ · · · ) ⊎ · · · Na¨ ıve lemma: indom : ∀x : ptr. ∀v : A. ∀h : heap. x ∈ dom (x → v ⊎ h) Let’s overload it!

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-56
SLIDE 56

indom overloaded

Define structure contains x, of heaps that contain x: structure contains (x : ptr) := Contains { heap of : heap; indomO : x ∈ dom heap of }

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-57
SLIDE 57

indom overloaded

Define structure contains x, of heaps that contain x: structure contains (x : ptr) := Contains { heap of : heap; indomO : x ∈ dom heap of } Induced projections: heap of : ∀x : ptr. contains x → heap indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) The second one is our overloaded lemma

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-58
SLIDE 58

indomO algorithm, informally

When solving x ∈ dom h

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-59
SLIDE 59

indomO algorithm, informally

When solving x ∈ dom h type inference should proceed as follows: If h is x → v, succeed with singleton pf : ∀x v. x ∈ dom (x → v)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-60
SLIDE 60

indomO algorithm, informally

When solving x ∈ dom h type inference should proceed as follows: If h is x → v, succeed with singleton pf : ∀x v. x ∈ dom (x → v) If h is h1 ⊎ h2:

If x ∈ dom h1, compose with left pf : ∀h1 h2. x ∈ dom h1 → x ∈ dom (h1 ⊎ h2)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-61
SLIDE 61

indomO algorithm, informally

When solving x ∈ dom h type inference should proceed as follows: If h is x → v, succeed with singleton pf : ∀x v. x ∈ dom (x → v) If h is h1 ⊎ h2:

If x ∈ dom h1, compose with left pf : ∀h1 h2. x ∈ dom h1 → x ∈ dom (h1 ⊎ h2) If x ∈ dom h2, compose with right pf : ∀h1 h2. x ∈ dom h2 → x ∈ dom (h1 ⊎ h2)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-62
SLIDE 62

Implementation of indomO

Algorithm encoded in canonical instances of contains x: canonical found A x (v : A) := Contains x (x → v) singleton pf canonical left x h (c : contains x) := Contains x ((heap of c) ⊎ h) (left pf (indomO c)) canonical right x h (c : contains x) := Contains x (h ⊎ (heap of c)) (right pf (indomO c))

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-63
SLIDE 63

Implementation of indomO

Algorithm encoded in canonical instances of contains x: canonical found A x (v : A) := Contains x (x → v) singleton pf canonical left x h (c : contains x) := Contains x ((heap of c) ⊎ h) (left pf (indomO c)) canonical right x h (c : contains x) := Contains x (h ⊎ (heap of c)) (right pf (indomO c))

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-64
SLIDE 64

Implementation of indomO

Algorithm encoded in canonical instances of contains x:

As a logic program

canonical found A x (v : A) := Contains x (x → v) singleton pf canonical left x h (c : contains x) := Contains x ((heap of c) ⊎ h) (left pf (indomO c)) canonical right x h (c : contains x) := Contains x (h ⊎ (heap of c)) (right pf (indomO c))

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-65
SLIDE 65

Implementation of indomO

Algorithm encoded in canonical instances of contains x:

Canonical structures ≈ term classes

canonical found A x (v : A) := Contains x (x → v) singleton pf canonical left x h (c : contains x) := Contains x ((heap of c) ⊎ h) (left pf (indomO c)) canonical right x h (c : contains x) := Contains x (h ⊎ (heap of c)) (right pf (indomO c))

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-66
SLIDE 66

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-67
SLIDE 67

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v) Solve it by apply indomO

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-68
SLIDE 68

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v) Solve it by apply indomO

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-69
SLIDE 69

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v) Solve it by apply indomO , unifying: x with y

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-70
SLIDE 70

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v) Solve it by apply indomO , unifying: x with y heap of c with (z → u ⊎ y → v)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-71
SLIDE 71

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v) Solve it by apply indomO , unifying: x with y heap of c with (z → u ⊎ y → v) Result: c = right y (z → u) (found y v)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-72
SLIDE 72

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v) Solve it by apply indomO , unifying: x with y heap of c with (z → u ⊎ y → v) Result: c = right y (z → u) (found y v)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-73
SLIDE 73

Example application of indomO

indomO : ∀x : ptr. ∀c : contains x. x ∈ dom (heap of c) y ∈ dom (z → u ⊎ y → v) Solve it by apply indomO , unifying: x with y heap of c with (z → u ⊎ y → v) Result: c = right y (z → u) (found y v)

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-74
SLIDE 74

The truth revealed

Overlapping instances not allowed in Coq!

canonical left x h (c : contains x) := Contains x ((heap of c) ⊎ h) (left pf (indomO c)) canonical right x h (c : contains x) := Contains x (h ⊎ (heap of c)) (right pf (indomO c))

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-75
SLIDE 75

The truth revealed

Overlapping instances not allowed in Coq! “Tagging” pattern for instance disambiguation!

canonical left x h (c : contains x) := Contains x ((heap of c) ⊎ h) (left pf (indomO c)) canonical right x h (c : contains x) := Contains x (h ⊎ (heap of c)) (right pf (indomO c))

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-76
SLIDE 76

What else is in the paper

“Tagging” pattern for instance disambiguation Example of proof by reflection “Hoisting” pattern for ordering unification subproblems “Search-and-replace” pattern for structural in-place-update

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-77
SLIDE 77

Conclusions

Proof automation by lemma overloading Curry-Howard correspondence! Overloading: infer code for a function based on arguments Lemma overloading: infer proof for a lemma based on arguments Robust, verifiable, composable automation routines

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-78
SLIDE 78

Questions?

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-79
SLIDE 79

Comparison with Coq Type Classes

Coq Type Classes (CTC) [Sozeau and Oury, TPHOLs ’08] Similar to canonical structures, which predated them Instance resolution for CTC guided by proof search, rather than by Coq unification They’re in beta and it’s not my fault! Overlapping instances resolved by weighted backtracking We’ve ported a number of our examples to CTC Could not figure out how to port “search-and-replace” pattern Sometimes CTC is faster, sometimes CS is faster Further investigation of the tradeoffs is needed Future work: unify the two concepts?

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-80
SLIDE 80

A word on performance

Performance for lemma overloading currently not great: Time to perform a simple assignment to a unification variable is quadratic in the number of variables in the context, and linear in the size of the term being assigned With tactics, it’s nearly constant-time Clearly a bug in the implementation of Coq unification: Not always a problem, since interactive proofs often keep variable contexts short But it needs to be fixed. . .

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-81
SLIDE 81

Solution: The “Tagging” Pattern

Present different constants for each instance: canonical found A x (v : A) := Contains x (found tag (x → v)) . . . canonical left x h (c : contains x) := Contains x (left tag ((heap of f ) ⊎ h)) . . . canonical right x h (c : contains x) := Contains x (right tag (h ⊎ (heap of f ))) . . . No overlap anymore! Where: found tag = left tag = right tag Lazy unification algorithm unrolls them upon matching failure!

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-82
SLIDE 82

The Tagging Pattern

We employ the “tagging” design pattern to disambiguate instances. Rely on lazy expansion of constant definitions by the unification algorithm. structure tagged heap := Tag {untag : heap} right tag h := Tag h left tag h := right tag h canonical found tag h := left tag h    all synonyms of Tag One synonym of Tag for each canonical instance of find x Listed in the reverse order in which we want them to be considered during pattern matching Last one marked as a canonical instance of tagged heap

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-83
SLIDE 83

The Tagging Pattern

And we tag each canonical instance of find x accordingly: canonical found A x (v : A) := Contains x (found tag (x → v)) . . . canonical left x h (f ′ : contains x) := Contains x (left tag (untag (heap of f ′) ⊎ h)) . . . canonical right x h (f ′′ : contains x) := Contains x (right tag (h ⊎ untag (heap of f ′′))) . . . No overlap! Each instance has a different constant.

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-84
SLIDE 84

Example

right tag left tag found tag Where f : contains y heap of ?f

  • = found tag (x → u ⊎ y → v)

Try instance found and fail

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-85
SLIDE 85

Example

right tag left tag Where f : contains y heap of ?f

  • = left tag (x → u ⊎ y → v)

Try instance left and fail

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-86
SLIDE 86

Example

right tag Where f : contains y heap of ?f

  • = right tag (x → u ⊎ y → v)

Try instance right and succeed

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-87
SLIDE 87

Overloaded cancellation lemma for heaps

Applying lemma cancelO on a heap equation x → v1 ⊎ (h3 ⊎ h4) = h4 ⊎ x → v2 cancels common terms to produce v1 = v2 ∧ h3 = ∅ Steps:

1

Logic program turn equations into abstract syntax trees Executed during type inference by unification engine Equal variables turn into equal natural indices

2

Functional program cancels common terms

3

Functional program translate back into equations Requires only the tagging pattern

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-88
SLIDE 88

Overloaded version of noalias

noalias : ∀h:heap. ∀x1 x2:ptr. ∀v1:A1. ∀v2:A2. def(x1 → v1 ⊎ x2 → v2 ⊎ h) → x1 != x2 noaliasO : ∀x y : ptr. ∀s : seq ptr. ∀f : scan s. ∀g : check x y s. def (heap of f ) → x != (y of g) Requires two recursive logic programs

scan traverses a heap collecting all pointers into a list s then check traverses s searching for x and y

Somewhat tricky to pass arguments from scan to check Employs the hoisting pattern to reorder unification subproblems.

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-89
SLIDE 89

Search-and-replace pattern

Useful lemma for verifying “Hoare triples”: bnd write : verify

initial heap

  • (x → v ⊎ h) e

post-condition

  • q

→ verify (x → w ⊎ h) (write x v; e)

  • write v in location x and then run e

q But we’d like to do “in-place update” on the initial heap, rather than shifting x → ? to the front of the heap and then back again.

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-90
SLIDE 90

Search-and-replace pattern: example

Example 1: To prove the goal G : verify (h1 ⊎ (x1 → 1 ⊎ x2 → 2)) (write x2 4; e) q we can apply bnd writeO to reduce it to: G : verify (h1 ⊎ (x1 → 1 ⊎ x2 → 4)) e q

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-91
SLIDE 91

Search-and-replace pattern: idea

Build a logic program that turns a heap into a function that abstracts the wanted pointer. Example: Turn h1 ⊎ (x1 → 1 ⊎ x2 → 2) into f = fun k. h1 ⊎ (x1 → 1 ⊎ k) Then the bnd writeO lemma can be stated roughly as verify (f (x → v)) e q → verify (f (x → w)) (write x v; e) q

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-92
SLIDE 92

Search-and-replace pattern: more formally

It turns out that f must have a dependent function type. structure partition (k r : heap) := Partition {heap of : tagged heap; : heap of = k ⊎ r} bnd writeO : ∀r : heap. ∀f : (Πk : heap. partition k r). ∀ . . . verify (untag (heap of (f (x → v)))) e q → verify (untag (heap of (f (x → w)))) (write x v; e) q

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc

slide-93
SLIDE 93

Search-and-replace pattern: forward reasoning

Example 2: Given hypothesis H : verify (h1 ⊎ (x1 → 1 ⊎ x2 → 4)) e q we can apply (bnd writeO (x := x2) (w := 2)) to it: H : verify (h1 ⊎ (x1 → 1 ⊎ x2 → 2)) (write x2 4; e) q Note: this duality of use is not possible with tactics

  • G. Gonthier, B. Ziliani, A. Nanevski, D. Dreyer

How to Make Ad Hoc Proof Automation Less Ad Hoc