ayushnoori commited on
Commit
3f02d46
Β·
1 Parent(s): e1fc3b2

Add examples and argument parsing.

Browse files
Code/arithmetic.py CHANGED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ ARTHIMETIC OPERATORS
3
+ This file contains Python classes that define the arithmetic operators for program synthesis.
4
+ '''
5
+
6
+ '''
7
+ CLASS DEFINITIONS
8
+ '''
9
+
10
+ class IntegerValue:
11
+ '''
12
+ Class to represent an arithmetic value.
13
+ '''
14
+ def __init__(self, value):
15
+ self.value = value
16
+ self.type = int
17
+
18
+ class Add:
19
+ '''
20
+ Operator to add two numerical values.
21
+ '''
22
+ def __init__(self):
23
+ self.arity = 2 # number of arguments of function
24
+ self.weight = 1 # weight of function
25
+ self.return_type = int # return type of function
26
+
27
+ def __call__(self, x, y):
28
+ return x + y
29
+
30
+ def str(x, y):
31
+ return f"{x} + {y}"
32
+
33
+ class Subtract:
34
+ '''
35
+ Operator to subtract two numerical values.
36
+ '''
37
+ def __init__(self):
38
+ self.arity = 2 # number of arguments of function
39
+ self.weight = 1 # weight of function
40
+ self.return_type = int # return type of function
41
+
42
+ def __call__(self, x, y):
43
+ return x - y
44
+
45
+ def str(x, y):
46
+ return f"{x} - {y}"
47
+
48
+ class Multiply:
49
+ '''
50
+ Operator to multiply two numerical values.
51
+ '''
52
+ def __init__(self):
53
+ self.arity = 2 # number of arguments of function
54
+ self.weight = 1 # weight of function
55
+ self.return_type = int # return type of function
56
+
57
+ def __call__(self, x, y):
58
+ return x * y
59
+
60
+ def str(x, y):
61
+ return f"{x} * {y}"
62
+
63
+ class Divide:
64
+ '''
65
+ Operator to divide two numerical values.
66
+ '''
67
+ def __init__(self):
68
+ self.arity = 2 # number of arguments of function
69
+ self.weight = 1 # weight of function
70
+ self.return_type = int # return type of function
71
+
72
+ def __call__(self, x, y):
73
+ try: # check for division by zero error
74
+ return x / y
75
+ except ZeroDivisionError:
76
+ return None
77
+
78
+ def str(x, y):
79
+ return f"{x} / {y}"
80
+
81
+
82
+ '''
83
+ FUNCTION DEFINITIONS
84
+ '''
85
+
86
+
87
+ '''
88
+ GLOBAL CONSTANTS
89
+ '''
90
+
91
+ # define operators
92
+ arithmetic_operators = [Add(), Subtract(), Multiply(), Divide()]
Code/demonstration.ipynb ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# PSET 1: Bottom-Up Synthesis\n",
8
+ "\n",
9
+ "I follow Algorithm 1 in the BUSTLE paper:\n",
10
+ "\n",
11
+ "> Odena, A. *et al.* BUSTLE: Bottom-Up Program Synthesis Through Learning-Guided Exploration. in *9th International Conference on Learning Representations*; 2021 May 3-7; Austria.\n",
12
+ "\n",
13
+ "First, I import the required libraries."
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "code",
18
+ "execution_count": 6,
19
+ "metadata": {},
20
+ "outputs": [],
21
+ "source": [
22
+ "import numpy as np\n",
23
+ "import itertools\n",
24
+ "\n",
25
+ "# argument parser for command line arguments\n",
26
+ "import argparse\n",
27
+ "\n",
28
+ "# import arithmetic module\n",
29
+ "# from arithmetic import *\n",
30
+ "from examples import examples\n",
31
+ "\n",
32
+ "# import project config file\n",
33
+ "import sys\n",
34
+ "sys.path.append('..')\n",
35
+ "import project_config"
36
+ ]
37
+ },
38
+ {
39
+ "cell_type": "markdown",
40
+ "metadata": {},
41
+ "source": [
42
+ "First, I define variables as proxies for command-line arguments provided to the synthesizer."
43
+ ]
44
+ },
45
+ {
46
+ "cell_type": "code",
47
+ "execution_count": null,
48
+ "metadata": {},
49
+ "outputs": [],
50
+ "source": [
51
+ "domain = \"arithmetic\"\n",
52
+ "examples_key = \"addition\"\n",
53
+ "examples = examples[examples_key]\n",
54
+ "max_level = 3"
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "markdown",
59
+ "metadata": {},
60
+ "source": [
61
+ "I provide examples of arithmetic operations."
62
+ ]
63
+ },
64
+ {
65
+ "cell_type": "code",
66
+ "execution_count": 5,
67
+ "metadata": {},
68
+ "outputs": [],
69
+ "source": [
70
+ "'''\n",
71
+ "ARTHIMETIC OPERATORS\n",
72
+ "This file contains Python classes that define the arithmetic operators for program synthesis.\n",
73
+ "'''\n",
74
+ "\n",
75
+ "'''\n",
76
+ "CLASS DEFINITIONS\n",
77
+ "''' \n",
78
+ "\n",
79
+ "class IntegerValue:\n",
80
+ " '''\n",
81
+ " Class to represent an arithmetic value.\n",
82
+ " '''\n",
83
+ " def __init__(self, value):\n",
84
+ " self.value = value\n",
85
+ " self.type = int\n",
86
+ "\n",
87
+ "class Add:\n",
88
+ " '''\n",
89
+ " Operator to add two numerical values.\n",
90
+ " '''\n",
91
+ " def __init__(self):\n",
92
+ " self.arity = 2 # number of arguments of function\n",
93
+ " self.weight = 1 # weight of function\n",
94
+ " self.return_type = int # return type of function\n",
95
+ "\n",
96
+ " def __call__(self, x, y):\n",
97
+ " return x + y\n",
98
+ " \n",
99
+ " def str(x, y):\n",
100
+ " return f\"{x} + {y}\"\n",
101
+ "\n",
102
+ "class Subtract:\n",
103
+ " '''\n",
104
+ " Operator to subtract two numerical values.\n",
105
+ " '''\n",
106
+ " def __init__(self):\n",
107
+ " self.arity = 2 # number of arguments of function\n",
108
+ " self.weight = 1 # weight of function\n",
109
+ " self.return_type = int # return type of function\n",
110
+ "\n",
111
+ " def __call__(self, x, y):\n",
112
+ " return x - y\n",
113
+ " \n",
114
+ " def str(x, y):\n",
115
+ " return f\"{x} - {y}\"\n",
116
+ " \n",
117
+ "class Multiply:\n",
118
+ " '''\n",
119
+ " Operator to multiply two numerical values.\n",
120
+ " '''\n",
121
+ " def __init__(self):\n",
122
+ " self.arity = 2 # number of arguments of function\n",
123
+ " self.weight = 1 # weight of function\n",
124
+ " self.return_type = int # return type of function\n",
125
+ "\n",
126
+ " def __call__(self, x, y):\n",
127
+ " return x * y\n",
128
+ " \n",
129
+ " def str(x, y):\n",
130
+ " return f\"{x} * {y}\" \n",
131
+ "\n",
132
+ "class Divide:\n",
133
+ " '''\n",
134
+ " Operator to divide two numerical values.\n",
135
+ " '''\n",
136
+ " def __init__(self):\n",
137
+ " self.arity = 2 # number of arguments of function\n",
138
+ " self.weight = 1 # weight of function\n",
139
+ " self.return_type = int # return type of function\n",
140
+ "\n",
141
+ " def __call__(self, x, y):\n",
142
+ " try: # check for division by zero error\n",
143
+ " return x / y\n",
144
+ " except ZeroDivisionError:\n",
145
+ " return None\n",
146
+ " \n",
147
+ " def str(x, y):\n",
148
+ " return f\"{x} / {y}\"\n",
149
+ "\n",
150
+ "\n",
151
+ "'''\n",
152
+ "FUNCTION DEFINITIONS\n",
153
+ "''' \n",
154
+ "\n",
155
+ "\n",
156
+ "'''\n",
157
+ "GLOBAL CONSTANTS\n",
158
+ "''' \n",
159
+ "\n",
160
+ "# define operators\n",
161
+ "arithmetic_operators = [Add(), Subtract(), Multiply(), Divide()]"
162
+ ]
163
+ },
164
+ {
165
+ "cell_type": "markdown",
166
+ "metadata": {},
167
+ "source": [
168
+ "I define input-output examples."
169
+ ]
170
+ },
171
+ {
172
+ "cell_type": "markdown",
173
+ "metadata": {},
174
+ "source": [
175
+ "I define a function to determine observational equivalence."
176
+ ]
177
+ },
178
+ {
179
+ "cell_type": "code",
180
+ "execution_count": null,
181
+ "metadata": {},
182
+ "outputs": [],
183
+ "source": [
184
+ "def observationally_equivalent(a, b):\n",
185
+ " \"\"\"\n",
186
+ " Returns True if a and b are observationally equivalent, False otherwise.\n",
187
+ " \"\"\"\n",
188
+ "\n",
189
+ " pass"
190
+ ]
191
+ },
192
+ {
193
+ "cell_type": "markdown",
194
+ "metadata": {},
195
+ "source": [
196
+ "Next, I define the bottom-up synthesis algorithm."
197
+ ]
198
+ },
199
+ {
200
+ "cell_type": "code",
201
+ "execution_count": 2,
202
+ "metadata": {},
203
+ "outputs": [],
204
+ "source": [
205
+ "# initialize program bank\n",
206
+ "program_bank = []\n",
207
+ "\n",
208
+ "# iterate over each level\n",
209
+ "for i in range(1, max_level):\n",
210
+ "\n",
211
+ " # define level program bank\n",
212
+ " level_program_bank = []\n",
213
+ "\n",
214
+ " for op in arithmetic_operators():\n",
215
+ "\n",
216
+ " break"
217
+ ]
218
+ }
219
+ ],
220
+ "metadata": {
221
+ "kernelspec": {
222
+ "display_name": "Python 3 (ipykernel)",
223
+ "language": "python",
224
+ "name": "python3"
225
+ },
226
+ "language_info": {
227
+ "codemirror_mode": {
228
+ "name": "ipython",
229
+ "version": 3
230
+ },
231
+ "file_extension": ".py",
232
+ "mimetype": "text/x-python",
233
+ "name": "python",
234
+ "nbconvert_exporter": "python",
235
+ "pygments_lexer": "ipython3",
236
+ "version": "3.10.12"
237
+ }
238
+ },
239
+ "nbformat": 4,
240
+ "nbformat_minor": 2
241
+ }
Code/examples.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''
2
+ EXAMPLES
3
+ This file contains input-output examples for both arithmetic and string domain-specific languages (DSLs).
4
+ To add a new example, add a new key to the dictionary 'examples' and set the value to be a list of tuples.
5
+ '''
6
+
7
+ # define examples
8
+ examples = {
9
+ # arithmetic examples
10
+ 'addition': [([7, 2], 9), ([4, 6], 10), ([8, 1], 9), ([3, 9], 12), ([5, 8], 13)],
11
+ 'subtraction': [([9, 2], 7), ([6, 1], 5), ([7, 3], 4), ([8, 4], 4), ([10, 2], 8)],
12
+ 'multiplication': [([2, 3], 6), ([4, 5], 20), ([7, 8], 56), ([9, 2], 18), ([3, 4], 12)],
13
+ 'division': [([6, 2], 3), ([8, 4], 2), ([9, 3], 3), ([10, 5], 2), ([12, 6], 2)]
14
+
15
+ # string examples
16
+
17
+ # custom user examples
18
+ }
Code/synthesizer.py CHANGED
@@ -2,14 +2,56 @@
2
  BOTTOM UP ENUMERATIVE SYNTHESIS
3
  Ayush Noori
4
  CS252R, Fall 2020
 
 
 
5
  '''
6
 
7
  # load libraries
8
  import numpy as np
9
- import os
 
 
 
10
 
11
  # import project config file
12
  import sys
13
  sys.path.append('..')
14
  import project_config
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  BOTTOM UP ENUMERATIVE SYNTHESIS
3
  Ayush Noori
4
  CS252R, Fall 2020
5
+
6
+ Example of usage:
7
+ python synthesizer.py --domain arithmetic --examples addition
8
  '''
9
 
10
  # load libraries
11
  import numpy as np
12
+ import argparse
13
+
14
+ # import examples
15
+ from examples import examples
16
 
17
  # import project config file
18
  import sys
19
  sys.path.append('..')
20
  import project_config
21
 
22
+
23
+ def parse_args(examples):
24
+ '''
25
+ Parse command line arguments.
26
+ '''
27
+
28
+ parser = argparse.ArgumentParser(description="Bottom-up enumerative synthesis in Python.")
29
+
30
+ # define valid choices for the 'domain' argument
31
+ valid_domain_choices = ["arithmetic", "string"]
32
+
33
+ # add examples
34
+ parser.add_argument('--domain', type=str, required=True, # default="arithmetic",
35
+ choices=valid_domain_choices,
36
+ help='Domain of synthesis (either "arithmetic" or "string").')
37
+
38
+ parser.add_argument('--examples', dest='examples_key', type=str, required=True, # default="addition",
39
+ choices=examples.keys(),
40
+ help='Examples to synthesize program from. Must be a valid key in the "examples" dictionary.')
41
+
42
+ parser.add_argument('--max_levels', type=int, required=False, default=3)
43
+
44
+ args = parser.parse_args()
45
+ return args
46
+
47
+
48
+ if __name__ == '__main__':
49
+
50
+ # parse command line arguments
51
+ args = parse_args(examples)
52
+ print(args.domain)
53
+ print(args.examples_key)
54
+ print(args.max_levels)
55
+
56
+ # run bottom-up enumerative synthesis
57
+ # run_synthesizer(args)
README.md CHANGED
@@ -1,8 +1,10 @@
1
- # Bottom-Up Enumerative Synthesis
 
 
2
 
3
  Completed for [CS252R: Program Synthesis](https://synthesis.metareflection.club/) at the Harvard John A. Paulson School of Engineering and Applied Sciences, taught Fall 2023 by Prof. Nada Amin.
4
 
5
- ## πŸ› οΈ Inductive Program Synthesis
6
 
7
  The following notes are adapted from [*Introduction to Program Synthesis*](http://people.csail.mit.edu/asolar/SynthesisCourse/TOC.htm) by Armando Solar-Lezama.
8
 
@@ -21,9 +23,12 @@ Synthesize(inputs, outputs):
21
 
22
  ## πŸ‘¨πŸ½β€πŸ’» Project Description
23
 
24
- Here, we implement the non-ML subset of BUSTLE, the algorithm proposed by Odena *et al.* (2021).
25
 
26
- ## πŸ“– References
27
 
28
- 1. Odena, A. *et al.* BUSTLE: Bottom-Up Program Synthesis Through Learning-Guided Exploration. in *9th International Conference on Learning Representations*; 2021 May 3-7; Austria.
 
 
29
 
 
 
1
+ # Bottom-Up Enumerative Program Synthesis
2
+
3
+ 🚨🚨PLEASE DO NOT GRADE YET🚨🚨
4
 
5
  Completed for [CS252R: Program Synthesis](https://synthesis.metareflection.club/) at the Harvard John A. Paulson School of Engineering and Applied Sciences, taught Fall 2023 by Prof. Nada Amin.
6
 
7
+ ## πŸ› οΈ Inductive Synthesis
8
 
9
  The following notes are adapted from [*Introduction to Program Synthesis*](http://people.csail.mit.edu/asolar/SynthesisCourse/TOC.htm) by Armando Solar-Lezama.
10
 
 
23
 
24
  ## πŸ‘¨πŸ½β€πŸ’» Project Description
25
 
26
+ Here, we implement the non-ML subset of BUSTLE, the algorithm proposed by Odena *et al.* (2021). That is, we implement bottom-up enumerative search for simple compound expressions, excluding conditionals, recursion and loops.
27
 
28
+ ## πŸ™πŸ½ Acknowledgements
29
 
30
+ I thank [Tyler Holloway](mailto:tylerholloway@g.harvard.edu), teaching fellow in CS252R, for her guidance in completing this implementation of bottom-up enumerative program synthesis.
31
+
32
+ ## πŸ“– References
33
 
34
+ 1. Odena, A. *et al.* BUSTLE: Bottom-Up Program Synthesis Through Learning-Guided Exploration. in *9th International Conference on Learning Representations*; 2021 May 3-7; Austria.