Skip to content

Commit 395cceb

Browse files
authored
Complete synthesis tutorial (metalift#74)
* Complete synthesis tutorial * Explain unboundedInts * Fill out initial release blog post
1 parent c4309ab commit 395cceb

7 files changed

+87
-17
lines changed

metalift/actors/synthesis.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def __call__(
170170
preds: Union[str, typing.List[Expr]],
171171
vc: Expr,
172172
loopAndPsInfo: typing.List[Union[CodeInfo, Expr]],
173-
cvcPath: str,
173+
cvcPath: str = "cvc5",
174174
uid: int = 0,
175175
noVerify: bool = False,
176176
unboundedInts: bool = False,

metalift/synthesize_cvc5.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def synthesize(
206206
preds: typing.List[Expr],
207207
vc: Expr,
208208
loopAndPsInfo: typing.List[Union[CodeInfo, Expr]],
209-
cvcPath: str,
209+
cvcPath: str = "cvc5",
210210
uid: int = 0,
211211
noVerify: bool = False, # currently ignored
212212
unboundedInts: bool = False, # currently ignored

metalift/synthesize_rosette.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,7 @@ def toExpr(
9595
elif ast[0] == "length":
9696
return Call("list_length", Int(), toExpr(ast[1], fnsType, varType, choices))
9797
elif ast[0] == "=":
98-
return Call(
99-
"=",
100-
Bool(),
98+
return Eq(
10199
toExpr(ast[1], fnsType, varType, choices),
102100
toExpr(ast[2], fnsType, varType, choices),
103101
)
@@ -301,7 +299,7 @@ def synthesize(
301299
preds: typing.List[Expr],
302300
vc: Expr,
303301
loopAndPsInfo: typing.List[Union[CodeInfo, Expr]],
304-
cvcPath: str,
302+
cvcPath: str = "cvc5",
305303
uid: int = 0,
306304
noVerify: bool = False,
307305
unboundedInts: bool = False,

website/blog/2019-05-28-first-blog-post.md

-8
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
slug: release-v0.1.0
3+
title: "First Metalift Release: v0.1.0"
4+
authors: [alvin, sahil, shadaj]
5+
tags: [release]
6+
---
7+
8+
We're excited to share the initial open-source release of Metalift, a Python framework for applying verified lifting and program synthesis techniques!

website/blog/authors.yml

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
alvin:
2+
name: Alvin Cheung
3+
title: Associate Professor @ UC Berkeley
4+
url: https://people.eecs.berkeley.edu/~akcheung/
5+
image_url: https://github.com/akcheung.png
6+
sahil:
7+
name: Sahil Bhatia
8+
title: PhD Student @ UC Berkeley
9+
url: https://scholar.google.com/citations?user=HwfGXkcAAAAJ
10+
image_url: https://github.com/sahilbhatia17.png
111
shadaj:
212
name: Shadaj Laddad
313
title: PhD Student @ UC Berkeley

website/docs/tutorial/creating-synthesis-problem.md

+65-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ sidebar_position: 1
55
# Solving a Synthesis Problem
66
Before we dive into an end-to-end verified lifting application, let's familiarize ourselves with the basic concepts in Metalift with a synthesis problem.
77

8-
Let us synthesize a function $f(x)$ such that for all integer $x$, $f(x) \geq 0$ and $f(x) \geq x$. Formally, we want to solve the following problem: $\exists{f}. \forall x \in \mathbb{N}. f(x) \geq 0 \wedge f(x) \geq x$. The $\forall$ **universal quantifier** is so key to verification that it's in our logo!
8+
Let us synthesize a function $f(x)$ such that for all integer $x$, $f(x) \geq 0$ and $f(x) \geq x$. Formally, we want to solve the following problem: $\exists{f}. \forall x \in \mathbb{Z}. f(x) \geq 0 \wedge f(x) \geq x$. The $\forall$ **universal quantifier** is so key to verification that it's in our logo!
99

1010
## Define the Verification Conditions
1111
The first step to encoding this with Metalift is to define the conditions that we want to verify. These conditions can be specified using the __Metalift IR__, which includes a variety of common operations on types like booleans, integers, lists, and sets that Metalift knows the meaning of.
@@ -41,8 +41,70 @@ correct = ir.And(
4141
)
4242
```
4343

44+
As an early check, we can print out these conditions in the SMT language:
45+
<!--phmdoctest-share-names-->
46+
```python
47+
print(correct.toSMT())
48+
```
49+
50+
```
51+
(and (>= (f x) 0) (>= (f x) x))
52+
```
53+
4454
## Create a Program Grammar
45-
TODO
55+
Next, we will create a program grammar that defines the search space for the function $f(x)$. In this case, we will use a simple grammar that only allows the function to be defined in terms of arithmetic operations over the integer variable $x$. Grammars are defined using the same IR nodes, but with the addition of the `Choose` node that represents multiple IR options.
56+
57+
To build up the grammar, which must have a fixed depth and cannot be recursive, we iteratively re-define the `grammar` variable to capture deeper programs.
58+
59+
<!--phmdoctest-share-names-->
60+
```python
61+
grammar = x
62+
63+
for i in range(2):
64+
grammar = ir.Choose(
65+
ir.Add(grammar, grammar),
66+
ir.Sub(grammar, grammar),
67+
ir.Mul(grammar, grammar)
68+
)
69+
```
70+
71+
Once the grammar is defined, we wrap it with a `Synth` node which declares a function to be synthesized:
72+
73+
<!--phmdoctest-share-names-->
74+
```python
75+
synthF = ir.Synth(
76+
"f", # function name
77+
grammar, # body
78+
x, # arguments
79+
)
80+
```
4681

4782
## Synthesize!
48-
TODO
83+
Now that we have both a program search space and verification conditions defined, we can use the `synthesize` function to synthesize a function that satisfies the verification conditions. `synthesize` takes a variety of parameters to inject utility functions, define variables to verify over, and introduce additional predicates. But we'll just use it for a simple synthesis execution.
84+
85+
```python
86+
from metalift.synthesize_auto import synthesize
87+
result = synthesize(
88+
"example", # name of the synthesis problem
89+
[], # list of utility functions
90+
[x], # list of variables to verify over
91+
[synthF], # list of functions to synthesize
92+
[], # list of predicates
93+
correct, # verification condition
94+
[synthF], # type metadata for functions to synthesize, just pass the Synth node otherwise
95+
unboundedInts=True, # verify against the full range of integers (by default integers are restricted to a fixed number of bits)
96+
)
97+
98+
print(result)
99+
```
100+
101+
If we run this code, Metalift will use the Rosette synthesis engine to generate a function that satisfies the requirements.
102+
103+
```
104+
====== verification
105+
Verification Output: unsat
106+
Verified PS and INV Candidates (FnDecl:(Function Int Int) f (Add:Int (Mul:Int x x) (Sub:Int x x)) x)
107+
[(FnDecl:(Function Int Int) f (Add:Int (Mul:Int x x) (Sub:Int x x)) x)]
108+
```
109+
110+
In this case, we get $f(x) = (x * x) + (x - x) = x * x$ which indeed satisfies the verification conditions!

0 commit comments

Comments
 (0)