Ejemplo n.º 1
0
def atLeastOneRule(myBools, x, graph):
    n = len(graph.items())

    for i in range(0, n):  # each row
        x.add(Or(myBools[i]))

    return x
Ejemplo n.º 2
0
    def concrete_transition_to_abstract(cls, nodes_from, abstract_witness):
        kripke = abstract_witness.get_kripke()
        tr = kripke.get_tr_formula()

        def sub_src(_tr, src_node):
            return _tr.assign_state(src_node.concrete_label)

        tr_from_concs = [sub_src(tr, node) for node in nodes_from]

        dst_vars = tr_from_concs[0].get_var_vectors()[0]
        in_tag = tr.get_input_vectors()[1]
        abs_formula = abstract_witness.get_descriptive_formula().substitute(
            dst_vars, 0).substitute_inputs(in_tag, 0)

        n_flags = len(tr_from_concs)
        flags = [Bool('f' + str(i)) for i in xrange(n_flags)]

        tr_flagged = [
            Or(Not(flags[i]), tr_from_concs[i].get_qbf().get_prop())
            for i in xrange(n_flags)
        ]
        all_tr_flagged = simplify(And(*tr_flagged))

        f_inner = simplify(
            And(all_tr_flagged,
                abs_formula.get_qbf().get_prop()))
        q_list = abs_formula.get_qbf().get_q_list()
        f_qbf = QBF(f_inner, q_list)
        f = FormulaWrapper(f_qbf, [dst_vars], tr.get_input_vectors())

        i, model = QbfSolverSelector.QbfSolverCtor().incremental_solve_flags(
            f, flags, sat)
        if i is False:
            return False
        return nodes_from[i], next(get_states(model, dst_vars, kripke))
Ejemplo n.º 3
0
    def constrain_no_inside_diagonal(y, x):
        """Add constraints for diagonally touching cells.

    "Inside" cells may not diagonally touch each other unless they also share
    an adjacent cell.
    """
        nw = sg.grid[Point(y, x)]
        ne = sg.grid[Point(y, x + 1)]
        sw = sg.grid[Point(y + 1, x)]
        se = sg.grid[Point(y + 1, x + 1)]
        sg.solver.add(
            Implies(And(nw == sym.I, se == sym.I), Or(ne == sym.I,
                                                      sw == sym.I)))
        sg.solver.add(
            Implies(And(ne == sym.I, sw == sym.I), Or(nw == sym.I,
                                                      se == sym.I)))
Ejemplo n.º 4
0
def get_state(doubles, browser):
    if browser == "node":
        browser = "chrome"
    elif browser not in ("chrome", "firefox", "safari"):
        raise ValueError(f"invalid browser {browser}")
    if browser == "chrome":
        doubles = doubles[::-1]

    # from the doubles, generate known piece of the original uint64
    generated = [from_double(double, browser) for double in doubles]

    # setup symbolic state for xorshift128+
    ostate0, ostate1 = BitVecs("ostate0 ostate1", 64)
    sym_state0 = ostate0
    sym_state1 = ostate1
    solver = Solver()
    conditions = []

    # run symbolic xorshift128+ algorithm for three iterations
    # using the recovered numbers as constraints
    for val in generated:
        sym_state0, sym_state1, ret_conditions = sym_xs128p(
            solver, sym_state0, sym_state1, val, browser)
        conditions += ret_conditions
    if solver.check(conditions) == sat:
        # get a solved state
        m = solver.model()
        state0 = m[ostate0].as_long()
        state1 = m[ostate1].as_long()
        solver.add(Or(ostate0 != m[ostate0], ostate1 != m[ostate1]))
        if solver.check(conditions) == sat:
            print("WARNING: multiple solutions found! use more doubles!")
        return state0, state1
    else:
        raise ValueError("unsat model")
Ejemplo n.º 5
0
def all_ret_val_used_constraint(env: Env) -> Constraint:
    I, C, F, P, _, o = env

    for f in F:
        # TODO Check if there's any performance gain from verifying if p is in
        # TODO Also, remove kind check if we're only checking for line equality
        # f.params.
        constr = Or([f.line == p.line \
                     for p in P
                     if p not in [q for q in f.params if p.kind == q.kind]
                     #\ and f.kind == p.kind # unplugable components
        ], f.ctx)
        if f.kind == o.kind:
            yield Or(constr, f.line == o.line, f.ctx)
        else:
            yield constr
 def scheduling_constraints(self):
     """
     DAG scheduling constraints optimization
     Sets overlap indicator variables
     """
     for gate in self.gate_start_time:
         for dep_gate in self.dag.successors(gate):
             if not dep_gate.type == 'op':
                 continue
             if isinstance(dep_gate.op, Measure):
                 continue
             if isinstance(dep_gate.op, Barrier):
                 continue
             fin_g = self.gate_start_time[gate] + self.gate_duration[gate]
             self.opt.add(self.gate_start_time[dep_gate] > fin_g)
     for g_1 in self.xtalk_overlap_set:
         for g_2 in self.xtalk_overlap_set[g_1]:
             if len(g_2.qargs
                    ) == 2 and self.gate_id[g_1] > self.gate_id[g_2]:
                 # Symmetry breaking: create only overlap variable for a pair
                 # of gates
                 continue
             s_1 = self.gate_start_time[g_1]
             f_1 = s_1 + self.gate_duration[g_1]
             s_2 = self.gate_start_time[g_2]
             f_2 = s_2 + self.gate_duration[g_2]
             # This constraint enforces full or zero overlap between two gates
             before = (f_1 < s_2)
             after = (f_2 < s_1)
             overlap1 = And(s_2 <= s_1, f_1 <= f_2)
             overlap2 = And(s_1 <= s_2, f_2 <= f_1)
             self.opt.add(Or(before, after, overlap1, overlap2))
             intervals_overlap = And(s_2 <= f_1, s_1 <= f_2)
             self.opt.add(
                 self.overlap_indicator[g_1][g_2] == intervals_overlap)
Ejemplo n.º 7
0
def add_nurikabe_constraints(sym, sg, rc):
    """Add the nurikabe constraints (one connected sea with no 2x2 regions)."""
    # There must be only one sea, containing all black cells.
    sea_id = Int("sea-id")
    for p in sg.lattice.points:
        sg.solver.add(sg.cell_is(p, sym.W) == (rc.region_id_grid[p] != sea_id))

    # Constrain sea_id to be the index of one of the points in
    # the smallest area, among those areas of size greater than 4.
    area_to_points = defaultdict(list)
    for p in sg.lattice.points:
        area_to_points[AREAS[p.y][p.x]].append(p)
    area_points = min((ps for ps in area_to_points.values() if len(ps) > 4),
                      key=len)
    sg.solver.add(
        Or(*[sea_id == sg.lattice.point_to_index(p) for p in area_points]))

    # The sea is not allowed to contain 2x2 areas of black cells.
    for sy in range(HEIGHT - 1):
        for sx in range(WIDTH - 1):
            pool_cells = [
                sg.grid[Point(y, x)] for y in range(sy, sy + 2)
                for x in range(sx, sx + 2)
            ]
            sg.solver.add(
                Not(And(*[Not(cell == sym.W) for cell in pool_cells])))
Ejemplo n.º 8
0
    def __add_shape_instance_constraints(self):  # pylint: disable=R0914
        int_vals = {}
        for i in range(max(len(self.__lattice.points), len(self.__variants))):
            int_vals[i] = IntVal(i)

        quadtree = ExpressionQuadTree(self.__lattice.points)
        for instance_id in [
                self.__lattice.point_to_index(p) for p in self.__lattice.points
        ]:
            quadtree.add_expr((HAS_INSTANCE_ID, instance_id),
                              lambda p, i=instance_id: fast_eq(
                                  self.__shape_instance_grid[p], int_vals[i]))
            quadtree.add_expr((NOT_HAS_INSTANCE_ID, instance_id),
                              lambda p, i=instance_id: fast_ne(
                                  self.__shape_instance_grid[p], int_vals[i]))
        for shape_index in range(len(self.__variants)):
            quadtree.add_expr((HAS_SHAPE_TYPE, shape_index),
                              lambda p, i=shape_index: fast_eq(
                                  self.__shape_type_grid[p], int_vals[i]))

        root_options = defaultdict(list)
        for shape_index, variants in enumerate(self.__variants):  # pylint: disable=R1702
            for variant in variants:
                for root_point in self.__lattice.points:
                    instance_id = self.__lattice.point_to_index(root_point)
                    point_payload_tuples = []
                    for offset_vector, payload in variant.offsets_with_payloads:
                        point = root_point.translate(offset_vector)
                        if point not in self.__shape_instance_grid:
                            point_payload_tuples = None
                            break
                        point_payload_tuples.append((point, payload))
                    if point_payload_tuples:
                        and_terms = []
                        for point, payload in point_payload_tuples:
                            and_terms.append(
                                quadtree.get_point_expr(
                                    (HAS_INSTANCE_ID, instance_id), point))
                            and_terms.append(
                                quadtree.get_point_expr(
                                    (HAS_SHAPE_TYPE, shape_index), point))
                            if self.__shape_payload_grid:
                                and_terms.append(
                                    self.__shape_payload_grid[point] ==
                                    payload)
                        and_terms.append(
                            quadtree.get_other_points_expr(
                                (NOT_HAS_INSTANCE_ID, instance_id),
                                [t[0] for t in point_payload_tuples]))
                        root_options[root_point].append(fast_and(*and_terms))
        for p in self.__lattice.points:
            instance_id = self.__lattice.point_to_index(p)
            not_has_instance_id_expr = quadtree.get_other_points_expr(
                (NOT_HAS_INSTANCE_ID, instance_id), [])
            or_terms = root_options[p]
            if or_terms:
                or_terms.append(not_has_instance_id_expr)
                self.__solver.add(Or(*or_terms))
            else:
                self.__solver.add(not_has_instance_id_expr)
Ejemplo n.º 9
0
    def __add_single_loop_constraints(self):
        solver = self.__symbol_grid.solver
        sym: LoopSymbolSet = self.__symbol_grid.symbol_set

        cell_count = len(self.__symbol_grid.grid)

        for p in self.__symbol_grid.grid:
            v = Int(f"log-{LoopConstrainer._instance_index}-{p.y}-{p.x}")
            solver.add(v >= -cell_count)
            solver.add(v < cell_count)
            self.__loop_order_grid[p] = v

        solver.add(Distinct(*self.__loop_order_grid.values()))

        for p, cell in self.__symbol_grid.grid.items():
            li = self.__loop_order_grid[p]

            solver.add(If(sym.is_loop(cell), li >= 0, li < 0))

            for idx, d1, d2 in self.__all_direction_pairs():
                pi = p.translate(d1)
                pj = p.translate(d2)
                if pi in self.__loop_order_grid and pj in self.__loop_order_grid:
                    solver.add(
                        Implies(
                            And(cell == idx, li > 0),
                            Or(self.__loop_order_grid[pi] == li - 1,
                               self.__loop_order_grid[pj] == li - 1)))
Ejemplo n.º 10
0
def create_random_query(num_functions=4, num_variables=5, num_clauses=4):
    # '(((a=x&b=y)&f(a,b,c)=g(a,b,c))&~f(a,b,c)=g(x,y,z)')
    uf = [UF("f{}".format(i), num_variables) for i in range(num_functions)]

    smt_vars = [SmtVar("a{}".format(i)) for i in range(num_variables)]

    str_clauses = []
    z3_clauses = []
    for _ in range(num_clauses):
        clause = smt_clause(uf, smt_vars)
        str_c, z3_c = clause.create_equality()
        str_clauses.append(str_c)
        z3_clauses.append(z3_c)

    str_clause = str_clauses[0]
    z3_clause = z3_clauses[0]
    for i in range(1, len(str_clauses)):
        op = choice(['&', '|'][:1])
        if op == '&':
            z3_clause = And(z3_clause, z3_clauses[i])
        else:
            z3_clause = Or(z3_clause, z3_clauses[i])
        str_clause = f"({str_clause}{op}{str_clauses[i]})"

    return str_clause, z3_clause
Ejemplo n.º 11
0
    def _get_components_in_quantified(cls, abs_targets, tr):
        untagged_in_vec, tag_input_vector = tr.get_input_vectors()
        new_state_vars = VarManager.duplicate_vars(tr.get_var_vectors()[0])
        new_tag_in_vec = VarManager.duplicate_vars(tag_input_vector)
        new_untag_in_vec = VarManager.duplicate_vars(untagged_in_vec)

        abs_targets_sub = [
            target.get_descriptive_formula().substitute_inputs(
                new_tag_in_vec, 0).substitute(new_state_vars,
                                              0).renew_quantifiers()
            for target in abs_targets
        ]
        abs_or = Or(*[_t.get_qbf().get_prop() for _t in abs_targets_sub])

        new_q_list = [
            _v for _t in abs_targets_sub for _v in _t.get_qbf().get_q_list()
        ]

        split_by_formula_tag = FormulaWrapper(QBF(abs_or, new_q_list),
                                              [new_state_vars],
                                              [new_tag_in_vec])
        ## RENAME QUNATIFIED HERE
        transitions_has_sons = tr.substitute(new_state_vars, 1) \
            .substitute_inputs(new_untag_in_vec, 0) \
            .substitute_inputs(new_tag_in_vec, 1)  # R(u,v) [v<-v']
        return split_by_formula_tag, transitions_has_sons
Ejemplo n.º 12
0
def any_overlap(ranges):
    predicates = []
    already_checked = []
    for r1 in ranges:
        for r2 in already_checked:
            predicates.append(overlap(r1, r2))
        already_checked.append(r1)
    return Or(predicates)
Ejemplo n.º 13
0
def has_token(x_list, j):
    """
    Generate a Z3 Boolean expression that represents whether P_j holds the token
    :param x_list: list of Z3 variables
    :param j: index of P_j
    :return: Z3 Boolean expression that if true then P_j is holding the token
    """
    return Or(And(j==0, x_list[0]==x_list[-1]), And(j!=0, x_list[j]!=x_list[j-1]))
Ejemplo n.º 14
0
 def add_clause(self, C):
     # C = map(neg, C)
     # self.stream.write("%s 0\n" %" ".join(map(str,C)))
     f = Or([self.literal(x) for x in C])
     self.__solver.add(f)
     self.stream.write("(assert (or %s))\n" %
                       (' '.join([self.literal_str(x) for x in C])))
     self.num_cls += 1
Ejemplo n.º 15
0
def sort_no_duplicates(z3_int_list):
    """Sort a list of integers that have distinct values"""
    n = len(z3_int_list)
    a = [FreshInt() for i in range(n)]
    constraints = [Or([a[i] == z3_int_list[j] for j in range(n)]) for i in range(n)]
    constraints.append(And([a[i] < a[i + 1] for i in range(n - 1)]))

    return a, constraints
Ejemplo n.º 16
0
 def c(attr):
     values = v.values(id)
     if isinstance(values, range):
         return And(attr >= values.start, attr < values.stop)
     elif isinstance(values, list):
         return Or(*(attr == int(x) for x in values))
     else:
         return (attr == int(values))
Ejemplo n.º 17
0
 def __add_grid_agreement_constraints(self):
     for p in self.__shape_type_grid:
         self.__solver.add(
             Or(
                 fast_and(self.__shape_type_grid[p] == -1,
                          self.__shape_instance_grid[p] == -1),
                 fast_and(self.__shape_type_grid[p] != -1,
                          self.__shape_instance_grid[p] != -1)))
Ejemplo n.º 18
0
def addDistinctRule(myBools, x, numColors, graph):
    n = len(graph.items())

    for i in range(0, n):  # each row
        for c in range(0, numColors):  # each color
            for c2 in range(c + 1, numColors):  # each color
                x.add(Or(Not(myBools[i][c]), Not(myBools[i][c2])))  # this cell cant be both these colors
    return x
Ejemplo n.º 19
0
    def addTimeVars(self):
        timeConstraints = []
        self.waitBefores = []
        # Create the wait before variables, which indicate, at each
        # time step t, how much time should be waited before starting
        # that time step. This value must be non-negative.
        for t in range(len(self.tasks)):
            self.waitBefores.append(z3.Int("waitBefore" + str(t)))
            self.solver.add(self.waitBefores[t] >= 0)
        if len(self.tasks) == 0:
            firstMoveTime = 0
        else:
            firstMoveTime = self.waitBefores[0]
        # The firstMoveTime is the time it takes to get to the first
        # location. Add a constraint for each location that could
        # possibly come first, that if it does come first, add the
        # time it takes to get to it to firstMoveTime
        for task in self.tasks:
            firstMoveTime += If(self.taskVars[task][0],
                                self.world.time(self.startLoc, task.location),
                                0)
        # Set this expression equal to a new variable.
        firstVar = z3.Int("TimeToFirstNode")
        timeConstraints.append(firstVar == firstMoveTime)
        # Aggregate the time variables.
        self.timeVars = [firstVar]
        # For each time step, create a new time variable.
        for t in range(len(self.tasks) - 1):
            # Start with the time variable from the previous iteration.
            time = self.timeVars[t] + self.waitBefores[t + 1]
            # This little while loop trick allows us to get every pair
            # of tasks.
            tasksLeft = list(self.tasks)
            while len(tasksLeft) > 0:
                task1 = tasksLeft.pop()
                for task2 in tasksLeft:
                    # If we traveled between these two tasks from this
                    # time step to the next, add the time taken to our
                    # time variable.
                    time += If(Or(And(self.taskVars[task1][t], self.taskVars[task2][t+1]), \
                                  And(self.taskVars[task2][t], self.taskVars[task1][t+1])),\
                               self.taskDistance(task1,task2), 0)
                # Add the time taken accomplishing a task at this step
                # to the time variable.
                time += If(self.taskVars[task1][t],
                           self.world.duration(task1.ID), 0)
            # Create a new time variable that cooresponds to this expression.
            var = z3.Int("TimeVar" + str(t))
            timeConstraints.append(var == time)
            # Add it to our aggregate.
            self.timeVars.append(var)

        if self.debugPrint:
            print "Added time variables: " + str(self.timeVars)
        for constraint in timeConstraints:
            self.solver.add(constraint)
        if self.debugPrint:
            print "Added time constraints: " + str(timeConstraints)
Ejemplo n.º 20
0
def myBinOp(op, *L):
    """
    Shortcut to apply operation op to a list L.
    Returns None if the list is empty.

    E.g. applying 'And'  over a list of formulas f1,f2..,fn
    yields And(f1,f2,...,fn).

    >>> from z3 import *
    >>> myAnd(*[Bool('x'),Bool('y')])
    And(x, y)

    >>> myAnd(*[Bool('x'),None])
    x

    >>> myAnd(*[Bool('x')])
    x

    >>> myAnd(*[])

    >>> myAnd(Bool('x'),Bool('y'))
    And(x, y)

    >>> myAnd(*[Bool('x'),Bool('y')])
    And(x, y)

    >>> myAnd([Bool('x'),Bool('y')])
    And(x, y)

    >>> myAnd((Bool('x'),Bool('y')))
    And(x, y)

    >>> myAnd(*[Bool('x'),Bool('y'),True])
    Traceback (most recent call last):
    ...
    AssertionError
    """

    assert op == Z3_OP_OR or op == Z3_OP_AND or op == Z3_OP_IMPLIES

    if len(L) == 1 and (isinstance(L[0], list) or isinstance(L[0], tuple)):
        L = L[0]

    assert all(not isinstance(l, bool) for l in L)

    L = [l for l in L if is_expr(l)]
    if L:
        if len(L) == 1:
            return L[0]
        else:
            if op == Z3_OP_OR:
                return Or(L)
            elif op == Z3_OP_AND:
                return And(L)
            else:  #IMPLIES
                return Implies(L[0], L[1])
    else:
        return None
    def solve_with(self, input_image, output_index):
        x = RealVector('x', len(input_image[0]))
        for i in range(len(input_image[0])):
            if i >= self.pixels_to_change:
                # x[i] = image[i]
                self.solver.add(x[i] == input_image[0][i].item())
            else:
                # 0 <= x[i] <= 1
                self.solver.add(x[i] >= 0)
                self.solver.add(x[i] <= 1)

        fc1_weights = fetch_weights(1)
        fc1_shape = fc1_weights.size()
        # o1 = fc1^T * x
        o1 = [
            Sum([fc1_weights[i, j].item() * x[j] for j in range(fc1_shape[1])])
            for i in range(fc1_shape[0])
        ]

        # y1 = ReLU(o1)
        y1 = [If(o1[i] > 0, o1[i], 0) for i in range(fc1_shape[0])]

        fc2_weights = fetch_weights(2)
        fc2_shape = fc2_weights.size()
        # y2 = fc2^T * y1
        y2 = [
            Sum([
                fc2_weights[i, j].item() * y1[j] for j in range(fc2_shape[1])
            ]) for i in range(fc2_shape[0])
        ]

        # If any y2 output is higher than the expected y2,
        # the model output changes
        self.solver.add(
            Or([
                y2[output_index] < y2[i] for i in range(len(y2))
                if i != output_index
            ]))
        # self.solver.add(And([y2[output_index] > y2[i]
        #                      for i in range(len(y2)) if i != output_index]))

        # Check if the classification can change
        check = self.solver.check()
        sat = str(check) == 'sat'

        if sat:
            m = self.solver.model()
            # Substitute the model back in
            x_new = input_image.clone().detach()
            for i in range(self.pixels_to_change):
                x_new[0][i] = model_to_val(m, x[i])
            for i in range(self.pixels_to_change, len(input_image[0])):
                x_new[0][i] = input_image[0][i]
            return x_new
        elif str(check) == 'unknown':
            return 'timeout'
        else:
            return 'unsat'
Ejemplo n.º 22
0
def addAdjacentRule(myBools, x, numColors, graph):
    n = len(graph.items())

    for i in range(0, n):  # each row
        for j in range(0, len(graph[i])):
            for c in range(0, numColors):  # each color
                if i < graph[i][j]:
                    x.add(Or(Not(myBools[i][c]), Not(myBools[graph[i][j]][c])))  # this cell cant be both these colors
    return x
Ejemplo n.º 23
0
 def is_consistent(self):
     return [
         Or(
             self.size == 0,
             And(ULT(self.start, self.end), is_pow_of_2(self.size),
                 self.size % self.hw_config.subregion_count == 0,
                 self.start % self.size == 0,
                 UGE(self.size, self.hw_config.region_min_size)))
     ]
Ejemplo n.º 24
0
def pick_exactly_one(indicators):
    """return constraints choosing exactly one of several options"""
    some_value = Or(*indicators)
    K = len(indicators)
    unique_value = [
        Not(And(indicators[j], indicators[i])) for i in range(K)
        for j in range(i + 1, K)
    ]
    return [some_value] + unique_value
Ejemplo n.º 25
0
def exhaust_models(solver, variables):
    while solver.check() == sat:
        model = solver.model()
        yield model

        blocker = []
        for var in variables:
            blocker.append(var != model.eval(var))
        solver.add(Or(*blocker))
Ejemplo n.º 26
0
    def solve_z3(self):

        print("[+] {}".format("Sovling using Z3\n"))

        symbols = {e: Int(e) for e in self.elements}

        # first we build a solver with the general constraints for sudoku puzzles:
        s = Solver()

        # assure that every cell holds a value of [1,9]
        for symbol in symbols.values():
            s.add(Or([symbol == int(i) for i in self.cols]))

        # assure that every row covers every value:
        for row in "ABCDEFGHI":
            s.add(Distinct([symbols[row + col] for col in "123456789"]))

        # assure that every column covers every value:
        for col in "123456789":
            s.add(Distinct([symbols[row + col] for row in "ABCDEFGHI"]))

        # assure that every block covers every value:
        for i in range(3):
            for j in range(3):
                s.add(
                    Distinct([
                        symbols["ABCDEFGHI"[m + i * 3] +
                                "123456789"[n + j * 3]] for m in range(3)
                        for n in range(3)
                    ]))

        # adding sum constraints if provided
        if self.constraints is not None:
            print("[+] {}\n{}".format("Applying constraints",
                                      self.constraints))
            sum_constr = self.get_constraints()
            for c in sum_constr:
                expr = []

                for i in c[0]:
                    expr.append("symbols['" + i + "']")

                s.add(eval("+".join(expr) + "==" + str(c[1])))

        # now we put the assumptions of the given puzzle into the solver:
        for elem, value in self.values.items():
            if value in "123456789":
                s.add(symbols[elem] == value)

        if not s.check() == sat:
            raise Exception("Unsolvable")

        model = s.model()
        values = {e: model.evaluate(s).as_string() for e, s in symbols.items()}

        self.solution = values
Ejemplo n.º 27
0
    def __init__(
        self,
        worker,
        distance: int,
        time_periods: Optional[list] = None,
        optional: Optional[bool] = False,
        mode: Optional[str] = "exact",
    ):
        if mode not in {"min", "max", "exact"}:
            raise Exception("Mode should be min, max or exact")

        super().__init__(optional)

        starts = []
        ends = []
        for start_var, end_var in worker.busy_intervals.values():
            starts.append(start_var)
            ends.append(end_var)
        # sort both lists
        sorted_starts, c1 = sort_no_duplicates(starts)
        sorted_ends, c2 = sort_no_duplicates(ends)
        for c in c1 + c2:
            self.set_assertions(c)
        # from now, starts and ends are sorted in asc order
        # the space between two consecutive tasks is the sorted_start[i+1]-sorted_end[i]
        # we just have to constraint this variable
        for i in range(1, len(sorted_starts)):
            if mode == "min":
                asst = sorted_starts[i] - sorted_ends[i - 1] >= distance
            elif mode == "max":
                asst = sorted_starts[i] - sorted_ends[i - 1] <= distance
            elif mode == "exact":
                asst = sorted_starts[i] - sorted_ends[i - 1] == distance
            #  another set of conditions, related to the time periods
            conditions = []
            if time_periods is not None:
                for (
                        lower_bound,
                        upper_bound,
                ) in time_periods:  # time_period should be a list also or a tuple
                    conditions.append(
                        And(
                            sorted_starts[i] >= lower_bound,
                            sorted_ends[i - 1] >= lower_bound,
                            sorted_starts[i] <= upper_bound,
                            sorted_ends[i - 1] <= upper_bound,
                        ))
            else:
                # add the constraint only if start and ends are positive integers,
                # that is to say they correspond to a scheduled optional task
                condition_only_scheduled_tasks = And(sorted_ends[i - 1] >= 0,
                                                     sorted_starts[i] >= 0)
                conditions = [condition_only_scheduled_tasks]
            # finally create the constraint
            new_cstr = Implies(Or(conditions), asst)
            self.set_assertions(new_cstr)
Ejemplo n.º 28
0
    def __add_loop_edge_constraints(self):
        solver = self.__symbol_grid.solver
        sym: LoopSymbolSet = self.__symbol_grid.symbol_set

        for p, cell in self.__symbol_grid.grid.items():
            for _, d in self.__symbol_grid.lattice.edge_sharing_directions():
                np = p.translate(d)
                dir_syms = sym.symbols_for_direction(d)
                ncell = self.__symbol_grid.grid.get(np, None)
                if ncell is not None:
                    opposite_syms = sym.symbols_for_direction(d.negate())
                    cell_points_dir = Or(*[cell == s for s in dir_syms])
                    neighbor_points_opposite = Or(
                        *[ncell == s for s in opposite_syms])
                    solver.add(
                        Implies(cell_points_dir, neighbor_points_opposite))
                else:
                    for s in dir_syms:
                        solver.add(cell != s)
Ejemplo n.º 29
0
def snake_orthogonally_connected(g):
    # Orthogonally, we don't branch
    for x, y in g.coords():
        c = g.snake(x, y)
        number_surrounding = sum(
            BoolToInt(g.snake(x2, y2)) for x2, y2 in orthogonal(g, x, y))
        is_head = (x, y) == g.head
        is_tail = (x, y) == g.tail
        is_endpoint = Or(is_head, is_tail)
        g.add(Implies(c, number_surrounding == If(is_endpoint, 1, 2)))
Ejemplo n.º 30
0
def condense(products, num_split):
    currIndex = 0
    while len(products) > num_split:
        lastCon = products.pop()
        products[currIndex] = products[currIndex] + lastCon
        currIndex = currIndex + 1
        if currIndex == num_split:
            currIndex = 0
    products = [Or(*i) for i in products]
    return products