Exemple #1
0
def GenerateConstraintForExample(spec, specConn, circuits, psiConn, newExample, iteration):
    substList = []

    for circuit in circuits:
        substList.append((circuit.outputPort.var, 
            circuit.outputPort.GenVarCopyForIteration(iteration)))
        substList.extend([(circuitInputPort.var, 
            circuitInputPort.GenVarCopyForIteration(iteration))
            for circuitInputPort in circuit.inputPorts])

        for comp in circuit.components:
            substList.append((comp.outputPort.var, 
                comp.outputPort.GenVarCopyForIteration(iteration)))
            substList.extend([(inputPort.var, inputPort.GenVarCopyForIteration(iteration))
                for inputPort in comp.inputPorts])

    substList.extend((port.var, val) for (port, val) in newExample.iteritems())

    constraints = [Bool(True)]

    constraints.append(substitute(psiConn, substList))
    constraints.append(substitute(specConn, substList))
    constraints.append(substitute(spec, substList))

    return And(constraints)
Exemple #2
0
    def subst(self,tab,subst):
        subs = [(term_to_z3(Constant(x)),term_to_z3(y)) for x,y in subst.iteritems()]
#        print subs
 #       print all([isinstance(p, tuple) and z3.is_expr(p[0]) and z3.is_expr(p[1]) and p[0].sort().eq(p[1].sort()) for p in subs])
        res = [z3.substitute(x,*subs) for x in tab]
#        print "subst: %s -> %s" % (tab,res)
        return res
Exemple #3
0
def substitute (t, *m):
  """ Re-implementation of z3.substitute """
  #return z3.substitute (t, *m)
  r = Substitute (*m)
  res = r.apply (t)

  # sanity check
  assert res.eq (z3.substitute (t, *m))
  return res
Exemple #4
0
def GenerateVerificationConstraint(spec, specConn, circuits, psiConn, circuitModel):
    constraints = [Bool(True)]

    substList = []
    for circuit in circuits:
        substList.extend([(Int(labelName), circuitModel.eval(Int(labelName), True))
            for (_, labelName) in circuit.labels.iteritems()])

    constraints.append(substitute(psiConn, substList))
    constraints.append(specConn)
    constraints.append(Not(spec))
    return And(constraints)
Exemple #5
0
def fp_add_cover (fp, pred, lemma, level=-1):
    # no trivial lemmas
    if z3.is_true (lemma): return

    assert (z3.is_app (pred))
    sub = []
    for i in range (0, pred.num_args ()):
        arg = pred.arg (i)
        sub.append ((arg,
                     z3.Var (i, arg.decl ().range ())))

    tlemma = z3.substitute (lemma, sub)
    if verbose:
        print "Lemma for ", pred.decl (), ": ", tlemma
    fp.add_cover (level, pred.decl (), tlemma)
Exemple #6
0
 def to_origin(self, formula) :
     """Convert all primed state variables into original state variables."""
     return z3.substitute(formula, self.boolp_pairs)
Exemple #7
0
 def select(self, idx):
     expr = z3.Select(self._mem, idx)
     if self._idx is not None:
         expr = z3.substitute(expr, (self._idx, idx))
     return expr
    # just used as "true"
    s.add(get_lit('-1'))

    # add property to initial states
    # IC3ref omits this for some reason
    init = And(init, prop)

    print("init -> inv...", end='')
    query = And(init, Not(inv))
    s.push()
    s.add(query)
    print('OK' if s.check() == unsat else 'FAIL')
    s.pop()

    s.push()
    print('inv /\ T |= inv...', end='')
    s.add(And(inv, trans, Not(substitute(inv, prime_mapping))))
    print('OK' if s.check() == unsat else 'FAIL')
    s.pop()

    s.push()
    print('inv -> prop...', end='')
    s.add(Not(Implies(inv, prop)))
    print('OK' if s.check() == unsat else 'FAIL')
    s.pop()

    free_vars = get_free_vars(inv)
    prime_mapping_ids = set(v0.get_id() for v0, v1 in prime_mapping)
    assert all(fv.get_id() in prime_mapping_ids
               for fv in free_vars), "expecting all current state variables"
Exemple #9
0
 def wp(self, Q):
     return z3.simplify(z3.substitute(Q, (self.lhs, self.rhs)))
Exemple #10
0
def relationalInduction():

	M = TransitionSystem()
	Msc = SelfComposedTransitionSystem(M)

	xs = Msc.variables
	xsp = Msc.addSuffix('prime')
	# print(xs)
	# print(xsp)

	bad = z3.simplify(z3.And(Msc.bad))
	init = z3.simplify(z3.And(Msc.init))
	check = z3.simplify(z3.And(init, bad))

	S = z3.Solver()
	S.push()
	S.add(check)
	rInit = (S.check())
	S.pop()
	assert (rInit == z3.unsat)

	S.push()

	bad_assume = bad                                                             #Shouldn't bad be a function defined over xs?
	bad_proofob = z3.simplify(z3.And(Msc.bad_sc(xsp)))
	trx = z3.simplify(z3.And([xsp[i]==Msc.tr[i] for i in range(len(xs))]))

	S.add(bad_assume)
	# print(bad_assume)
	# print(bad_proofob)
	S.add(bad_proofob)
	S.add(trx)

	n = len(xsp) // 2
	while S.check() == z3.sat:
                #print "Msc CounterExample Found"
                m = S.model()
		xm1 = [m.eval(xsi) for xsi in xs[:n]]
		xm2 = [m.eval(xsi) for xsi in xs[n:]]
		bad1 = lambda xs: [z3.And(*[xi == xmi for (xi, xmi) in itertools.izip(xm1, xs)])]
		bad2 = lambda xs: [z3.And(*[xi == xmi for (xi, xmi) in itertools.izip(xm2, xs)])]

		#r1, count1 = getLength(M, bad1)
                #no1 = bad1(M.variables)
                r1, arg1, expr1 = getLength1(M, bad1)
                print "ARG1: ", arg1
                print "xs[:n]: ", xs[:n]
                
                if r1 == z3.unsat:
			#sub1 = zip(M.variables, xs[:n])
                        #sub2 = zip(M.variables, xs[n:])
                        sub1 = zip(arg1, xs[:n])
                        sub2 = zip(arg1, xs[n:])
                        #p1 = z3.substitute(*(no1 + sub1))
			#p2 = z3.substitute(*(no1 + sub2))
                        p1 = z3.substitute(expr1, *sub1)
			p2 = z3.substitute(expr1, *sub2)
                        #S.add(z3.Not(p1))
			#S.add(z3.Not(p2))
                        S.add(p1)
			S.add(p2)
			continue

		#r2, count2 = checkLength(M, bad2, arg1)                         # arg1 stores the value of length when r1 is sat
                no2 = bad2(M.variables)
                #r2, arg2, expr2 = checkLength1(M, bad2, arg1)
                r2, arg2, expr2 = checkLengthBMC(M, bad2, arg1)
                
                if r2 == z3.unsat:
                        #sub1 = zip(M.variables, xs[:n])
                        #sub2 = zip(M.variables, xs[n:])
                        sub1 = zip(arg2[:n], xs[:n])
                        sub2 = zip(arg2[n:], xs[n:])
                        #p1 = z3.substitute(*(no2 + sub1))
			#p2 = z3.substitute(*(no2 + sub2))
                        p1 = z3.substitute(expr2, sub1)
			p2 = z3.substitute(expr2, sub2)
			#S.add(z3.Not(p1))
			#S.add(z3.Not(p2))
                        S.add(p1)
			S.add(p2)
			continue

		print("UNSAFE")
		return

	print("SAFE")
	S.pop()
Exemple #11
0
def solve_exists_forall(exp, given_insts=None, model=False):
    print 'Exists Forall exp:', exp

    assert z3.is_quantifier(exp) and not exp.is_forall()
    (exist_consts, e) = strip_qblock(exp)

    if not z3.is_quantifier(e):
        # just an smt problem
        m = check_sat(e)
        if m is None:
            return (None, None, None)
        else:
            if model: return (m, None, None)
            sub = mk_subst_from_model(m, exist_consts, model_completion=True)
            return (sub, None, None)
    else:
        assert e.is_forall()

    (univ_consts, matrix) = strip_qblock(e)

    print 'Exist consts:', exist_consts
    print 'Univ consts:', univ_consts
    print 'Matrix:', matrix

    w_cons = []  # constraints for witness

    # initialize w with given_insts
    if given_insts is not None:
        for inst in given_insts:
            sub = mk_subst_from_model(inst, univ_consts, model_completion=True)
            w_cons.append(z3.substitute(matrix, *sub))

    new_insts = list()
    witnesses = list()
    while True:
        print 'Solver for witness:'
        for cons in w_cons:
            print cons.sexpr()

        w = z3.Solver(ctx=exp.ctx)
        for cons in w_cons:
            w.add(cons)
        # obtain witness for instances
        res = w.check()

        if res == z3.unsat:
            print 'FALSE\n', new_insts
            return (None, new_insts, witnesses)
        m = w.model()
        witnesses.append(m)
        print 'Model for new witness:\n', m
        sub = mk_subst_from_model(m, exist_consts, model_completion=True)
        print 'New witness:', sub

        # check if the witness is sufficient
        s = z3.Solver(ctx=exp.ctx)
        print 'checking validity of ', z3.substitute(matrix, *sub)
        s.add(z3.Not(z3.substitute(matrix, *sub)))
        print 'Solver for validity:', z3.Not(z3.substitute(matrix,
                                                           *sub)).sexpr()
        res = s.check()
        if res == z3.unsat:
            print 'TRUE\n', sub
            if model: return (m, None, None)
            return (sub, None, None)
        inst = s.model()
        new_insts.append(inst)
        print 'New instance:\n', inst
        sub = mk_subst_from_model(inst, univ_consts, model_completion=True)
        w_cons.append(z3.substitute(matrix, *sub))
Exemple #12
0
    def visit_FunctionDef(self, node):
        annotation = NodeVerifier.parse_docstring(ast.get_docstring(node))
        if annotation is not None:
            forall_vars, precondition, self._type_map = annotation

            # set the distance vars for the corresponding normal vars
            from collections import OrderedDict
            for name, var_type in OrderedDict(self._type_map).items():
                constraint = None
                if isinstance(var_type, NumType):
                    self._type_map['^' + name] = NumType(0)

                    if var_type.value != '*':
                        # TODO: distance variables should be simpler
                        distance_vars = re.findall(
                            r"""\^([_a-zA-Z][0-9a-zA-Z_]*)""", var_type.value)
                        constraint = self._symbol('^' + name) == \
                                     self.visit(self.parse_expr(var_type.value.replace('^', '')))[0]
                        for distance_var in distance_vars:
                            constraint = z3.substitute(
                                constraint, (self._symbol(distance_var),
                                             self._symbol('^' + distance_var)))

                elif isinstance(var_type, BoolType):
                    self._type_map['^' + name] = NumType(0)
                    constraint = self._symbol('^' + name) == \
                                 self.visit(self.parse_expr('0'))[0]
                elif isinstance(var_type, FunctionType):
                    # TODO: consider FunctionType
                    pass
                elif isinstance(var_type, ListType):
                    # TODO: consider list inside list
                    self._type_map['^' + name] = ListType(NumType(0))
                    symbol_i = self._symbol('i')
                    if isinstance(var_type.elem_type,
                                  NumType) and var_type.elem_type.value != '*':
                        constraint = self._symbol('^' + name)[symbol_i] == \
                                     self.visit(self.parse_expr(var_type.elem_type.value))[0]
                    elif isinstance(var_type.elem_type, BoolType):
                        constraint = self._symbol('^' + name)[symbol_i] == \
                                     self.visit(self.parse_expr('0'))[0]
                if constraint is not None:
                    self._declarations.append(constraint)

            # parse the precondition to constraint
            distance_vars = re.findall(r"""\^([_a-zA-Z][0-9a-zA-Z_]*)""",
                                       precondition)

            pre_constraint = self.visit(
                self.parse_expr(precondition.replace('^', '')))[0]
            for distance_var in distance_vars:
                pre_constraint = z3.substitute(
                    pre_constraint, (self._symbol(distance_var),
                                     self._symbol('^' + distance_var)))

            if forall_vars is not None:
                pre_constraint = z3.ForAll(
                    [self._symbol(var) for var in forall_vars], pre_constraint)

            del self._precondition[:]
            self._precondition.append(pre_constraint)

            # empty the check list
            del self._if_checks[:]
            del self._assign_checks[:]

            self.generic_visit(node)
Exemple #13
0
 def F(*args):
     replacements = zip([v1, v2, vout], [create_z3_var(s, vtype) for s in args])
     return z3.substitute(expr == vout, *replacements)
Exemple #14
0
 def _substitute_inner(self, prev_vec, substitute_with, vec_num):
     substitutions = zip(prev_vec[vec_num], substitute_with)
     new_prop_formula = simplify(substitute(self._qbf.get_prop(), *substitutions))
     new_qbf = QBF(new_prop_formula, self._qbf.get_q_list())
     return new_qbf
Exemple #15
0
def check_substitution(wstate_a, wstate_b):
    logging.info('Checking if %s subsumes %s', wstate_a.trace, wstate_b.trace)
    if len(
            set(wstate_b.address_to_account) -
            set(wstate_a.address_to_account)):
        logging.debug('check_substitution: Different gstate number')
        return False
    constraints_a = wstate_a.constraints
    constraints_b = wstate_b.constraints
    sum_vars = []
    focus_a = []
    focus_b = []
    mapping_ids = set()
    x_index = 0
    y_index = 1
    x_var = z3.BitVec('X_var', 256)
    # y_var = z3.BitVec('Y_var', 256)
    focus_constraints_a = []
    focus_constraints_b = []
    for address in wstate_b.address_to_account:
        gstate_a = wstate_a.address_to_account[address]
        gstate_b = wstate_b.address_to_account[address]
        focus_constraints_a.append(
            x_var == z3.simplify(gstate_a.storage.load(x_index)))
        # focus_constraints_a.append(y_var == gstate_a.storage.load(y_index))
        focus_constraints_b.append(
            x_var == z3.simplify(gstate_b.storage.load(x_index)))
        # focus_constraints_b.append(y_var == gstate_b.storage.load(y_index))
    focus_constraints_a = z3.And(focus_constraints_a)
    focus_constraints_b = z3.And(focus_constraints_b)
    constraints_a = z3.And(constraints_a)
    constraints_b = z3.And(constraints_b)
    vars_a = get_wstate_z3vars(wstate_a)
    vars_b = get_wstate_z3vars(wstate_b)
    vars_a = set([v.n for v in vars_a])
    vars_b = set([v.n for v in vars_b])
    substitution_dict_a = substitute_bvset(vars_a, 'A')
    substitution_dict_b = substitute_bvset(vars_b, 'B')

    # hash_constraints_a = z3.substitute(hash_constraints, [(bv, bv_s) for bv, bv_s in substitution_dict_a.items()])
    # hash_constraints_b = z3.substitute(hash_constraints, [(bv, bv_s) for bv, bv_s in substitution_dict_b.items()])
    sub_pairs_a = [(bv, bv_s) for bv, bv_s in substitution_dict_a.items()]
    sub_pairs_b = [(bv, bv_s) for bv, bv_s in substitution_dict_b.items()]
    focus_a = z3.substitute(focus_constraints_a, sub_pairs_a)
    focus_b = z3.substitute(focus_constraints_b, sub_pairs_b)

    constraints_a_s = z3.substitute(constraints_a, sub_pairs_a)
    constraints_b_s = z3.substitute(constraints_b, sub_pairs_b)

    B = z3.And(focus_b, constraints_b_s)
    nA1 = z3.Not(focus_a)
    nA2 = z3.Not(constraints_a_s)

    abstraction_not_implies = z3.Or(z3.And(B, nA1), z3.And(B, nA2))

    bv_solver = z3.Solver()
    bv_solver.set('timeout', 10000)

    a_vars = list(substitution_dict_a.values())
    b_vars = list(substitution_dict_b.values())
    q_vars = [x_var]
    q_vars.extend(b_vars)
    bv_solver.add(
        z3.simplify(
            z3.ForAll(
                q_vars,
                z3.Exists(a_vars, z3.Implies(z3.And(focus_b),
                                             z3.And(focus_a))))))
    res = bv_solver.check()
    print(res)
    assert res == z3.sat or res == z3.unsat
    return res == z3.sat
Exemple #16
0
def solve_exists_forall_incremental(exp, model=False):
    print 'Exists Forall exp:', exp

    assert z3.is_quantifier(exp) and not exp.is_forall()
    (exist_consts, e) = strip_qblock(exp)

    if not z3.is_quantifier(e):
        # just an smt problem
        m = check_sat(e)
        if m is None:
            return (None, None, None)
        else:
            if model: return (m, None, None)
            sub = mk_subst_from_model(m, exist_consts, model_completion=True)
            return (sub, None, None)
    else:
        assert e.is_forall()

    (univ_consts, matrix) = strip_qblock(e)

    print 'Exist consts:', exist_consts
    print 'Univ consts:', univ_consts
    print 'Matrix:', matrix

    print 'Solving by negating the problem'

    cex_size = 0
    curr_exist_consts = []
    curr_matrix_disjs = []

    for i in range(cex_size):
        sub = []
        for c in univ_consts:
            name = '{}_{}'.format(c.decl().name(), str(i))
            const = z3.Const(name, c.sort())
            curr_exist_consts.append(const)
            sub.append((c, const))
        new_disj = z3.substitute(z3.Not(matrix), *sub)
        curr_matrix_disjs.append(new_disj)

    while True:
        print 'CURRENT SIZE:', cex_size + 1
        # look for a cex of size 'cex_size'
        # Exists U1,U2,..U_cex_size. Forall E. Not (matrix),
        #   where U and E are univ_consts and exist_consts

        # add a new set of exist consts
        sub = []
        for c in univ_consts:
            name = '{}_{}'.format(c.decl().name(), str(cex_size))
            const = z3.Const(name, c.sort())
            curr_exist_consts.append(const)
            sub.append((c, const))
        new_disj = z3.substitute(z3.Not(matrix), *sub)
        curr_matrix_disjs.append(new_disj)
        curr_exp = z3.Exists(
            curr_exist_consts,
            z3.ForAll(exist_consts, z3.Or(*curr_matrix_disjs)))
        (cex_model, witnesses, _unused_insts) = solve_exists_forall(curr_exp,
                                                                    model=True)

        if cex_model is not None:
            print 'FALSE\n', cex_model
            print 'Size:', cex_size + 1
            # TODO: split cex_model into list of models for the original set of
            # universal variables
            return (None, cex_model, witnesses)
        else:
            # no cex of current size

            # check if any of the witnesses already works
            for m in witnesses:
                w = z3.Solver(ctx=exp.ctx)
                sub = mk_subst_from_model(m,
                                          exist_consts,
                                          model_completion=True)
                w.add(z3.substitute(z3.Not(matrix), *sub))
                if w.check() == z3.unsat:
                    print 'TRUE\n', sub
                    if model: return (m, None, None)
                    return (sub, None, None)

            # increment size
            cex_size += 1
Exemple #17
0
 def F(*args):
     replacements = zip([v1, v2, vout],
                        [create_z3_var(s, vtype) for s in args])
     return z3.substitute(expr == vout, *replacements)
Exemple #18
0
def walk_block(node, prev_g=None):
    g = z3.Goal()
    if prev_g is not None:
        for e in prev_g:
            if isinstance(e, z3.Goal):
                g.add(e.as_expr())
            else:
                g.add(e)

    if isinstance(node, pycp.c_ast.Compound):
        if node.block_items is not None:
            for e in node.block_items:
                if isinstance(e, pycp.c_ast.Decl):
                    if "int" in e.type.type.names:
                        vars[e.name] = z3.BitVec(e.name, 32)
            for e in reversed(node.block_items):
                g_next = walk_block(e, g)
                g = g_next
    elif isinstance(node, pycp.c_ast.FuncCall):
        if node.name.name == "__ASSERT":
            li = []
            for e_exp in node.args.exprs:
                li.append(gen_smt_expr(e_exp))
            g.add(z3.Not(z3.And(li)))
        elif node.name.name == "__ASSUME":
            assumptions = z3.Goal()
            for e_exp in node.args.exprs:
                assumptions.add(gen_smt_expr(e_exp))
            print("solving..")
            print("WP:", g.as_expr())
            print("assume:", assumptions)
            s.add(assumptions.as_expr())
            s.add(g.as_expr())
            status = s.check()
            print(s)

            if status == z3.sat:
                model = s.model()
                print("program is unsafe.\nlisting an unsafe assignments..")
                for e in vars:
                    print(e, ':', model[vars[e]].as_signed_long())
            elif status == z3.unsat:
                print("program is safe.")
            elif status == z3.unknown:
                print("unknown")

            s.reset()
        else:
            print("found a func call")
    elif isinstance(node, pycp.c_ast.Assignment):
        rexp = gen_smt_expr(node.rvalue)
        g_ = z3.Goal()
        if node.op == "=":
            g_.add(z3.substitute(g.as_expr(), (vars[node.lvalue.name], rexp)))
        elif node.op == "+=":
            g_.add(
                z3.substitute(
                    g.as_expr(),
                    (vars[node.lvalue.name], vars[node.lvalue.name] + rexp)))
        elif node.op == "-=":
            g_.add(
                z3.substitute(
                    g.as_expr(),
                    (vars[node.lvalue.name], vars[node.lvalue.name] - rexp)))
        elif node.op == "*=":
            g_.add(
                z3.substitute(
                    g.as_expr(),
                    (vars[node.lvalue.name], vars[node.lvalue.name] * rexp)))
        elif node.op == "%=":
            g_.add(
                z3.substitute(
                    g.as_expr(),
                    (vars[node.lvalue.name], vars[node.lvalue.name] % rexp)))
        g = t(g_)
        # g = g.simplify()
    elif isinstance(node, pycp.c_ast.If):
        cond_exp = gen_smt_expr(node.cond)
        true_expr, false_expr = None, None
        if node.iftrue is not None:
            true_ = walk_block(node.iftrue, g)
            true_expr = true_.as_expr()
        else:
            true_expr = g.as_expr()
        if node.iffalse is not None:
            false_ = walk_block(node.iffalse, g)
            false_expr = false_.as_expr()
        else:
            false_expr = g.as_expr()
        true_expr = z3.And(cond_exp, true_expr)
        false_expr = z3.And(z3.Not(cond_exp), false_expr)
        g = z3.Goal()
        g.add(z3.Or(true_expr, false_expr))
        g = t(g)  # g.simplify()
    else:
        g = prev_g
    # print(g.as_expr(), "\n")
    return g