Example #1
0
 def visit_AsgnStmt(self, node, *args, **kwargs):
     exp = self.visit(node.rhs, *args, **kwargs)
     name = node.lhs.name
     st = kwargs['state']
     st.env[name] = z3.FreshInt(name)
     st.add_pc(st.env[name] == exp)
     return [st]
Example #2
0
 def visit_AsgnStmt(self, node, *args, **kwargs):
     val = self.visit(node.rhs, *args, **kwargs)
     st = kwargs["state"]
     name = node.lhs.name
     sym_val = z3.FreshInt(name)
     st.env[name] = sym_val
     st.add_pc(sym_val == val)
     return st
Example #3
0
    def visit_WhileStmt_inv (self, node, *args, **kwargs):
        """" Symbolic execution of while loops with invariants """
        print("node.inv=",node.inv)
        # evaluate invariant before the loop
        inv_pre = self.visit (node.inv, *args, **kwargs)
        print("node.inv_2.0=",inv_pre)
        # fork symbolic state to evaluate the invariant in the pre-condition
        pre_st, loop_st = kwargs['state'].fork ()

        # pre_st.add_pc (z3.Not (inv_pre))
        # if not pre_st.is_empty ():
        pre_st.add_pc (inv_pre)
        if pre_st.is_empty ():
            print ('Invariant not true on loop entry')
            print (node.inv)
            print (pre_st)

        # havoc all variables modified by the loop
        for v in self._defs (node.body):
            loop_st.env [v.name] = z3.FreshInt (v.name)
            # print("v",v,loop_st)

        # evaluate invariant after havoc and assume it
        inv_pre = z3.simplify (self.visit (node.inv, *args, state=loop_st))
        loop_st.add_pc (inv_pre)

        # evaluate loop condition
        cond_val = self.visit (node.cond, *args, state=loop_st);

        # one state enters the loop, one exits
        enter_st, exit_st = loop_st.fork ()

        # if enter loop, loop condition is true
        enter_st.add_pc (cond_val)
        # if exit loop, loop condition is false
        exit_st.add_pc (z3.Not (cond_val))

        # if loop condition can be satisfied, check invariant preserved by loop body
        if not enter_st.is_empty ():
            # do loop body, might produce many new states
            # print("------------",kwargs["state"],enter_st)
            for out in self.visit (node.body, *args, state=enter_st):
                # print("--------------",out)
                # check that invariant holds at the end of each body
                inv_post = z3.simplify (self.visit (node.inv, *args, state=out))
                # inv_post =self.visit (node.inv, *args, state=out)
                out.add_pc (z3.Not (inv_post))
                if not out.is_empty ():
                    print ('Invariant does not hold on loop exit')
                    print( "2",exit_st)
                    # print ('inv:', node.inv)
                    # print ('inv_post', inv_post)
                    # print ('out', out)
                    # print ('pc', z3.And (out.path).sexpr ())

        # if negation of loop condition is satisfied, continue execution after the loop
        if not exit_st.is_empty ():
            yield exit_st
Example #4
0
    def visit_WhileStmt(self, node, *args, **kwargs):
        if node.inv is not None:
            pre_inv = z3.simplify(self.visit(node.inv, *args, **kwargs))
            p_st, loop_st = kwargs['state'].fork()

            p_st.add_pc(z3.Not(pre_inv))
            if not p_st.is_empty():
                print('Invariant is false before entry the loop')
                print(node.inv)
                print(p_st)
            checker = wlang.undef_visitor.UndefVisitor()
            checker.check(node.body)

            for v in checker.get_defs():
                loop_st.env[v.name] = z3.FreshInt(v.name)

            inv_pre = z3.simplify(self.visit(node.inv, *args, state=loop_st))
            loop_st.add_pc(inv_pre)
            #if else
            cond = self.visit(node.cond, *args, state=loop_st)
            st = loop_st.fork()
            st[0].add_pc(cond)
            st[1].add_pc(z3.Not(cond))
            #enter loop
            if not st[0].is_empty():
                result = self.visit(node.body, state=st[0])
                for out in result:
                    inv_post = z3.simplify(
                        self.visit(node.inv, *args, state=out))
                    out.add_pc(z3.Not(inv_post))
                    if not out.is_empty():
                        print('Invariant violation on loop exit')
                        print('inv:', node.inv)
                        print('out', out)
                        print('pc', z3.And(out.path).sexpr())
            if not st[1].is_empty():
                return [st[1]]
            else:
                return []

        todo = [kwargs['state']]
        done = []
        for _ in range(11):
            if not todo: break
            res = []
            for i in todo:
                cond = self.visit(node.cond, state=i)
                st = i.fork()
                st[0].add_pc(cond)
                st[1].add_pc(z3.Not(cond))

                if not st[0].is_empty():
                    res.extend(self.visit(node.body, state=st[0]))
                if not st[1].is_empty(): done.append(st[1])
            todo = res

        return done
Example #5
0
 def visit_WhileStmt(self, node, *args, **kwargs):
     # print ("In visit_WhileStmt------------------------------------------",self.While_Output)
     #no invariant branch
     if node.inv is None:
         cond = self.visit(node.cond, *args, **kwargs)
         IN, NOIN = kwargs["state"].fork()
         IN.add_pc(cond)
         NOIN.add_pc(z3.Not(cond))
         # print ("What's in IN?",IN,cond)
         if not IN.is_empty() and self.count <= 10:
             self.count = self.count + 1
             st = self.visit(node.body, *args, **kwargs)
             kwargs["state"] = st
             stt = self.visit(node, *args, **kwargs)
             # self.While_Output.append(kwargs["state"])
         elif self.count > 10:
             self.While_Output = []
             return self.While_Output
         if not NOIN.is_empty():
             # self.While_Output=[]
             self.While_Output.append(NOIN)
         return self.While_Output
     else:
         inv = self.visit(node.inv, *args, **kwargs)
         first_check, check_over = kwargs["state"].fork()
         first_check.add_pc(inv)
         # 1 assert inv;
         if first_check.is_empty():
             print("invariant cannot be hold on entry")
             return first_check
         else:
             # 2 havoc V;
             for var in self.havoc(node.body):
                 check_over.env[var.name] = z3.FreshInt(var.name)
             kwargs["state"] = check_over
             # 3 assume inv;
             inv = self.visit(node.inv, *args, **kwargs)
             check_over.add_pc(inv)
             cond = self.visit(node.cond, *args, **kwargs)
             # 4 if b then { s ; assert inv; assume false }
             IN, NOIN = check_over.fork()
             IN.add_pc(cond)
             NOIN.add_pc(z3.Not(cond))
             if not IN.is_empty():
                 st = self.visit(node.body, *args, **kwargs)
                 kwargs["state"] = st
                 check_inv = self.visit(node.inv, *args, **kwargs)
                 st.add_pc(z3.Not(check_inv))
                 if not st.is_empty():
                     print(
                         "invariant cannot be hold at the end of the loop")
             if not NOIN.is_empty():
                 return NOIN
Example #6
0
    def visit_WhileStmt(self, node, *args, **kwargs):
        if node.inv is not None:
            sim_inv = z3.simplify(self.visit(node.inv, *args, **kwargs))
            init_state = kwargs['state'].fork()
            not_inv_state = init_state[0]
            inv_state = init_state[1]

            # inv fails initiation
            if not_inv_state.addcond_isSolvable(z3.Not(sim_inv)):
                print("inv fails initiation")
            # use Undefined Use Visitor to find all variables that are modified or defined
            for var in self._defs(node.body):
                inv_state.env[var.name] = z3.FreshInt(var.name)
            
            # add inv into pc of inv_state
            inv_state.add_pc(z3.simplify(self.visit(node.inv, *args, state=inv_state)))
            # fork the state based on the condition and process both conditions accordingly
            cond = self.visit(node.cond, *args, state=inv_state)
            inv_states = inv_state.fork()

            #cond is satisfied, enter the loop
            if inv_states[0].addcond_isSolvable(cond):
                final_state = self.visit(node.body, state=inv_states[0])
                for st in final_state:
                    if st.addcond_isSolvable(z3.simplify(self.visit(node.inv, *args, state=st))):
                        print("inv fails invariance")
            if inv_states[1].addcond_isSolvable(z3.Not(cond)):
                return[inv_states[1]]
            else:
                return[]

        done = []
        while_states = [kwargs['state']]

        executed_time = 1

        while(len(while_states) != 0 and executed_time <= 10):
            executed_time += 1
            updated_while_states = []
            for state in while_states:
                cond = self.visit(node.cond, state=state) 
                cond_fork = state.fork()

                # if after adding condition, state is still solvable, visit node.body,
                # and extend returned state-list
                if cond_fork[0].addcond_isSolvable(cond):
                    updated_while_states.extend(self.visit(node.body, state=cond_fork[0]))
                # if after adding not condition, state is still solvable, append the termination state into returning states
                if cond_fork[1].addcond_isSolvable(z3.Not(cond)):
                    done.append(cond_fork[1])
            while_states = updated_while_states
        return done
Example #7
0
 def visit_HavocStmt(self, node, *args, **kwargs):
     # print ("[sym]In visit_HavocStmt")
     st = kwargs["state"]
     for v in node.vars:
         st.env[v.name] = z3.FreshInt(v.name)
     return st
 def visit_HavocStmt(self, node, *args, **kwargs):
     st = kwargs['state']
     for v in node.vars:
         st.env[v.name] = z3.FreshInt(v.name)
     yield st
Example #9
0
 def visit_HavocStmt(self, node, *args, **kwargs):
     st = kwargs['state']
     for var in node.vars:
         st.env[var.name] = z3.FreshInt(var.name)
     return [st]
Example #10
0
    def visit_WhileStmt(self, node, *args, **kwargs):
        if node.inv is not None:
            pre_inv = z3.simplify(self.visit(node.inv, *args, **kwargs))
            pre_state, loop_state = kwargs['state'].fork()

            pre_state.add_pc(z3.Not(pre_inv))
            if not pre_state.is_empty():
                print("Invariant does not hold before initial loop entry")
                print(node.inv)
                print(pre_state)
                pre_state.mk_error()

            get_def = wlang.undef_visitor.UndefVisitor()
            get_def.check(node.body)

            for var in get_def.get_defs():
                loop_state.env[var.name] = z3.FreshInt(var.name)

            inv_pre = z3.simplify(self.visit(node.inv, *args,
                                             state=loop_state))
            loop_state.add_pc(inv_pre)

            cond = self.visit(node.cond, *args, state=loop_state)
            enter_st, exit_st = loop_state.fork()

            if not enter_st.is_empty():
                res = self.visit(node.body, state=enter_st)

                for i in res:
                    inv_post = z3.simplify(self.visit(node.inv, *args,
                                                      state=i))
                    i.add_pc(z3.Not(inv_post))

                    if not i.is_empty():
                        print("Invariant does not hold within the loop")
                        print("inv: ", node.inv)
                        print("inv_post: ", inv_post)
                        print("i: ", i)
                        print("pc", z3.And(i.path).sexpr())
                        i.mk_error()

            if not exit_st.is_empty():
                return [exit_st]

        out = []
        count = 1
        execution = [kwargs['state']]

        while count <= 10:
            res = []
            for x in execution:

                cond = self.visit(node.cond, state=x)
                true_case, false_case = x.fork()
                true_case.add_pc(cond)
                false_case.add_pc(z3.Not(cond))

                if not false_case.is_empty():
                    out.append(false_case)

                if not true_case.is_empty():
                    kwargs['state'] = self.visit(node.body, state=true_case)
                    res.extend(kwargs['state'])

            execution = res
            count += 1

        return out
Example #11
0
 def visit_AsgnStmt(self, node, *args, **kwargs):
     st = kwargs['state']
     x = self.visit(node.rhs, *args, **kwargs)
     st.env[node.lhs.name] = z3.FreshInt(node.lhs.name)
     st.add_pc(st.env[node.lhs.name] == x)
     return [st]