on the simplicity of synthesizing linked data structure ...dkurilov/slides/gpce13slides.pdf · on...

33
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

Upload: vuongkhuong

Post on 05-Feb-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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!

Page 2: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

Ideal Code Generation Scenario

I want the program to...

...

...

...

*.java  *.exe  *.c  *.js  

...

Magic  Box  2!

© Darya Kurilova 2013!

[GPCE‘13, Indianapolis, IN, USA]!

Page 3: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

@SpecField(…)  @Modifies(…)  

...

...

...

3!

*.java  *.class  *.exe  

Proposed Code Generation Scenario

SAT Solver © Darya Kurilova 2013!

[GPCE‘13, Indianapolis, IN, USA]!

Page 4: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 5: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 6: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 7: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

Code Generation Algorithm

1.  Part I: Programmer’s Actions 2.  Part II: Automatic Actions

7!© Darya Kurilova 2013!

[GPCE‘13, Indianapolis, IN, USA]!

Page 8: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 9: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 10: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 11: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 12: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 13: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 14: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 15: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 16: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 17: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 18: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 19: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 20: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 21: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 22: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 23: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 24: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 25: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 26: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 27: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 28: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 29: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 30: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 31: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 32: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!

Page 33: On the Simplicity of Synthesizing Linked Data Structure ...dkurilov/slides/gpce13slides.pdf · On the Simplicity of Synthesizing Linked Data Structure Operations ... – Proof of

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]!