generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword...

217
generating programs from types Nadia Polikarpova lambda D A λ S

Transcript of generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword...

Page 1: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

generating programs from types

Nadia Polikarpova

lambdaD A λ S

Page 2: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

2

goal: automate programming

Page 3: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

3

append:push ebpmov ebp, esppush eaxpush ebxpush lencall mallocmov ebx, [ebp + 12]mov [eax + info], ebxmov dword [eax + next], 0mov ebx, [ebp + 8]cmp dword [ebx], 0je null_pointermov ebx, [ebx]

next_element:cmp dword [ebx + next], 0je found_lastmov ebx, [ebx + next]jmp next_element

found_last:push eaxpush addMescall putsadd esp, 4pop eaxmov [ebx + next], eax

go_out:pop ebxpop eaxmov esp, ebppop ebpret 8

null_pointer:push eaxpush nullMescall putsadd esp, 4pop eaxmov [ebx], eaxjmp go_out

Assembly

Page 4: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

3

void insert(node *xs, int x) {node *new;node *temp;node *prev;

new = (node *)malloc(sizeof(node)); if(new == NULL) {printf("Insufficient memory.");return;

} new->val = x;new->next = NULL;if (xs == NULL) {xs = new;

} else if(x < xs->val) {new->next = xs;xs = new;

} else { prev = xs;temp = xs->next;while(temp != NULL && x > temp->val) {prev = temp;temp = temp->next;

}if(temp == NULL) {prev->next = new;

} else {new->next = temp;prev->next = new;

}}

}

append:push ebpmov ebp, esppush eaxpush ebxpush lencall mallocmov ebx, [ebp + 12]mov [eax + info], ebxmov dword [eax + next], 0mov ebx, [ebp + 8]cmp dword [ebx], 0je null_pointermov ebx, [ebx]

next_element:cmp dword [ebx + next], 0je found_lastmov ebx, [ebx + next]jmp next_element

found_last:push eaxpush addMescall putsadd esp, 4pop eaxmov [ebx + next], eax

go_out:pop ebxpop eaxmov esp, ebppop ebpret 8

null_pointer:push eaxpush nullMescall putsadd esp, 4pop eaxmov [ebx], eaxjmp go_out

Assembly C

Page 5: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

3

void insert(node *xs, int x) {node *new;node *temp;node *prev;

new = (node *)malloc(sizeof(node)); if(new == NULL) {printf("Insufficient memory.");return;

} new->val = x;new->next = NULL;if (xs == NULL) {xs = new;

} else if(x < xs->val) {new->next = xs;xs = new;

} else { prev = xs;temp = xs->next;while(temp != NULL && x > temp->val) {prev = temp;temp = temp->next;

}if(temp == NULL) {prev->next = new;

} else {new->next = temp;prev->next = new;

}}

}

insert x xs =match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

append:push ebpmov ebp, esppush eaxpush ebxpush lencall mallocmov ebx, [ebp + 12]mov [eax + info], ebxmov dword [eax + next], 0mov ebx, [ebp + 8]cmp dword [ebx], 0je null_pointermov ebx, [ebx]

next_element:cmp dword [ebx + next], 0je found_lastmov ebx, [ebx + next]jmp next_element

found_last:push eaxpush addMescall putsadd esp, 4pop eaxmov [ebx + next], eax

go_out:pop ebxpop eaxmov esp, ebppop ebpret 8

null_pointer:push eaxpush nullMescall putsadd esp, 4pop eaxmov [ebx], eaxjmp go_out

Assembly C Haskell

Page 6: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

what’s next?

3

void insert(node *xs, int x) {node *new;node *temp;node *prev;

new = (node *)malloc(sizeof(node)); if(new == NULL) {printf("Insufficient memory.");return;

} new->val = x;new->next = NULL;if (xs == NULL) {xs = new;

} else if(x < xs->val) {new->next = xs;xs = new;

} else { prev = xs;temp = xs->next;while(temp != NULL && x > temp->val) {prev = temp;temp = temp->next;

}if(temp == NULL) {prev->next = new;

} else {new->next = temp;prev->next = new;

}}

}

insert x xs =match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

append:push ebpmov ebp, esppush eaxpush ebxpush lencall mallocmov ebx, [ebp + 12]mov [eax + info], ebxmov dword [eax + next], 0mov ebx, [ebp + 8]cmp dword [ebx], 0je null_pointermov ebx, [ebx]

next_element:cmp dword [ebx + next], 0je found_lastmov ebx, [ebx + next]jmp next_element

found_last:push eaxpush addMescall putsadd esp, 4pop eaxmov [ebx + next], eax

go_out:pop ebxpop eaxmov esp, ebppop ebpret 8

null_pointer:push eaxpush nullMescall putsadd esp, 4pop eaxmov [ebx], eaxjmp go_out

Assembly C Haskell

?future

Page 7: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

4

How to split a string in Haskell?

How do I split a string on a custom separator? I want the following behavior:149

split ‘,’ “my,comma,separated,list” → [“my”, “comma”, “separated”, “list”]

Page 8: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

4

How to split a string in Haskell?

How do I split a string on a custom separator? I want the following behavior:149

split ‘,’ “my,comma,separated,list” → [“my”, “comma”, “separated”, “list”]

split :: Char -> String -> [String] split c s = case dropWhile (== c) s of

"" -> [] s' -> w : split c s’’

where (w, s'') = break (== c) s'

157

You can implement it like this:

Page 9: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

4

How to split a string in Haskell?

How do I split a string on a custom separator? I want the following behavior:149

split ‘,’ “my,comma,separated,list” → [“my”, “comma”, “separated”, “list”]

split :: Char -> String -> [String] split c s = case dropWhile (== c) s of

"" -> [] s' -> w : split c s’’

where (w, s'') = break (== c) s'

157

You can implement it like this:

Page 10: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

program synthesis

5

programspecification

Page 11: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

program synthesis

5

programsearch

program space

specification

Page 12: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

program synthesis

5

programsearch

program space

? specification

Page 13: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

program synthesis

6

programsearchspecification

program space

examplesassertions

natural language…

Page 14: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

program synthesis

6

programsearchspecification

program space

examplesassertions

natural language…types!

Page 15: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

the future is (almost) here

7

Char -> String -> [String] Search

Page 16: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

the future is (almost) here

7

Char -> String -> [String] Search

split :: Char -> String -> [String]

ghc Util

Page 17: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

the future is (almost) here

7

Char -> String -> [String] Search

split :: Char -> String -> [String]

ghc Util

Page 18: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

8

simple types expressive types

Page 19: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

8

simple types expressive types

more programmer-friendlymore ambiguous

Page 20: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

8

simple types expressive types

more programmer-friendlymore ambiguous

less programmer-friendlyless ambiguous

Page 21: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

8

simple types expressive types

Page 22: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

this talk

9

simple types expressive types

part I: synquid

refinement types → recursive programs

Page 23: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

this talk

9

simple types expressive types

part I: synquid

refinement types → recursive programs

part II: hoogle+

H+Haskell types →

function compositions

Page 24: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part I

10

synquid

refinement types → recursive programs

Page 25: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part I

10

synquid

refinement types → recursive programs

Polikarpova, Kuraj, Solar-Lezama: Program Synthesis from Polymorphic Refinement Types. [PLDI’16]

Page 26: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part I

10

synquid

refinement types → recursive programs

1. types as specifications

2. type-directed search

Polikarpova, Kuraj, Solar-Lezama: Program Synthesis from Polymorphic Refinement Types. [PLDI’16]

Page 27: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part I

11

synquid

refinement types → recursive programs

1. types as specifications

2. type-directed search

Page 28: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: insert into a sorted list

12

Page 29: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: insert into a sorted list

Input:

12

5x

Page 30: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: insert into a sorted list

Input:

12

1 2 7 8

5

xs

x

Page 31: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: insert into a sorted list

Input:

Output:

12

1 2 7 8

5

xs

x

1 2 7 85ys

Page 32: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs = 5

Page 33: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

5

Page 34: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

Nil →

Cons h t →

5

Page 35: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

Nil →Cons x Nil

Cons h t →5

5

Page 36: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

Nil →Cons x Nil

Cons h t →

5

Page 37: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

Nil →Cons x Nil

Cons h t →if x ≤ h

87 9

5

Page 38: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

Nil →Cons x Nil

Cons h t →if x ≤ h

then Cons x xs 875 9

5

Page 39: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

Nil →Cons x Nil

Cons h t →if x ≤ h

then Cons x xselse Cons h (insert x t)

5

7 82

Page 40: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in a functional language

13

insert x xs =match xs with

Nil →Cons x Nil

Cons h t →if x ≤ h

then Cons x xselse Cons h (insert x t)

Page 41: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

our goal

14

match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

Nil, Cons, ≤, … program

space

Page 42: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

our goal

14

match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

Nil, Cons, ≤, …

?

program space

Page 43: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types are specifications

15

Page 44: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types are specifications

15

insert :: a → List a → List a

Page 45: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types are specifications

15

insert :: a → List a → List a

Page 46: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types are specifications

15

insert :: a → List a → List a

Page 47: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification

insert in synquid

16

a → List a→ List a

Nil, Cons, ≤, …

Page 48: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

insert in synquid

16

a → List a→ List a

Nil, Cons, ≤, …

Page 49: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

insert in synquid

16

a → List a→ List a

Nil, Cons, ≤, …

?

Page 50: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

demo: insert

17

http://comcom.csail.mit.edu/demos/#1-insert

Page 51: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification

insert in synquid

18

a → List a→ List a

Nil, Cons, ≤, …

Page 52: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

insert in synquid

18

a → List a→ List a

Nil

Nil, Cons, ≤, …

Page 53: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

insert in synquid

18

a → List a→ List a

Nil

Nil, Cons, ≤, …

Page 54: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

insert in synquid

18

a → List a→ List a

Nil

Nil, Cons, ≤, …

power to the types!

Page 55: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification for insert

19

Page 56: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification for insert

19

Input:

x

Page 57: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification for insert

19

Input:

x

xs: sorted list

Page 58: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification for insert

19

Input:

x

xs: sorted list

Output:

ys: sorted list

Page 59: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification for insert

19

Input:

x

xs: sorted list

Output:

ys: sorted list

elems ys = elems xs ∪ {x}

Page 60: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification for insert

19

Input:

x

xs: sorted list

Output:

ys: sorted list

elems ys = elems xs ∪ {x}

can I write this as a type?

Page 61: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

refinement types

20

{ v:Int | 0 ≤ v }

Page 62: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

refinement types

20

{ v:Int | 0 ≤ v }

refinement

Page 63: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

refinement types

20

{ v:Int | 0 ≤ v }

natural numbers

Page 64: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

refinement types

20

{ v:Int | 0 ≤ v }List

lists of nats

Page 65: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a where

refinement types: sorted lists

21

List a

Page 66: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a whereNil :: SList a

refinement types: sorted lists

21

List aList a

Page 67: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a whereNil :: SList aCons :: h:a →

t:SList {v:a | h ≤ v} →SList a

refinement types: sorted lists

21

List aList a

List aList a →

Page 68: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a whereNil :: SList aCons :: h:a →

t:SList {v:a | h ≤ v} →SList a

refinement types: sorted lists

21

List a

List aList a →

Page 69: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a whereNil :: SList aCons :: h:a →

t:SList {v:a | h ≤ v} →SList a

refinement types: sorted lists

21

7 82SList a →

Page 70: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a whereNil :: SList aCons :: h:a →

t:SList {v:a | h ≤ v} →SList a

refinement types: sorted lists

21

7 82SList a →

Page 71: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a whereNil :: SList aCons :: h:a →

t:SList {v:a | h ≤ v} →SList a

refinement types: sorted lists

21

7 82

Page 72: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

data SList a whereNil :: SList aCons :: h:a →

t:SList {v:a | h ≤ v} →SList a

refinement types: sorted lists

21

7 82

all you need is one simple predicate!

Page 73: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert :: x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

refinement type for insert

22

SList aList axs:List a

Page 74: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert :: x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

refinement type for insert

22

SList aList a

Page 75: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert :: x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

refinement type for insert

22

SList a

Page 76: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert :: x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

refinement type for insert

22

Page 77: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

insert in synquid

23

match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification code

Page 78: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

demo: insert

24

http://comcom.csail.mit.edu/demos/#1-insert

Page 79: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part I

25

synquid

refinement types → recursive programs

1. types as specifications

2. type-directed search

Page 80: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

?

how did this happen?

26

match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification code

Page 81: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

27

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification

Page 82: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification

Page 83: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

Page 84: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

code

Page 85: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

code

Page 86: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

code

Page 87: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

...

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

code

Page 88: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

...

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

code

Page 89: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

...

too many

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

code

Page 90: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synthesis as search

28

...

too many270

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Nil, Cons, ≤, …

specification

components

code

Page 91: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

synthesis as search

Page 92: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

synthesis as search

Page 93: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

synthesis as search

Page 94: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

synthesis as search

Page 95: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

synthesis as search

Page 96: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

synthesis as search

Page 97: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

synthesis as search

Page 98: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

key idea: reject hopeless programs early

synthesis as search

Page 99: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

29

key idea: reject hopeless programs early

synthesis as search

(during construction)

Page 100: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

rejecting hopeless programs

30

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification

Page 101: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

rejecting hopeless programs

30

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification

previous work*: bottom-up type checking

*Rondon, Kawaguchi, Jhala: Liquid types. [PLDI 2008]

Page 102: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

rejecting hopeless programs

31

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification

??

our work: top-down type checking

Page 103: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

rejecting hopeless programs

31

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

specification

??

our work: top-down type checking

Page 104: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

rejecting hopeless programs

32

Page 105: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =

rejecting hopeless programs

32

??

Page 106: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =

rejecting hopeless programs

32

??hopeless?

Page 107: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =

rejecting hopeless programs

32

??

Page 108: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

??

rejecting hopeless programs

32

Page 109: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

??

rejecting hopeless programs

32

hopeless?

Page 110: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

??

rejecting hopeless programs

32

Page 111: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

rejecting hopeless programs

32

Page 112: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

rejecting hopeless programs

32

hopeless?

Page 113: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

rejecting hopeless programs

32

hopeless?hopeless:output must always contain x!

Page 114: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

rejecting hopeless programs

32

250

hopeless?hopeless:output must always contain x!

Page 115: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

top-down type checking

33

Page 116: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

{v:SList a | elems v = elems xs ∪ {x}}

top-down type checking

33

insert x xs =match xs with

Nil → NilCons h t → ??

Page 117: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

{v:SList a | elems v = elems xs ∪ {x}}

top-down type checking

33

insert x xs =match xs with

Nil → NilCons h t → ??

insert x xs =match xs with

Nil → NilCons h t → ??

Page 118: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

{v:SList a | elems v = elems xs ∪ {x}}

top-down type checking

33

insert x xs =match xs with

Nil → NilCons h t → ??

insert x xs =match xs with

Nil → NilCons h t → ??

Constraints: ∀x: {} = {} ∪ {x}

Page 119: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

{v:SList a | elems v = elems xs ∪ {x}}

top-down type checking

33

insert x xs =match xs with

Nil → NilCons h t → ??

insert x xs =match xs with

Nil → NilCons h t → ??

Constraints: ∀x: {} = {} ∪ {x}

Page 120: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

x:a → xs:SList a →{v:SList a | elems v = elems xs ∪ {x}}

insert x xs =match xs with

Nil → NilCons h t → ??

{v:SList a | elems v = elems xs ∪ {x}}

top-down type checking

33

insert x xs =match xs with

Nil → NilCons h t → ??

insert x xs =match xs with

Nil → NilCons h t → ??

Constraints: ∀x: {} = {} ∪ {x}

Page 121: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

insert in synquid

36

match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Page 122: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

specification code

insert in synquid

36

match xs withNil → Cons x NilCons h t →if x ≤ hthen Cons x xselse Cons h (insert x t)

insert :: x:a →xs:SList a →{v:SList a | elems v =elems xs ∪ {x}}

Page 123: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

¬(a ⇒ b ∨ c)

case study: negation normal form

37

Page 124: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)

case study: negation normal form

37

1. only ¬, ∧, ∨

2. ¬ only at variables

Page 125: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)

case study: negation normal form

37

1. only ¬, ∧, ∨

2. ¬ only at variables

Page 126: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)

case study: negation normal form

37

1. only ¬, ∧, ∨

2. ¬ only at variables

¬(¬a ∨ (b ∨ c))⇒ def.

Page 127: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)

case study: negation normal form

37

1. only ¬, ∧, ∨

2. ¬ only at variables

¬(¬a ∨ (b ∨ c))

¬¬a ∧ ¬(b ∨ c)

⇒ def.

De Morgan

Page 128: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)

case study: negation normal form

37

1. only ¬, ∧, ∨

2. ¬ only at variables

¬(¬a ∨ (b ∨ c))

¬¬a ∧ ¬(b ∨ c)

a ∧ ¬(b ∨ c)

⇒ def.

De Morgan

double-neg

Page 129: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)¬(a ⇒ b ∨ c)

case study: negation normal form

37

a ∧ (¬b ∨ ¬c)

1. only ¬, ∧, ∨

2. ¬ only at variables

¬(¬a ∨ (b ∨ c))

¬¬a ∧ ¬(b ∨ c)

a ∧ ¬(b ∨ c)

⇒ def.

De Morgan

double-neg

De Morgan

Page 130: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml where

Page 131: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → Fml

Page 132: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → Fml

Page 133: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → Fml

Page 134: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → Fml

Page 135: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

Page 136: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF where

Page 137: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNF

Page 138: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNF

negated?

Page 139: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNF

negated?

Page 140: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: data types

38

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

negated?

Page 141: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

Page 142: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool where

Page 143: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env v

Page 144: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)

Page 145: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)And l r → eval l && eval r

Page 146: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)And l r → eval l && eval rOr l r → eval l || eval r

Page 147: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)And l r → eval l && eval rOr l r → eval l || eval rImp l r → eval l ==> eval r

Page 148: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)And l r → eval l && eval rOr l r → eval l || eval rImp l r → eval l ==> eval r

measure nEval :: NNF → Bool where

Page 149: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)And l r → eval l && eval rOr l r → eval l || eval rImp l r → eval l ==> eval r

measure nEval :: NNF → Bool whereNAtom neg v → if neg then env v

else !(env v)

Page 150: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)And l r → eval l && eval rOr l r → eval l || eval rImp l r → eval l ==> eval r

measure nEval :: NNF → Bool whereNAtom neg v → if neg then env v

else !(env v)NAnd l r → nEval l && nEval r

Page 151: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

39

data Fml whereVar :: String → FmlNot :: Fml → FmlAnd :: Fml → Fml → FmlOr :: Fml → Fml → FmlImp :: Fml → Fml → Fml

data NNF whereNAtom :: String → Bool

→ NNFNAnd :: NNF → NNF → NNFNOr :: NNF → NNF → NNF

measure eval :: Fml → Bool whereVar v → env vNot f → !(eval f)And l r → eval l && eval rOr l r → eval l || eval rImp l r → eval l ==> eval r

measure nEval :: NNF → Bool whereNAtom neg v → if neg then env v

else !(env v)NAnd l r → nEval l && nEval rNOr l r → nEval l || nEval r

Page 152: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: specification

40

nnf :: f:Fml → {v:NNF | nEval v = eval f}

Page 153: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: synthesized code

41

nnf :: f:Fml → {v:NNF | nEval v = eval f}

Page 154: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: synthesized code

41

nnf :: f:Fml → {v:NNF | nEval v = eval f}nnf p = match p with

BoolLiteral x2 → if x2then NOr (NAtom dummy x2) (NAtom dummy False)else NAnd (NAtom dummy x2) (NAtom dummy True)

Var x16 → NAtom x16 FalseNot x20 → match x20 withBoolLiteral x22 → if x22then nnf (BoolLiteral False)else nnf (BoolLiteral True)

Var x28 → NAtom x28 TrueNot x32 → nnf x32And x36 x37 → NOr (nnf (Not x36)) (nnf (Not x37))Or x46 x47 → NAnd (nnf (Not x46)) (nnf (Not x47))Implies x56 x57 → NAnd (nnf x56) (nnf (Not x57))

And x65 x66 → NAnd (nnf x65) (nnf x66)Or x73 x74 → NOr (nnf x73) (nnf x74)Imp x81 x82 → NOr (nnf x82) (nnf (Not x81))

Page 155: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: synthesized code

41

nnf :: f:Fml → {v:NNF | nEval v = eval f}nnf p = match p with

BoolLiteral x2 → if x2then NOr (NAtom dummy x2) (NAtom dummy False)else NAnd (NAtom dummy x2) (NAtom dummy True)

Var x16 → NAtom x16 FalseNot x20 → match x20 withBoolLiteral x22 → if x22then nnf (BoolLiteral False)else nnf (BoolLiteral True)

Var x28 → NAtom x28 TrueNot x32 → nnf x32And x36 x37 → NOr (nnf (Not x36)) (nnf (Not x37))Or x46 x47 → NAnd (nnf (Not x46)) (nnf (Not x47))Implies x56 x57 → NAnd (nnf x56) (nnf (Not x57))

And x65 x66 → NAnd (nnf x65) (nnf x66)Or x73 x74 → NOr (nnf x73) (nnf x74)Imp x81 x82 → NOr (nnf x82) (nnf (Not x81)) ⇒ def.

Page 156: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: synthesized code

41

nnf :: f:Fml → {v:NNF | nEval v = eval f}nnf p = match p with

BoolLiteral x2 → if x2then NOr (NAtom dummy x2) (NAtom dummy False)else NAnd (NAtom dummy x2) (NAtom dummy True)

Var x16 → NAtom x16 FalseNot x20 → match x20 withBoolLiteral x22 → if x22then nnf (BoolLiteral False)else nnf (BoolLiteral True)

Var x28 → NAtom x28 TrueNot x32 → nnf x32And x36 x37 → NOr (nnf (Not x36)) (nnf (Not x37))Or x46 x47 → NAnd (nnf (Not x46)) (nnf (Not x47))Implies x56 x57 → NAnd (nnf x56) (nnf (Not x57))

And x65 x66 → NAnd (nnf x65) (nnf x66)Or x73 x74 → NOr (nnf x73) (nnf x74)Imp x81 x82 → NOr (nnf x82) (nnf (Not x81)) ⇒ def.

double-neg

Page 157: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

nnf: synthesized code

41

nnf :: f:Fml → {v:NNF | nEval v = eval f}nnf p = match p with

BoolLiteral x2 → if x2then NOr (NAtom dummy x2) (NAtom dummy False)else NAnd (NAtom dummy x2) (NAtom dummy True)

Var x16 → NAtom x16 FalseNot x20 → match x20 withBoolLiteral x22 → if x22then nnf (BoolLiteral False)else nnf (BoolLiteral True)

Var x28 → NAtom x28 TrueNot x32 → nnf x32And x36 x37 → NOr (nnf (Not x36)) (nnf (Not x37))Or x46 x47 → NAnd (nnf (Not x46)) (nnf (Not x47))Implies x56 x57 → NAnd (nnf x56) (nnf (Not x57))

And x65 x66 → NAnd (nnf x65) (nnf x66)Or x73 x74 → NOr (nnf x73) (nnf x74)Imp x81 x82 → NOr (nnf x82) (nnf (Not x81)) ⇒ def.

double-neg

De Morgan

Page 158: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

this talk

42

simple types expressive types

part I: synquid

refinement types → recursive programs

part II: hoogle+

H+Haskell types →

function compositions

Page 159: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part II

43

hoogle+

Haskell types → function compositions

H+

Page 160: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synquid: limitation

44

programspecification

Page 161: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

synquid: limitation

44

programspecification

Page 162: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part II

45

hoogle+

Haskell types → function compositions

H+Guo et al.: Program Synthesis by Type-Guided Abstraction Refinement [POPL’20]

1. overcoming ambiguity

2. helping beginners with types

James et al.: Digging for Fold: Synthesis-Aided API Discovery for Haskell [OOPSLA’20]

Page 163: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

inspiration: hoogle

46

Char -> String -> [String] Search

split :: Char -> String -> [String]

ghc Util

Page 164: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

inspiration: hoogle

46

Char -> String -> [String] Search

split :: Char -> String -> [String]

ghc Util

Page 165: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: compress a list

Input:

47

1 1 2 1

Page 166: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: compress a list

Input:

Output:

47

1 1 2 1

1 2 1

Page 167: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: compress a list

Input:

Output:

47

1 1 2 1

1 2 1

1 1 2 1

group

Page 168: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

example: compress a list

Input:

Output:

47

1 1 2 1

1 2 1

1 1 2 1

group

map head

Page 169: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

compress: specification

48

compress :: Eq a => [a] → [a]

Page 170: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

compress: specification

48

compress :: Eq a => [a] → [a]

Page 171: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

hoogle+

49

programs

Haskell libraries

specification

H+ 1.2.3.4.

Eq a => [a] → [a]

Page 172: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

hoogle+

49

programs

Haskell libraries

specification

H+ 1.2.3.4.

Eq a => [a] → [a]

Page 173: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

hoogle+

49

programs

Haskell libraries

specification

H+ 1.2.3.4.

Eq a => [a] → [a]

Page 174: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

hoogle+

49

programs

Haskell libraries

specification

H+ 1.2.3.4.

Eq a => [a] → [a]

Page 175: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

hoogle+

50

Eq a => [a] → [a] SearchHoogλe+\xs -> concat (group xs)

\xs -> head (group xs)

\xs -> last (group xs)

\xs -> map head (group xs)

[0,1] -> [0,1][0,0] -> [0,0]

[0,1] -> [0][0,0] -> [0,0]

[0,1] -> [1][0,0] -> [0,0]

[0,1] -> [0,1][0,0] -> [0]

Page 176: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

hoogle+

50

Eq a => [a] → [a] SearchHoogλe+\xs -> concat (group xs)

\xs -> head (group xs)

\xs -> last (group xs)

\xs -> map head (group xs)

[0,1] -> [0,1][0,0] -> [0,0]

[0,1] -> [0][0,0] -> [0,0]

[0,1] -> [1][0,0] -> [0,0]

[0,1] -> [0,1][0,0] -> [0]

Page 177: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part III

51

hoogle+

Haskell types → function compositions

H+ 1. overcoming ambiguity

2. helping beginners with types

Page 178: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

too many irrelevant results

52

Eq a => [a] → [a] SearchHoogλe+

\xs -> []

\xs -> xs

\xs -> head []

\xs -> tail xs

Page 179: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

too many irrelevant results

52

Eq a => [a] → [a] SearchHoogλe+

\xs -> []

\xs -> xs

\xs -> head []

\xs -> tail xs

always crashes!

Page 180: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

too many irrelevant results

52

Eq a => [a] → [a] SearchHoogλe+

\xs -> []

\xs -> xs

\xs -> head []

\xs -> tail xs

ignores the argument!

always crashes!

Page 181: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

too many irrelevant results

52

Eq a => [a] → [a] SearchHoogλe+

\xs -> []

\xs -> xs

\xs -> head []

\xs -> tail xs

ignores the argument!

always crashes!

ignores the type class!

ignores the type class!

Page 182: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

too many irrelevant results

53

Eq a => [a] → [a] SearchHoogλe+

\xs -> head (group xs)

\xs -> init (head (group xs))

\xs -> tail (head (group xs))

Page 183: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

too many irrelevant results

53

Eq a => [a] → [a] SearchHoogλe+

\xs -> head (group xs)

\xs -> init (head (group xs))

\xs -> tail (head (group xs)) duplicate!

Page 184: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

test-based filtering

54

candidatessearchtype query

Eq a =>[a] → [a]

Page 185: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

test-based filtering

54

candidatessearchtype query

Eq a =>[a] → [a]

results

QuickCheck / SmallCheck

Page 186: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

test-based filtering

54

candidatessearchtype query

Eq a =>[a] → [a]

results

QuickCheck / SmallCheck

1. does it crash on all inputs?

Page 187: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

test-based filtering

54

candidatessearchtype query

Eq a =>[a] → [a]

results

QuickCheck / SmallCheck

1. does it crash on all inputs?2. is the output always the same as another candidate?

Page 188: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

test-based filtering

54

candidatessearchtype query

Eq a =>[a] → [a]

results

QuickCheck / SmallCheck

1. does it crash on all inputs?2. is the output always the same as another candidate?

3. does the output stay the same when changing an input?

Page 189: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

comprehension

55

Eq a => [a] → [a] SearchHoogλe+

\xs -> concat (group xs)

\xs -> head (group xs)

\xs -> last (group xs)

\xs -> map head (group xs)

Page 190: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

comprehension

55

Eq a => [a] → [a] SearchHoogλe+

\xs -> concat (group xs)

\xs -> head (group xs)

\xs -> last (group xs)

\xs -> map head (group xs)

how do I know what these

programs do?

Page 191: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

test-based comprehension

56

Eq a => [a] → [a] SearchHoogλe+\xs -> concat (group xs)

\xs -> head (group xs)

\xs -> last (group xs)

\xs -> map head (group xs)

[0,1] -> [0,1][0,0] -> [0,0]

[0,1] -> [0][0,0] -> [0,0]

[0,1] -> [1][0,0] -> [0,0]

[0,1] -> [0,1][0,0] -> [0]

Page 192: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

test-based comprehension

56

Eq a => [a] → [a] SearchHoogλe+\xs -> concat (group xs)

\xs -> head (group xs)

\xs -> last (group xs)

\xs -> map head (group xs)

[0,1] -> [0,1][0,0] -> [0,0]

[0,1] -> [0][0,0] -> [0,0]

[0,1] -> [1][0,0] -> [0,0]

[0,1] -> [0,1][0,0] -> [0]

Page 193: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part III

57

hoogle+

Haskell types → function compositions

H+ 1. overcoming ambiguity

2. helping beginners with types

Page 194: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

Eq a => [a] → [a]

hoogle+

58

programsspecification

H+ 1.2.3.4.

Page 195: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

Eq a => [a] → [a]

hoogle+

58

programsspecification

H+ 1.2.3.4.

Page 196: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

can we infer type from tests?

59

programsspecification

H+ 1.2.3.4.

Eq a => [a] → [a]

[1,1,2,1] → [1,2,1]

“abba” → “aba”

Page 197: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

60

[1,1,2,1] → [1,2,1] “abba” → “aba”

Page 198: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

60

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

ghci ghci

Page 199: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

60

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

ghci ghci

least common generalization

Page 200: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

60

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

ghci ghci

least common generalization

Page 201: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

60

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

[a] → [a]

ghci ghci

least common generalization

Page 202: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

60

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

[a] → [a]

a → [b] [a] → b

ghci ghci

least common generalization

[a] → [b]

more general types

Page 203: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

61

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

[a] → [a]

a → [b] [a] → b

[a] → [b]

Page 204: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

61

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

[a] → [a]

a → [b] [a] → b

[a] → [b]

generalizes over complex type

Page 205: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

61

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

[a] → [a]

[a] → [b]

Page 206: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

61

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

[a] → [a]

[a] → [b] unreachable type variable b

Page 207: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

61

Ord a => [a] → [a]

[1,1,2,1] → [1,2,1] “abba” → “aba”

[Int] → [Int] [Char] → [Char]

Eq a => [a] → [a]

[a] → [a]

Page 208: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

types from tests

61

Ord a => [a] → [a]

Eq a => [a] → [a]

[a] → [a]

Page 209: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

part II

62

hoogle+

Haskell types → function compositions

H+ user study

Page 210: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

user study

30 participants

63

Page 211: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

user study

30 participants

4 tasks

63

Page 212: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

user study

30 participants

4 tasks

2 with Hoogle, then 2 with Hoolge+

63

Page 213: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

results: completed tasks

64

29

44

0

15

30

45

60

Hoogle Hoogle+

Page 214: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

results: completed tasks

64

29

44

0

15

30

45

60

Hoogle Hoogle+

51%more!

Page 215: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

modes of specificationtype only

19%

type + test

39%

test only

42%

65

Page 216: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

modes of specification: beginnerstype only

19% type + test

27%

test only

54%66

Page 217: generating programs from typesnpolikarpova/talks/lambda-days-2021.pdfmov [eax + info], ebx mov dword [eax + next], 0 mov ebx, [ebp + 8] cmp dword [ebx], 0 je null_pointer mov ebx,

this talk

67

simple types expressive types

part I: synquid

refinement types → recursive programs

part II: hoogle+

H+Haskell types →

function compositions