コード例 #1
0
ファイル: backend_z3.py プロジェクト: danse-macabre/claripy
 def _op_raw_Or(self, *args):
     return z3.Or(*(tuple(args) + (self._context, )))
コード例 #2
0
ファイル: cln_training.py プロジェクト: ksuenaga/cln2inv
def construct_invariant(var_names,
                        eq_coeff,
                        ges,
                        les,
                        eqs,
                        learned_ineqs,
                        pred_str='',
                        non_loop_invariant=None):

    OPS = {
        '=': operator.eq,
        '>': operator.gt,
        '<': operator.lt,
        '>=': operator.ge,
        '<=': operator.le,
    }

    pred1, pred2 = None, None
    if pred_str is not None:
        if ('<' in pred_str) or ('<=' in pred_str):
            pred = pred_str.split()
            try:
                v1 = int(pred[2])
            except ValueError:
                v1 = z3.Real(pred[2])
            try:
                v2 = int(pred[3])
            except ValueError:
                v2 = z3.Real(pred[3])

            if pred[1] == '<':
                pred1 = v1 < v2
                pred2 = v1 <= v2
            elif pred[1] == '<=':
                pred1 = v1 <= v2
                pred2 = v1 <= v2 + 1

    reals = []
    for var in var_names:
        if var == '1':
            reals.append(1)
        else:
            reals.append(z3.Real(var))

    ands = []
    ineqs = []

    if eq_coeff is not None:
        eq_constraint = 0 * 0
        if (eq_coeff[0, 0] != 0):
            eq_constraint = reals[0] * eq_coeff[0, 0]
        for i, real in enumerate(reals[1:]):
            if (eq_coeff[0, i + 1] != 0):
                eq_constraint += eq_coeff[0, i + 1] * real

        if isinstance(eq_constraint == 0, z3.BoolRef):
            ands += [eq_constraint == 0]

    for ge in ges:
        ands.append(reals[var_names.index(ge[0])] >= ge[1])
        ineqs.append(reals[var_names.index(ge[0])] >= ge[1])

    for le in les:
        ands.append(reals[var_names.index(le[0])] <= le[1])
        ineqs.append(reals[var_names.index(ge[0])] >= ge[1])

    for eq_ in eqs:
        if eq_[0] != '1':
            ands.append(reals[var_names.index(eq_[0])] == eq_[1])

    for ineq in learned_ineqs:
        coeffs, b, op_str = ineq
        op = OPS[op_str]
        z3_ineq = 0
        for i, (var, coeff) in enumerate(coeffs.items()):
            if i == 0:
                z3_ineq = reals[var_names.index(var)] * coeff
            else:
                z3_ineq += reals[var_names.index(var)] * coeff

        ands.append(op(z3_ineq, b))

    I0 = z3.And(*ineqs)
    I1 = z3.And(*ands)
    I2, I3 = None, None
    if pred1 is not None and pred2 is not None:
        I2 = z3.And(*ands, pred1)
        I3 = z3.And(*ands, pred2)

    if non_loop_invariant is not None:
        I1 = z3.Or(I1, non_loop_invariant)
        if pred1 is not None and pred2 is not None:
            I2 = z3.Or(I2, non_loop_invariant)
            I3 = z3.Or(I3, non_loop_invariant)

    Is = [I1]
    if I2 is not None and I3 is not None:
        Is.extend([I2, I3])
    Is.append(I0)
    return Is
    def solve(self, G):
        """
        Find the pipes diameter for a given aqueduct topology respecting the following constraints:
            - pipes velocities between 0.5 and 1 m/s
            - pipes diameters commercially available
        """

        import z3
        # add a solver
        solver = z3.Solver()

        # +-----------------------+
        # | variables declaration |
        # +-----------------------+

        # water demand in each node
        X = dict([(node, z3.Real("demand_%s" % i))
                  for i, (node, datadict) in enumerate(G.nodes.items())])
        # water flow in each pipe
        Q = dict([(edge, z3.Real("Q_%s" % i))
                  for i, (edge, datadict) in enumerate(G.edges.items())])
        # water speed in each pipe
        V = dict([(edge, z3.Real("V_%s" % i))
                  for i, (edge, datadict) in enumerate(G.edges.items())])
        # pipes diameter
        D = dict([(edge, z3.Real("D_%s" % i))
                  for i, (edge, datadict) in enumerate(G.edges.items())])

        # +---------------------+
        # | boundary conditions |
        # +---------------------+

        # water demand in each node
        boudary_c = []
        for node, datadict in G.nodes.items():
            if not datadict["Tank"]:
                boudary_c.append(X[node] == datadict["DEMAND"])

        # closing equation in each pipe: Q = V * A
        def sym_abs(x):
            return z3.If(x >= 0, x, -x)

        closing_c = [
            sym_abs(Q[edge]) / 1000 == V[edge] * (D[edge] / 1000 / 2)**2 *
            math.pi for edge in G.edges
        ]

        # speed limits
        speed_c = []
        for edge, datadict in G.edges.items():
            if datadict["LEVEL"] == 1:
                speed_c.append(z3.And(V[edge] >= 0.1, V[edge] <= 1.))
            else:
                speed_c.append(z3.And(V[edge] >= 0.01, V[edge] <= 1.5))

        # pipes diameters
        diameter_c = []
        available_measures = [
            75., 90., 110., 125., 140., 160., 180., 200., 225., 250., 280.,
            315., 355., 400.
        ]
        for edge, datadict in G.edges.items():
            if datadict["LEVEL"] == 1:
                diameter_c += [
                    z3.Or(
                        [D[edge] == measure for measure in available_measures])
                ]
            else:
                diameter_c += [
                    z3.Or([
                        D[edge] == measure
                        for measure in available_measures + [15., 25., 50.]
                    ])
                ]

        # kirchoff lows in the nodes
        kirchoff_c = []
        for n1 in G.nodes:
            kirchoff_c.append(
                z3.Sum([X[n1]] + [
                    Q[(n1, n2)] if (n1, n2) in Q else -Q[(n2, n1)]
                    for n2 in G.neighbors(n1)
                ]) == 0)
        # add conditons
        solver.add(boudary_c + closing_c + speed_c + kirchoff_c + diameter_c)

        def compute_head():
            """
            Computes head in meters for each node in the graph. The value is calculated imposing the head in the tank
            and than subtracting the loss on the pipes
            """
            for node, datadict in G.nodes.items():
                if datadict["Tank"] == True:
                    start = node
            H = {start: 164}
            visited, queue = set(), [start]
            while queue:
                node = queue.pop(0)
                if node not in visited:
                    visited.add(node)
                    queue.extend(set(G.neighbors(node)) - visited)
                    for neighbour in G.neighbors(node):
                        l = G[node][neighbour]["LENGHT"]
                        K = 10.67 / 120**1.852

                        def contain(d, k1, k2):
                            if k1 in d:
                                if k2 in d[k1]:
                                    return True
                            return False

                        if (node, neighbour) in dict(G.nodes):
                            q = G[node][neighbour]["Q"]
                        else:
                            q = -G[neighbour][node]["Q"]
                        d = G[node][neighbour]["DIAMETER"]
                        H[neighbour] = H[node] - (K * l * math.copysign(
                            (abs(q) / 1000)**1.852, q) / (d / 1000)**4.8704)
            return H

        if solver.check() == z3.sat:
            print("solved")
            m = solver.model()
            solver.add(
                z3.Or([D[edge] != m.evaluate(D[edge]) for edge in G.edges]))

            X = dict([(node, float(m.evaluate(X[node]).numerator_as_long()) /
                       float(m.evaluate(X[node]).denominator_as_long()))
                      for node in X])
            nx.set_node_attributes(G, X, "Q")

            Q = dict([(edge, float(m.evaluate(Q[edge]).numerator_as_long()) /
                       float(m.evaluate(Q[edge]).denominator_as_long()))
                      for edge in Q])
            V = dict([(edge, float(m.evaluate(V[edge]).numerator_as_long()) /
                       float(m.evaluate(V[edge]).denominator_as_long()))
                      for edge in V])
            D = dict([(edge, float(m.evaluate(D[edge]).numerator_as_long()) /
                       float(m.evaluate(D[edge]).denominator_as_long()))
                      for edge in D])
            data = dict([("Q", Q), ("V", V), ("DIAMETER", D)])
            for key, datadict in data.items():
                nx.set_edge_attributes(G, datadict, key)

            H = compute_head()
            nx.set_node_attributes(G, H, "H")

        else:
            print("no solutions")
コード例 #4
0
ファイル: checker.py プロジェクト: pretl/ALIGN-public
 def Or(*expressions):
     return z3.Or(*expressions)
コード例 #5
0
    def _sat_expr(
            self, regex: Tuple
    ) -> Tuple[z3.SeqRef, z3.BoolRef, z3.BoolRef, z3.BoolRef]:
        """

        :returns: string that matches regex, constraint on string,
             whether string contains caret, whether string contains dollar

        Whether there is a caret or dollar needs to be tracked because they imply constraints on
        neighboring strings to the one returned.

        """

        ty = regex[0]

        if ty == EMPTY:
            return (z3.StringVal(''), z3.BoolVal(True), z3.BoolVal(False),
                    z3.BoolVal(False))

        elif ty == CHAR:
            return (z3.StringVal(regex[1]), z3.BoolVal(True),
                    z3.BoolVal(False), z3.BoolVal(False))

        elif ty == DOT:
            x = self._gen_string_var()
            constraint = z3.And(
                z3.Implies(self.ignore_wildcards, x == z3.StringVal('')),
                z3.Implies(
                    z3.Not(self.ignore_wildcards),
                    z3.Or(*(x == z3.StringVal(y) for y in self.dot_charset))))
            return (x, constraint, z3.BoolVal(False), z3.BoolVal(False))

        elif ty == STAR:
            # STAR should have been approximated with something else during preprocessing.
            raise NotImplementedError

        elif ty == BAR:
            ys, constraints_list, carets_list, dollars_list = zip(
                *map(self._sat_expr, regex[1:]))

            x = self._gen_string_var()
            x_constraint = z3.Or(
                *(z3.And(x == y, y_constraint)
                  for y, y_constraint in zip(ys, constraints_list)))

            return (x, x_constraint, z3.Or(*carets_list), z3.Or(*dollars_list))
        elif ty == CONCAT:

            ys, y_constraints, carets_list, dollars_list = zip(
                *map(self._sat_expr, regex[1:]))

            x = z3.Concat(*ys)

            start_constraints = (z3.Implies(b,
                                            z3.Length(y) == 0)
                                 for ii, b in enumerate(carets_list)
                                 for y in ys[:ii])

            end_constraints = (z3.Implies(b,
                                          z3.Length(y) == 0)
                               for ii, b in enumerate(dollars_list)
                               for y in ys[ii + 1:])

            x_constraint = z3.And(*toolz.concatv(
                y_constraints, start_constraints, end_constraints))

            return (x, x_constraint, z3.Or(*carets_list), z3.Or(*dollars_list))

        elif ty == GROUP:
            # backrefs not supported
            idx = regex[
                1] - 1  # not used currently; would be used to implement backrefs
            inner = regex[2]
            return self._sat_expr(inner)

        elif ty == BACKREF:
            raise NotImplementedError

        elif ty == CARET:
            assert len(regex) == 1
            b = self._gen_bool_var()
            return (z3.StringVal(''), b, b, z3.BoolVal(False))

        elif ty == DOLLAR:
            assert len(regex) == 1
            b = self._gen_bool_var()
            return (z3.StringVal(''), b, z3.BoolVal(False), b)

        else:
            raise ValueError("Unknown regex_parser type '%s'" % repr(ty))
コード例 #6
0
def spec_invariants(kernelstate):
    conj = []

    pid = util.FreshBitVec('pid', dt.pid_t)
    pn = util.FreshBitVec('pn', dt.pn_t)

    #
    # procs' page table, hvm and stack are
    #
    # 1) valid
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
        z3.And(
            is_pn_valid(kernelstate.procs[pid].page_table_root),
            is_pn_valid(kernelstate.procs[pid].hvm),
            is_pn_valid(kernelstate.procs[pid].stack)))))
    # 2) owned by that proc
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
        z3.Implies(
            is_status_live(kernelstate.procs[pid].state),
            z3.And(
                kernelstate.pages[kernelstate.procs[pid].page_table_root].owner == pid,
                kernelstate.pages[kernelstate.procs[pid].hvm].owner == pid,
                kernelstate.pages[kernelstate.procs[pid].stack].owner == pid)))))

    # 3) have the correct type
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
        z3.Implies(
            is_status_live(kernelstate.procs[pid].state),
            z3.And(
                kernelstate.pages[kernelstate.procs[pid].page_table_root].type == dt.page_type.PAGE_TYPE_X86_PML4,
                kernelstate.pages[kernelstate.procs[pid].hvm].type == dt.page_type.PAGE_TYPE_PROC_DATA,
                kernelstate.pages[kernelstate.procs[pid].stack].type == dt.page_type.PAGE_TYPE_PROC_DATA)))))

    ##

    # Sleeping PROC's ipc_page is a frame owned by that pid
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
        z3.Implies(
            kernelstate.procs[pid].state == dt.proc_state.PROC_SLEEPING,
            z3.And(
                is_pn_valid(kernelstate.procs[pid].ipc_page),
                kernelstate.pages[kernelstate.procs[pid]
                    .ipc_page].type == dt.page_type.PAGE_TYPE_FRAME,
                kernelstate.pages[kernelstate.procs[pid].ipc_page].owner == pid)))))

    ## Non-zombie procs with use_io_bitmaps own their (valid) bitmap pages
    conj.append(z3.ForAll([pid],
        z3.Implies(
            z3.And(
                is_pid_valid(pid),
                kernelstate.procs[pid].use_io_bitmap,
                kernelstate.procs[pid].state != dt.proc_state.PROC_ZOMBIE),
            z3.And(
                is_pn_valid(kernelstate.procs[pid].io_bitmap_a),
                is_pn_valid(kernelstate.procs[pid].io_bitmap_b),
                kernelstate.pages[kernelstate.procs[pid].io_bitmap_a].owner == pid,
                kernelstate.pages[kernelstate.procs[pid].io_bitmap_b].owner == pid,
                kernelstate.pages[kernelstate.procs[pid].io_bitmap_a].type == dt.page_type.PAGE_TYPE_PROC_DATA,
                kernelstate.pages[kernelstate.procs[pid].io_bitmap_b].type == dt.page_type.PAGE_TYPE_PROC_DATA))))

    # page has an owner <=> page is not free
    conj.append(z3.ForAll([pn], z3.Implies(is_pn_valid(pn),
        is_pid_valid(kernelstate.pages[pn].owner) == (kernelstate.pages[pn].type != dt.page_type.PAGE_TYPE_FREE))))

    conj.append(z3.ForAll([pn], z3.Implies(is_pn_valid(pn),
        z3.Implies(kernelstate.pages[pn].type == dt.page_type.PAGE_TYPE_FREE,
            z3.Not(is_pid_valid(kernelstate.pages[pn].owner))))))

    # a sleeping proc's ipc_fd is either invalid or empty
    conj.append(z3.ForAll([pid], z3.Implies(z3.And(
        is_pid_valid(pid),
        kernelstate.procs[pid].state == dt.proc_state.PROC_SLEEPING),

        z3.Or(z3.Not(is_fd_valid(kernelstate.procs[pid].ipc_fd)),
              z3.Not(is_fn_valid(kernelstate.procs[pid].ofile(kernelstate.procs[pid].ipc_fd)))))))

    ##############
    # Unused procs's refcount is all zero
    # conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
    #     z3.Implies(kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED,
    #         z3.And(
    # kernelstate.procs[pid].nr_pages(dt.NPAGE - 1) == z3.BitVecVal(0, dt.size_t))))))
    # kernelstate.procs[pid].nr_children(dt.NPROC - 1) == z3.BitVecVal(0, dt.size_t),
    # kernelstate.procs[pid].nr_fds(dt.NOFILE - 1) == z3.BitVecVal(0, dt.size_t),
    # kernelstate.procs[pid].nr_devs(dt.NPCIDEV - 1) == z3.BitVecVal(0, dt.size_t))))))

    # # unused procs don't have a parent
    # conj.append(z3.ForAll([pid], z3.Implies(
    #     z3.And(
    #         is_pid_valid(pid),
    #         kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED),
    #     kernelstate.procs[pid].ppid == z3.BitVecVal(0, dt.pid_t))))

    # # unused procs don't have fds
    # conj.append(z3.ForAll([pid, fd], z3.Implies(
    #     z3.And(
    #         is_pid_valid(pid),
    #         kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED),
    #     z3.Not(is_fn_valid(kernelstate.procs[pid].ofile(fd))))))

    # unused fn has refcount == 0
    # conj.append(z3.ForAll([fn], z3.Implies(is_fn_valid(fn),
    #     z3.Implies(kernelstate.files[fn].type == dt.file_type.FD_NONE,
    #         kernelstate.files[fn].refcnt(
    #             z3.Concat(
    #                 z3.BitVecVal(dt.NPROC - 1, dt.pid_t),
    #                 z3.BitVecVal(dt.NOFILE - 1, dt.fd_t))) == z3.BitVecVal(0, dt.size_t)))))

    ##############

    # disjointed-ness of memory regions
    conj.append(z3.And(
        z3.Extract(63, 40, z3.UDiv(kernelstate.pages_ptr_to_int, util.i64(4096)) + dt.NPAGES_PAGES) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.proc_table_ptr_to_int, util.i64(4096)) + dt.NPAGES_PROC_TABLE) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.page_desc_table_ptr_to_int, util.i64(4096)) + dt.NPAGES_PAGE_DESC_TABLE) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.file_table_ptr_to_int, util.i64(4096)) + dt.NPAGES_FILE_TABLE) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.devices_ptr_to_int,util.i64(4096)) + dt.NPAGES_DEVICES) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.dmapages_ptr_to_int,util.i64(4096)) + dt.NDMAPAGE) == z3.BitVecVal(0, 24),

        z3.Extract(63, 40, z3.UDiv(kernelstate.pages_ptr_to_int, util.i64(4096))) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.proc_table_ptr_to_int, util.i64(4096))) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.page_desc_table_ptr_to_int, util.i64(4096))) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.file_table_ptr_to_int, util.i64(4096))) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.devices_ptr_to_int, util.i64(4096))) == z3.BitVecVal(0, 24),
        z3.Extract(63, 40, z3.UDiv(kernelstate.dmapages_ptr_to_int, util.i64(4096))) == z3.BitVecVal(0, 24),

        z3.ULT(z3.UDiv(kernelstate.pages_ptr_to_int, util.i64(4096)) + dt.NPAGES_PAGES, z3.UDiv(kernelstate.proc_table_ptr_to_int, util.i64(4096))),
        z3.ULT(z3.UDiv(kernelstate.proc_table_ptr_to_int, util.i64(4096)) + dt.NPAGES_PROC_TABLE, z3.UDiv(kernelstate.page_desc_table_ptr_to_int, util.i64(4096))),
        z3.ULT(z3.UDiv(kernelstate.page_desc_table_ptr_to_int, util.i64(4096)) + dt.NPAGES_PAGE_DESC_TABLE, z3.UDiv(kernelstate.file_table_ptr_to_int, util.i64(4096))),
        z3.ULT(z3.UDiv(kernelstate.file_table_ptr_to_int, util.i64(4096)) + dt.NPAGES_FILE_TABLE, z3.UDiv(kernelstate.devices_ptr_to_int, util.i64(4096))),
        z3.ULT(z3.UDiv(kernelstate.devices_ptr_to_int, util.i64(4096)) + dt.NPCIDEV, z3.UDiv(kernelstate.dmapages_ptr_to_int, util.i64(4096))),
        z3.ULT(z3.UDiv(kernelstate.dmapages_ptr_to_int, util.i64(4096)) + dt.NDMAPAGE, z3.UDiv(dt.PCI_START, util.i64(4096))),
    ))

    # Current is a valid pid
    conj.append(is_pid_valid(kernelstate.current))
    # Current is always running
    conj.append(kernelstate.procs[kernelstate.current].state == dt.proc_state.PROC_RUNNING),
    # A running proc must be current
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
        z3.Implies(kernelstate.procs[pid].state == dt.proc_state.PROC_RUNNING,
            pid == kernelstate.current))))

    return z3.And(*conj)
コード例 #7
0
def impl_invariants_py(ctx):
    conj = []

    pid = util.FreshBitVec('pid', dt.pid_t)
    pn = util.FreshBitVec('pn', dt.pn_t)
    fd = util.FreshBitVec('fd', dt.fd_t)
    # fn = util.FreshBitVec('fn', dt.fn_t)

    # embryos, runnable or running processes own the pages in their structs
    conj.append(z3.ForAll([pid], z3.Implies(
        z3.Or(util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_EMBRYO,
              util.global_field_element(
                  ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_RUNNING,
              util.global_field_element(
                  ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_RUNNABLE,
              util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_SLEEPING),
        z3.And(
            pn_has_owner_and_type(ctx, util.global_field_element(
                ctx, '@proc_table', 'page_table_root', pid), pid, dt.page_type.PAGE_TYPE_X86_PML4),
            pn_has_owner_and_type(ctx, util.global_field_element(
                ctx, '@proc_table', 'hvm', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA),
            pn_has_owner_and_type(ctx, util.global_field_element(
                ctx, '@proc_table', 'stack', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA),
        ))))

    # sleeping processes own their ipc_page
    conj.append(z3.ForAll([pid], z3.Implies(z3.And(is_pid_valid(pid),
        util.global_field_element(ctx, '@proc_table', 'state', pid) != dt.proc_state.PROC_ZOMBIE),
        z3.Implies(util.global_field_element(ctx, '@proc_table', 'use_io_bitmap', pid) != 0,
            z3.And(
                is_pn_valid(util.global_field_element(ctx, '@proc_table', 'io_bitmap_a', pid)),
                is_pn_valid(util.global_field_element(ctx, '@proc_table', 'io_bitmap_b', pid)),
                pn_has_owner_and_type(ctx, util.global_field_element(ctx, '@proc_table', 'io_bitmap_a', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA),
                pn_has_owner_and_type(ctx, util.global_field_element(ctx, '@proc_table', 'io_bitmap_b', pid), pid, dt.page_type.PAGE_TYPE_PROC_DATA))))))

    # sleeping processes own their ipc_page
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
        z3.Implies(util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_SLEEPING,
            pn_has_owner_and_type(ctx, util.global_field_element(ctx, '@proc_table', 'ipc_page', pid), pid, dt.page_type.PAGE_TYPE_FRAME)))))

    conj.append(z3.ForAll([pid],
                          z3.And(
        is_pn_valid(util.global_field_element(
                ctx, '@proc_table', 'page_table_root', pid)),
        is_pn_valid(util.global_field_element(
            ctx, '@proc_table', 'hvm', pid)),
        is_pn_valid(util.global_field_element(ctx, '@proc_table', 'stack', pid)))))

    # sleeping processes' ipc fd are empty if valid
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_valid(pid),
        z3.Implies(util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_SLEEPING,
            z3.Implies(is_fd_valid(util.global_field_element(ctx, '@proc_table', 'ipc_fd', pid)),
                util.global_field_element(ctx, '@proc_table', 'ofile', pid,
                    z3.ZeroExt(32, util.global_field_element(ctx, '@proc_table', 'ipc_fd', pid))) == z3.BitVecVal(0, dt.fn_t))))))

    conj.append(z3.ForAll([pid],
                          z3.And(
        is_pn_valid(util.global_field_element(
                ctx, '@proc_table', 'page_table_root', pid)),
        is_pn_valid(util.global_field_element(
            ctx, '@proc_table', 'hvm', pid)),
        is_pn_valid(util.global_field_element(ctx, '@proc_table', 'stack', pid)))))

    # page has an owner <=> page is not free
    conj.append(z3.ForAll([pn], z3.Implies(is_pn_valid(pn),
        is_pid_valid(util.global_field_element(ctx, '@page_desc_table', 'pid', pn)) ==
        (util.global_field_element(ctx, '@page_desc_table', 'type', pn) != dt.page_type.PAGE_TYPE_FREE))))

    # unused procs have zero refcnt
    conj.append(z3.ForAll([pid], z3.Implies(
        z3.And(
            is_pid_valid(pid),
            util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_UNUSED),
        z3.And(
            util.global_field_element(ctx, '@proc_table', 'nr_children', pid) == z3.BitVecVal(0, dt.size_t),
            util.global_field_element(ctx, '@proc_table', 'nr_fds', pid) == z3.BitVecVal(0, dt.size_t),
            util.global_field_element(ctx, '@proc_table', 'nr_pages', pid) == z3.BitVecVal(0, dt.size_t),
            util.global_field_element(ctx, '@proc_table', 'nr_dmapages', pid) == z3.BitVecVal(0, dt.size_t),
            util.global_field_element(ctx, '@proc_table', 'nr_devs', pid) == z3.BitVecVal(0, dt.size_t),
            util.global_field_element(ctx, '@proc_table', 'nr_ports', pid) == z3.BitVecVal(0, dt.size_t),
            util.global_field_element(ctx, '@proc_table', 'nr_vectors', pid) == z3.BitVecVal(0, dt.size_t),
            util.global_field_element(ctx, '@proc_table', 'nr_intremaps', pid) == z3.BitVecVal(0, dt.size_t)))))

    # conj.append(z3.ForAll([pid, fd], z3.Implies(z3.And(is_pid_valid(pid), is_fd_valid(fd)),
    #     z3.Implies(
    #         util.global_field_element(ctx, '@proc_table', 'nr_fds', pid) == z3.BitVecVal(0, dt.size_t),
    #         z3.Not(is_fn_valid(util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd))))))))

    # # unused procs have zero fds
    # conj.append(z3.ForAll([pid, fd], z3.Implies(z3.And(is_pid_valid(pid), is_fd_valid(fd)),
    #     z3.Implies(
    #         util.global_field_element(ctx, '@proc_table', 'state', pid) == dt.proc_state.PROC_UNUSED,
    #         util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)) == z3.BitVecVal(0, dt.fn_t)))))

    # fds valid
    conj.append(z3.ForAll([pid, fd], z3.Implies(z3.And(is_pid_valid(pid), is_fd_valid(fd)),
        z3.Or(
            util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)) == z3.BitVecVal(0, dt.fn_t),
            is_fn_valid(util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)))))))

    # # FD_NONE's refcount is 0
    # conj.append(z3.ForAll([fn], z3.Implies(
    #     z3.And(
    #         is_fn_valid(fn),
    #         util.global_field_element(ctx, '@file_table', 'type', fn) == dt.file_type.FD_NONE),
    #     util.global_field_element(ctx, '@file_table', 'refcnt', fn) == z3.BitVecVal(0, dt.size_t))))

    # # FD never points to FD_NONE
    # conj.append(z3.ForAll([pid, fd], z3.Implies(
    #     z3.And(
    #         is_pid_valid(pid),
    #         is_fd_valid(fd),
    #         is_fn_valid(util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd)))),
    #     util.global_field_element(ctx, '@file_table', 'type',
    #         util.global_field_element(ctx, '@proc_table', 'ofile', pid, z3.ZeroExt(32, fd))) != dt.file_type.FD_NONE)))

    # page freelist is well formed
    conj.append(z3.ForAll([pn], z3.Implies(is_pn_valid(pn),
        z3.And(
            is_pn_valid(util.global_field_element(ctx, '@page_desc_table', ['link', 'prev'], pn)),
            is_pn_valid(util.global_field_element(ctx, '@page_desc_table', ['link', 'next'], pn))))))

    # ready queue is well formed
    # don't use is_pid_valid as some ->prev and ->next are zeros
    conj.append(z3.ForAll([pid], z3.Implies(is_pid_bounded(pid),
        z3.And(
            is_pid_bounded(util.global_field_element(ctx, '@proc_table', ['ready', 'prev'], pid)),
            is_pid_bounded(util.global_field_element(ctx, '@proc_table', ['ready', 'next'], pid))))))

    # Current is always a valid and running
    conj.append(is_pid_valid(util.global_value(ctx, '@current')))

    conj.append(util.global_field_element(ctx, '@proc_table', 'state', util.global_value(ctx, '@current')) == dt.proc_state.PROC_RUNNING)

    return z3.And(*conj)
コード例 #8
0
ファイル: coverability_icover.py プロジェクト: gsutre/icover
def comparable_coverability(petrinet, init, targets, prune=False, max_iter=None):

    global total_check_time
    global total_build_time
    global UUcomp
    global nbcomp
    global error


    # Verify if non coverable in CPN first
    if prune and non_coverable(petrinet, init, targets):
        print "non_coverable in Q"
        print "result find with non_coverable"
        return False
    
    # Otherwise, proceed with backward coverability
    def smallest_elems(x):
        return set(sorted(x, key=sum_norm)[:int(10 + 0.2 * len(x))])

    solverQ, variables = build_cpn_solver(petrinet, init, targets=None,
                                         domain='N')

    transitions = get_transitions(petrinet)
    solverL,_ = build_limit_solver(transitions,init)
    _, _, target_vars = variables

   

    def comparaison_coverable(markings):
        global glitch
        global UUcomp
        global nbcomp
        global error

        nbcomp += 1
        #print solverQ
        #print solverL
        resQ = check_cpn_coverability_z3(solverQ, target_vars, markings)
        resL = check_limit_coverability_z3(solverL, markings)
    

        if resQ and resL == False:
            print "qcover solver say cover and limit solver say not cover"
            print "impossible"
            print "error"
            #print markings
            
            error +=1
            print
            exit(1)

        if resQ == False and resL:

            glitch +=1
        
            
        return resQ


    
    

    init_marking = _omega_marking(init)

    basis = {tuple(constraint_vector(m)) for m in targets}
    precomputed = {}
    covered = in_upward(init_marking, basis)    

    num_iter = 0

    while not covered:
        if max_iter is not None and num_iter >= max_iter:
            return None # Unknown result
        else:
            num_iter += 1

        # Compute prebasis

        print "step :",num_iter


        prebasis = pre_upward(petrinet, basis, precomputed)


        # Coverability pruning
        nbover = glitch
        pruned = {x for x in prebasis if prune and not comparaison_coverable([x])}
        print "nb over ", glitch-nbover
        print "prebasis size : ", len(prebasis)
        print "size of pruned :", len(pruned)
        prebasis.difference_update(pruned)
        

        
        for x in pruned:
            solverQ.add(z3.Or([target_vars[p] < x[p] for p in
                              range(len(x))]))

        # Continue?
        if len(prebasis) == 0:
            break
        else:
            prebasis = smallest_elems(prebasis)
            merge_upward(basis, prebasis)
            covered = in_upward(init_marking, basis)
         
        
        print 


    print "total build time :", total_build_time
    print "total check time :", total_check_time
    print "glitch: ", glitch
    print "error", error
    print "comparison", nbcomp

    return covered
コード例 #9
0
        return z3.ZeroExt(64 - 8, parse_byte(b))
    return (pl(chars[0]) << 56) | (pl(chars[1]) << 48) | (pl(chars[2]) << 40) | (pl(chars[3]) << 32) | (pl(chars[4]) << 24) | (pl(chars[5]) << 16) | (pl(chars[6]) << 8) | (pl(chars[7]))

print("sanity checking parse_byte function")
print(s.check())
print(s.model().eval(z3.BitVecVal(int('aF', 16), 16)))

for idx, c in enumerate(begin):
    s.add(flag[idx] == ord(c))

s.add(flag[-1] == ord('}'))

for c in flag[5:-1]: # change our domain to allow 0
    s.add(z3.Or(
        z3.And(c >= ord('0'), c <= ord('9')),
        z3.And(c >= ord('a'), c <= ord('f')),
        z3.And(c >= ord('A'), c <= ord('F'))
    ))

target = 1140336659
# res = z3.BitVecVal(0, 32)
# flag_len = len(flag)
# for idx, c in enumerate(flag):
#     res = res + z3.ZeroExt(24, c) * (31**(flag_len - idx - 1))
# print(res)
r3 = z3.BitVecVal(0, 32)
for c in flag:
    r3 = r3 * 31 + z3.ZeroExt(24, c)
s.add(r3 == target)
# s.add(res == target)
コード例 #10
0
Z = ZHolder()
Z.Wrapbool = Unk.bool
Z.Wrapint = Unk.int
Z.Wrapstring = Unk.string
Z.Wrapfunc = Unk.func
Z.Wrapnone = Unk.none
Z.Bool = Unk.tobool
Z.Int = Unk.toint
Z.String = Unk.tostring
Z.Func = Unk.tofunc
Z.Isbool = lambda x: Unk.is_bool(x)
Z.Isint = lambda x: Unk.is_int(x)
Z.Isstring = lambda x: Unk.is_string(x)
Z.Isfunc = lambda x: Unk.is_func(x)
Z.Istuple = lambda x: z3.Or(Unk.is_app(x), Unk.is__(x))
Z.Isnone = lambda x: Unk.is_none(x)
Z.Isdefined = lambda x: z3.Not(Unk.is_undef(x))
Z.Isundefined = lambda x: Unk.is_undef(x)
Z.Eq = lambda x, y: x == y
Z.Neq = lambda x, y: x != y
Z.Distinct = z3.Distinct
Z.T = z3.Function('T', Unk, z3.BoolSort())
Z.F = z3.Function('F', Unk, z3.BoolSort())
Z.N = Unk.none
Z.Length = z3.Length
Z.Implies = z3.Implies
Z.And = z3.And
Z.Or = z3.Or
Z.Not = z3.Not
Z.Negate = lambda x: -x
コード例 #11
0
    i_value, bv_value3, value_relationship,
    True, True, bv_type='intle:32'))
print("Is conversion precise for bit-vector:" +
      str(bv_value3) + " in integer domain:" + str(i_value))
print(explanation)

#check given constraints that should make them precise
i_value = i_y - 2
bv_value4 = yconcat + z3.BitVecVal(-2, 32)
value_relationship = (z3.BV2Int(bv_value4) == i_value)
i_condition = i_y > 6
bv_condition = yconcat > z3.BitVecVal(6, 32)
print("Alas, can we prove that bit-vector: " + str(bv_value4) +
      " in integer domain: " + str(i_value) + " under constraints: " +
      str(i_condition) + " and " + str(bv_condition) + " is precise?")
print("... wait for demonstration of timeout")
(same, model, explanation) = (
    bar2020.single_variable_bit_vector_domain_equals_integer_domain(
    i_y, y, variable_relationship,
    i_value, bv_value4, value_relationship,
    i_condition, bv_condition, bv_type='intle:32'))
print(explanation)

#example using logic synthesis
constraint = z3.And(z3.Or(y > 6, y == 6), z3.Not(y == 6))
using_sis = bar2020.simplify_z3_boolean_using_logic_synthesis_approach(constraint)
print("Using sis, we can simplify " + str(constraint) + " to " + str(using_sis))
            


コード例 #12
0
    def _sat_expr(self, x, r, i, l):
        if l not in self._len_set(r):
            return z3.BoolVal(False)
        if i + l > self.length:
            return z3.BoolVal(False)

        ty = r[0]

        if ty == regex_parser.EMPTY:
            return z3.BoolVal(True)

        elif ty == regex_parser.CHAR:
            return (x[i] == ord(r[1]))

        elif ty == regex_parser.DOT:
            expr = z3.BoolVal(False)
            for ch in regex_parser.CHARSET:
                expr = z3.Or(expr, x[i] == ord(ch))
            return expr

        elif ty == regex_parser.STAR:
            # SAT(r*, i, l) = Union for l' in LEN(r):
            #                   [ SAT(r, i, l') && SAT(r*, i+l', l-l') ]
            if l == 0:
                return z3.BoolVal(True)
            else:
                expr = z3.BoolVal(False)
                for l1 in self._len_set(r[1]):
                    expr = z3.Or(
                        expr,
                        z3.And(self._sat_expr(x, r[1], i, l1),
                               self._sat_expr(x, r, i + l1, l - l1)))
                return expr

        elif ty == regex_parser.BAR:
            # SAT(r1 | r2, i, l) = SAT(r1, i, l) || SAT(r2, i, l)
            expr = z3.Or(self._sat_expr(x, r[1], i, l),
                         self._sat_expr(x, r[2], i, l))
            return expr

        elif ty == regex_parser.CONCAT:
            # SAT(r1 r2, i, l) = Union for l1 in LEN(r1):
            #                      [ SAT(r1, i, l1) && SAT(r2, i+l1, l-l1) ]
            expr = z3.BoolVal(False)
            for l1 in self._len_set(r[1]):
                expr = z3.Or(
                    expr,
                    z3.And(self._sat_expr(x, r[1], i, l1),
                           self._sat_expr(x, r[2], i + l1, l - l1)))
            return expr

        elif ty == regex_parser.GROUP:
            idx = r[1] - 1
            inner = r[2]
            if (idx + 1) in self.backrefs:
                expr = z3.And((self.p[idx] == i),
                              self._sat_expr(x, inner, i, l))
                self.possible_pos[idx].add(i)
            else:
                expr = self._sat_expr(x, inner, i, l)
            return expr

        elif ty == regex_parser.BACKREF:
            idx = r[1] - 1
            expr = z3.BoolVal(False)
            for j in self.possible_pos[idx]:
                clause = (self.p[idx] == j)
                for k in range(l):
                    clause = z3.And(clause, (x[i + k] == x[j + k]))
                expr = z3.Or(expr, clause)
            return expr

        elif ty == regex_parser.CARET:
            inner = r[1]
            if i == 0:
                return self._sat_expr(x, inner, i, l)
            else:
                return z3.BoolVal(False)

        elif ty == regex_parser.DOLLAR:
            inner = r[1]
            if i + l == self.length:
                return self._sat_expr(x, inner, i, l)
            else:
                return z3.BoolVal(False)

        else:
            raise ValueError("Unknown regex_parser type '%s'" % repr(ty))
コード例 #13
0
ファイル: player.py プロジェクト: abarth/z3p
    'east',
    'north',
    'west',
)

def _generate_cards_for_player(player):
    for suit in suits:
        for rank in ranks:
            yield z3.Int('%s_%s_%s' % (player.key, suit.key, rank.key))

def _cards_for_player(player):
    return list(_generate_cards_for_player(player))

hands = map(_cards_for_player, players)

axioms = []
axioms += [z3.Or(card == 0, card == 1) for card in sum(hands, [])]
axioms += [sum(cards) == 1 for cards in zip(*hands)]
axioms += [sum(cards) == 13 for cards in hands]

solver = z3.Solver()
solver.add(axioms)

solver.check()
model = solver.model()

for cards in hands:
    for card in cards:
        if z3.is_true(model.eval(card == 1)):
            print card
コード例 #14
0
 def int01(self, name):
     v = z3.Int(name)
     self.solver.add(z3.Or(v == 0, v == 1))
     return v
コード例 #15
0
def Or(*args):
    return z3.Or(*(args + (getCtx(), )))
コード例 #16
0
ファイル: position.py プロジェクト: leonardt/SMT-PNR
 def delta_x(self, other):
     delta_x = z3.BitVec(self.name + '-' + other.name + '_delta_x',
                         self.fabric.cols)
     constraint = z3.Or(self.x == other.x << delta_x,
                        other.x == self.x << delta_x)
     return constraint, delta_x
コード例 #17
0
ファイル: virtual.py プロジェクト: mfkiwl/riscv_axiomatic
        def _walk(a, i, c):
            if a.size() != self.options.physical_address_bits:
                raise Exception(
                    f"walk expected a "
                    f"{self.options.physical_address_bits}-bit PA, "
                    f"but got an address of {a.size()} bits")
            hi, lo = self.vpn_bits[i]
            vpn_i = z3.Extract(hi, lo, va)

            possibly_n = i == 0 and self.pte_size == 8
            if possibly_n:
                # offset is further constrained in the second `possibly_n`
                # block below
                offset = self.physical_address(
                    z3.BitVec(f"{op_name}_walk_{i}_offset", 9))
            else:
                offset = self.physical_address(vpn_i)

            # Calculate the PTE address
            pte_addr = a + offset * self.pte_size

            # Generate an Implicit Read
            read_name = f"{op_name}_walk_{i}"
            builder.read(
                meta,
                tid,
                read_name,
                "PT Walk",
                c,
                self.pte_size,
                pte_addr,
                False,
                False,
                reserve=True,
                implicit=True,
                satp_asid=self.asid,
            )

            # Update translation_order
            nonlocal previous_implicit
            for prev_op, prev_condition in previous_implicit:
                builder.translation_order.update((prev_op, read_name),
                                                 z3.And(c, prev_condition))
            previous_implicit.append((read_name, c))

            # Interpret the return value as a PTE of the appropriate size
            value = builder.return_value[read_name]
            if self.pte_size == 4:
                pte = pte32(value)
            elif self.pte_size == 8:
                pte = pte64(value)
            else:
                assert False

            # Fault if any of the reserved bits are set
            if self.pte_size == 8:
                custom = z3.Extract(63, 63, pte.value())
                reserved = z3.Extract(61, 54, pte.value())
                c = _fault_if("access", c, z3.Or(custom != 0, reserved != 0))

            # Batch the page faults for better solver performance
            page_fault_conditions = []

            # Check for NAPOT pages
            if possibly_n:
                # For Svnapot translations, the offset must either match the
                # original offset or be to a valid NAPOT PTE in the same region
                napot64k = z3.And(
                    pte.n,
                    z3.Extract(3, 0, pte.ppn) == z3.BitVecVal(0b1000, 4))

                builder.fact(
                    z3.Or(
                        offset == self.physical_address(vpn_i),
                        z3.And(
                            napot64k,
                            z3.Extract(8, 4,
                                       offset) == z3.Extract(8, 4, vpn_i),
                        ),
                    ),
                    "Svnapot offset",
                )

                # Fault if the offset points to an invalid NAPOT PTE
                page_fault_conditions.append(z3.And(pte.n, z3.Not(napot64k)))
            else:
                page_fault_conditions.append(pte.n)
                napot64k = False

            # Fault if not V
            page_fault_conditions.append(z3.Not(pte.v))

            # Fault if W and not R
            page_fault_conditions.append(z3.And(pte.w, z3.Not(pte.r)))

            # Check R, W, X, U
            leaf = z3.Or(pte.r, pte.x)
            page_fault_conditions.append(z3.And(leaf, read, z3.Not(pte.r)))
            page_fault_conditions.append(z3.And(leaf, write, z3.Not(pte.w)))
            page_fault_conditions.append(z3.And(leaf, execute, z3.Not(pte.x)))
            page_fault_conditions.append(z3.And(user, z3.Not(pte.u)))

            # Fault if i == 0 and this is not a leaf PTE
            if i == 0:
                page_fault_conditions.append(z3.Not(leaf))

            # Fault if this is a misaligned superpage
            for j in range(i):
                hi, lo = self.ppn_bits[j]
                ppn_j = z3.Extract(hi, lo, pte.value())
                page_fault_conditions.append(
                    z3.And(leaf, ppn_j != z3.BitVecVal(0, ppn_j.size())), )

            # Fault if A and D are not set properly
            a_d_insufficient = z3.And(
                c,
                z3.Or(
                    z3.And(leaf, z3.Not(pte.a)),
                    z3.And(leaf, write, z3.Not(pte.d)),
                ),
            )
            if self.options.hardware_a_d_bit_update:
                # That's it for page fault checks
                c = _fault_if("page", c, z3.Or(page_fault_conditions))

                old_pte_value = pte.value()
                updated_pte_value = z3.Concat(
                    z3.Extract(old_pte_value.size() - 1, 8, old_pte_value),
                    z3.If(write, resize(1, 1), z3.Extract(7, 7,
                                                          old_pte_value)),
                    resize(1, 1),
                    z3.Extract(5, 0, old_pte_value),
                )
                write_name = f"{op_name}_walk_{i}_a_d"

                # We are assuming this SC always succeeds just as a way of
                # filtering out some of the space that needs to be explored
                builder.write(
                    meta,
                    tid,
                    write_name,
                    "A/D Update",
                    a_d_insufficient,
                    self.pte_size,
                    pte_addr,
                    updated_pte_value,
                    aq=False,
                    rl=False,
                    conditional_dst="x0",
                    implicit=True,
                    satp_asid=self.asid,
                )
                builder.implicit_pair.update((read_name, write_name),
                                             a_d_insufficient)
                builder.datadep.update((read_name, write_name),
                                       a_d_insufficient)
                for prev_op, prev_condition in previous_implicit:
                    builder.translation_order.update(
                        (prev_op, write_name),
                        z3.And(c, prev_condition, a_d_insufficient),
                    )
                previous_implicit.append(
                    (write_name, z3.And(c, a_d_insufficient)))
                pte_value = z3.If(a_d_insufficient, old_pte_value,
                                  updated_pte_value)
            else:
                page_fault_conditions.append(a_d_insufficient)

                # That's it for page fault checks
                c = _fault_if("page", c, z3.Or(page_fault_conditions))

                pte_value = pte.value()

            # Update the PPN to account for PTE.N
            pte_size = pte_value.size()
            pte_value = z3.If(
                napot64k,
                z3.Concat(
                    z3.Extract(pte_size - 1, 14, pte_value),
                    z3.Extract(15, 12, va),
                    z3.Extract(9, 0, pte_value),
                ),
                pte_value,
            )

            # Generate the PTE from the PPNs and offsets
            pa_components = []
            for j in range(self.levels - 1, i - 1, -1):
                hi, lo = self.ppn_bits[j]
                pa_components.append(z3.Extract(hi, lo, pte_value))
            for j in range(i - 1, -1, -1):
                hi, lo = self.vpn_bits[j]
                pa_components.append(z3.Extract(hi, lo, va))
            pa_components.append(z3.Extract(11, 0, va))
            pa_leaf = self.physical_address(z3.Concat(pa_components))

            # Fault if the calculated PA is out of range
            c = _fault_if(
                "access",
                c,
                z3.And(leaf,
                       truncates(pa_leaf, self.options.physical_address_bits)),
            )

            # Recurse to the next level, unless this is a leaf PTE
            if i == 0 or true(leaf):
                return pa_leaf, c
            else:
                hi = self.ppn_bits[-1][0]
                lo = self.ppn_bits[0][1]
                ppn = z3.Extract(hi, lo, pte_value)
                a = self.physical_address(z3.Concat(ppn, z3.BitVecVal(0, 12)))
                c = z3.And(c, z3.Not(leaf))
                pa, c_walk = _walk(a, i - 1, c)
                return z3.If(leaf, pa_leaf, pa), z3.If(leaf, c, c_walk)
コード例 #18
0
ファイル: position.py プロジェクト: leonardt/SMT-PNR
 def delta_y(self, other):
     delta_y = z3.BitVec(self.name + '-' + other.name + '_delta_y',
                         self.fabric.rows)
     constraint = z3.Or(self.y == other.y << delta_y,
                        other.y == self.y << delta_y)
     return constraint, delta_y
コード例 #19
0
 def or_(ctx, *args):
     return z3.Or(*args)
コード例 #20
0
ファイル: position.py プロジェクト: leonardt/SMT-PNR
 def delta_fun(constant):
     if constant == 0:
         return self.y == other.y
     else:
         return z3.Or(self.y == other.y << constant,
                      other.y == self.y << constant)
コード例 #21
0
ファイル: sep.py プロジェクト: secure-foundations/mypyvy-fork
            elif isinstance(e, AppExpr) and e.callee in functions:
                return functions[e.callee](*(map(to_z3, e.args)))
            elif (isinstance(e, AppExpr) and e.callee in relations
                  and isinstance(r := relations[e.callee], z3.FuncDeclRef)):
                return r(*(map(to_z3, e.args)))
            elif isinstance(e, UnaryExpr) and e.op == 'NOT':
                return z3.Not(to_z3(e.arg))
            elif isinstance(e, BinaryExpr) and e.op == 'EQUAL':
                return to_z3(e.arg1) == to_z3(e.arg2)
            else:
                assert False, e

        value = z3.Implies(
            z3.And(*(universes[s](v)
                     for v, s in zip(z3_vs, self.prefix_names))),
            z3.And(*(z3.Or(*(z3.And(self.lit_vs[i, lit], to_z3(lit))
                             for lit in self.literals))
                     for i in range(self.n_clauses))))
        if len(z3_vs) > 0:
            value = z3.ForAll(z3_vs, value)
        assertions.append(state_models_sep == value)

        return assertions, state_models_sep


def sep_main(solver: Solver) -> str:
    prog = syntax.the_program
    print(f'\n[{datetime.now()}] [PID={os.getpid()}] Starting sep\n')

    safety = tuple(
        chain(*(as_clauses(inv.expr) for inv in prog.invs()
                if inv.is_safety)))  # convert to CNF
コード例 #22
0
def get_accelerations_from_z3(trans: [OmegaTransition],
                              init_marking: np.array,
                              timeout=1):
    time_start = time.time()
    trans_var = []
    strictly_greater_constrain = []
    dim = trans[0].get_dim()
    accelerations = []
    marking = init_marking
    if init_marking is None:
        marking = [0] * dim
    solver = z3.Solver()

    for i in range(len(trans)):
        name = "t" + i.__str__()
        trans_var.append(z3.Int(name))

    first = True
    for p in range(dim):
        if marking[p] == float("inf"):
            continue

        terms = []
        for t in range(len(trans)):
            terms.append((trans[t].get_incidence())[p] * trans_var[t])

        # terms = ([c * x for (c, x) in zip(constants, trans_var)])
        sum = z3.Sum(terms)
        if first:
            temp = sum >= 0
            first = False
        else:
            temp = z3.And(temp, sum >= 0)

        strictly_greater_constrain.append(sum > 0)

    solver.add(temp)
    solver.add(z3.Or(strictly_greater_constrain))
    above_zero = [x >= 0 for x in trans_var]
    solver.add(above_zero)
    solver.add(z3.Sum(trans_var) <= 15)
    n = 0

    while time.time() - time_start < timeout:

        if solver.check() != z3.sat:
            break
        sol = solver.model()
        new_acc = from_solution_to_acceleration(sol, trans_var, trans, dim)
        to_add_the_new_acc = True

        num_of_acc = len(accelerations)
        for i in range(num_of_acc):
            acc = accelerations[num_of_acc - i - 1]
            if new_acc > acc:
                accelerations.remove(acc)
            if new_acc <= acc:
                to_add_the_new_acc = False
                break
        if to_add_the_new_acc:
            accelerations.append(new_acc)
        par = z3.Int("c" + n.__str__())
        n += 1
        not_the_same_answer = ([y != par * sol[y] for y in trans_var])
        solver.add(z3.Or(not_the_same_answer))
    return accelerations
コード例 #23
0
ファイル: z3_interface.py プロジェクト: hermetique/boole



################################################################################
#
# These dictionaries gives the Z3 translations of the built-in symbols,
# built-in sorts, and Z3 functions for building constants of the built-in
# sorts.
#
################################################################################

_built_in_z3_funs = {
    eq.name: (lambda args, context: args[0] == args[1]),
    And.name: (lambda args, context: z3.And(args)),
    Or.name: (lambda args, context: z3.Or(args)),
    implies.name: 
        (lambda args, context: z3.Implies(args[0], args[1], context)),
    Not.name: (lambda args, context: z3.Not(args[0], context)),
    add.name: (lambda args, context: args[0] + args[1]),
    mul.name: (lambda args, context: args[0] * args[1]),
    minus.name: (lambda args, context: args[0] - args[1]),
    div.name: (lambda args, context: args[0] / args[1]),
    power.name: (lambda args, context: pow(args[0], args[1])),
    uminus.name: (lambda args, context: -args[0]),
    absf.name: (lambda args, context: abs(args[0])),
    lt.name: (lambda args, context: args[0] < args[1]),
    le.name: (lambda args, context: args[0] <= args[1])
# these are not used
#    ne.name: (lambda args, context: args[0] != args[1]),
#    Sum.name: (lambda args, context: z3.Sum(args)),
コード例 #24
0
 def valid(self):
     valid_list = []
     for member_name, _ in self.fields:
         member_hdr = self.resolve_reference(member_name)
         valid_list.append(member_hdr.isValid())
     return z3.simplify(z3.Or(*valid_list))
コード例 #25
0
def solve(foods):
    s = z3.Solver()

    # encode all ingredients and allergens
    ingredients_ = list(set(item for pair in foods for item in pair[0]))
    allergens_ = list(set(item for pair in foods for item in pair[1]))

    ingredients = dict((v, i) for i, v in enumerate(ingredients_))
    allergens = dict((v, i) for i, v in enumerate(allergens_))

    # we want to find out which ingredient is an allergen
    # we treat this as an MxN assignment problem
    # ie. solve for which ingredient can be possibly assigned as an allergen, while satisfying all input constrains
    assignments = z3.IntVector('allergen', len(allergens))

    # program the valid range of our ingredient encodings
    for a in assignments:
        s.add(z3.And(a >= 0, a < len(ingredients)))

    # there can only be one possible ingredient assigned to an allergen
    s.add(z3.Distinct(assignments))

    for i, a in foods:

        # program the all possible pairs of assignment for this food
        for a_ in a:
            food = []
            for i_ in i:
                # encode the input constrain
                I = ingredients[i_]
                A = assignments[allergens[a_]]

                # one of these (allergen == ingredient) pair could be valid
                food.append(A == I)
            s.add(z3.Or(food))

        # ensure that this food doesn't contain any other types of allergen
        food = []

        not_a = set(allergens.keys()) - set(a)
        for i_, a_ in itertools.product(i, not_a):
            # encode the input constrain
            I = ingredients[i_]
            A = assignments[allergens[a_]]

            # not any other types of allergen
            # print(f"{(i_, a_)=}")
            food.append(I != A)

        s.add(z3.Or(food))

    # are we asking the impossible?
    print(f"{s=}")
    print()

    r = s.check()
    print(f"{r=}")

    if r == z3.sat:
        # constrain satisfied, now we extract the solution from the model
        m = s.model()
        print(f"{m=}")

        # reverse the our integer encoding into string
        allergen = dict(enumerate(allergens_))
        ingredient = dict(enumerate(ingredients_))

        solution = [{'ingredient': ingredient[m.eval(a).as_long()], 'allergen': allergen[i]}
                    for i, a in enumerate(assignments)]
        return solution
コード例 #26
0
        def expt_rules():
            rules = collections.deque()
            solver = z3.Solver()
            solver.set('arith.nl', False)
            solver.add(hyps)

            def show(p):
                report('trying to show(', p, '):')
                report('  hypotheses = ', solver)
                solver.push()
                solver.add(z3.Not(p))
                outcome = solver.check()
                s1 = '  the negation is ' + str(outcome)
                if(outcome == z3.unsat):
                  report(s1, "; therefore the original claim is valid")
                elif(outcome == z3.sat):
                  report(s1, "\n  here's a counter-example to ", p, "\n  ", solver.model())
                elif(outcome == z3.unknown):
                  report(s1, "; therefore, the original claim is undecided")
                else:
                  report(s1, "; how'd that happen?")
                solver.pop()
                return outcome == z3.unsat

            def add_rule(p):
                report('add_rule(', p, ')')
                rules.append(p)
                solver.add(p)

            while(len(workQ) > 0):
                v = workQ.pop()
                x = v.children()[0]
                n = v.children()[1]

                report('rewriting expt(', x, ', ', n, ')')

                # Many of the rules below should have guards to ensure that we don't
                # accidentally say expt(x, n) is defined when x==0 and n < 0.
                # Rather that figuring out # all of the corner cases, I first check to
                # see if (x == 0) and (n < 0) is satisfiable.  If so, this code just
                # throws an exception.  I could probably work out a better error message
                # later.
                #   Now that we know that expt(x, n) is well-defined, we still need to be careful.
                # Consider expt(x, n+m) where x==0, n==3, and m==(-2).  In this case, expt(x, n+m)
                # is well-defined, but we can't conclude:
                #    expt(x, n+m) == expt(x, n) * expt(x, m)
                # Rather than working out lots of side conditions (and probably making a mistake),
                # I just check to see if implies(hyps, x > 0), and then plunge ahead without fear.
                # Of course, this means I don't generate all of the rules that I could, but I'll
                # do that later if this simple version turns out to be useful.

                def expt_rewrite_const(x2, n2):
                    if(n2 == 0): return z3.intVal(1)
                    elif((0 < n2) and (n2 <= self.maxPowExpand)):
                        add_rule(v == prod(map(lambda _: x2, range(n2))))
                    elif((-self.maxPowExpand <= n2) and (n2 < 0)):
                        add_rule(v*prod(map(lambda _: x2, range(-n2))) == 1)
                if(not show(z3.Or(x != 0, n >= 0))):
                    raise ExptRewriteFailure('possible attempt to raise 0 to a negative power')

                x_is_pos = show(x > 0)
                x_is_nz  = x_is_pos or show(x != 0)
                x_is_z   = (not x_is_nz) and show(x == 0)

                n_is_pos = show(n > 0)
                n_is_neg = (not n_is_pos) and show(n < 0)
                n_is_z   = (not n_is_pos) and (not n_is_neg) and show(n == 0)

                if(n_is_z or x_is_z):
                    if(n_is_z): add_rule(v == 1)
                    elif(n_is_pos): add_rule(v == 0)
                    else: add_rule(v == z3.If(n == 0, 1, 0))
                    continue
                elif(x_is_pos):
                    x_lt_1 = show(x < 1)
                    x_gt_1 = (not x_lt_1) and show(x > 1)
                    if((not x_lt_1) and (not x_gt_1) and show(x == 1)):
                        add_rule(v == 1)
                        continue
                    add_rule(v > 0)
                else:
                  add_rule(z3.Implies(x > 0, v > 0))
                  if(x_is_nz): add_rule(z != 0)
                  else: add_rule(z3.Implies(z3.Or(x != 0, n==0), v != 0))

                if((x.decl().name() == '*') and (len(x.children()) > 1)): # expt(x0*x1*..., n)
                    add_rule(v == prod(map(lambda y: xpt(y, n), x.children())))
                elif((n.decl().name() == '+') and (len(n.children()) > 1)): # expt(x, n0+n1+...)
                    add_rule(v == prod(map(lambda m: xpt(x, m), n.children())))
                elif(n.decl().name() == '-'):
                    nn = n.children()
                    if(len(nn) == 0): pass  # a variable named '-'
                    elif(len(nn) == 1): # expt(x, -n)
                        add_rule(z3.Implies(x != 0, v*xpt(x, nn[0]) == 1))
                    elif(len(nn) == 2): # expt(x, n-m)
                        add_rule(z3.Implies(x != 0, v*xpt(x, nn[1]) == xpt(x, nn[0])))
                    else: RewriteExptFailure("unexpected: '-' expression with more than two children")
                elif(n.decl().name() == '*'):  # expt(x, n0*n1*...)
                    # check to see if n0 is integer constants and not "too big".
                    # if so, replace it with repeated multiplication
                    nn = n.children()
                    if((len(nn) > 0) and not (longVal(nn[0]) is None)):
                        if(len(nn) == 1): ex = x
                        else: ex = xpt(x, prod(nn[1:]))
                        expt_rewrite_const(ex, longVal(nn[0]))
                elif(not (longVal(n) is None)):
                    expt_rewrite_const(x, longVal(n))
                else: # we can't think of a way to simplify it
                    if(x_lt_1 or x_gt_1):
                        if(n_is_pos or n_is_neg): pass
                        else: add_rule(z3.Implies(n == 0, v == 1))
                    else:
                        if(n_is_pos or n_is_neg): add_rule(z3.Implies(x==1, v == 1))
                        else: add_rule(z3.Implies(z3.Or(x==1, n == 0), v == 1))
                    if(x_is_pos):
                        if(x_lt_1):
                            if(n_is_pos): add_rule(v <= x)
                            elif(n_is_neg): add_rule(v*x >= 1)
                            else: add_rule(z3.And(
                                z3.Implies(n > 0, v <= x),
                                z3.Implies(n < 0, v*x >= 1)))
                        elif(x_gt_1):
                            if(n_is_pos): add_rule(v >= x)
                            elif(n_is_neg): add_rule(v*x <= 1)
                            else: add_rule(z3.And(
                                z3.Implies(n > 0, v >= x),
                                z3.Implies(n < 0, v*x <= 1)))
                        else: add_rule(z3.And(
                            z3.Implies(z3.And(x < 1, n > 0), v <= x),
                            z3.Implies(z3.And(x < 1, n < 0), v*x >= 1),
                            z3.Implies(z3.And(x > 1, n > 0), v >= x),
                            z3.Implies(z3.And(x > 1, n < 0), v*x <= 1)))
            return rules
コード例 #27
0
ファイル: fuzzy.py プロジェクト: ukk1/ITKST53
 def _z3expr(self, printable):
     return z3.Or(*[z3expr(a, printable) for a in self.args])
コード例 #28
0
ファイル: ae64.py プロジェクト: veritas501/ae64
 def z3_isalnum(ch):
     return z3.Or(
         z3.And(0x30 <= ch, ch <= 0x39),
         z3.And(0x41 <= ch, ch <= 0x5a),
         z3.And(0x61 <= ch, ch <= 0x7a),
     )
コード例 #29
0
ファイル: core.py プロジェクト: yxwangcs/lightdp
    ast.Gt: lambda x, y: x > y,
    ast.Lt: lambda x, y: x < y,
    ast.LtE: lambda x, y: x <= y,
    ast.GtE: lambda x, y: x >= y
}

_binop_map = {
    ast.Add: lambda x, y: x + y,
    ast.Sub: lambda x, y: x - y,
    ast.Mult: lambda x, y: x * y,
    ast.Div: lambda x, y: x / y
}

_boolop_map = {
    ast.And: lambda x, y: z3.And(x, y),
    ast.Or: lambda x, y: z3.Or(x, y)
}

_unop_map = {ast.USub: lambda x: -x}


class NodeVerifier(ast.NodeVisitor):
    """
    Walks through the :py:class:`ast.AST` and generate constraints to be solved by z3.
    """
    def __init__(self):
        """
        Initialization of :py:class:`NodeVerifier`.
        """
        self._precondition = []
        self._declarations = []
コード例 #30
0
def In(val, lst):
    assert len(lst) > 0, "List must be non-empty"
    return z3.Or(*[val == a for a in lst])