예제 #1
0
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])
예제 #2
0
파일: test_ssa.py 프로젝트: bluepine/pysv
    def test_program_already_in_ssa_form(self):
        code = 'x = 0; y = 1; z = 2'
        post = 'z < 2'
        vars = contract.ProgramVars({'x': 'Int', 'y': 'Int'}, {'z': 'Int'})

        # Running SSA conversion
        ib = ast_utils.py_to_interm_ib(code)
        post = ast_utils.py_to_interm_expr(post)
        ib2, post2 = ssa_converter.convert(ib, post, vars)
        vars.add_marked_variables(ib2.src.collect_variables())

        # Assertions
        self.assertFalse(ib.src.equals(ib2.src))
        # -----------------------------------
        self.assertEquals("|x'|", ib2.src.instructions[0].var.id)
        self.assertEquals("|y'|", ib2.src.instructions[1].var.id)
        self.assertEquals("z", ib2.src.instructions[2].var.id)
        self.assertEquals(3, ib2.src.size())
        self.assertEquals("z", post2.src.expr.args[0].id)

        ib2, post2 = ssa_converter.convert(ib2, post2, vars)
        self.assertFalse(ib.src.equals(ib2))
        # -----------------------------------
        self.assertEquals("|x'|", ib2.src.instructions[0].var.id)
        self.assertEquals("|y'|", ib2.src.instructions[1].var.id)
        self.assertEquals("z", ib2.src.instructions[2].var.id)
        self.assertEquals(3, ib2.src.size())
        self.assertEquals("z", post2.src.expr.args[0].id)
예제 #3
0
def test_4():
    code = """
res = x
if x < 0:
    HOLE
return res
"""
    input_vars = contract.ProgramVars({'x': 'Int', 'res': 'Double'})
    pre = 'True'
    post = 'res >= 0'

    pysv.smt_synthesis.synthesize(code, pre, post, input_vars)
예제 #4
0
파일: test_ssa.py 프로젝트: bluepine/pysv
    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)
예제 #5
0
    def test_verify_smt2_simple_program(self):
        prog = "(= res (ite (= x 5) -1 1))"
        pre = "true"
        post = "(> res 0)"
        program_vars = contract.ProgramVars({'x': 'Int'}, {'res': 'Int'})
        env = utils.Options(["--lang", "smt2"])
        res = smt_verifier.verify(prog, pre, post, program_vars, env)

        self.assertEquals('sat', res.decision)
        self.assertEquals('5', res.model['x'])
        self.assertEquals({'x': '5'}, res.witness)

        post = "(>= res -1)"
        res = smt_verifier.verify(prog, pre, post, program_vars, env)
        self.assertEquals('unsat', res.decision)
        self.assertEquals({}, res.model)
        self.assertEquals({}, res.witness)
예제 #6
0
 def test_verify_smt2_minimize(self):
     prog = "true"
     pre = "true"
     post = "(and (< res 0) (<= res 0) (= res 0) (= res 0))"
     program_vars = contract.ProgramVars({'res': 'Int'}, {})
     env = utils.Options([
         "--lang", "smt2", "--ver_mode", "min", "--post_in_cnf", 1,
         "--ver_annotate_post", 1, "--logic", "LIA",
         "--produce_assignments", 1
     ])
     res = smt_verifier.verify(prog, pre, post, program_vars, env)
     self.assertEquals('sat', res.decision)
     self.assertEquals(True, int(res.model['res']) > 0)
     self.assertEquals('false', res.assignments['post_0'])
     self.assertEquals('false', res.assignments['post_1'])
     self.assertEquals('false', res.assignments['post_2'])
     self.assertEquals('false', res.assignments['post_3'])
예제 #7
0
def test_6():
    """Testing the synthesis of a Python program."""
    code = """
trigger = False
newAcc = acc + 1
if newAcc < limit:
    trigger = False
else:
    newAcc = HOLE # should be 0
    newAcc = newAcc - 1
    trigger = True
    """
    vars = contract.ProgramVars({
        'acc': 'Int',
        'limit': 'Int'
    }, {
        'newAcc': 'Int',
        'trigger': 'Bool'
    })
    code_pre = 'acc < limit and acc >= 0 and limit > 0'
    t1 = (['acc == limit - 1'], ['trigger == True', 'newAcc == 0'])
    t2 = (['acc < limit - 1'], ['trigger == False', 'newAcc == acc + 1'])
    code_post = contract.formula_test_cases_py([t1, t2])

    grammar_spec = """
(
    ( Start Int
        ( ( Constant Int ) acc limit newAcc)
    )
)
    """
    import pysv.templates
    grammar = pysv.templates.load_gramar_from_SYGUS_spec(grammar_spec)

    hole = pysv.smt_synthesis.HoleDecl('HOLE', grammar, vars.input_vars, True)
    holes_defs = {hole.id: hole}

    res = pysv.smt_synthesis.synthesize(code, code_pre, code_post, vars,
                                        holes_defs)

    # Printing result
    print('******** Z3 RESULT ********\n' + str(res))
    if res.decision == 'sat':
        print("MODEL FOUND!")
    elif res.decision == 'unsat':
        print("MODEL NOT FOUND!")
예제 #8
0
파일: test_ssa.py 프로젝트: bluepine/pysv
    def test_simple_program_no_ifs(self):
        code = 'x=0; y=1; z=2; x=3; y=4'
        post = 'x<2 and z<2'
        vars = contract.ProgramVars({'x': 'Int', 'y': 'Int', 'z': 'Int'})

        # Running SSA conversion
        ib = ast_utils.py_to_interm_ib(code)
        post = ast_utils.py_to_interm_expr(post)
        ib2, post2 = ssa_converter.convert(ib, post, vars)

        # Assertions
        self.assertEquals("|x'|", ib2.src.instructions[0].var.id)
        self.assertEquals("|y'|", ib2.src.instructions[1].var.id)
        self.assertEquals("|z'|", ib2.src.instructions[2].var.id)
        self.assertEquals("|x''|", ib2.src.instructions[3].var.id)
        self.assertEquals("|y''|", ib2.src.instructions[4].var.id)
        self.assertEquals(5, ib2.src.size())
        self.assertEquals("|x''|", post2.src.expr.args[0].args[0].id)
        self.assertEquals("|z'|", post2.src.expr.args[1].args[0].id)
예제 #9
0
파일: synth_max.py 프로젝트: bluepine/pysv
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
예제 #10
0
def test_7():
    """Testing the synthesis of a Python program."""
    code = """
a = HOLE
if x != 5:
    a = a + 1
else:
    a = a - 1
    """
    vars = contract.ProgramVars({'x': 'Int', 'y': 'Int'}, {'a': 'Int'})
    code_pre = 'x >= 1 and y >= 1'
    code_post = 'a == 6*x + y'

    grammar_spec = """
(
    ( Start Int
        ( ( Constant Int ) x y (+ Start Start) (* ( Constant Int ) Start) )
    )
)
    """
    import pysv.templates
    grammar = pysv.templates.load_gramar_from_SYGUS_spec(grammar_spec)
    hole = pysv.smt_synthesis.HoleDecl('HOLE',
                                       grammar, {
                                           'x': 'Int',
                                           'y': 'Int'
                                       },
                                       True,
                                       max_depth=3)
    holes_defs = {hole.id: hole}

    res = pysv.smt_synthesis.synthesize(code, code_pre, code_post, vars,
                                        holes_defs)

    # Printing result
    print('******** Z3 RESULT ********')
    print(res.text)
    print('--------------------------\n')
    print('SYNTHESIZED PYTHON CODE:')
    print(res.final_code)
예제 #11
0
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
예제 #12
0
def test_5():
    """Testing the generation of SMT-LIB script and solving it with z3.
    """
    code = """
z = 6
if (y > 4):
    y = x * (x + y)
else:
    z = 6
"""
    input_vars = contract.ProgramVars({'x': 'Int', 'y': 'Int', 'z': 'Int'})
    code_pre = 'x >= 2 and y > 2'
    code_post = 'y > x and y < z'

    # Converting source code into internal code representation
    ib, pre, post = pysv.smt_verifier.process_source_code(
        code, code_pre, code_post)
    ib, post = pysv.ssa_converter.convert(ib, pre, post, input_vars)

    # Specifying variables and their types
    input_vars.add_marked_variables(ib.collect_variables())
    print('VARIABLES: ' + str(input_vars))

    # Producing SMT-LIB script
    smtlib = SMTLIBConstraints(show_comments=False)
    script = smtlib.produce_script_verification(ib, pre, post, input_vars)
    print('\n\n******** SCRIPT ********:\n' + script)

    # Solving constraints
    solverZ3 = SolverZ3()
    res = solverZ3.apply(script)

    # Printing result
    print('******** Z3 RESULT ********\n' + str(res))
    if res.decision == 'sat':
        print("MODEL FOUND!")
    elif res.decision == 'unsat':
        print("MODEL NOT FOUND!")
예제 #13
0
    if res.decision == 'unsat':
        print('Counterexample not found! Program is correct.')
    elif res.decision == 'sat':
        print(res.witness)
        print('Counterexample found! Program is incorrect.')
    print('----------------------------------------------\n\n')
    return res


#------------------------------------------------------------------------
#                                 MAIN
#------------------------------------------------------------------------

precondition = 'True'
postcondition = "res >= x and res >= y and (res == x or res == y)"
variables = contract.ProgramVars({'x': 'Int', 'y': 'Int'}, {'res': 'Int'})

# First, we will verify incorrect implementation of the program. Notice that a counterexample is returned.
code =\
"""
if x < y:
    res = x
else:
    res = y
"""
verify_code(code, precondition, postcondition, variables)

# After previous verification we analyzed the code and slightly changed condition in the IF statement.
# The code should now be correct, but just to be sure we run verifier yet again.
code =\
"""
예제 #14
0
# Only one leap
zune_simplified = """
#year = 1980
#if days > 365: # handled by precondition
days2 = days
year2 = year
if year % 4 == 0:
    if days > 366:
        days2 = days - 366
        year2 = year + 1
    # lack of else statement
else:
    days2 = days - 365
    year2 = year + 1
"""
input_vars = contract.ProgramVars({"days": 'Int', "year": 'Int'})
pre = "days > 365 and year >= 1980"
# For this postcondition program doesn't meet the specification because the postcondition
# is based on user intent and cod has a bug.
# post = "((not days == 366 or not year == 1980) or (year2 == 1980 and days2 == 0)) and " +\
#        "((not days == 366 or not year == 1981) or (year2 == 1982 and days2 == 1))"

# For this postcondition program meets the specification because the postcondition
# is based on the code.
#post = "((not days == 366 or not year == 1980) or (year2 == 1980 and days2 == 366)) and " +\
#      "((not days == 366 or not year == 1981) or (year2 == 1982 and days2 == 1))"
t1 = (["days == 366", "year == 1980"], ["year2 == 1980", "days2 == 366"])
t2 = (["days == 366", "year == 1981"], ["year2 == 1982", "days2 == 1"])
post = contract.formula_test_cases_py([t1, t2])

days = 9
예제 #15
0
파일: test_ssa.py 프로젝트: bluepine/pysv
    def test_simple_program_one_if(self):
        code = """
x = 0
y = 0
if x<2:
    x = 1
    x = x + 1
else:
    x = 3
    y = 2
x = x + 5
        """

        post = 'x<2 and y<2'
        vars = contract.ProgramVars({'x': 'Int'}, {'y': 'Int'})

        # Running SSA conversion
        ib = ast_utils.py_to_interm_ib(code)
        post = ast_utils.py_to_interm_expr(post)
        ib2, post2 = ssa_converter.convert(ib, post, vars)

        # Assertions
        self.assertEquals("|x'|", ib2.src.instructions[0].var.id)
        self.assertEquals("y", ib2.src.instructions[1].var.id)

        if_instr = ib2.src.instructions[2]
        self.assertEquals("<(|x'|, 2)", str(if_instr.condition))

        # BODY branch
        self.assertEquals("|x''| = 1", str(if_instr.body[0]))
        self.assertEquals("|x''|", if_instr.body[0].var.id)
        self.assertEquals(False, if_instr.body[0].is_meta)
        self.assertEquals("|x'''| = +(|x''|, 1)", str(if_instr.body[1]))
        self.assertEquals("|x'''|", if_instr.body[1].var.id)
        self.assertEquals(False, if_instr.body[1].is_meta)
        # meta
        self.assertEquals("|x'''''| = |x'''|  (meta)", str(if_instr.body[2]))
        self.assertEquals("|x'''''|", if_instr.body[2].var.id)
        self.assertEquals("|x'''|", if_instr.body[2].expr.id)
        self.assertEquals(True, if_instr.body[2].is_meta)
        self.assertEquals("|y''| = y  (meta)", str(if_instr.body[3]))
        self.assertEquals("|y''|", if_instr.body[3].var.id)
        self.assertEquals("y", if_instr.body[3].expr.id)
        self.assertEquals(True, if_instr.body[3].is_meta)

        # ORELSE branch
        self.assertEquals("|x''''| = 3", str(if_instr.orelse[0]))
        self.assertEquals("|x''''|", if_instr.orelse[0].var.id)
        self.assertEquals(False, if_instr.orelse[0].is_meta)
        self.assertEquals("|y'| = 2", str(if_instr.orelse[1]))
        self.assertEquals("|y'|", if_instr.orelse[1].var.id)
        self.assertEquals(False, if_instr.orelse[1].is_meta)
        # meta
        self.assertEquals("|x'''''| = |x''''|  (meta)",
                          str(if_instr.orelse[2]))
        self.assertEquals("|x'''''|", if_instr.orelse[2].var.id)
        self.assertEquals("|x''''|", if_instr.orelse[2].expr.id)
        self.assertEquals(True, if_instr.orelse[2].is_meta)
        self.assertEquals("|y''| = |y'|  (meta)", str(if_instr.orelse[3]))
        self.assertEquals("|y''|", if_instr.orelse[3].var.id)
        self.assertEquals("|y'|", if_instr.orelse[3].expr.id)
        self.assertEquals(True, if_instr.orelse[3].is_meta)

        # After if
        self.assertEquals("|x''''''|", ib2.src.instructions[3].var.id)
        self.assertEquals("|x'''''|", ib2.src.instructions[3].expr.args[0].id)
        # Postcondition
        self.assertEquals("|x''''''|", post2.src.expr.args[0].args[0].id)
        self.assertEquals("|y''|", post2.src.expr.args[1].args[0].id)
예제 #16
0
파일: runner.py 프로젝트: bluepine/pysv
def get_program_vars(env):
    in_vars = {vt.split(":")[0]: vt.split(":")[1] for vt in env.input_vars}
    loc_vars = {vt.split(":")[0]: vt.split(":")[1] for vt in env.local_vars}
    return contract.ProgramVars(in_vars, loc_vars)
예제 #17
0
                                True,
                                max_depth=4)
    return [h1]


if __name__ == "__main__":
    if len(sys.argv) == 1 or "-h" in sys.argv or "--help" in sys.argv:
        print("Usage: ./get_final_code.py [raw output from SMT solver]")
        exit()

    result = sys.argv[1]

    # Original source code (fixed for this prettifier instance).
    original_code = get_original_code()

    # Hole declarations (fixed for this prettifier instance).
    holes_decls = get_hole_declarations(
        contract.ProgramVars(input_vars={
            "x": "Int",
            "y": "Int",
            "z": "Int"
        }))

    # Options (fixed for this prettifier instance).
    env = utils.Options(merge_with_vargs=False)

    res = smt_synthesis.SynthesisResult(result, original_code, holes_decls,
                                        env)
    print("FINAL CODE:")
    print(res.final_code)
예제 #18
0
#
# I think that this is a very convenient compromise between full formal contracts and test cases as
# we know from GP.

t1 = (['acc == limit - 1'], ['trigger == True', 'newAcc == 0'])
t2 = (['acc < limit - 1'], ['trigger == False', 'newAcc == acc + 1'])
postcondition = contract.formula_test_cases_py([t1, t2])

# We must also specify types of variables used in the program, because dynamic typing in Python
# does not allow us to reliably obtain this information via reflection. In Scala this could be
# automatically generated from the source code.

variables = contract.ProgramVars({
    'acc': 'Int',
    'limit': 'Int'
}, {
    'newAcc': 'Int',
    'trigger': 'Bool'
})

# First, we will verify incorrect implementation of the modulo counter. If user invokes this program
# for example with 'acc' equal to 2 and 'limit' equal to 3, then counter modulo three will return 3,
# which is incorrect.
#
# As can be seen, verifier without any problems discovers an example of incorrect behavior.
code =\
"""
trigger = False
if acc < limit:
    newAcc = acc + 1
else: