Beispiel #1
0
 def __eq__(self, other):
     if isinstance(other, z3.ExprRef):
         # if we compare to a z3 expression we are free to chose the value
         # it does not matter if we are out of range, this just means false
         # with this we can generate an interpretable type
         # TODO: Should the type differ per invocation?
         z3_type = other.sort()
         return z3.Const(self.name, z3_type) == other
     else:
         log.warning("Enum: Comparison to %s of type %s not supported",
                     other, type(other))
         return z3.BoolVal(False)
Beispiel #2
0
    def _addConstraints(self, solver):
        solver.add(self.constraints)
        p = z3.Const('__ips_acl_Packet_%s' % (self.ips), self.ctx.packet)
        addr_a = z3.Const('__ips_acl_cache_a_%s' % (self.ips),
                          self.ctx.address)
        port_a = z3.Const('__ips_acl_port_a_%s' % (self.ips), z3.IntSort())
        addr_b = z3.Const('__ips_acl_cache_b_%s' % (self.ips),
                          self.ctx.address)
        port_b = z3.Const('__ips_acl_port_b_%s' % (self.ips), z3.IntSort())
        aclConstraints = map(lambda (a, b): z3.And(self.ctx.packet.src(p) == a, \
                                              self.ctx.packet.dest(p) == b),
                                              self.acls)
        eh = z3.Const('__ips_acl_node_%s' % (self.ips), self.ctx.node)

        # Constraints for what holes are punched
        # \forall a, b cached(a, b) \iff \exists e, p send(f, e, p) \land
        #                 p.src == a \land p.dest == b \land ctime(a, b) = etime(ips, p, R) \land
        #                   neg(ACL(p))
        if len(aclConstraints) > 0:
            solver.add(z3.ForAll([addr_a, port_a, addr_b, port_b], self.cached(addr_a, port_a, addr_b, port_b) ==\
                           z3.Exists([eh, p], \
                               z3.And(self.ctx.recv(eh, self.ips, p), \
                               z3.And(self.ctx.packet.src (p) == addr_a, self.ctx.packet.dest(p) == addr_b, \
                                       self.ctx.src_port (p) == port_a,  self.ctx.dest_port (p) == port_b, \
                                       self.ctime (addr_a, port_a, addr_b, port_b) == self.ctx.etime(self.ips, p, self.ctx.recv_event), \
                                       z3.Not(z3.Or(aclConstraints)))))))
        else:
            solver.add(z3.ForAll([addr_a, port_a, addr_b, port_b], self.cached(addr_a, port_a, addr_b, port_b) ==\
                           z3.Exists([eh, p], \
                               z3.And(self.ctx.recv(eh, self.ips, p), \
                               z3.And(self.ctx.packet.src (p) == addr_a, self.ctx.packet.dest(p) == addr_b, \
                                       self.ctx.src_port (p) == port_a,  self.ctx.dest_port (p) == port_b, \
                                       self.ctime (addr_a, port_a, addr_b, port_b) == self.ctx.etime(self.ips, p, self.ctx.recv_event))))))
Beispiel #3
0
    def reconciliate(self, context):
        """Generate specialization predicates

        Translation has generated semi specialized predicates. It is time now
        to define those semi specialized predicates using the fully specialized
        ones.

        :param context: A Z3 context to create the new rules.
        """
        for table, fixed_pos in six.iteritems(self.grounded):
            base_pred = self.relations[table]
            arity = base_pred.arity()
            # For each argument of the base pred we build a variable
            vars = [
                z3.Const("V_{}_{}".format(table, i), base_pred.domain(i))
                for i in range(arity)
            ]
            # All the tuples of ground values associated to our pred.
            row = self.items.get(table, {})
            # from argument position to index in the tuple of ground value.
            idx = {i: p for p, i in enumerate(fixed_pos)}
            # enumerate all the values and associated pred.
            for val1, pred1 in six.iteritems(row.get(fixed_pos, {})):
                # get partial predicates
                for partial_pos, valpred in six.iteritems(row):
                    if partial_pos == fixed_pos:
                        # not this one: it is not partial
                        continue
                    # project our full tuple to what is fixed for this
                    # combination
                    val2 = tuple([val1[idx[pos]] for pos in partial_pos])
                    pred2 = valpred.get(val2, None)
                    if pred2 is None:
                        continue
                    # We found a predicate. We build the rule.
                    #    forall args1. pred2(args2) :- pred1(args1)
                    # args2 is args1 augmented with fixed args from the record
                    # not captured by pred2.
                    args1 = [
                        vars[i]
                        for i in range(arity)
                        if i not in fixed_pos
                    ]
                    args2 = [
                        (val1[idx[i]] if i in fixed_pos else vars[i])
                        for i in range(arity)
                        if i not in partial_pos
                    ]
                    rule = z3.Implies(pred1(*args1), pred2(*args2))
                    if len(args1) > 0:
                        rule = z3.ForAll(args1, rule)
                    context.rule(rule)
Beispiel #4
0
 def make_z3_const(self, etype, name):
     if etype.equals(Bool) or etype.is_const():
         z3_sort = self.get_z3_sort(etype)
         z3_const = z3.Const(name, z3_sort)
         self.symbol_dict[name] = z3_const
         return z3_const
     elif etype.is_bound() and etype.binder.is_pi():
         arg_sorts, return_sort = self.get_z3_fun_type(etype)
         z3_func = z3.Function(name, *(arg_sorts + [return_sort]))
         self.symbol_dict[name] = z3_func
         return z3_func
     else:
         raise Z3_Unexpected_Type('Cannot handle polymorphism')
Beispiel #5
0
def numeral_to_z3(num):
    # TODO: allow other numeric types
    z3sort = lookup_native(num.sort, sorts, "sort")
    if z3sort == None:
        return z3.Const(num.name, num.sort.to_z3())  # uninterpreted sort
    try:
        name = num.name[1:-1] if num.name.startswith('"') else num.name
        if isinstance(z3sort, z3.SeqSortRef) and z3sort.is_string():
            return z3.StringVal(name)
        return z3sort.cast(str(int(name, 0)))  # allow 0x,0b, etc
    except:
        raise iu.IvyError(
            None, 'Cannot cast "{}" to native sort {}'.format(num, z3sort))
Beispiel #6
0
    def _firewallSendRules(self):
        p_0 = z3.Const('%s_firewall_send_p_0' % (self.fw), self.ctx.packet)
        p_1 = z3.Const('%s_firewall_send_p_1' % (self.fw), self.ctx.packet)
        n_0 = z3.Const('%s_firewall_send_n_0' % (self.fw), self.ctx.node)
        n_1 = z3.Const('%s_firewall_send_n_1' % (self.fw), self.ctx.node)
        t_0 = z3.Int('%s_firewall_send_t_0' % (self.fw))
        t_1 = z3.Int('%s_firewall_send_t_1' % (self.fw))

        self.acl_func = z3.Function('%s_acl_func' % (self.fw), self.ctx.packet,
                                    z3.BoolSort())

        self.constraints.append(z3.ForAll([n_0, p_0, t_0], z3.Implies(self.ctx.send(self.fw, n_0, p_0, t_0), \
                                       z3.Exists([n_1, t_1], \
                                       z3.And(self.ctx.recv(n_1, self.fw, p_0, t_1), \
                                              z3.Not(self.failed(t_0)), \
                                              z3.Not(self.failed(t_1)), \
                                              t_1 < t_0)))))

        # Let us first try a non-learning firewall
        self.constraints.append(z3.ForAll([n_0, p_0, t_0], z3.Implies(\
                self.ctx.send(self.fw, n_0, p_0, t_0), \
                z3.And(self.acl_func(p_0), z3.Not(self.failed(t_0))))))
Beispiel #7
0
    def _wanOptSendRule(self):
        p1 = z3.Const('__wanopt_unmoded_packet_%s' % (self.opt),
                      self.ctx.packet)
        p2 = z3.Const('__wanopt_moded_packet_%s' % (self.opt), self.ctx.packet)
        e1 = z3.Const('__wanopt_ingress_node_%s' % (self.opt), self.ctx.node)
        e2 = z3.Const('__wanopt_egress_node_%s' % (self.opt), self.ctx.node)
        e3 = z3.Const('__wanopt_not_egress_node_%s' % (self.opt),
                      self.ctx.node)

        self.constraints.append( \
                z3.ForAll([e1, p1], \
                    z3.Implies(self.ctx.send(self.opt, e1, p1), \
                        z3.Exists([e2, p2], \
                           z3.And(self.ctx.recv(e2, self.opt, p2), \
                            self.ctx.PacketsHeadersEqual(p1, p2), \
                            self.ctx.packet.body(p1) == self.transformation(self.ctx.packet.body(p2)), \
                            self.ctx.packet.orig_body(p1) == self.ctx.packet.orig_body(p2), \
                            z3.Not(z3.Exists([e3], \
                                z3.And(e3 != e1, \
                                    self.ctx.send(self.opt, e3, p2)))), \
                            self.ctx.etime(self.opt, p1, self.ctx.send_event) > \
                                self.ctx.etime(self.opt, p2, self.ctx.recv_event))))))
Beispiel #8
0
    def CheckDataIsolationProperty(self, src, dest):
        class DataIsolationResult(object):
            def __init__(self,
                         result,
                         violating_packet,
                         last_hop,
                         last_time,
                         ctx,
                         assertions,
                         model=None):
                self.ctx = ctx
                self.result = result
                self.violating_packet = violating_packet
                self.last_hop = last_hop
                self.model = model
                self.last_time = last_time
                self.assertions = assertions

        assert (src in self.net.elements)
        assert (dest in self.net.elements)
        self.solver.push()
        self.AddConstraints()
        p = z3.Const('check_isolation_p_%s_%s' % (src.z3Node, dest.z3Node),
                     self.ctx.packet)
        n_0 = z3.Const('check_isolation_n_0_%s_%s' % (src.z3Node, dest.z3Node),
                       self.ctx.node)
        n_1 = z3.Const('check_isolation_n_1_%s_%s' % (src.z3Node, dest.z3Node),
                       self.ctx.node)
        t = z3.Int('check_isolation_t_%s_%s' % (src.z3Node, dest.z3Node))
        self.solver.add(self.ctx.recv(n_0, dest.z3Node, p, t))
        self.solver.add(self.ctx.packet.origin(p) == src.z3Node)
        result = self.solver.check()
        model = None
        assertions = self.solver.assertions()
        if result == z3.sat:
            model = self.solver.model()
        self.solver.pop()
        return DataIsolationResult(result, p, n_0, t, self.ctx, assertions,
                                   model)
    def _relational_cardinality_constraint(self, relation: z3.FuncDeclRef,
                                           n: int) -> z3.ExprRef:
        if relation.arity() == 0:
            return z3.BoolVal(True)

        consts = [[
            z3.Const(f'card$_{relation}_{i}_{j}', relation.domain(j))
            for j in range(relation.arity())
        ] for i in range(n)]

        vs = [
            z3.Const(f'x$_{relation}_{j}', relation.domain(j))
            for j in range(relation.arity())
        ]

        result = z3.ForAll(
            vs,
            z3.Implies(
                relation(*vs),
                z3.Or(*(z3.And(*(c == v for c, v in zip(cs, vs)))
                        for cs in consts))))
        return result
Beispiel #10
0
 def does_contain(*tup):
     assert len(tup) == len(kept_columns)
     col_map = dict(zip(kept_columns, tup))
     variables = []
     existentials = []
     for c in self.columns:
         if c in col_map:
             variables.append(col_map[c])
         else:
             var = z3.Const(c, self.sort)
             existentials.append(var)
             variables.append(var)
     return z3.Exists(existentials, self.does_contain(*variables))
Beispiel #11
0
def lemma_to_string(lemma, pred):
    """
    convert a lemma returned by get_cover_delta into a string that parse_smt2_string can parse
    """
    const_list = [z3.Const(pred.name()+"_"+str(j), pred.domain(j)) for j in range(pred.arity())]
    lhs = pred(*const_list)
    rhs = z3.substitute_vars(lemma, *(const_list))
    imp = z3.Implies(lhs, rhs)
    forall = z3.ForAll(list(reversed(const_list)), imp)
    lemma_str = "(assert %s)"%forall.sexpr()
    print("\toriginal lemma:", lemma)
    print("\tforall lemma:", forall.body().arg(1))
    assert lemma == forall.body().arg(1)
    return lemma_str
def smt_var(typ: Type, name: str):
    z3type = type_to_smt_sort(typ)
    if z3type is None:
        if getattr(typ, '__origin__', None) is Tuple:
            if len(typ.__args__) == 2 and typ.__args__[1] == ...:
                z3type = z3.SeqSort(type_to_smt_sort(typ.__args__[0]))
            else:
                return tuple(
                    smt_var(t, name + str(idx))
                    for (idx, t) in enumerate(typ.__args__))
    var = z3.Const(name, z3type)
    if isinstance(z3type, z3.SeqSortRef):
        var = SymbolicSeq(var)
    return var
Beispiel #13
0
 def bind_to_name(self, name):
     for member_name, member_constructor in self.members.items():
         var_name = f"{name}.{member_name}"
         # retrieve the member we are accessing
         member = self.resolve_reference(member_name)
         member_type = member_constructor.range()
         if isinstance(member, P4ComplexInstance):
             # it is a complex type
             # propagate the parent constant to all children
             member.bind_to_name(var_name)
         else:
             # a simple z3 type, just update the constructor
             self.set_or_add_var(
                 member_name, z3.Const(var_name, member_type))
Beispiel #14
0
def _(term, smt):
  with smt.local_nonpoison() as n:
    x = smt.eval(term.x)

  # if term is never poison, return it's interp directly
  if not n:
    return x

  ty = smt.type(term)
  u  = z3.Const('frozen_' + term.name, _ty_sort(ty))
  # TODO: don't assume unique names
  smt.add_qvar(u)

  return z3.If(mk_and(n), x, u)
Beispiel #15
0
    def _webProxyFunctions(self):
        self.cached = z3.Function('__webproxy_cached_%s' % (self.proxy),
                                  self.ctx.address, z3.IntSort(),
                                  z3.BoolSort())
        self.ctime = z3.Function('__webproxy_ctime_%s' % (self.proxy),
                                 self.ctx.address, z3.IntSort(), z3.IntSort())
        self.cresp = z3.Function('__webproxy_cresp_%s' % (self.proxy),
                                 self.ctx.address, z3.IntSort(), z3.IntSort())
        self.corigbody = z3.Function('__webproxy_corigbody_%s' % (self.proxy),
                                     self.ctx.address, z3.IntSort(),
                                     z3.IntSort())
        self.corigin = z3.Function('__webproxy_corigin_%s' % (self.proxy),
                                   self.ctx.address, z3.IntSort(),
                                   self.ctx.node)
        self.crespacket = z3.Function(
            '__webproxy_crespacket_%s' % (self.proxy), self.ctx.address,
            z3.IntSort(), self.ctx.packet)
        self.creqpacket = z3.Function(
            '__webproxy_creqpacket_%s' % (self.proxy), self.ctx.address,
            z3.IntSort(), self.ctx.packet)
        self.creqopacket = z3.Function(
            '__webproxy_creqopacket_%s' % (self.proxy), self.ctx.address,
            z3.IntSort(), self.ctx.packet)

        a = z3.Const('__webproxyfunc_cache_addr_%s' % (self.proxy),
                     self.ctx.address)
        i = z3.Const('__webproxyfunc_cache_body_%s' % (self.proxy),
                     z3.IntSort())

        # Model cache as a function
        # If not cached, cache time is 0
        self.constraints.append(
            z3.ForAll([a, i],
                      z3.Not(self.cached(a, i)) == (self.ctime(a, i) == 0)))
        self.constraints.append(
            z3.ForAll([a, i],
                      z3.Not(self.cached(a, i)) == (self.cresp(a, i) == 0)))
Beispiel #16
0
 def find_val_in_heap(self, value: object) -> z3.ExprRef:
     lastheap = self.heaps[-1]
     with self.framework():
         for (curref, curtyp, curval) in lastheap:
             if curval is value:
                 debug('HEAP value lookup for ', type(value),
                       ' value type; found', curref)
                 return curref
         ref = z3.Const('heapkey' + str(value) + self.uniq(), HeapRef)
         for (curref, _, _) in lastheap:
             self.add(ref != curref)
         self.add_value_to_heaps(ref, type(value), value)
         debug('HEAP value lookup for ', type(value),
               ' value type; created new ', ref)
         return ref
Beispiel #17
0
    def relation_to_z3(
            r: syntax.RelationDecl,
            key: Optional[str]) -> Union[z3.FuncDeclRef, z3.ExprRef]:
        if r.mutable:
            assert key is not None
            if key not in r.mut_z3:
                if r.arity:
                    a = [Z3Translator.sort_to_z3(s)
                         for s in r.arity] + [z3.BoolSort()]
                    r.mut_z3[key] = z3.Function(key + '_' + r.name, *a)
                else:
                    r.mut_z3[key] = z3.Const(key + '_' + r.name, z3.BoolSort())

            return r.mut_z3[key]
        else:
            if r.immut_z3 is None:
                if r.arity:
                    a = [Z3Translator.sort_to_z3(s)
                         for s in r.arity] + [z3.BoolSort()]
                    r.immut_z3 = z3.Function(r.name, *a)
                else:
                    r.immut_z3 = z3.Const(r.name, z3.BoolSort())

            return r.immut_z3
Beispiel #18
0
def numeral_to_z3(num):
    # TODO: allow other numeric types
    tn = ivy_logic.sig.default_numeric_sort
    if num.sort != tn:
        return z3.Const(num.name, num.sort.to_z3())
    num = num.name
    z3sort = lookup_native(tn, sorts, "sort")
    if z3sort == None:
        raise iu.IvyError(
            None, 'default numeric type {} is uninterpreted'.format(tn))
    try:
        return z3sort.cast(num)
    except:
        raise IvyError(None,
                       'Cannot cast "{}" to native sort {}'.format(num, tn))
Beispiel #19
0
def LearningFwModel(mc, acl):
    p = z3.Const('p', mc.ctx.packet)
    #acl = ConfigMap('acl', mc, [mc.ctx.address, mc.ctx.address], z3.BoolSort())
    flows = ModelMap(
        'flows', mc,
        [mc.ctx.address, mc.ctx.address,
         z3.IntSort(),
         z3.IntSort()], z3.BoolSort())
    src = z3.Const('src', mc.ctx.address)
    dest = z3.Const('dest', mc.ctx.address)
    sp = z3.Int('sp')
    dp = z3.Int('dp')
    Body(mc, \
     [lambda: ModelRecv(mc, p),
      lambda: If(mc, acl[(mc.ctx.packet.src(p), mc.ctx.packet.dest(p))], \
               [lambda: ModelSend(mc, p), \
                lambda: src == mc.ctx.packet.src(p), \
                lambda: dest == mc.ctx.packet.dest(p), \
                lambda: sp == mc.ctx.src_port(p), \
                lambda: dp == mc.ctx.dest_port(p), \
                lambda: flows.set((src, dest, sp, dp), True, [src, dest, sp, dp])], \
               [lambda: If(mc, flows[(mc.ctx.packet.dest(p), mc.ctx.packet.src(p), mc.ctx.dest_port(p), \
                                      mc.ctx.src_port(p))], \
                        [lambda: ModelSend(mc, p)])])])
Beispiel #20
0
def CacheModel(mc):
    cache = ModelMap('cached', mc, [z3.IntSort()], z3.BoolSort())
    cbody = ModelMap('cbody', mc, [z3.IntSort()], z3.IntSort())
    is_request = ModelMap(
        'is_request', mc,
        [mc.ctx.address, z3.IntSort(),
         z3.IntSort()], z3.BoolSort())
    p_req = z3.Const('p_req', mc.ctx.packet)
    p_resp = z3.Const('p_resp', mc.ctx.packet)
    Body(mc, \
    [lambda: ModelRecv(mc, p_req), \
     lambda: If(mc, cache[mc.ctx.packet.body(p_req)], \
                  [lambda: mc.ctx.packet.body(p_resp) == cbody[mc.ctx.packet.body(p_req)], \
                   lambda: mc.ctx.packet.src(p_resp) == mc.ctx.packet.dest(p_req), \
                   lambda: mc.ctx.src_port(p_resp) == mc.ctx.dest_port(p_req), \
                   lambda: mc.ctx.dest_port(p_resp) == mc.ctx.src_port(p_req), \
                   lambda: ModelSend(mc, p_resp)],
                   [lambda: mc.ctx.packet.body(p_resp) == mc.ctx.packet.body(p_req),
                    lambda: mc.ctx.packet.dest(p_resp) == mc.ctx.packet.dest(p_req),
                    lambda: mc.ctx.packet.dest_port(p_resp) == mc.ctx.packet.dest_port(p_req),
                    lambda: mc.ctx.packet.origin(p_resp) == mc.ctx.packet.origin(p_req),
                    lambda: mc.ctx.packet.orig_body(p_resp) == mc.ctx.packet.orig_body(p_req),
                    lambda: mc.ctx.nodeHasAddr(mc.ctx.packet.src(p_resp), mc.node),
                    lambda: ModelSend(mc, p_resp)])])
Beispiel #21
0
 def register(self, definition):
     # print('register?', definition)
     refs = self.env.refs
     if type(definition) == ast.Name:
         raise ResolutionError(definition)
         return z3.Const(definition.id, Unk)
     if type(definition) == ast.arg:
         name = definition.arg
     elif type(definition) == ast.FunctionDef:
         name = definition.name
     else:  # z3 function (z3 functions must be called immediately - they are not values)
         # print('register abort : ', repr(definition))
         return definition
         # if hasattr(definition, 'name'):
         #     name = definition.name()
         # else:
         #     name = definition.__name__
     if definition not in refs:
         #print('register new ref: ', name, id(definition), " at ",
         #      getattr(definition, 'lineno', ''), ":",
         #      getattr(definition, 'col_offset', '')
         #)
         refs[definition] = z3.Const(name, Unk)
     return refs[definition]
Beispiel #22
0
 def get_type(self, typ: Type) -> z3.ExprRef:
     pytype_to_smt = self.pytype_to_smt
     if typ not in pytype_to_smt:
         stmts = []
         expr = z3.Const('typrepo_'+typ.__qualname__, PYTYPE_SORT)
         for other_pytype, other_expr in pytype_to_smt.items():
             stmts.append(other_expr != expr)
             stmts.append(SMT_SUBTYPE_FN(expr, other_expr) ==
                          issubclass(typ, other_pytype))
             stmts.append(SMT_SUBTYPE_FN(other_expr, expr) ==
                          issubclass(other_pytype, typ))
         stmts.append(SMT_SUBTYPE_FN(expr, expr) == True)
         self.solver.add(stmts)
         pytype_to_smt[typ] = expr
     return pytype_to_smt[typ]
Beispiel #23
0
    def _update(self):
        self._sig = []
        for i in range(self._fdecl.arity()):
            name = self._mk_arg_name(i)
            sort = self._fdecl.domain(i)
            self._sig.append(z3.Const(name, sort))

        # compute pysmt version of the signature
        env = pysmt.environment.reset_env()
        mgr = env.formula_manager
        ctx = z3.get_ctx(None)
        converter = pyz3.Z3Converter(env, ctx)
        self._pysmt_sig = [
            mgr.Symbol(v.decl().name(), converter._z3_to_type(v.sort()))
            for v in self._sig
        ]
Beispiel #24
0
 def __init__(self, name, type_params=[], methods=[]):
     # Externs are this weird bastard child of callables and a complex type
     # FIXME: Unify types
     z3_type = z3.Datatype(name)
     z3_type.declare(f"mk_{name}")
     self.members = OrderedDict()
     self.z3_type = z3_type.create()
     self.const = z3.Const(name, self.z3_type)
     self.p4_attrs = {}
     # simple fix for now until I know how to initialize params for externs
     self.params = {}
     self.name = name
     self.type_params = type_params
     # these are method declarations, not methods
     for method in methods:
         self.p4_attrs[method.lval] = method.rval
Beispiel #25
0
    def _update(self):
        self._sig = []
        for i in range(self._fdecl.arity()):
            name = self._mk_arg_name(i)
            sort = self._fdecl.domain(i)
            self._sig.append(z3.Const(name, sort))

        # compute pysmt version of the signature

        mgr = self._env.formula_manager
        converter = pyz3.Z3Converter(self._env, self.get_ctx())
        # noinspection PyProtectedMember
        self._pysmt_sig = [
            mgr.Symbol(v.decl().name(), converter._z3_to_type(v.sort()))
            for v in self._sig
        ]
Beispiel #26
0
    def generate_kconnected_smt(self, paths):
        src, dst = paths[0][0], paths[0][-1]
        path_costs = [self._get_path_cost(path) for path in paths]
        path_names = [get_path_name(path) for path in paths]
        cuttoff = self.gen_paths
        count = 0
        path_key_req = tuple(paths[0])
        if path_key_req not in self.saved_path_gen:
            self.saved_path_gen[path_key_req] = self.generate_random_paths(
                src, dst, 0.6, self.random_gen)
        elif path_key_req not in self.counter_examples:
            return
        path_costs_var = []
        for index, cost in enumerate(path_costs):
            if is_symbolic(cost):
                path_costs_var.append(cost)
                continue
            var = z3.Const("%s_cost" % path_names[index], z3.IntSort())
            self.solver.add(var == cost)
            path_costs_var.append(var)

        for rand_path in self.saved_path_gen[path_key_req]:
            # Skip if we generated the same path as the requirement
            if rand_path in paths:
                continue
            if rand_path:
                for index, path in enumerate(paths):
                    path_name = path_names[index]
                    path_cost = path_costs[index]
                    rand_path_name = get_path_name(rand_path)
                    rand_path_cost = self._get_path_cost(rand_path)
                    track_name = '%s_ISLESS_%s' % (path_name, rand_path_name)
                    if track_name in self._names_cache:
                        continue
                    else:
                        self._names_cache.append(track_name)
                    if is_symbolic(path_cost) or is_symbolic(rand_path_cost):
                        self.solver.assert_and_track(
                            path_cost < rand_path_cost, track_name)
                    else:
                        if not (path_cost < rand_path_cost):
                            path_cost_var = path_costs_var[index]
                            self.solver.assert_and_track(
                                path_cost_var < rand_path_cost, track_name)
            count += 1
            if count > cuttoff:
                break
Beispiel #27
0
def extract_implies(clause):
    clause = fix_quantifier(clause)
    qvars = [
        z3.Const(clause.var_name(n), clause.var_sort(n))
        for n in range(0, clause.num_vars())
    ]

    implies = fix_implies(clause.body())
    kids = implies.children()
    body = get_conjuncts(qvars, kids[0])
    head = z3.substitute_vars(kids[1], *qvars)

    return {
        'qvars': qvars,
        'body': body,
        'head': head,
    }
Beispiel #28
0
    def __init__(self, name, p4z3_type, member_id):
        super(StructInstance, self).__init__(name, p4z3_type, member_id)
        self.const = z3.Const(name, self.z3_type)

        # we use the overall index of the struct for a uniform naming scheme
        flat_idx = self.member_id
        for member_name, member_type in self.fields:

            if isinstance(member_type, P4ComplexType):
                # the z3 variable of the instance is only an id
                instance = member_type.instantiate(str(flat_idx), flat_idx)
                # but what we add is its fully qualified name, e.g. x.y.z
                self.locals[member_name] = instance
                flat_idx += len(member_type.flat_names)
            else:
                # this is just a filler value, it must be overridden by bind()
                self.locals[member_name] = None
                flat_idx += 1
Beispiel #29
0
def Const(name, uct_sort, annctx=default_annctx):
    """
    Declare a constant with the given name and uct sort.  
    :param name: string  
    :param uct_sort: naturalproofs.uct.UCTSort  
    :param annctx: naturalproofs.AnnotatedContext.AnnotatedContext  
    :return: z3.ExprRef  
    """
    if not isinstance(uct_sort, UCTSort):
        raise TypeError('UCTSort expected.')
    z3const = z3.Const(name, uct_sort.z3sort)
    if not isinstance(annctx, AnnotatedContext):
        raise TypeError('AnnotatedContext expected.')
    # The constant must be tracked as a 0-arity function
    declaration = z3const.decl()
    annctx.add_alias_annotation(declaration, tuple([uct_sort]))
    annctx.add_vocabulary_annotation(declaration)
    return z3const
Beispiel #30
0
def write_clauses_datalog(declarations, clauses, writer):
    reserved_exit_point = 'reserved_exit_point'
    writer.write('(declare-rel {} ())\n\n'.format(reserved_exit_point))

    for decl in declarations:
        symbol = quote_symbol_if_needed(decl.name())
        writer.write('(declare-rel {} ('.format(symbol))
        for n in range(0, decl.arity()):
            writer.write((" {}".format(decl.domain(n))))
        writer.write(' ))\n')

    known_vars = set([])
    implications = []
    writer.write('\n')

    for clause in clauses:
        if not (z3.is_quantifier(clause) and clause.is_forall()):
            raise Exception("Illegal clause for write_clause_smt2: {}".format(
                clause.decl()))

        for idx in range(0, clause.num_vars()):
            if (clause.var_name(idx), clause.var_sort(idx)) not in known_vars:
                known_vars.add((clause.var_name(idx), clause.var_sort(idx)))
                writer.write("(declare-var {} {})\n".format(
                    clause.var_name(idx),
                    clause.var_sort(idx).sexpr()))

        implication = clause.body()
        subst = list(
            reversed([
                z3.Const(clause.var_name(n), clause.var_sort(n))
                for n in range(0, clause.num_vars())
            ]))

        implications.append(z3.substitute_vars(implication, *subst))

    writer.write('\n')

    for implication in implications:
        writer.write('(rule\n')
        write_implication_smt2(implication, '  ', reserved_exit_point, writer)
        writer.write('\n)\n')

    writer.write('\n\n(query {})\n\n'.format(reserved_exit_point))