def get_hole_declarations(program_vars): """Helper function for creating hole declaration with a grammar blow.""" grammar_spec = "((Start Int ( (Constant Real) )))" grammar = templates.load_gramar_from_SYGUS_spec(grammar_spec) h1 = HoleDecl('HOLE1', grammar, program_vars, True, max_depth=4) h2 = HoleDecl('HOLE2', grammar, program_vars, True, max_depth=4) return {h1.id: h1, h2.id: h2}
def get_synthesizer(): code = """a = HOLE""" vars = contract.ProgramVars({'x': 'Int', 'y': 'Int'}, {'a': 'Int'}) code_pre = 'x >= 1 and y >= 1' code_post = 'a == 6*x + y' sygus_grammar = """ ( ( Start Int ( ( Constant Int ) x y (+ Start Start) (* ( Constant Int ) Start) ) ) ) """ #(- Start Start) grammar = templates.load_gramar_from_SYGUS_spec(sygus_grammar) hole = smt_synthesis.HoleDecl('HOLE', grammar, { 'x': 'Int', 'y': 'Int' }, is_expression_hole=True, max_depth=3) env = utils.Options({ '--solver': 'z3', '--logic': 'NIA', '--produce_proofs': True, '--silent': True }) return smt_synthesis.SynthesizerSMT(code, code_pre, code_post, vars, env, [hole])
def test_synthesis_simple(self): grammar = templates.load_gramar_from_SYGUS_spec("((Start Int (x y)))") h = smt_synthesis.HoleDecl('H0', grammar, None, True, 2) code = "(= res (* 2 (+ H0 y)))" env = utils.Options({ '--solver': 'z3', '--logic': 'NIA', '--silent': 1, '--lang': 'smt2', '--output_data': 'holes_content', '--solver_timeout': '2000' }) vars = ProgramVars({'x': 'Int', 'y': 'Int'}, {'res': 'Int'}) # Trivial case with the postcondition being always true. res = smt_synthesis.synthesize(code, 'true', 'true', vars, env, [h]) self.assertEquals('sat', res.decision) # Slightly less trivial case. res = smt_synthesis.synthesize(code, 'true', '(= res (+ (* 2 x) (* 2 y)))', vars, env, [h]) self.assertEquals('sat', res.decision) self.assertEquals('0', res.model['H0Start0_r0']) self.assertEquals('x', res.holes_content['H0']) self.assertEquals("{'H0': 'x'}", res.str_formatted()) # Case for which UNSAT is the expected answer. res = smt_synthesis.synthesize(code, 'true', '(= res 0)', vars, env, [h]) self.assertEquals('unsat', res.decision)
def synthesize_max(): code = """ if H1: res = H2 else: res = H3 """ code_pre = 'True' code_post = 'res >= x and res >= y and (res == x or res == y)' # Specification of the hole's template in the form of the grammar in SYGUS format. sygus_grammar_hole1 = """ ( ( Start Bool ( (Constant Bool) (> TermInt TermInt) (>= TermInt TermInt) (= TermInt TermInt) (<= TermInt TermInt) (< TermInt TermInt) ) ) ( TermInt Int ( (Constant Int) x y ) ) ) """ sygus_grammar_hole23 = """ ( ( Start Int ( (Constant Int) x y (+ x y) (- x y) (- y x) (+ x ( Constant Int )) (+ y ( Constant Int )) ) ) ) """ grammar1 = templates.load_gramar_from_SYGUS_spec(sygus_grammar_hole1) grammar23 = templates.load_gramar_from_SYGUS_spec(sygus_grammar_hole23) pv = contract.ProgramVars({'x': 'Int', 'y': 'Int'}, {'res': 'Int'}) h1 = smt_synthesis.HoleDecl('H1', grammar1, pv, True, 2) h2 = smt_synthesis.HoleDecl('H2', grammar23, pv, True, 2) h3 = smt_synthesis.HoleDecl('H3', grammar23, pv, True, 2) hole_decls = [h1, h2, h3] # The result is currently only a raw output from the solver, but one can verify from the model # that synthesized program is correct. env = utils.Options(['--solver', 'z3', '--logic', 'NIA']) res = smt_synthesis.synthesize(code, code_pre, code_post, pv, env, hole_decls) return res
def test_ssa_form_holes(self): code = """ trigger = False newAcc = acc + 2 newAcc = newAcc - 1 if newAcc < limit: trigger = False else: newAcc = HOLE # should be 0 newAcc = newAcc - 1 trigger = True """ post = 'True' vars = contract.ProgramVars({ 'acc': 'Int', 'limit': 'Int' }, { 'newAcc': 'Int', 'trigger': 'Bool' }) grammar_spec = """ ( ( Start Int ( ( Constant Int ) acc limit newAcc) ) ) """ from pysv import templates grammar = templates.load_gramar_from_SYGUS_spec(grammar_spec) hole = smt_synthesis.HoleDecl('HOLE', grammar, None, True) ib = ast_utils.py_to_interm_ib(code, [hole]) holes = ib.src.get_holes_definitions() self.assertEquals(1, len(holes)) self.assertEquals({ 'acc': 'Int', 'limit': 'Int', 'newAcc': 'Int' }, holes[0].vars) post = ast_utils.py_to_interm_expr(post) ib2, post2 = ssa_converter.convert(ib, post, vars) holes = ib2.src.get_holes_definitions() self.assertEquals(1, len(holes)) self.assertEquals({ 'acc': 'Int', 'limit': 'Int', "|newAcc'|": 'Int' }, holes[0].vars)
def test_synthesis_instruction_hole(self): code = "H0" grammar = templates.load_gramar_from_SYGUS_spec("((Start Int (x y)))") h = smt_synthesis.HoleDecl('H0', grammar, None, True, 2) env = utils.Options({ '--logic': 'NIA', '--silent': 1, '--lang': 'python', '--output_data': 'holes_content' }) vars = ProgramVars({'x': 'Int', 'y': 'Int'}, {'res': 'Int'}) with self.assertRaises(Exception) as context: smt_synthesis.synthesize(code, 'True', 'True', vars, env, [h]) self.assertEquals("Instruction holes are currently not supported!", str(context.exception))
def get_hole_declarations(program_vars): """Helper function for creating hole declaration with a grammar blow.""" grammar_spec = """ ( (Start Int ( (Constant Int) (Variable Int) (+ Start Start) (* Start Start) )) ) """ grammar = templates.load_gramar_from_SYGUS_spec(grammar_spec) h1 = smt_synthesis.HoleDecl('HOLE1', grammar, program_vars, True, max_depth=4) h2 = smt_synthesis.HoleDecl('HOLE2', grammar, program_vars, True, max_depth=4) return [h1, h2]
def get_hole_declarations(program_vars): """Returns hole declarations. Customize this for your needs.""" grammar_spec = """ ( (Start Int ( (Constant Int) (Variable Int) (+ Start Start) )) ) """ grammar = templates.load_gramar_from_SYGUS_spec(grammar_spec) h1 = smt_synthesis.HoleDecl('HOLE1', grammar, program_vars, True, max_depth=4) return [h1]
def test_1(): grammar_spec_4 = """ ( ( Start Bool ((> StartInt StartInt) (and Start Start) ) ) ( StartInt Int (x y (+ StartInt StartInt ) (* StartInt (Constant Int) )) ) ) """ grammar = templates.load_gramar_from_SYGUS_spec(grammar_spec_4) hole = smt_synthesis.HoleDecl('H', grammar, {'x': 'Int', 'y': 'Int'}, True) tree = templates.HoleGrammarTree(hole, max_depth=3) node = tree.root[0] gra = tree.root[0].args[0] print(gra.function_name) # is HStartInt1
def synthesize_keijzer12(): smtgp_nia_grammar = """ ( ( Start Int ( x y (Constant Int) (+ Start Start) (- Start Start) (* Start Start) (div Start Start) (ite SBool Start Start) ) ) ( SBool Bool ( (> Start Start) (>= Start Start) (< Start Start) (<= Start Start) (= Start Start) (= SBool SBool) ) ) ) """ vars = contract.ProgramVars({'x': 'Int', 'y': 'Int'}, {'res': 'Int'}) code = """(= res H1)""" code_pre = 'true' code_post = 'true' grammar = templates.load_gramar_from_SYGUS_spec(smtgp_nia_grammar) h1 = smt_synthesis.HoleDecl('H1', grammar, {'x': 'Int', 'y': 'Int'}, True, 6) hole_decls = [h1] tc = contract.TestCases.from_csv(csv_keijzer12) env = utils.Options(['--solver', 'z3', '--logic', 'NIA', "--lang", "smt2"]) res = smt_synthesis.synthesize_tc(tc, code, code_pre, code_post, vars, env, hole_decls) return res
def test_synthesis_recursive_grammar(self): code = """ if x > y: res = HOLE2 else: res = HOLE3 """ vars = ProgramVars({'x': 'Int', 'y': 'Int'}, {'res': 'Int'}) code_pre = 'True' code_post = 'res >= x and res >= y and (res == x or res == y)' sygus_grammar_hole23 = """ ( ( Start Int ( ( Constant Int ) x y (+ Start Start) (- Start Start) (- y x) (+ x ( Constant Int )) (* Start Start) ) ) ) """ grammar23 = templates.load_gramar_from_SYGUS_spec(sygus_grammar_hole23) h2 = smt_synthesis.HoleDecl('HOLE2', grammar23, None, True, 2) h3 = smt_synthesis.HoleDecl('HOLE3', grammar23, None, True, 2) hole_decls = [h2, h3] assertions = [] #['(assert (= HOLE3_r0 3))'] env = utils.Options({ '--solver': 'z3', '--solver_interactive_mode': 0, '--logic': 'NIA', '--silent': 0, '--solver_timeout': '2000' }) res = smt_synthesis.synthesize(code, code_pre, code_post, vars, env, hole_decls, assertions) print('[test_synthesis_recursive_grammar] RES:') print(res.text) print('[test_synthesis_recursive_grammar] SYNTHESIZED CODE:') print(res.final_code) self.assertTrue(res.decision == 'sat' or res.decision == "unknown")