on the simplicity of synthesizing linked data structure ...dkurilov/slides/gpce13slides.pdf · on...
Post on 05-Feb-2018
215 Views
Preview:
TRANSCRIPT
On the Simplicity of Synthesizing Linked Data Structure Operations
Darya Kurilova, Carnegie Mellon University Derek Rayside, University of Waterloo
© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
1!
Ideal Code Generation Scenario
I want the program to...
...
...
...
*.java *.exe *.c *.js
...
Magic Box 2!
© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
@SpecField(…) @Modifies(…)
...
...
...
3!
*.java *.class *.exe
Proposed Code Generation Scenario
SAT Solver © Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Our Approach • Given: – Prior work on code synthesis – SAT-solver limits
• Problem: – Generating code for data structures that require heap
manipulations is believed to be hard • Our solution: – Use “divide-and-conquer” and a common pattern
for code generation – Proof of concept: code generation via systematic
manual procedure
4!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Common Pattern 1 public return-type method-name(arguments) { 2 if (condition1 && condition2 && ... && conditionN1) { 3 statement1; 4 statement2; 5 ... 6 statementM1; 7 return object-of-the-return-type-or-nothing; 8 } 9 ... 10 if (condition1 && condition2 && ... && conditionNk) { 11 statement1; 12 statement2; 13 ... 14 statementMk; 15 return object-of-the-return-type-or-nothing; 16 } 17 }
5!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
AVL Trees • A self-balancing binary search tree • Difference between height of the left
subtree and of the right subtree is at most 1
4
2
1 3
6
5 7
4
2
1 3
5
5
2
1 4
6
3
This is an AVL tree. This is not an AVL tree. This is an AVL tree.
6!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm
1. Part I: Programmer’s Actions 2. Part II: Automatic Actions
7!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part I(Programmer’s Actions)
1. Define basic data structures. 2. Write invariants. 3. Declare and specify methods.
8!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part I(Programmer’s Actions)
1. Define basic data structures. 2. Write invariants. 3. Declare and specify methods.
9!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Basic Data Structures 1 class Node { 2 int value; 3 int height; 4 Node left; 5 Node right; 6 Node parent; 7 }
8 class AVLTree { 9 Node root; 10 }
10!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part I(Programmer’s Actions)
1. Define basic data structures. 2. Write invariants. 3. Declare and specify methods.
11!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Invariants for an AVL Tree 1 @Invariant({ 2 // root has no parents 3 "no (left + right).(this.root)", 4 5 // acyclic 6 "no this in this.^(left + right)", 7 8 // ordered 9 "all x : this.left.^(left + right) + this.left -‐ null | x.value < this.value", 10 "all x : this.right.^(left + right) + this.right -‐ null | x.value > this.value", 11 12 // height of a leaf node is 1 13 "(this.left = null and this.right = null) => this.height = 1", 14 15 // height for semi-‐leaf nodes 16 "(this.left = null and this.right != null) => this.height = this.right.height + 1", 17 "(this.left != null and this.right = null) => this.height = this.left.height + 1", 18 19 // height for interior nodes 20 "(this.left != null and this.right = null) => this.height = this.left.height + 1", 21 "this.left != null => this.height > this.left.height", 22 "this.right != null => this.height > this.right.height", 23 "no null in this.(left + right) => this.left.height -‐ this.right.height <= 1", 24 "no null in this.(left + right) => this.right.height -‐ this.left.height <= 1", 25 "no null in this.(left + right) => (this.height = this.left.height + 1) 26 or (this.height = this.right.height + 1)" 27 }) 12!
© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part I(Programmer’s Actions)
1. Define basic data structures. 2. Write invariants. 3. Declare and specify methods.
13!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Methods and Their Specifications 1 @Pure 2 @Returns("x in this.values") 3 public boolean contains(int x) { 4 // generated code goes here 5 } 6 7 @Modifies("Node.value, Node.height, Node.left, Node.right, Node.parent, this.root") 8 @Ensures("x in this.values") 9 public void insert(int x) { 10 // generated code goes here 11 } 12 13 @Modifies("Node.value, Node.height, Node.left, Node.right, Node.parent, this.root") 14 @Ensures("no x in this.values") 15 public void delete(int x) { 16 // generated code goes here 17 }
14!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part II(Automatic Actions)
1. Generate helper methods and their specifications based on basic data structures definitions.
2. Generate helper methods and their specifications based on invariants.
3. Determine the helper methods’ call order.
15!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part II(Automatic Actions)
1. Generate helper methods and their specificationsbased on basic data structures definitions.
2. Generate helper methods and their specifications based on invariants.
3. Determine the helper methods’ call order.
16!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
swapChildren() Helper Method 1 @Ensures("this.right = @old(this.left) 2 and this.left = @old(this.right)") 3 4 private void swapChildren(Node one) { 5 Node temp = one.right; 6 one.right = one.left; 7 one.left = temp; 8 }
17!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part II(Automatic Actions)
1. Generate helper methods and their specifications based on basic data structures definitions.
2. Generate helper methods and their specificationsbased on invariants.
1) Analyze invariants. 2) Generate helper methods’ bodies. 3) Clean up.
3. Determine the helper methods’ call order.
18!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Invariant Analysis
19!
1 @Invariant({ 2 // root has no parents 3 "no (left + right).(this.root)", 4 5 // acyclic 6 "no this in this.^(left + right)", 7 8 // ordered 9 "all x : this.left.^(left + right) + this.left -‐ null | x.value < this.value", 10 "all x : this.right.^(left + right) + this.right -‐ null | x.value > this.value", 11 12 // height of a leaf node is 1 13 "(this.left = null and this.right = null) => this.height = 1", 14 15 // height for semi-‐leaf nodes 16 "(this.left = null and this.right != null) => this.height = this.right.height + 1", 17 "(this.left != null and this.right = null) => this.height = this.left.height + 1", 18 19 // height for interior nodes 20 "(this.left != null and this.right = null) => this.height = this.left.height + 1", 21 "this.left != null => this.height > this.left.height", 22 "this.right != null => this.height > this.right.height", 23 "no null in this.(left + right) => this.left.height -‐ this.right.height <= 1", 24 "no null in this.(left + right) => this.right.height -‐ this.left.height <= 1", 25 "no null in this.(left + right) => (this.height = this.left.height + 1) 26 or (this.height = this.right.height + 1)" 27 })
© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Invariant Analysis Conclusion
20!
• Invariants that mention the value field are related to ordering.
• Invariants that mention the height field are related to balancing.
• Therefore: – two groups of invariants, – two main properties, and – two helper methods.
© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Invariant Analysis Results 1 @Pure 2 @Returns("x in this.values") 3 public boolean contains(int x) { 4 @Pure 5 @Returns("x in this.values") 6 containsHelper(...); 7 } 8 @Modifies("Node.value, Node.height, Node.left, Node.right, Node.parent, this.root") 9 @Ensures("x in this.values") 10 public void insert(int x) { 11 @Modifies("Node.value, Node.left, Node.right, Node.parent, this.root") 12 @Ensures("x in this.values") 13 orderingInsertHelper(...); 14 15 @Modifies("Node.height, Node.left, Node.right, Node.parent, this.root") 16 balancingInsertHelper(...); 17 } 18 @Modifies("Node.value, Node.height, Node.left, Node.right, Node.parent, this.root") 19 @Ensures("no x in this.values") 20 public void delete(int x) { 21 @Modifies("Node.value, Node.left, Node.right, Node.parent, this.root") 22 @Ensures("no x in this.values") 23 orderingDeleteHelper(...); 24 25 @Modifies("Node.height, Node.left, Node.right, Node.parent, this.root") 26 balancingDeleteHelper(...); 27 }
21!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part II(Automatic Actions)
1. Generate helper methods and their specifications based on basic data structures definitions.
2. Generate helper methods and their specificationsbased on invariants.
1) Analyze invariants. 2) Generate helper methods’ bodies. 3) Clean up.
3. Determine the helper methods’ call order.
22!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Common Pattern 1 public return-type method-name(arguments) { 2 if (condition1 && condition2 && ... && conditionN1) { 3 statement1; 4 statement2; 5 ... 6 statementM1; 7 return object-of-the-return-type-or-nothing; 8 } 9 ... 10 if (condition1 && condition2 && ... && conditionNk) { 11 statement1; 12 statement2; 13 ... 14 statementMk; 15 return object-of-the-return-type-or-nothing; 16 } 17 }
23!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Pattern Fillers • Conditions: – Mathematical comparisons using ==, !=, <, <=, >, >=. – Node fields, null, and numeric values from
specifications. • Executable statements: – a recursive call to the method itself, – a call to another method, – an assignment to an existing variable, – a variable declaration, – an assignment to the introduced variable.
24!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Generated containsHelper() 1 public boolean containsHelper(int x, Node node) { 2 if (node != null && node.left == null && node.right == null && node.value > x) { 3 return false; 4 } 5 if (node != null && node.left == null && node.right == null && node.value < x) { 6 return false; 7 } 8 if (node != null && node.left == null && node.right == null && node.value == x) { 9 return true; 10 } 11 if (node != null && node.left == null && node.right != null && node.value > x) { 12 return false; 13 } 14 if (node != null && node.left == null && node.right != null && node.value < x) { 15 return containsHelper(x, node.right); 16 } 17 18 ... // 42 MORE IF-‐BLOCKS 19 20 if (node == null && node.left != null && node.right != null && node.value == x) { 21 return false; 22 } 23 } 25!
© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part II(Automatic Actions)
1. Generate helper methods and their specifications based on basic data structures definitions.
2. Generate helper methods and their specificationsbased on invariants.
1) Analyze invariants. 2) Generate helper methods’ bodies. 3) Clean up.
3. Determine the helper methods’ call order.
26!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
containsHelper() After Clean Up 1 public boolean containsHelper(int x, Node node) { 2 if (node == null) { 3 return false; 4 } 5 if (node.value == x) { 6 return true; 7 } 8 if (node.value < x) { 9 if (node.right != null) { 10 return containsHelper(x, node.right); 11 } else { 12 return false; 13 } 14 } 15 if (node.value > x) { 16 if (node.left != null) { 17 return containsHelper(x, node.left); 18 } else { 19 return false; 20 } 21 } 22 }
27!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm: Part II(Automatic Actions)
1. Generate helper methods and their specifications based on basic data structures definitions.
2. Generate helper methods and their specifications based on invariants.
1) Analyze invariants. 2) Generate helper methods’ bodies. 3) Clean up.
3. Determine the helper methods’ call order.
28!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Helper Methods’ Call Order 1 @Pure 2 @Returns("x in this.values") 3 public boolean contains(int x) { 4 @Pure 5 @Returns("x in this.values") 6 containsHelper(...); 7 } 8 @Modifies("Node.value, Node.height, Node.left, Node.right, Node.parent, this.root") 9 @Ensures("x in this.values") 10 public void insert(int x) { 11 @Modifies("Node.value, Node.left, Node.right, Node.parent, this.root") 12 @Ensures("x in this.values") 13 orderingInsertHelper(...); 14 15 @Modifies("Node.height, Node.left, Node.right, Node.parent, this.root") 16 balancingInsertHelper(...); 17 } 18 @Modifies("Node.value, Node.height, Node.left, Node.right, Node.parent, this.root") 19 @Ensures("no x in this.values") 20 public void delete(int x) { 21 @Modifies("Node.value, Node.left, Node.right, Node.parent, this.root") 22 @Ensures("no x in this.values") 23 orderingDeleteHelper(...); 24 25 @Modifies("Node.height, Node.left, Node.right, Node.parent, this.root") 26 balancingDeleteHelper(...); 27 } 29!
© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm Summary Part I: Programmer’s Actions
1. Define basic data structures. 2. Write invariants. 3. Declare and specify methods.
Part II: Automatic Actions
1. Generate helper methods and their specifications based on basic data structures definitions.
2. Generate helper methods and their specifications based on invariants. 1) Analyze the invariants. 2) Generate helper methods’
bodies. 3) Clean up.
3. Determine the helper methods’ call order.
30!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Code Generation Algorithm Summary Part I: Programmer’s Actions
1. Define basic data structures. 2. Write invariants. 3. Declare and specify methods.
Part II: Automatic Actions
1. Generate helper methods and their specifications based on basic data structures definitions.
2. Generate helper methods and their specifications based on invariants. 1) Analyze the invariants. 2) Generate helper methods’
bodies. 3) Clean up.
3. Determine the helper methods’ call order.
31!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Search Space Analysis • Usual case: – 6 statements + 2 levels of dereferencing = 230
– Can be handled by modern SAT solvers • Exception: tree re-balance helper method – 12 statements + 3 levels of dereferencing = 284
– Mitigated by “smart” order in which types of statements are introduced
32!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
Conclusion • Use “divide-and-conquer” and the common
pattern • Search spaces manageable by current SAT-
solvers • Problem might be not as difficult as previously
imagined • Approach is applicable to recursive linked data
structures; possibly to others
33!© Darya Kurilova 2013!
[GPCE‘13, Indianapolis, IN, USA]!
top related