Beispiel #1
0
def solve(grid):
    """

    . . .
    .1.1.
    . .3.

    """
    s = z3.Solver()

    # Construct atoms to represent the dots
    Dot = z3.Datatype("Dot")
    for d in grid.dots():
        Dot.declare("dot_{}".format(d))
    Dot = Dot.create()

    dot_atom = {d: getattr(Dot, "dot_{}".format(d)) for d in grid.dots()}

    # Booleans for each of the points
    dot = {d: z3.Bool("dot-{}".format(d)) for d in grid.dots()}

    # Booleans for each of the connectors
    line = {l: z3.Bool("line-{}".format(l)) for l in grid.lines()}

    # For each point: if it is on, it must have precisely two adjoining lines activated
    # If it's off, then there are zero adjoining lines activated
    bool_to_int = z3.Function("bool_to_int", z3.BoolSort(), z3.IntSort())
    s.add(bool_to_int(True) == 1)
    s.add(bool_to_int(True) != 0)
    s.add(bool_to_int(False) == 0)
    s.add(bool_to_int(False) != 1)

    for d in grid.dots():
        # Get all lines coming out of this dot
        ls = [line[l] for l in d.lines()]

        sm = z3.Sum(*(bool_to_int(l) for l in ls))
        s.add(z3.Implies(dot[d], sm == 2))
        s.add(z3.Implies(z3.Not(dot[d]), sm == 0))

    # For each line: if it is activated, then the points at both ends are activated
    for l in line:
        d1, d2 = l.ends()
        s.add(z3.Implies(line[l], z3.And(dot[d1], dot[d2])))

    # "Is connected to" relationship
    connected = z3.Function("connected", Dot, Dot, z3.BoolSort())

    # For each line:
    # The Dot at each end is connected to the other iff the line is activated
    for d1 in grid.dots():
        for d2 in grid.dots():
            a = dot_atom[d1]
            b = dot_atom[d2]
            if (l := grid.line(d1, d2)) is None:
                # These dots are never connected
                s.add(connected(a, b) != True)
            else:
                s.add(z3.Implies(line[l], connected(a, b)))
                s.add(z3.Implies(z3.Not(line[l]), z3.Not(connected(a, b))))
Beispiel #2
0
  def solve(self):
    self.lamps = {(x,y): self.int01(x,y) for x in range(self.xsize) for y in range(self.ysize)}

    # No lamps on walls
    # Numbers count lamps next to node (diagonals don't count)

    for y in range(self.ysize):
      for x in range(self.xsize):
        if self.data[x,y] != ".":
          self.solver.add(self.lamps[x,y] == 0)
          if self.data[x,y] in "01234":
            self.solver.add(z3.Sum(self.lamps_next_to_cell(x,y)) == int(self.data[x,y]))

    # Every cell is in raycast of a lamp
    # No lamp is in raycast of another lamp
    for y in range(self.ysize):
      for x in range(self.xsize):
        raycast = z3.Sum(self.raycast_cells(x,y))
        self.solver.add(z3.Implies(self.lamps[x,y] == 0, raycast >= 1))
        self.solver.add(z3.Implies(self.lamps[x,y] == 1, raycast == 0))

    if self.solver.check() == z3.sat:
      self.model = self.solver.model()
      self.print_answer()
    else:
      print("failed to solve")
Beispiel #3
0
def _add_firing_constraints_places(petrinet, marking, solver,
                                   variables, backward=False):
    tag = "bl" if backward else "fl"

    global _unique_tag
    places_variables = [z3.Int("{}_{}_{}".format(tag, _unique_tag, p))
                        for p in range(petrinet.num_places())]
    _unique_tag += 1
    
    for p in range(petrinet.num_places()):
        var = places_variables[p]
        preset = petrinet.transitions_preset({p}, reverse=backward)
        constraints = []

        for t in preset:
            t_preset = petrinet.places_preset({t}, reverse=backward)

            constraint = z3.And(variables[t] > 0,
                                z3.And([z3.And(places_variables[q] > 0,
                                               var > places_variables[q])
                                        for q in t_preset]))
            constraints.append(constraint)

        solver.add(z3.Implies(marking[p] >  0, var == 1))
        solver.add(z3.Implies(marking[p] == 0, z3.Implies(var > 0,
                                                   z3.Or(constraints))))

    for t in range(petrinet.num_transitions()):
        places = petrinet.places_set({t}, pre=True, post=True, 
                                     reverse=backward)

        places_reachable = z3.And([places_variables[p] > 0 for p in
                                   places])
        
        solver.add(z3.Implies(variables[t] > 0, places_reachable))
Beispiel #4
0
def spec_lemma_nr_dmapages_refcnt(kernelstate):
    conj = []

    pid = util.FreshBitVec('pid', dt.pid_t)
    dmapn = util.FreshBitVec('dmapn', dt.dmapn_t)

    # General invariant -- a free dma page has no owner
    conj.append(
        z3.ForAll([dmapn],
                  z3.Implies(
                      is_dmapn_valid(dmapn),
                      is_pid_valid(kernelstate.dmapages[dmapn].owner) == (
                          kernelstate.dmapages[dmapn].type !=
                          dt.page_type.PAGE_TYPE_FREE))))

    # PROC_UNUSED state implies refcount is 0 (sys_clone needs this)
    conj.append(
        z3.ForAll(
            [pid],
            z3.Implies(
                is_pid_valid(pid),
                z3.Implies(
                    kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED,
                    kernelstate.procs[pid].nr_dmapages() == z3.BitVecVal(
                        0, dt.size_t)))))

    # # Correctness definition for `permutation` based refcount
    kernelstate.procs.nr_dmapages.check(
        conj,
        is_owner_valid=is_pid_valid,
        is_owned_valid=is_dmapn_valid,
        max_refs=dt.NDMAPAGE,
        ownerfn=lambda dmapn: kernelstate.dmapages[dmapn].owner)

    return z3.And(*conj)
Beispiel #5
0
def spec_lemma_nr_devs_refcnt(kernelstate):
    conj = []

    pid = util.FreshBitVec('pid', dt.pid_t)
    devid = util.FreshBitVec('devid', dt.devid_t)

    # unused procs don't own any devices
    conj.append(
        z3.ForAll([devid],
                  z3.Implies(
                      is_pid_valid(kernelstate.pci[devid].owner),
                      kernelstate.procs[kernelstate.pci[devid].owner].state !=
                      dt.proc_state.PROC_UNUSED)))

    conj.append(
        z3.ForAll(
            [pid],
            z3.Implies(
                kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED,
                kernelstate.procs[pid].nr_devs() == z3.BitVecVal(0,
                                                                 dt.size_t))))

    # Correctness definition for `permutation` based refcount
    kernelstate.procs.nr_devs.check(
        conj,
        is_owner_valid=is_pid_valid,
        is_owned_valid=lambda n: z3.BoolVal(True),
        max_refs=2**dt.devid_t.size(),
        ownerfn=lambda devid0: kernelstate.pci[devid0].owner)

    return z3.And(*conj)
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))
        t_2 = z3.Int('%s_firewall_send_t_2' % (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),\
                                       t_1 < t_0)))))

        self.constraints.append(z3.ForAll([n_0, p_0, t_0], z3.Implies(\
                z3.And(self.ctx.send(self.fw, n_0, p_0, t_0), \
                  z3.Not(self.acl_func(p_0))), \
                z3.Exists([n_1, p_1, t_1], \
                  z3.And(self.ctx.send(self.fw, n_1, p_1, t_1), \
                         t_1 + 1 <= t_0, \
                         self.acl_func(p_1), \
                         self.ctx.packet.src(p_0) == self.ctx.packet.dest(p_1), \
                         self.ctx.packet.dest(p_0) == self.ctx.packet.src(p_1), \
                         self.ctx.src_port(p_0) == self.ctx.dest_port(p_1), \
                         self.ctx.dest_port(p_0) == self.ctx.src_port(p_1), \
                   )))))
def assert_any_transition(s: Solver,
                          t: Z3Translator,
                          state_index: int,
                          allow_stutter: bool = False) -> None:
    prog = syntax.the_program
    uid = str(state_index)

    tids = []
    for transition in prog.transitions():
        tid = z3.Bool(get_transition_indicator(uid, transition.name))
        tids.append(tid)
        s.add(
            z3.Implies(
                tid,
                t.translate_expr(
                    New(transition.as_twostate_formula(prog.scope),
                        state_index))))

    if allow_stutter:
        tid = z3.Bool(get_transition_indicator(uid, '$stutter'))
        tids.append(tid)
        frame = syntax.And(*DefinitionDecl._frame(prog.scope, mods=()))
        s.add(z3.Implies(tid, t.translate_expr(New(frame, state_index))))

    s.add(z3.Or(*tids))
Beispiel #8
0
    def _add_postconditions(self, gate, ctrl_ones, trgtqb, trgtvar):
        """create boolean variables for each qubit the gate is applied to
            and apply the relevant post conditions.
            a gate rotating out of the z-basis will not have any valid
            post-conditions, in which case the qubit state is unknown
        Args:
            gate (Gate): gate to inspect
            ctrl_ones (BoolRef): z3 condition asserting all control qubits to 1
            trgtqb (list((QuantumRegister, int))): list of target qubits
            trgtvar (list(BoolRef)): z3 variables corresponding to latest state
                                     of target qubits
        """
        import z3

        new_vars = []
        for qbt in trgtqb:
            new_vars.append(self._gen_variable(qbt))

        try:
            self.solver.add(
                z3.Implies(ctrl_ones,
                           gate._postconditions(*(trgtvar + new_vars))))
        except AttributeError:
            pass

        for i, tvar in enumerate(trgtvar):
            self.solver.add(z3.Implies(z3.Not(ctrl_ones), new_vars[i] == tvar))
Beispiel #9
0
def merge_queries_new_pred(clauses, queries, decls):
    if len(queries) > 1:
        false1 = z3.Bool("CHC_COMP_FALSE")
        decls.add(false1.decl())

        for query in queries:
            assert (z3.is_quantifier(query) and query.is_forall())

            qvars = [
                z3.Const(query.var_name(n), query.var_sort(n))
                for n in range(0, query.num_vars())
            ]

            body = query.body()
            assert (body.decl().kind() == z3.Z3_OP_IMPLIES)
            kids = body.children()
            assert (kids[1] == z3.BoolVal(False))

            newBody = z3.Implies(kids[0], false1)
            newClause = z3.ForAll(qvars, newBody)

            clauses.append(newClause)

        queries.clear()

        queries.append(
            z3.ForAll(z3.Bool("CHC_COMP_UNUSED"),
                      z3.Implies(z3.And(false1), z3.BoolVal(False))))
Beispiel #10
0
def string_indexOf(x, args):
    if z3.is_array(x):
        if str(x.decl()) not in ARRAY_LENGTHS:
            raise Exception('We do not know how large the underlying array should be thus we cannot include on it')
        helper_int = z3.Int('__ignore_arr_indexOf_helper_' + randomString())
        search_string = createZ3ExpressionFromConstraint(args[0], {})
        all = []
        presentImplications = []
        for i in range(ARRAY_LENGTHS[str(x.decl())]):
            conditional = z3.Select(x, i) == search_string
            all.append(conditional)
            true_imply = z3.Implies(conditional, helper_int <= i)
            false_imply = z3.Implies(z3.Not(conditional), helper_int > i)
            presentImplications.append(true_imply)
            presentImplications.append(false_imply)
        all = z3.Or(all)
        GLOBAL_CONSTRAINTS.append(z3.And(z3.Implies(all, z3.And(presentImplications)), z3.Implies(all, helper_int >= 0),
                                         z3.Implies(z3.mk_not(all), helper_int == -1)))
        return helper_int

    else:
        if len(args) > 1:
            return z3.IndexOf(x, createZ3ExpressionFromConstraint(args[0], {}),
                              createZ3ExpressionFromConstraint(args[1], {}))
        else:
            return z3.IndexOf(x, createZ3ExpressionFromConstraint(args[0], {}), 0)
Beispiel #11
0
def construct_axioms(variables):  # List[StatVar]
    _axioms = []
    for var in variables:
        # A variable must be continuous or categorical, but not both.
        _axioms.append(
            z3.And(
                z3.Or(continuous(var).__z3__,
                      categorical(var).__z3__),
                z3.Not(z3.And(continuous(var).__z3__,
                              categorical(var).__z3__))))

        # If a variable is an explanatory variable and all explanatory variables are categorical,
        # then the variable must be categorical.
        # It isn't clear how to reason about whether a variable is an explanatory or explained variable.
        # _axioms.append(z3.Implies(all_x_variables_categorical(var).__z3__, categorical(var).__z3__))

        # Not sure how to reason about test properties like one_x_variable and one_y_variable.
        # _axioms.append(z3.Not(z3.And(one_x_variable(var).__z3__, one_y_variable(var).__z3__)))

        # If a variable is normal, then it cannot be categorical.
        _axioms.append(
            z3.Implies(normal(var).__z3__, z3.Not(categorical(var).__z3__)))

        # If a variable is continuous or ordinal, it must be continuous.
        _axioms.append(
            z3.Implies(
                continuous_or_ordinal(var).__z3__,
                continuous(var).__z3__))

        # If a variable has two categories, then it must be categorical.
        # _axioms.append(z3.Implies(two_x_variable_categories(var).__z3__, categorical(var).__z3__))

    return _axioms
Beispiel #12
0
def spec_lemma_nr_pages_refcnt(kernelstate):
    conj = []

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

    # PROC_UNUSED state implies refcount is 0 (sys_clone needs this)
    conj.append(
        z3.ForAll(
            [pid],
            z3.Implies(
                is_pid_valid(pid),
                z3.Implies(
                    kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED,
                    kernelstate.procs[pid].nr_pages() == z3.BitVecVal(
                        0, dt.size_t)))))

    # Correctness definition for `permutation` based refcount
    kernelstate.procs.nr_pages.check(
        conj,
        is_owner_valid=is_pid_valid,
        is_owned_valid=is_pn_valid,
        max_refs=dt.NPAGE,
        ownerfn=lambda pn: kernelstate.pages[pn].owner)

    return z3.And(*conj)
Beispiel #13
0
    def _constraints(self):
        #self.count_func = z3.Function('count_%s'%(self.node), self.ctx.address, self.ctx.address, \
        #z3.IntSort(), z3.IntSort())
        p0 = z3.Const('_counter_p0_%s' % (self.node), self.ctx.packet)
        p1 = z3.Const('_counter_p1_%s' % (self.node), self.ctx.packet)
        n0 = z3.Const('_counter_n0_%s' % (self.node), self.ctx.node)
        n1 = z3.Const('_counter_n1_%s' % (self.node), self.ctx.node)
        n2 = z3.Const('_counter_n2_%s' % (self.node), self.ctx.node)
        t0 = z3.Int('_counter_t0_%s' % (self.node))
        t1 = z3.Int('_counter_t1_%s' % (self.node))
        a0 = z3.Const('_counter_a0_%s' % (self.node), self.ctx.address)
        a1 = z3.Const('_counter_a1_%s' % (self.node), self.ctx.address)

        # Make sure all packets sent were first recved
        self.constraints.append(z3.ForAll([n0, p0], \
                              z3.Implies(self.ctx.send(self.node, n0, p0), \
                                z3.And( \
                                    z3.Exists([n1], \
                                      z3.And (self.ctx.recv(n1, self.node, p0), \
                                       n0 != n1)), \
                                       z3.Not(z3.Exists([n2], \
                                              z3.And(self.ctx.send(self.node, n2, p0), \
                                                     n2 != n0))), \
                                       self.ctx.etime(self.node, p0, self.ctx.send_event) > \
                                           self.ctx.etime(self.node, p0, self.ctx.recv_event)))))

        # Make sure packets go one at a time
        self.constraints.append(z3.ForAll([p0, t0], \
                              z3.Implies(z3.And(self.ctx.etime(self.node, p0, self.ctx.send_event) == t0, \
                                               t0 != 0), \
                                           z3.ForAll([p1], \
                                                z3.Or(p0 == p1, \
                                                   self.ctx.etime(self.node, p1, \
                                                                 self.ctx.send_event) != \
                                                       t0)))))
Beispiel #14
0
def spec_lemma_nr_ports_refcnt(kernelstate):
    conj = []

    pid = util.FreshBitVec('pid', dt.pid_t)
    port = util.FreshBitVec('port', dt.uint16_t)

    # unused procs don't own any ports
    # valid([port:pid]) ==> [port:pid].state != UNUSED
    conj.append(
        z3.ForAll([port],
                  z3.Implies(
                      is_pid_valid(kernelstate.io[port].owner),
                      kernelstate.procs[kernelstate.io[port].owner].state !=
                      dt.proc_state.PROC_UNUSED)))
    # pid.state == UNUSED ==> pid.nr_ports == 0
    conj.append(
        z3.ForAll(
            [pid],
            z3.Implies(
                kernelstate.procs[pid].state == dt.proc_state.PROC_UNUSED,
                kernelstate.procs[pid].nr_ports() == z3.BitVecVal(
                    0, dt.size_t))))

    # Correctness definition for `permutation` based refcount
    kernelstate.procs.nr_ports.check(
        conj,
        is_owner_valid=is_pid_valid,
        is_owned_valid=lambda n: z3.BoolVal(True),
        max_refs=2**dt.uint16_t.size(),
        ownerfn=lambda port0: kernelstate.io[port0].owner)

    return z3.And(*conj)
Beispiel #15
0
def spec_corollary_pgwalk(kernelstate):
    pid = util.FreshBitVec('pid', dt.pid_t)
    va = dt.FreshVA()

    pml4 = kernelstate.procs[pid].page_table_root
    # Abstract model of a page_walk starting from some root
    page, writable, present = page_walk(kernelstate, pml4, *va)

    # If a four level page-walk from some pid returns a page,
    # that page must be exclusively owned by the pid.
    # furthermore, if the page is writable,
    # it has to be a frame.
    isolation = util.Implies(
        present, kernelstate.pages[page].owner == pid,
        z3.Implies(
            writable,
            kernelstate.pages[page].type == dt.page_type.PAGE_TYPE_FRAME))
    # valid(pid) & pid.state == active & valid(va) ==> page.owner == pid && page.type == FRAME (active is either EMBRYO, RUNNABLE or RUNNING)

    return z3.ForAll([pid] + va,
                     z3.Implies(
                         z3.And(
                             is_pid_valid(pid),
                             is_status_live(kernelstate.procs[pid].state),
                             is_va_valid(va),
                         ), isolation))
Beispiel #16
0
    def _populateLoadBalancerConstraints(self):
        self.hash_function = z3.Function(
            'load_balancer_hash_%s' % (self.balancer), z3.IntSort(),
            z3.IntSort(), z3.IntSort())
        p0 = z3.Const('_load_balancer_p0_%s' % (self.balancer),
                      self.ctx.packet)
        p1 = z3.Const('_load_balancer_p1_%s' % (self.balancer),
                      self.ctx.packet)
        n0 = z3.Const('_load_balancer_n0_%s' % (self.balancer), self.ctx.node)
        n1 = z3.Const('_load_balancer_n1_%s' % (self.balancer), self.ctx.node)
        n2 = z3.Const('_load_balancer_n2_%s' % (self.balancer), self.ctx.node)
        hash_same = [self.ctx.packet.src(p0) == self.ctx.packet.src(p1), \
                     self.ctx.packet.dest(p0) == self.ctx.packet.dest(p1), \
                     self.hash_function(self.ctx.src_port(p0), self.ctx.dest_port(p0)) == \
                        self.hash_function(self.ctx.src_port(p1), self.ctx.dest_port(p1)), \
                     self.ctx.send(self.balancer, n0, p0), \
                     self.ctx.send(self.balancer, n1, p1)
                    ]
        self.constraints.append(z3.ForAll([n0, p0, n1, p1], \
                                z3.Implies(z3.And(hash_same), \
                                            n0 == n1)))

        self.constraints.append(z3.ForAll([n0, p0], \
                                  z3.Implies(\
                                      self.ctx.send(self.balancer, n0, p0), \
                                    z3.And( \
                                        z3.Exists([n1], \
                                          z3.And(self.ctx.recv(n1, self.balancer, p0), \
                                            n1 != n0)), \
                                          z3.Not(z3.Exists([n2], \
                                              z3.And(n2 != n0, \
                                                self.ctx.send(self.balancer, n2, p0)))), \
                                          self.ctx.etime(self.balancer, p0, self.ctx.send_event) > \
                                            self.ctx.etime(self.balancer, p0, self.ctx.recv_event)))))
Beispiel #17
0
def elim_bool_ite(exp):
    if z3.is_quantifier(exp):
        (qvars, matrix) = strip_qblock(exp)
        matrix = elim_bool_ite(matrix)
        if exp.is_forall():
            e = z3.ForAll(qvars, matrix)
        else:
            e = z3.Exists(qvars, matrix)
        return e
    if not z3.is_bool(exp): return exp
    if z3.is_true(exp) or z3.is_false(exp): return exp
    assert z3.is_app(exp)
    decl = exp.decl()
    args = map(elim_bool_ite, exp.children())
    # need to worry about And and Or because they can take >2 args and
    # decl(*args) doesn't seem to work with the py interface
    if z3.is_and(exp):
        return z3.And(*args)
    elif z3.is_or(exp):
        return z3.Or(*args)
    elif is_ite(exp):
        impl1 = z3.Implies(args[0], args[1])
        impl2 = z3.Implies(z3.Not(args[0]), args[2])
        return z3.And(impl1, impl2)
    else:
        return decl(*args)
Beispiel #18
0
def pages_equiv(conj, ctx, kernelstate):
    pn = util.FreshBitVec('pn', dt.pn_t)
    idx = util.FreshBitVec('page_index', 64)

    conj.append(
        z3.ForAll([pn, idx],
                  z3.Implies(
                      z3.And(is_pn_valid(pn), z3.ULT(idx, 512)),
                      util.global_to_uf_dict(ctx, '@pages')[()](
                          util.i64(0), pn,
                          idx) == kernelstate.pages[pn].data(idx))))

    conj.append(
        z3.ForAll(
            [pn],
            z3.Implies(
                is_pn_valid(pn),
                util.global_field_element(ctx, '@page_desc_table', 'pid',
                                          pn) == kernelstate.pages[pn].owner)))

    conj.append(
        z3.ForAll(
            [pn],
            z3.Implies(
                is_pn_valid(pn),
                util.global_field_element(ctx, '@page_desc_table', 'type',
                                          pn) == kernelstate.pages[pn].type)))
Beispiel #19
0
def check_move(move):
    """
    Given a move, use Z3 to check if it is good or bad. The move is encodeed as a 36-size bit vector
    as described above. Assumes no player has already won.
    """

    # Initialize and introduce z3 constants
    solver = z3.Solver()
    z3_board = [
        z3.Const("board_state_" + str(i), z3.BoolSort()) for i in range(27)
    ]
    z3_board_res = [
        z3.Const("res_board_state_" + str(i), z3.BoolSort()) for i in range(27)
    ]

    # Add constraints for input
    for z3_const, cond in zip(z3_board, move[:27]):
        solver.add(z3_const if cond else z3.Not(z3_const))

    # Add constraints for the fact that z3_board_res is obtained via move on z3_board
    solver.add(encode_move(z3_board, z3_board_res, move[27:], 1))

    # If player one can win, move must be winnig
    solver.add(
        z3.Implies(encode_has_winning_move(z3_board, 1),
                   encode_has_won(z3_board_res, 1)))

    # If player one cannot win, player one should not win in next round
    solver.add(
        z3.Implies(z3.Not(encode_has_winning_move(z3_board, 1)),
                   z3.Not(encode_has_winning_move(z3_board_res, 2))))
    # Finally, check sat
    return solver.check() == z3.sat
Beispiel #20
0
    def finalizePiFun(
            self,
            rf_force={}
    ):  # rf_force is a dict of rf-relation: read (KEY) <- write
        # print log
        rf_force_local = rf_force.copy(
        )  # make a copy because we will modify it
        if DEBUG:
            mm.printPossibleReadFrom(self._logcat(), self.PiVarList.values(),
                                     self.TsThatWritesVar)
        # add PI function
        for sname, piVar, ts in self.PiVarList.values():  # k
            timestamp = ts.timestamp
            writerTraceSteps = self.TsThatWritesVar[
                sname]  #mm.possibleRFts(TsThatWritesVar, sname, ts)

            OrClauses = []

            # lookup if the read is registered as a special rf relation
            read_relId_tuple = self.TsNameToRelLookup[ts.name]

            if read_relId_tuple in rf_force_local:
                # ts->tuple->lookup in rf_force (find the write)->back to ref
                writeTsRef = self.relTsLookupDict[
                    rf_force_local[read_relId_tuple]]
                #print writeTsRef.name,ts.name
                assert writeTsRef is not ts
                constraint = mm.build_rf_constraint(sname,
                                                    piVar,
                                                    self.TsThatWritesVar,
                                                    read=ts,
                                                    write=writeTsRef)
                if ONLY_CONSTRAINT_ON_READABLE_PI:
                    constraint = z3.Implies(ts.decodeExpr, constraint)
                OrClauses = [constraint]
                del rf_force_local[read_relId_tuple]

            else:
                for traceStep in writerTraceSteps:  # i
                    if traceStep is ts:
                        continue
                    constraint = mm.build_rf_constraint(sname,
                                                        piVar,
                                                        self.TsThatWritesVar,
                                                        read=ts,
                                                        write=traceStep)
                    if ONLY_CONSTRAINT_ON_READABLE_PI:
                        constraint = z3.Implies(ts.decodeExpr, constraint)
                    OrClauses.append(constraint)
            # special case:
            # read from initial (rf_init)

            if len(OrClauses) == 0:
                print '<E>: no writer for state: ', sname, '. It should at least appear in the init steps.'
                assert False
            elif len(OrClauses) == 1:
                self.ConstraintList.append(OrClauses[0])
            else:
                self.ConstraintList.append(z3.Or(OrClauses))
Beispiel #21
0
 def wp(self, Q):
     """
     wp(while[inv](b){s},Q) == inv and (inv and b => (wp(s,inv))) and (inv and not b => Q)
     See lec7.pdf
     """
     f2 = z3.Implies(z3.And(self.inv, self.b), self.s.wp(self.inv))
     f3 = z3.Implies(z3.And(self.inv, z3.Not(self.b)), Q)
     return z3.simplify(z3.And([self.inv, f2, f3]))
Beispiel #22
0
def check_valid(bounds, bound2s, ref, ref2, pre, lc, rec, s):
    s.add(
        z3.Not(
            z3.And(
                z3.Implies(pre, z3.And(*bounds, z3.And(*ref))),
                z3.Implies(z3.And(*bounds, z3.And(*ref), lc, rec),
                           z3.And(*bound2s, z3.And(*ref2))))))
    res = s.check()
    return res
Beispiel #23
0
    def walk_ite(self, formula, args):
        i = args[0]
        t = args[1]
        e = args[2]

        if self._get_type(formula) == types.BOOL:
            return z3.And(z3.Implies(i, t), z3.Implies(z3.Not(i), e))
        else:
            return z3.If(i, t, e)
Beispiel #24
0
    def walk_ite(self, formula, args, **kwargs):
        i = args[0]
        t = args[1]
        e = args[2]

        if self._get_type(formula).is_bool_type():
            return z3.And(z3.Implies(i, t), z3.Implies(z3.Not(i), e))
        else:
            return z3.If(i, t, e)
Beispiel #25
0
 def solve(self):
     # get puzzle dimensions
     num_rows = len(self.input_grid)
     num_cols = len(self.input_grid[0])
     # declaring matrix of Bool variables
     X = [[z3.Bool("x_%s_%s" % (i, j)) for i in range(num_rows)]
          for j in range(num_cols)]
     # boundary conditions
     instance_c = [z3.If(self.input_grid[i][j] == None,
                         True,
                         X[i][j] == self.input_grid[i][j])
                   for i in range(num_rows) for j in range(num_cols)]
     # sur chaque colonne ou ligne de la grille, il ne peut y avoir plus de deux 0 ou deux 1 consécutifs
     row_combo = [z3.Implies(X[i][j] == X[i][j + 1], z3.Not(X[i][j + 2] == X[i][j]))
                  for j in range(num_cols - 2)
                  for i in range(num_rows)]
     ''' TODO not working
     row_combo = [
         z3.And(
             z3.Or(z3.Not(X[i][j+1]), z3.Not(X[i][j+2])),
             z3.Or(X[i][j], X[i][j+1], z3.Not(X[i][j+2])),
             z3.Or(z3.Not(X[i][j]), z3.Not(X[i][j+1]), X[i][j+2]),
             z3.Or(X[i][j+1], X[i][j+2])
         )
         for j in range(num_cols-2)
         for i in range(num_rows)]
     	'''
     col_combo = [z3.Implies(X[i][j] == X[i + 1][j], z3.Not(X[i + 2][j] == X[i][j]))
                  for i in range(num_cols - 2)
                  for j in range(num_rows)]
     # il y a le même nombre de 0 et de 1 sur chaque ligne et chaque colonne
     combs = set(itertools.permutations(
         [0 for _ in range(num_rows // 2)] + [1 for _ in range(num_rows // 2)],
         r=num_rows))
     row_par = [z3.Or([z3.And([X[i][j] if coefs[j] == 1 else z3.Not(X[i][j])
                               for j in range(num_cols)])
                       for coefs in combs])
                for i in range(num_rows)]
     col_par = [True]
     # il n’y a pas deux lignes (ou deux colonnes) remplies identiquement
     row_eg = [True]
     col_eg = [True]
     # add condition to the solver
     binero_c = row_combo + col_combo + row_par + col_par + row_eg + col_eg
     self.solver.add(instance_c + binero_c)
     # solve
     if self.solver.check() == z3.sat:
         m = self.solver.model()
         r = [[m.evaluate(X[i][j]) for j in range(num_cols)]
              for i in range(num_rows)]
         output_grid = [[1 if r[i][j] == True else 0
                         for j in range(num_cols)]
                        for i in range(num_rows)]
         BineroIO.write_binero(self.PATH + "/output/" + self.filename, output_grid)
     else:
         print("failed to solve")
Beispiel #26
0
    def _float_binary_operator(self, term, op):
        logger.debug('_fbo: %s\n%s', term, self.attrs[term])
        x = self.eval(term.x)
        y = self.eval(term.y)
        z = op(x, y)

        conds = []
        if 'nnan' in self.attrs[term]:
            df = z3.And(z3.Not(z3.fpIsNaN(x)), z3.Not(z3.fpIsNaN(y)),
                        z3.Not(z3.fpIsNaN(z)))
            conds.append(z3.Implies(self.attrs[term]['nnan'], df))

        elif 'nnan' in term.flags:
            conds += [
                z3.Not(z3.fpIsNaN(x)),
                z3.Not(z3.fpIsNaN(y)),
                z3.Not(z3.fpIsNaN(z))
            ]

        if 'ninf' in self.attrs[term]:
            df = z3.And(z3.Not(z3.fpIsInf(x)), z3.Not(z3.fpIsInf(y)),
                        z3.Not(z3.fpIsInf(z)))
            conds.append(z3.Implies(self.attrs[term]['ninf'], df))

        elif 'ninf' in term.flags:
            conds += [
                z3.Not(z3.fpIsInf(x)),
                z3.Not(z3.fpIsInf(y)),
                z3.Not(z3.fpIsInf(z))
            ]

        if 'nsz' in self.attrs[term] or 'nsz' in term.flags:
            # NOTE: this will return a different qvar for each (in)direct reference
            # to this term. Is this desirable?
            b = self.fresh_bool()
            self.add_qvar(b)
            z = op(x, y)

            c = z3.fpIsZero(z)
            if 'nsz' in self.attrs[term]:
                c = z3.And(self.attrs[term]['nsz'], c)

            s = _ty_sort(self.type(term))
            z = z3.If(c, z3.If(b, 0, z3.fpMinusZero(s)), z)

            if isinstance(term, FDivInst):
                c = [z3.Not(z3.fpIsZero(x)), z3.fpIsZero(y)]
                if 'nsz' in self.attrs[term]:
                    c.append(self.attrs[term]['nsz'])

                z = z3.If(
                    z3.And(c),
                    z3.If(b, z3.fpPlusInfinity(s), z3.fpMinusInfinity(s)), z)

        return self._conditional_value(conds, z, term.name)
Beispiel #27
0
    def split_query(self):
        """Split query if it is not simple into a query and a rule"""

        assert (self.is_query())
        if self.is_simple_query():
            return (self, None)

        q = z3.Bool("simple!!query")
        query = HornRule(z3.Implies(q, z3.BoolVal(False)))
        rule = HornRule(
            z3.ForAll(self._bound_constants,
                      z3.Implies(z3.And(*self.body()), q)))
        return query, rule
Beispiel #28
0
    def _consistency_constraints(self):
        conjuncts = []

        for v in self._domain:
            if (v.unique):
                expr = z3.Implies(Formula._id(v), Formula._id(v.opposite()))
            else:
                expr = z3.Implies(z3.Not(Formula._id(v)),
                                  z3.Not(Formula._id(v.opposite())))

            conjuncts.append(expr)

        return z3.And(conjuncts)
Beispiel #29
0
def z3_check_implies(e1, e2, for_all=False):
    """Check whether there is a solution to the implication of the two expressions"""
    solver.push()
    if for_all:
        solver.add(z3.Not(z3.Implies(e1, e2)))
    else:
        solver.add(z3.Implies(e1, e2))
    result = solver.check()
    solver.pop()

    if for_all:
        return result.r == z3.Z3_L_FALSE
    else:
        return result.r == z3.Z3_L_TRUE
Beispiel #30
0
 def _idsSendRules(self):
     p_0 = z3.Const('%s_p_0' % (self.node), self.ctx.packet)
     n_0 = z3.Const('%s_n_0' % (self.node), self.ctx.node)
     n_1 = z3.Const('%s_n_1' % (self.node), self.ctx.node)
     t_0 = z3.Int('%s_t_0' % self.node)
     t_1 = z3.Int('%s_t_1' % self.node)
     self.constraints.append(z3.ForAll([n_0, p_0, t_0], z3.Implies(self.ctx.send(self.node, n_0, p_0, t_0), \
                                z3.Exists([n_1, t_1], \
                                  z3.And(self.ctx.recv(n_1, self.node, p_0, t_1), \
                                         t_1 < t_0)))))
     self.constraints.append(z3.ForAll([n_0, p_0, t_0], \
             z3.Implies(z3.And(self.ctx.send(self.node, n_0, p_0, t_0), \
                               self.suspicious(p_0)), \
                         n_0 == self.shunt)))