def expr_count_of(self, char):
     """Counts char in string, returns expression.
     
     Returns a z3 expression representing the number of times char appears in
     the string.
     """
     return (z3.Sum([z3.If(bv == ord(char), 1, 0) for bv in self.bitvecs]))
def applications_to_solver(applications):
    # try building applications one by one
    solver = z3.Solver()
    solver_list = []

    for application in applications:
        l, m, r = application.split(' ')
        l_c = z3.Sum( [z3.Int(elem) for elem in l.split('+')] )
        try:
            r_c = float(r)
            r_c_lb = r_c - 1
            r_c_ub = r_c + 1
        except:
            r_c = z3.Int(r)

        # all of type elem_1 <= elem_2
        if m == '<=':
            solver.add(l_c <= r_c)
            solver_list.append(l_c <= r_c)
        # all of type elem == int
        elif m == '==':
            # NOTE: works only if we allow a margin of error -- is this coming from the conversion from mean to sum?
            solver.add(l_c >= r_c_lb)
            solver.add(l_c <= r_c_ub)
            solver_list.append(l_c >= r_c_lb)
            solver_list.append(l_c <= r_c_ub)
            # solver.add(l_c == r_c)
            # solver_list.append(l_c == r_c)
        # all of type elem >= 0
        elif m == '>=':
            solver.add(l_c >= r_c)
            solver_list.append(l_c >= r_c)

    return(solver, solver_list)
def main(nanobots):
    solver = z3.Optimize()
    bx = z3.Int("x")
    by = z3.Int("y")
    bz = z3.Int("z")
    d = z3.Int("d")

    bots = []
    for i, bot in enumerate(nanobots):
        print("adding bot {} to z3".format(i))
        b = z3.Int("b{:04}".format(i))
        solver.add(b == z3.If(manhattan_distance((bx, by, bz), (bot.x, bot.y, bot.z)) <= bot.radius, 1, 0))
        bots.append(b)

    print("adding constraints")
    solver.add(d == manhattan_distance((bx, by, bz), (0, 0, 0)))
    solver.maximize(z3.Sum(*bots))
    solver.minimize(d)

    print("solving...")
    print(solver.check())

    model = solver.model()
    print("answer:")
    print(model[d])
Beispiel #4
0
    def getNearestFeasible(self, coord):
        # get the variables corresponding to the axis names
        for i in self.axis_names:
            locals()[i] = Globals.z3variables[i]

        # Convert into parameters
        rpp = self.search.coordToPerfParams(coord)
        for i, name in enumerate(self.axis_names):
            if not self.z3IsNumeric(i):
                rpp[name] = Globals.z3types[name].index(rpp[name])

        # create a new scope
        self.optim.push()

        # Get a possible point that minimizes the 1-norm distance to this random point
        # forget the booleans

        l = []
        for name in self.axis_names:
            if not z3.is_bool(locals()[name]):
                l.append(self.z3abs(locals()[name] - rpp[name]))
        definition = z3.Sum(l)
        self.optim.minimize(definition)
        # For some reason, it does not work with a list comprehension.
        #        self.optim.minimize( z3.Sum( [ self.z3abs( locals()[name] - rpp[name] )for name in self.axis_names  if not z3.is_bool( locals()[name] ) ] ) )
        if z3.unsat == self.optim.check():
            return None
        model = self.optim.model()

        # restore the state (exit the scope)
        self.optim.pop()
        return self.z3ToPoint(model)
Beispiel #5
0
def Sum(*args: BitVec) -> BitVec:
    """Create sum expression.

    :return:
    """
    raw = z3.Sum([a.raw for a in args])
    annotations = []  # type: Annotations
    bitvecfuncs = []

    for bv in args:
        annotations += bv.annotations
        if isinstance(bv, BitVecFunc):
            bitvecfuncs.append(bv)

    if len(bitvecfuncs) >= 2:
        return BitVecFunc(raw=raw,
                          func_name=None,
                          input_=None,
                          annotations=annotations)
    elif len(bitvecfuncs) == 1:
        return BitVecFunc(
            raw=raw,
            func_name=bitvecfuncs[0].func_name,
            input_=bitvecfuncs[0].input_,
            annotations=annotations,
        )

    return BitVec(raw, annotations)
Beispiel #6
0
    def _link_affine(self, phi, include_bterm=True):
        assert isinstance(phi, amnet.Affine) or \
               isinstance(phi, amnet.Linear)

        m, n = phi.w.shape
        assert m >= 1 and n >= 1

        # extract children
        yvar = self.var_of(phi)
        xvar = self.var_of(phi.x)
        assert (len(yvar) == m) and (len(xvar) == n)

        # go row-by-row of w
        for i in range(m):
            rowi = phi.w[i, :]
            assert len(rowi) == n

            rowsum = z3.Sum(
                [wij * xj for wij, xj in izip(rowi, xvar) if wij != 0])

            if include_bterm:
                assert isinstance(phi, amnet.Affine), \
                    'Warning: tried to encode bterm in non-Affine'
                self.solver.add(yvar[i] == (rowsum + phi.b[i]))
            else:
                self.solver.add(yvar[i] == rowsum)
Beispiel #7
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 #8
0
def incidence_sums(petrinet,
                   variables,
                   subnet_transitions="all",
                   reverse=False):
    if subnet_transitions == "all":
        subnet_transitions = set(range(petrinet.num_transitions))

    sums = []

    for p in range(petrinet.num_places()):
        nonzero = petrinet.transitions_set({p}, reverse)
        incidence_row = [(petrinet.get_post(p, t) - petrinet.get_pre(p, t),
                          variables[t]) for t in nonzero
                         if t in subnet_transitions]

        sum_elements = [
            expression(coeff, var) for coeff, var in incidence_row
            if coeff != 0
        ]

        curr_sum = z3.Sum(
            sum_elements) if len(sum_elements) > 0 else z3.IntVal(0)

        sums.append(curr_sum)

    return sums
Beispiel #9
0
    def add_cage_constraints(self, cage):
        cage_sum = int(cage[:2])
        cage_vars = []
        for r, c in zip(cage[2::2], cage[3::2]):
            cage_vars.append(self._grid[int(r) - 1][int(c) - 1])

        self._solver.add(z3.Distinct(cage_vars))
        self._solver.add(z3.Sum(cage_vars) == cage_sum)
Beispiel #10
0
def add_killer_cage(s, cage_coords, cage_sum):
    '''Add a single killer sudoku cage.
    Takes a list of (row, col) coordinates and the sum
    '''
    cagecells = [X[i][j] for i, j in cage_coords]
    # Digits dont repeat within cages
    s.add(z3.Distinct(cagecells))
    s.add(z3.Sum(cagecells) == cage_sum)
Beispiel #11
0
def do_POPCOUNT(op, stack, state):
    b, = pop_values(stack, state)

    n = b.size()
    bits = [z3.Extract(i, i, b) for i in range(n)]
    bvs = [z3.Concat(z3.BitVecVal(0, n - 1), b) for b in bits]
    nb = z3.Sum(*bvs)

    stack.append(z3.simplify(nb))
Beispiel #12
0
def Sum(*args: BitVec) -> BitVec:
    """Create sum expression.

    :return:
    """
    nraw = z3.Sum([a.raw for a in args])
    annotations = []  # type: Annotations
    for bv in args:
        annotations += bv.annotations
    return BitVec(nraw, annotations)
Beispiel #13
0
    def _bin_packing_constraints(manifest, storage, color, volume):
        constraint = []
        # heuristic = []
        limits = [z3.And(0 <= v, v <= s['volume_left']) for v, s in zip(volume, storage)]

        for i, stor in enumerate(storage):
            summation = z3.Sum([z3.If(col == i, vol, 0) for col, vol in zip(color, volume)])
            constraint.append(summation <= stor['volume_left'])
            # heuristic.append(  z3.Sum([z3.If(z3.Or(summation==0, summation==stor['volume_left']), 1, 0)]) )
        return limits + constraint  # , z3.Sum(heuristic)
Beispiel #14
0
 def setup_line(self, x0, y0, dx, dy, sum):
     if sum == 0:
         return
     vs = []
     x, y = x0 + dx, y0 + dy
     while (x, y) in self.cells:
         vs.append(self.cells[x, y])
         x += dx
         y += dy
     self.solver.add(z3.Distinct(vs))
     self.solver.add(z3.Sum(vs) == sum)
Beispiel #15
0
        def make_hash_equation(pj: int, var_b: Tuple[int], b1: int):
            domain_bit_count = int(ceil(log2(pj)))
            bc = int(ceil(log2(pj + 1)))
            slices = get_slices(domain_bit_count)

            return z3.URem(
                z3.Sum([
                    z3.ZeroExt(bc - s.size(), s) * z3.BitVecVal(var_b[i], bc)
                    for i, s in enumerate(slices)
                ]) + z3.BitVecVal(b1, bc),
                z3.BitVecVal(pj, bc)) == z3.BitVecVal(0, bc)
Beispiel #16
0
def agreesAtLeastNTimes(inputOutputList, expressionValues, gene, aVars, rVars,
                        n):

    both = [
        totalAgreement(inputOutputList[p], gene, aVars, rVars,
                       expressionValues, p)
        for p in range(len(inputOutputList))
    ]
    encodings = [both[i][0] for i in range(len(both))]
    scoreValues = [both[i][1] for i in range(len(both))]

    return z3.And(z3.And(encodings), z3.Sum(scoreValues) >= n)
Beispiel #17
0
    def largest_clique(self, timeout=120):
        if z3 is None:
            raise ImportError()
        solver = z3.Optimize()
        solver.set("timeout", timeout)
        vars = {}
        # rev = {}
        start = time.clock()
        m = z3.Int(name="cliquesize")
        for v in self.nodes_iter():
            vars[v] = z3.Int(name="node{0}".format(v))
            # rev[vars[v]] = v
            solver.add(vars[v] <= 1)
            solver.add(vars[v] >= 0)

        solver.add(z3.Sum([vars[v] for v in self.nodes_iter()]) >= m)
        # solver.add(z3.Or([vars[v] == 1 for v in self.nodes_iter()]))
        adj = self.adj
        for u in self.nodes_iter():
            for v in self.nodes_iter():
                if u < v and u not in adj[v]:
                    solver.add(z3.Or(vars[u] == 0, vars[v] == 0))
            if timeout != 0 and time.clock() - start >= timeout:
                return None
        r = None
        try:
            r = solver.maximize(m)
            solver.check()
        except z3.Z3Exception as e:
            logging.error(e.message)
        if r is None:
            return None

        res = solver.lower(r)
        # assert(str(res) != 'epsilon' and str(res) != 'unsat' and isinstance(res, z3.IntNumRef) and res.as_long() >= 1)
        if str(res) == 'epsilon' or str(res) == 'unsat':
            logging.error(res)
        elif not isinstance(res, z3.IntNumRef):
            logging.error("not an int")
        elif res.as_long() < 1:
            logging.error("clique result < 1")
        else:
            cl = [
                k for (k, v) in vars.items()
                if solver.model()[v].as_long() == 1
            ]
            if len(cl) != res.as_long():
                logging.error("{0} vs. {1}".format(len(cl), res.as_long()))
                # assert(len(cl) == res.as_long())
                return None
            # print cl
            return cl
        return None
def solve_part_2(nanobots):
    s = z3.Optimize()
    x = z3.Int('x')
    y = z3.Int('y')
    z = z3.Int('z')
    d = z3.Int('d')
    dists = [z3.Int(i) for i in range(len(nanobots))]
    for i, bot in enumerate(nanobots):
        dists[i] = z3.If(dist2(bot['pos'], (x, y, z)) <= bot['r'], 1, 0)
    s.maximize(z3.Sum(*dists))
    s.add(d == dist2((x, y, z), (0, 0, 0)))
    s.minimize(d)
    s.check()
    return s.model()[d]
Beispiel #19
0
def _solve(
    solver: z3.Optimize, channels: List[Channel], devices: List[Device]
) -> Tuple[Problem, z3.Model]:
    problem = _problem(solver, freqs=[c.frequency for c in channels], devices=devices)
    if solver.check() != z3.sat:
        # TODO: consider getting an unsat core
        raise ValueError(f"No valid assignment possible, add more devices")

    # find the minimal number of devices that cover all frequencies
    # it is faster to do this iteratively than to offload these to
    # smt constraints. do this in reverse so we end up assigning
    # the lowest numbered devices
    for r in problem.ranges[::-1]:
        # to control the device placements adjust the order they're eliminated from
        # the solution. for example, this will prefer devices that have a smaller
        # minimum sample rate over devices with a larger one:
        # for r, _ in zip(problem.ranges, problem.devices), key=lambda x: -x[1].min_sample_rate
        solver.push()
        solver.add(r == 0)
        if solver.check() != z3.sat:
            solver.pop()
            break

    devices_required = z3.Sum([z3.If(r > 0, 1, 0) for r in problem.ranges])

    # minimize the sum of frequency ranges
    solver.minimize(z3.Sum(*problem.ranges))
    # and the frequency, just to produce deterministic results
    solver.minimize(z3.Sum(*problem.lower_freq))

    assert solver.check() == z3.sat

    model = solver.model()
    print(f"Devices required: {model.eval(devices_required)}", file=sys.stderr)

    return problem, model
Beispiel #20
0
def generate_constraints(capacity, sizes, endpoints, caches):
    print('Generate constraints...')

    print('SERVE_SUM')
    SERVE_SUM = SERVE == z3.Sum([
        find_max(e.L.items(), v, e.L_D) * ratio
        for e, _ in ((e, print('.', end='', flush=True)) for e in endpoints)
        for v, ratio in e.requests.items()
    ])
    print()
    print('CAPACITY')
    CAPACITY = [
        z3.Sum([z3.If(has_video(v, c), sizes[v], 0)
                for v in videos]) == capacity for c, videos in caches.items()
    ]
    VIDEO = z3.Int('VIDEO')
    print('IMP')
    IMP = [
        z3.ForAll([VIDEO],
                  z3.Implies(has_video(VIDEO, c),
                             z3.Or([VIDEO == v for v in videos])))
        for c, videos in caches.items()
    ]
    return [CAPACITY, SERVE_SUM, IMP]
Beispiel #21
0
def find_sum_combo_with_z3(numbers, n, target=2020):
    solver = z3.Solver()

    symvars = [z3.Int(f'sv_{i}') for i in range(n)]
    solver.add(z3.Sum(symvars) == target)
    solver.add(z3.Distinct(symvars))

    for sv in symvars:
        solver.add(z3.Or([sv == number for number in numbers]))

    if str(solver.check()) == 'sat':
        print(f'Model = {solver.model()}')
        return mult(solver.model()[sv].as_long() for sv in symvars)
    else:
        print('No solution')
        return -1
Beispiel #22
0
def prepare_solver(instance: Instance) -> Tuple[z3.Solver, Dict[int, str]]:
    solver = z3.Solver()
    variables = []
    ingredient_indices: Dict[str, int] = {}
    ingredient_names: Dict[int, str] = {}
    num_of_meals = len(MEAL_NAMES)
    # create a list of variables for each ingredient
    for ingredient_id in range(len(instance.ingredients)):
        meal_vars = []
        name = instance.ingredients[ingredient_id].name
        ingredient_indices[name] = ingredient_id
        ingredient_names[ingredient_id] = name
        for meal_id in range(num_of_meals):
            var_name = make_variable_name(meal_id, ingredient_id)
            var = z3.Int(var_name)
            solver.add(var >= 0)
            meal_vars.append(z3.ToReal(var))
        variables.append(meal_vars)
    # add constraints for food conflicts
    for food1, food2 in instance.conflicts:
        food1_id = ingredient_indices[food1]
        food2_id = ingredient_indices[food2]
        food1_vars = variables[food1_id]
        food2_vars = variables[food2_id]
        for var1, var2 in zip(food1_vars, food2_vars):
            solver.add(z3.Or(var1 == 0, var2 == 0))
    # add constraints for total amount of substances
    macro_sums = {}
    for macro in instance.macros:
        macro_sums[macro] = 0.0
    for ingredient_vars, ingredient in zip(variables, instance.ingredients):
        ingredient_sum = z3.Sum(ingredient_vars)
        for macro in instance.macros:
            macro_sums[macro] += ingredient_sum * ingredient.macros[macro]
    for target in instance.targets:
        macro_sum = macro_sums[target.macro]
        solver.add(macro_sum >= target.min)
        solver.add(macro_sum <= target.max)
    # ensure that meals are not empty
    num_of_ingredients = len(variables)
    for meal_id in range(num_of_meals):
        meal_conditions = []
        for ingredient_id in range(num_of_ingredients):
            meal_conditions.append(variables[ingredient_id][meal_id] > 0)
        solver.add(z3.Or(meal_conditions))

    return solver, ingredient_names
Beispiel #23
0
 def __init__(self, variable_names: Sequence[str],
              qualities: Sequence[float]):
     assert len(variable_names) == len(qualities)
     # Improve optimizer performance by sorting qualities decreasingly; adapt order of variable names accordingly:
     qualities, variable_names = zip(
         *sorted(zip(qualities, variable_names), key=lambda x: -x[0]))
     self.qualities = qualities
     self.variables = [expr.Variable(name=x) for x in variable_names]
     self.constraints = []
     self.optimizer = z3.Optimize()
     # Direct multiplication between bool var and real quality returns wrong type (BoolRef) if quality is 1,
     # so we use "If" instead (multiplication is transformed to such an expression anyway):
     objective = z3.Sum([
         z3.If(var.get_z3(), q, 0)
         for (q, var) in zip(qualities, self.get_variables())
     ])
     self.objective = self.optimizer.maximize(objective)
     self.optimizer.push()  # restore point for state without constraints
    def objective_function(self):
        """
        Objective function is a weighted combination of gate errors and decoherence errors
        """
        import z3

        self.fidelity_terms = [self.gate_fidelity[gate] for gate in self.gate_fidelity]
        self.coherence_terms = []
        for q in self.qubit_lifetime:
            val = -self.qubit_lifetime[q] / min(self.bp_t1_time[q], self.bp_t2_time[q])
            self.coherence_terms.append(val)

        all_terms = []
        for item in self.fidelity_terms:
            all_terms.append(self.weight_factor * item)
        for item in self.coherence_terms:
            all_terms.append((1 - self.weight_factor) * item)
        self.opt.maximize(z3.Sum(all_terms))
Beispiel #25
0
def orderG(G, offset):
    solver = z3.Solver()
    solver.set('timeout', 1000)  # Timeout in one minute
    V, E = G.nodes, G.edges

    # Assignment: uniquely give vertical positions ([0, 1, ..., N-1]) to the vertices in G.
    Positions = [z3.Int('v' + n) for n in V]  # positions
    assignment = dict(zip(V, Assignment))  # vertex -> position
    solver.add(z3.Distinct(Positions))  # Uniqueness condition on Positions

    for pos in Positions:
        solver.add(position >= 0)  # Two range constraints on Positions
        solver.add(position < len(V))

    # Objective function CumLengths: A weighted sum of the edge lengths
    WeightedLengths = []
    for n1, n2 in E:
        pos1, pos2 = assignment[n1], assignment[n2]
        weight = E[n1, n2]['connections']
        WeightedLengths.append(weight * Abs(pos1 - pos2))
    Objective = z3.Sum(*WeightedLengths)  # Objective formula

    # Optimization
    length_contraint = sys.maxsize
    current_best = dict(zip(Positions,
                            range(len(Positions))))  # Default assignment
    history = [current_best.evaluate(Objective).as_long()]
    while True:
        solver.add(Objective < length_constraint)
        result = solver.check()
        if result != z3.sat: break
        current_best = solver.model()
        length_constraint = current_best.evaluate(
            Objective).as_long()  # Tighter constraint
        history.append(length_constraint)

    Solution = [(v, current_best[v].as_long() + offset) for v in Assignment]
    print(f'Solution: {Solution}')
    print(f'Is optimum: {result == z3.unsat}')
    print(f'Optimum CumLength: {length_constraint}')
    print('Reduction history:', *history)
    return Solution
Beispiel #26
0
def encode_network(weights, biases, z3_input):
    """
    Returns a z3 expression representing the output of the dnn when applied to the input represented
    by the list of z3 RealSort constants `z3_input`. The dnn is characterised by the given array of
    weights and biases, where `weights` is a list of weight matrices for each non-input layer, and
    `biases` is a list of corresponding bias vectors. The matrices are represented as lists of
    lists in a column first manner, vecorts as lists. Returns a list of z3 expressions representing
    the output.
    """

    # z3 consts for values of each layer
    z3_nodes = [z3_input]
    for w, b in zip(weights, biases):
        z3_nodes.append([
            z3.Sum([w[j][i] * z3_nodes[-1][j]
                    for j in range(len(w[i]))]) + b[i] for i in range(len(b))
        ])
        z3_nodes[-1] = [z3.If(z >= 0, z, 0) for z in z3_nodes[-1]]

    return z3_nodes[-1]
Beispiel #27
0
    def _coalesing_constraints(manifest, storage, color, volume):
        constraint = []
        # heuristic  = z3.Int('coalesing_heuristic')

        chemical_dict = {}
        for s in storage:
            for c in s['chemicals']:
                name = c['chemical']
                if not name in chemical_dict:
                    chemical_dict[name] = 0
                chemical_dict[name] += c['total_volume'] - c['current_volume']

        for key, value in chemical_dict.items():
            # value=0 means no coalesing, therefore no need to have a constraint.
            if value != 0:
                summation = z3.Sum([m['volume'] - v for m, v in zip(manifest, volume) if m['chemical'] == key])
                constraint.append(summation <= value)
                # heuristic = heuristic + summation

        return constraint  # , heuristic
Beispiel #28
0
 def _optimize(self):
     """
 The current implementation of the optimization is based on minimizing the number of selected cpvs, by asking the SAT solver to minimize that number.
 """
     optimize = z3.Optimize()
     cpvs = set()
     packages = set()
     # add the constraint
     for k, v in self._loaded_map.items():
         if (v[0] is dep_solver.kind.cpv):
             p = self._repo.get_package(k)
             cpvs.add(k)
             packages.add(p)
             optimize.add(self._z3_translator.visit(p.get_spc()))
         else:
             optimize.add(self._z3_translator.visit(self._repo.get_cp(k)))
     # define the optimization criteria
     optimize.minimize(
         z3.Sum(
             tuple(
                 z3.If(self._z3_translator.visit(cpv), 1, 0)
                 for cpv in cpvs)))
     # forbid to use non loaded packages
     simplify = gzl.substitutionVisitor({}).visit
     for p in packages:
         to_disable = p._dep_package.difference(cpvs)
         if (len(to_disable) is not 0):
             optimize.add(
                 self._z3_translator.visit(
                     simplify(gzl.Not(gzl.Or(*to_disable)))))
             cpvs.update(to_disable)
     # get the model
     optimize.check()
     self._solution = optimize.model()
     self._solution = {
         str(var)
         for var in self._z3_translator._var_map.values()
         if (self._solution[var])
     }
Beispiel #29
0
def solve_weights_problem(N):
    solver = z3.Solver()
    weights = [z3.Int("w" + str(i)) for i in range(N)]
    for i in range(N):
        # Weights positive
        solver.add(weights[i] > 0)
        for j in range(i + 1, N):
            # Weights not equal
            solver.add(weights[i] != weights[j])
            # Sum of these is equal to the sum of some other subset
            others = weights[:i] + weights[i + 1:j] + weights[j + 1:]
            sums = [z3.Sum(otherset) for otherset in powerset(others)]
            solver.add(z3.Or([weights[i] + weights[j] == sum for sum in sums]))

    # Solve the constraints.
    ## Uncomment to print assertions
    # print(f"Constraints: {solver.assertions()}")
    result = str(solver.check())
    print(f"Result: {result}")
    if result == 'sat':
        print(f"Model: {solver.model()}")
    return result
Beispiel #30
0
def incidence_sums(petrinet,
                   variables,
                   subnet_transitions='all',
                   reverse=False):
    pre_matrix, post_matrix = petrinet
    num_places, num_transitions = pre_matrix.shape

    if subnet_transitions == 'all':
        subnet_transitions = set(range(num_transitions))

    if reverse:
        pre_matrix, post_matrix = post_matrix, pre_matrix

    sums = []

    for p in range(num_places):
        if config.representation_mode == config.DENSE:
            nonzero = np.union1d(pre_matrix[p].getA1().nonzero()[0],
                                 post_matrix[p].getA1().nonzero()[0])
        elif config.representation_mode == config.SPARSE:
            nonzero = np.union1d(
                pre_matrix.getrow(p).nonzero()[1],
                post_matrix.getrow(p).nonzero()[1])

        incidence_row = [(post_matrix[p, t] - pre_matrix[p, t], variables[t])
                         for t in nonzero if t in subnet_transitions]

        sum_elements = [
            _expression(coeff, var) for coeff, var in incidence_row
            if coeff != 0
        ]

        curr_sum = z3.Sum(
            sum_elements) if len(sum_elements) > 0 else z3.IntVal(0)

        sums.append(curr_sum)

    return sums