ayushnoori commited on
Commit
6a3cab3
·
1 Parent(s): da55da3

Add custom example functionality

Browse files
Files changed (2) hide show
  1. app.py +26 -7
  2. examples.py +5 -5
app.py CHANGED
@@ -5,6 +5,7 @@ import numpy as np
5
  import argparse
6
  import itertools
7
  import time
 
8
 
9
  # import examples and synthesizer
10
  from arithmetic import *
@@ -24,13 +25,13 @@ Completed for [CS252R: Program Synthesis](https://synthesis.metareflection.club/
24
  st.header("👨🏽‍💻 Project Description")
25
 
26
  st.markdown('''
27
- Here, we implement the non-ML subset of BUSTLE, the algorithm proposed by [Odena *et al.* (2021)](https://arxiv.org/abs/2007.14381). That is, we implement bottom-up enumerative search for simple compound expressions, excluding conditionals, recursion, and loops. The implementation is generic and flexibly supports multiple target languages. Arithmetic and string manipulations are natively supported, defined in `arithmetic.py` and `string.py`, respectively.
28
  ''')
29
 
30
  st.subheader("Input-Output Examples")
31
 
32
  st.markdown('''
33
- Select input-output examples as defined in `examples.py`, or define your own custom examples. The examples are used to synthesize a satisfying program.
34
  ''')
35
 
36
  # define variables
@@ -38,11 +39,29 @@ Select input-output examples as defined in `examples.py`, or define your own cus
38
  # examples_key = "addition"
39
  # max_weight = 3
40
  domain = st.selectbox("Domain", ["arithmetic", "strings"])
41
- examples_key = st.selectbox("Examples", example_set.keys())
42
  max_weight = st.slider("Maximum Weight", 2, 10, 3)
43
 
44
- # retrieve selected input-output examples
45
- examples = example_set[examples_key]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  # extract constants from examples
48
  st.subheader("Synthesis Steps")
@@ -134,9 +153,9 @@ else:
134
  st.header("🔎 Algorithm Details")
135
 
136
  st.markdown('''
137
- The most important data structure in this implementation is the abstract syntax tree (AST). The AST is a tree representation of a program, where each node is either a primitive or a compound expression. The AST is represented by the `OperatorNode` class in `abstract_syntax_tree.py`. My AST implementation includes functions to recursively evaluate the operator and its operands and also to generate a string representation of the program.
138
 
139
- At program evaluation time, the AST is evaluated from the bottom up. That is, the operands are evaluated first, and then the operator is evaluated on the operands. This is implemented in the `evaluate` method of the `OperatorNode` class. In the case of integers, variable inputs are represented by the `IntegerVariable` class in `arithmetic.py`. When input is not `None`, input type checking and validation is performed by the `evaluate` function in this class.
140
 
141
  The pseudocode for the bottom-up synthesis algorithm is reproduced below from [Odena *et al.* (2021)](https://arxiv.org/abs/2007.14381):
142
  ''')
 
5
  import argparse
6
  import itertools
7
  import time
8
+ import ast
9
 
10
  # import examples and synthesizer
11
  from arithmetic import *
 
25
  st.header("👨🏽‍💻 Project Description")
26
 
27
  st.markdown('''
28
+ Here, we implement the non-ML subset of BUSTLE, the algorithm proposed by [Odena *et al.* (2021)](https://arxiv.org/abs/2007.14381). That is, we implement bottom-up enumerative search for simple compound expressions, excluding conditionals, recursion, and loops. The implementation is generic and flexibly supports multiple target languages. Arithmetic and string manipulations are natively supported, defined in [`arithmetic.py`](https://github.com/ayushnoori/program-synthesis/blob/main/arithmetic.py) and [`string.py`](https://github.com/ayushnoori/program-synthesis/blob/main/string.py), respectively.
29
  ''')
30
 
31
  st.subheader("Input-Output Examples")
32
 
33
  st.markdown('''
34
+ Select input-output examples as defined in [`examples.py`](https://github.com/ayushnoori/program-synthesis/blob/main/examples.py), or define your own custom examples as a list of tuples. The examples are used to synthesize a satisfying program.
35
  ''')
36
 
37
  # define variables
 
39
  # examples_key = "addition"
40
  # max_weight = 3
41
  domain = st.selectbox("Domain", ["arithmetic", "strings"])
 
42
  max_weight = st.slider("Maximum Weight", 2, 10, 3)
43
 
44
+ # example_keys = list(example_set.keys())
45
+ custom_example = st.toggle("Custom Example", value = False)
46
+ if custom_example:
47
+ if domain == "arithmetic":
48
+ default_example = "[([7, 2], 9), ([8, 1], 9), ([4, 6], 10), ([3, 9], 12), ([5, 8], 13)]"
49
+ else:
50
+ default_example = '[(["a", "b"], "ab"), (["c", "d"], "cd"), (["e", "f"], "ef")]'
51
+
52
+ example_text = st.text_input(label = "Example", value = default_example)
53
+ examples = ast.literal_eval(example_text)
54
+
55
+ if not isinstance(examples, list) or not all(isinstance(item, tuple) for item in examples):
56
+
57
+ st.write(":x: Invalid example format. Please enter a list of tuples.")
58
+
59
+ else:
60
+ example_keys = ['addition', 'subtraction', 'multiplication', 'division', 'concatenate', 'right', 'left']
61
+ examples_key = st.selectbox("Examples", example_keys)
62
+
63
+ # retrieve selected input-output examples
64
+ examples = example_set[examples_key]
65
 
66
  # extract constants from examples
67
  st.subheader("Synthesis Steps")
 
153
  st.header("🔎 Algorithm Details")
154
 
155
  st.markdown('''
156
+ The most important data structure in this implementation is the abstract syntax tree (AST). The AST is a tree representation of a program, where each node is either a primitive or a compound expression. The AST is represented by the `OperatorNode` class in [`abstract_syntax_tree.py`](https://github.com/ayushnoori/program-synthesis/blob/main/abstract_syntax_tree.py). My AST implementation includes functions to recursively evaluate the operator and its operands and also to generate a string representation of the program.
157
 
158
+ At program evaluation time, the AST is evaluated from the bottom up. That is, the operands are evaluated first, and then the operator is evaluated on the operands. This is implemented in the `evaluate` method of the `OperatorNode` class. In the case of integers, variable inputs are represented by the `IntegerVariable` class in [`arithmetic.py`](https://github.com/ayushnoori/program-synthesis/blob/main/arithmetic.py). When input is not `None`, input type checking and validation is performed by the `evaluate` function in this class.
159
 
160
  The pseudocode for the bottom-up synthesis algorithm is reproduced below from [Odena *et al.* (2021)](https://arxiv.org/abs/2007.14381):
161
  ''')
examples.py CHANGED
@@ -12,20 +12,20 @@ function in the synthesizer.
12
  # define examples
13
  example_set = {
14
  # basic arithmetic examples
15
- 'addition': [([7, 2], 9), ([8, 1], 9), ([3, 9], 12), ([5, 8], 13)], # ([4, 6], 10),
16
  'subtraction': [([9, 2], 7), ([6, 1], 5), ([7, 3], 4), ([8, 4], 4), ([10, 2], 8)],
17
  'multiplication': [([2, 3], 6), ([4, 5], 20), ([7, 8], 56), ([9, 2], 18), ([3, 4], 12)],
18
  'division': [([6, 2], 3), ([8, 4], 2), ([9, 3], 3), ([10, 5], 2), ([12, 6], 2)],
19
 
20
- # advanced arithmetic examples
21
- 'add_5_multiply_2': [([1, 2], 12), ([3, 4], 22), ([5, 6], 32), ([7, 8], 42), ([9, 10], 52)],
22
- 'multiply_add_9': [([1, 2], 11), ([3, 4], 21), ([5, 6], 39), ([7, 8], 65), ([9, 10], 9)],
23
-
24
  # basic string examples
25
  'concatenate': [(["a", "b"], "ab"), (["c", "d"], "cd"), (["e", "f"], "ef")],
26
  'right': [(["hello", 3], "llo"), (["world", 4], "orld"), (["fox", 1], "x")],
27
  'left': [(["hello", 2], "he"), (["world", 3], "wor"), (["fox", 2], "fo")],
28
 
 
 
 
 
29
  # advanced string examples
30
  'concatenate_3': [(["a", "b", "c"], "abc"), (["d", "e", "f"], "def"), (["g", "h", "i"], "ghi")],
31
 
 
12
  # define examples
13
  example_set = {
14
  # basic arithmetic examples
15
+ 'addition': [([7, 2], 9), ([8, 1], 9), ([4, 6], 10), ([3, 9], 12), ([5, 8], 13)],
16
  'subtraction': [([9, 2], 7), ([6, 1], 5), ([7, 3], 4), ([8, 4], 4), ([10, 2], 8)],
17
  'multiplication': [([2, 3], 6), ([4, 5], 20), ([7, 8], 56), ([9, 2], 18), ([3, 4], 12)],
18
  'division': [([6, 2], 3), ([8, 4], 2), ([9, 3], 3), ([10, 5], 2), ([12, 6], 2)],
19
 
 
 
 
 
20
  # basic string examples
21
  'concatenate': [(["a", "b"], "ab"), (["c", "d"], "cd"), (["e", "f"], "ef")],
22
  'right': [(["hello", 3], "llo"), (["world", 4], "orld"), (["fox", 1], "x")],
23
  'left': [(["hello", 2], "he"), (["world", 3], "wor"), (["fox", 2], "fo")],
24
 
25
+ # advanced arithmetic examples
26
+ 'add_5_multiply_2': [([1, 2], 12), ([3, 4], 22), ([5, 6], 32), ([7, 8], 42), ([9, 10], 52)],
27
+ 'multiply_add_9': [([1, 2], 11), ([3, 4], 21), ([5, 6], 39), ([7, 8], 65), ([9, 10], 9)],
28
+
29
  # advanced string examples
30
  'concatenate_3': [(["a", "b", "c"], "abc"), (["d", "e", "f"], "def"), (["g", "h", "i"], "ghi")],
31