示例#1
0
def search_rectangle(b1, e1, b2, e2, b3, e3, b4, e4):
    x1 = Real('x1')
    x2 = Real('x2')
    x3 = Real('x3')
    x4 = Real('x4')

    y1 = Real('y1')
    y2 = Real('y2')
    y3 = Real('y3')
    y4 = Real('y4')

    optimizer = Optimize()

    add_cond_on_segment(optimizer, b1, e1, x1, y1)
    add_cond_on_segment(optimizer, b2, e2, x2, y2)
    add_cond_on_segment(optimizer, b3, e3, x3, y3)
    add_cond_on_segment(optimizer, b4, e4, x4, y4)

    add_cond_orthogonal(optimizer, x1, y1, x2, y2, x3, y3)
    add_cond_orthogonal(optimizer, x2, y2, x3, y3, x4, y4)
    add_cond_orthogonal(optimizer, x3, y3, x4, y4, x1, y1)
    add_cond_orthogonal(optimizer, x4, y4, x1, y1, x2, y2)

    # equal_distance
    #optimizer.add_soft((x2-x1)**2+(y2-y1)**2==(x4-x3)**2+(y4-y3)**2)
    #optimizer.add_soft((x3-x2)**2+(y3-y2)**2==(x4-x1)**2+(y4-y1)**2)

    #optimizer.maximize(z3abs((x2-x1)*(y4-y1)-(x4-x1)*(y2-y1)))

    result = optimizer.check()

    print(result)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    plotline(ax, b1, e1)
    plotline(ax, b2, e2)
    plotline(ax, b3, e3)
    plotline(ax, b4, e4)

    if result != z3.unsat:
        print(optimizer.model())
        model = optimizer.model()
        x1 = convert_py_type(model[x1])
        x2 = convert_py_type(model[x2])
        x3 = convert_py_type(model[x3])
        x4 = convert_py_type(model[x4])
        y1 = convert_py_type(model[y1])
        y2 = convert_py_type(model[y2])
        y3 = convert_py_type(model[y3])
        y4 = convert_py_type(model[y4])

        plotline(ax, [x1, y1], [x2, y2], 'k')
        plotline(ax, [x2, y2], [x3, y3], 'k')
        plotline(ax, [x3, y3], [x4, y4], 'k')
        plotline(ax, [x4, y4], [x1, y1], 'k')

    else:
        print('no soltion')
    plt.gca().set_aspect('equal', adjustable='box')
    plt.show()
示例#2
0
def find_max(constraints, expr, l = None):
    if l is None:
        l = logger

    if type(expr) == int:
        return expr

    constraint_strs = [f'{c}' for c in constraints]

    max_optimize = Optimize()
    max_optimize.set('timeout', 10000)
    max_optimize.assert_exprs(*constraints)
    max_optimize.maximize(expr)
    status = max_optimize.check()
    if status != sat:
        l.warning(f'Unable to find max ({status}) for:\n' + '\n'.join(constraint_strs))
        return None

    max_val = max_optimize.model().eval(expr).as_long()

    # Make sure it's actually the max, since z3 has a bug
    #   https://github.com/Z3Prover/z3/issues/4670
    solver = Solver()
    solver.set('timeout', 10000)
    solver.add(constraints + [expr > max_val])
    status = solver.check()

    if status != unsat:
        l.error(f'Z3 bug\nFind max ({expr}) => {max_val} with status ({status}):\n' + '\n'.join(constraint_strs))
        return None
    return max_val
示例#3
0
    def __init__(self, state_graph: StateGraph, default_value: Fraction,
                 statistics: Statistics, settings: Settings,
                 model_type: PrismModelType):

        self.state_graph = state_graph
        self.statistics = statistics
        self.settings = settings
        self.model_type = model_type

        if default_value < 0:
            raise ValueError("Oracle values must be greater or equal to 0")

        self.default_value = RealVal(default_value)

        self.solver = Solver()
        self.solver_mdp = Optimize()

        # The way we refine the Oracle depends on the model type
        if model_type == PrismModelType.DTMC:
            self.refine_oracle = self.refine_oracle_mc

        elif model_type == PrismModelType.MDP:
            self.refine_oracle = self.refine_oracle_mdp

        else:
            raise Exception("Oracle: Unsupported model type")

        self.oracle_states: Set[StateId] = set()

        self.oracle: Dict[StateId, z3.ExprRef] = dict()
示例#4
0
def search_rectangle(b1, e1, b2, e2, b3, e3, b4, e4):
    x1 = Real('x1')
    x2 = Real('x2')
    x3 = Real('x3')
    x4 = Real('x4')

    y1 = Real('y1')
    y2 = Real('y2')
    y3 = Real('y3')
    y4 = Real('y4')

    optimizer = Optimize()

    add_cond_on_segment(optimizer, b1, e1, x1, y1)
    add_cond_on_segment(optimizer, b2, e2, x2, y2)
    add_cond_on_segment(optimizer, b3, e3, x3, y3)
    add_cond_on_segment(optimizer, b4, e4, x4, y4)

    add_cond_orthogonal(optimizer, x1, y1, x2, y2, x3, y3)
    add_cond_orthogonal(optimizer, x2, y2, x3, y3, x4, y4)
    add_cond_orthogonal(optimizer, x3, y3, x4, y4, x1, y1)
    add_cond_orthogonal(optimizer, x4, y4, x1, y1, x2, y2)

    # equal_distance
    #optimizer.add_soft((x2-x1)**2+(y2-y1)**2==(x4-x3)**2+(y4-y3)**2)
    #optimizer.add_soft((x3-x2)**2+(y3-y2)**2==(x4-x1)**2+(y4-y1)**2)

    #optimizer.maximize(z3abs((x2-x1)*(y4-y1)-(x4-x1)*(y2-y1)))

    result = optimizer.check()

    print(result)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    plotline(ax, b1, e1)
    plotline(ax, b2, e2)
    plotline(ax, b3, e3)
    plotline(ax, b4, e4)

    if result != z3.unsat:
        print(optimizer.model())
        model = optimizer.model()
        x1 = convert_py_type(model[x1])
        x2 = convert_py_type(model[x2])
        x3 = convert_py_type(model[x3])
        x4 = convert_py_type(model[x4])
        y1 = convert_py_type(model[y1])
        y2 = convert_py_type(model[y2])
        y3 = convert_py_type(model[y3])
        y4 = convert_py_type(model[y4])

        plotline(ax, [x1, y1], [x2, y2], 'k')
        plotline(ax, [x2, y2], [x3, y3], 'k')
        plotline(ax, [x3, y3], [x4, y4], 'k')
        plotline(ax, [x4, y4], [x1, y1], 'k')

    else:
        print('no soltion')
    plt.gca().set_aspect('equal', adjustable='box')
    plt.show()
示例#5
0
def find_min(constraints, expr, default_min=0):
    if type(expr) == int:
        return expr

    constraint_strs = [f'{c}' for c in constraints]

    min_optimize = Optimize()
    min_optimize.set('timeout', 10000)

    min_optimize.assert_exprs(*constraints)
    min_optimize.minimize(expr)
    status = min_optimize.check()
    if status != sat:
        print(f'Unable to find min ({status}) for:\n' +
              '\n'.join(constraint_strs))
        return None

    min_val = min_optimize.model().eval(expr).as_long()

    # Make sure it's actually the min, since z3 has a bug
    #   https://github.com/Z3Prover/z3/issues/4670
    solver = Solver()
    solver.set('timeout', 10000)
    solver.add(constraints + [expr < min_val])
    status = solver.check()

    if status != unsat:
        print(
            f'Z3 bug\nFind min ({expr}) => {min_val} with status ({status}):\n'
            + '\n'.join(constraint_strs))
        return None
    return min_val
示例#6
0
def main():
    bots = []

    with open("input.txt") as f:
        for line in f:
            bots.append(tuple(map(int, re.findall(r"-?\d+", line))))

    x, y, z, r = max(bots, key=lambda b: b[3])
    in_range = sum(
        (abs(x - b[0]) + abs(y - b[1]) + abs(z - b[2]) <= r) for b in bots)
    print("Part 1:", in_range)

    x, y, z = Int("x"), Int("y"), Int("z")
    point = (x, y, z)
    count = sum(If(z3_dist(b[:3], point) <= b[3], 1, 0) for b in bots)

    opt = Optimize()
    opt.maximize(count)
    opt.minimize(z3_dist(point, (0, 0, 0)))

    opt.check()
    model = opt.model()
    result = model[x].as_long() + model[y].as_long() + model[z].as_long()

    print("Part 2:", result)
def test(qcirc):
    #print(qcirc)
    print("Translate to Z3")
    circ = QuantumCircuit_to_Circuit(qcirc, melbourne_rels, positions)
    # Collect Constraints
    print("Create Constraint Generator")
    cons = circ.constraints()
    # New Optimizer
    s = Optimize()
    # Add constraints
    print("Add All constraints")
    for con in cons:
        s.add(con)
        #print(con)
    # Add reliability objective
    print("Add Objective")
    s.maximize(reliability_objective(circ))
    # Check and print
    print("Checking")
    sat = str(s.check())
    print(sat)
    if sat == "unsat":
        raise Exception("unsat")

    print("Extracting Model")
    m = s.model()

    # Confirm that an improvement in reliability was made
    print("Reliability Checking")
    improved_reliability(m, s, melbourne_rels, qcirc)

    # Translate to qiskit QuantumCircuit
    print("Translate to Qiskit")
    rcirc = model_to_QuantumCircuit(m, circ)
示例#8
0
def part_2(nanobots: List[Nanobot]) -> int:
    x, y, z = Ints("x y z")
    opt = Optimize()
    bot_cond = []
    for i, bot in enumerate(nanobots):
        cond = Int(f"bot_{i}")
        bot_cond.append(cond)
        opt.add(cond == If(z_manhattan(x, y, z, bot.point) <= bot.r, 1, 0))
    overlaps = Sum(bot_cond)
    dist_zero = Int('dist_zero')
    opt.add(dist_zero == z_manhattan(x, y, z, Point(0, 0, 0)))
    _ = opt.maximize(overlaps)
    dist = opt.maximize(dist_zero)
    opt.check()
    return dist.upper()
 def solve_optimization(self):
     """
     Setup and solve a Z3 optimization for finding the best schedule
     """
     self.opt = Optimize()
     self.create_z3_vars()
     self.basic_bounds()
     self.scheduling_constraints()
     self.fidelity_constraints()
     self.coherence_constraints()
     self.objective_function()
     # Solve step
     self.opt.check()
     # Extract the schedule computed by Z3
     result = self.extract_solution()
     return result
def test_allBadSpecsAreBad(spec):
    badSpecs = getAllBadSpecs(spec, 15)
    for badSpec in badSpecs:
        foundry = Foundry(
            Optimize()).applyAndTrackSpec(badSpec).applyAndTrackSpec(spec)
        assert foundry.check() == unsat
        assert len(foundry.getReasonsForUnsat()) != 0
示例#11
0
def optimum_dist(bots):
    x = Int('x')
    y = Int('y')
    z = Int('z')
    cost_expr = x * 0
    for i, j, k, r in bots:
        cost_expr += If(z3_dist((x, y, z), (i, j, k)) <= r, 1, 0)
    opt = Optimize()
    opt.maximize(cost_expr)
    opt.minimize(z3_dist((0, 0, 0), (x, y, z)))
    opt.check()
    model = opt.model()
    coords = (model[x].as_long(), model[y].as_long(), model[z].as_long())
    return dist((0, 0, 0), coords)
示例#12
0
def to_z3_problem(problem: DependencyProblem,
                  states: List[EncodedState]) -> Optimize:
    minimizer = Optimize()
    minimizer.add(to_formula(problem, states))

    cost = Int('cost')
    cost_constraint = cost == total_cost(states, problem.repository)
    minimizer.add(cost_constraint)

    minimizer.minimize(cost)
    return minimizer
示例#13
0
    def __init__(self, state_graph, statistics, settings, model_type):
        self.statistics = statistics
        self.state_graph = state_graph
        self.model_type = model_type

        logger.debug("Initialize oracle...")

        self._initialize_oracle(settings)

        logger.debug("Initialize obligation cache...")
        self._obligation_cache = ObligationCache()
        logger.debug("Initialize optimization solver...")
        # Initialize solver for optimization queries
        self.opt_solver = Optimize()

        self._realval_zero = RealVal(0)
        self._realval_one = RealVal(1)

        self.obligation_queue_class = settings.get_obligation_queue_class()
def bruteForceRepairLine(broken: List[Pitch], spec: Spec) -> List[int]:
    foundry = Foundry(Optimize())
    foundry.applySpec(spec)
    for fixedNoteIndexes in revpowset(range(0, len(broken))):
        foundry.opt.push()
        for i in fixedNoteIndexes:
            foundry.apply(
                Constraint(spec.line[i] == broken[i], ConstraintType.REPAIRER,
                           "Ignore"))
        if foundry.check() == sat:
            return foundry.extractPitches(spec.line)
        foundry.opt.pop()
    raise Exception("No valid line could be found")
示例#15
0
 def check_with_stats(solver: z3.Optimize) -> z3.CheckSatResult:
     start: float = time.perf_counter()
     SchedulingStatistics.__instance.number_smt_calls += 1
     r = solver.check()
     solving_time = time.perf_counter() - start
     if r == z3.sat:
         SchedulingStatistics.__instance.number_sat_results += 1
         SchedulingStatistics.__instance.sat_solving_time += solving_time
     elif r == z3.unsat:
         SchedulingStatistics.__instance.number_unsat_results += 1
         SchedulingStatistics.__instance.unsat_solving_time += solving_time
     else:
         assert False
     return r
示例#16
0
    def __init__(self, file_name):
        self.solver = Optimize()

        inputs = [Int(f'model_{i}') for i in range(14)]
        self.solver.add([i >= 1 for i in inputs])
        self.solver.add([i <= 9 for i in inputs])

        # Please don't ask me to explain this. There's a common pattern in the input code that treats z like a number
        # of base 26 and the operations are either right shift or left shift on that number +- some value.
        self.solver.add(inputs[0] + 6 - 6 == inputs[13])
        self.solver.add(inputs[1] + 11 - 6 == inputs[12])
        self.solver.add(inputs[2] + 5 - 13 == inputs[11])
        self.solver.add(inputs[3] + 6 - 8 == inputs[8])
        self.solver.add(inputs[4] + 8 - 1 == inputs[5])
        self.solver.add(inputs[6] + 9 - 16 == inputs[7])
        self.solver.add(inputs[9] + 13 - 16 == inputs[10])

        my_sum = IntVal(0)
        for index in range(len(inputs)):
            my_sum = (my_sum * 10) + inputs[index]

        self.value = Int('value')
        self.solver.add(my_sum == self.value)
    def solve_boolean_formula_with_z3_smt2(self, bf):
        """Find minimum satisfying assignemnt for the boolean formula.
        # Example:
        # >>> bf = '(and (or a b) (not (and a c)))'
        # >>> appeared_symbol_list = ['a', 'b', 'c']
        # >>> solve_boolean_formula_with_z3_smt2(bf, appeared_symbol_list)
        # ([b = True, a = False, c = False, s = 1], 1)
        """
        appeared_symbol_list = list(
            set([
                a if "not " not in a else a[5:-1]
                for a in self.prov_notations.values()
            ]))
        declaration_str = '\n'.join(
            list(
                map(lambda x: '(declare-const {} Bool)'.format(x),
                    appeared_symbol_list)))
        declaration_str += '\n(declare-const s Int)'
        declaration_str += '\n(define-fun b2i ((x Bool)) Int (ite x 1 0))'

        size_str = '(+ {})'.format(' '.join(
            list(map(lambda x: '(b2i {})'.format(x), appeared_symbol_list))))
        assert_str = '(assert {})\n'.format(bf)
        assert_str += '(assert (= s {}))\n(assert (>= s 0))'.format(
            size_str)  # changed from (> s 0)

        z3_bf = parse_smt2_string(declaration_str + '\n' + assert_str)
        opt = Optimize()
        opt.add(z3_bf)
        s = Int('s')
        opt.minimize(s)  # changed from opt.minimize(s)

        if opt.check() == sat:
            best_model = opt.model()
            min_size = 0
            for cl in best_model:
                if isinstance(best_model[cl], BoolRef) and best_model[cl]:
                    min_size += 1
            return best_model, min_size
        else:
            return None, -1
示例#18
0
def create_optimizer():
    s = Optimize()

    input = Ints(' '.join(map(lambda s: str(s), range(14))))
    for i in input:
        s.add(i > 0, i < 10)

    data = [
        (1, 11, 16),
        (1, 12, 11),
        (1, 13, 12),
        (26, -5, 12),
        (26, -3, 12),
        (1, 14, 2),
        (1, 15, 11),
        (26, -16, 4),
        (1, 14, 12),
        (1, 15, 9),
        (26, -7, 10),
        (26, -11, 11),
        (26, -6, 6),
        (26, -11, 15),
    ]

    x, y, z = 0, 0, 0
    for (zz, b, c), i in zip(data, input):
        w = i
        x = z % 26
        z /= zz
        x += b
        x = x != w
        y = 25
        y *= x
        y += 1
        z *= y
        y = w + c
        y *= x
        z += y

    s.add(z == 0)

    num = 0
    for i in input:
        num *= 10
        num += i

    return s, num
示例#19
0
def getAllBadSpecs(spec: Spec,
                   maxCount=None,
                   doShuffle=True,
                   filterOutUnsatisfiable=True) -> List[Spec]:
    badSpecs = []
    constraintsToInclude = powset(spec.constraints)
    constraintsToInvert = constraintsToInclude[::-1]

    constraintsToInclude = constraintsToInclude[:-1]
    constraintsToInvert = constraintsToInvert[:-1]

    if doShuffle:
        constraintsToInclude, constraintsToInvert = shuffle(
            constraintsToInclude, constraintsToInvert)

    if maxCount is None:
        maxCount = len(constraintsToInclude)
    else:
        maxCount = min(maxCount, len(constraintsToInclude))

    for i in range(maxCount):
        constraints = [
            pitchesLetterValueValid(spec.line)
        ]  # Needed ensure that the spec doesn't cheat on the gamut constraint
        constraints += constraintsToInclude[i]
        constraints += [x.inv() for x in constraintsToInvert[i]]
        badSpec = Spec(spec.line, constraints, spec.maximisations,
                       spec.minimisations)
        foundry = Foundry(Optimize()).applySpec(badSpec)

        if filterOutUnsatisfiable:
            if foundry.check() == sat:
                badSpecs.append(badSpec)
        else:
            badSpecs.append(badSpec)

    return badSpecs
示例#20
0
def solve_pkgver_z3(pkg_dict,
                    constrain_version_dict,
                    optim_target="approximate"):
    # solver = Solver()
    solver = Optimize()
    int_dict = build_int_dict(pkg_dict)
    order_dict = build_order_dict(pkg_dict)
    solver = add_dependency_constrains(solver, pkg_dict, order_dict, int_dict)
    solver = add_int_constrains(solver, pkg_dict, int_dict)
    solver = add_version_constrains(solver, constrain_version_dict, order_dict,
                                    int_dict)
    if optim_target == "approximate":
        solver = add_optimize_targets(solver, int_dict)
    if optim_target == "exact":
        solver = add_optimize_targets2(solver, int_dict, order_dict)
        solver.set(timeout=60000)
    try:
        if solver.check():
            pkgvers = parse_z3_model(solver.model(), int_dict, order_dict)
            return pkgvers
        else:
            return None
    except:
        return None
示例#21
0
文件: newsmt.py 项目: Cwickniss/OLSQ
    num_swap = Int('num_swap')
# for fidelity optimization

    if objective_name == "fidelity":
        u = [Int("num_1qbg_p{}".format(n)) for n in range(N)]
        v = [Int("num_2qbg_e{}".format(k)) for k in range(K)]
        vv = [Int("num_swap_e{}".format(k)) for k in range(K)]
        w = [Int("num_meas_p{}".format(n)) for n in range(N)]
        fidelity = Int('log_fidelity')

    # else:
# for depth optimization
    depth = Int('depth')


    z3 = Optimize()


    """
    Constraints
    """

    for t in range(T):
        for m in range(M):
            z3.add(pi[m][t] >= 0, pi[m][t] < N)
            for mm in range(m):
                z3.add(pi[m][t] != pi[mm][t])

    for l in range(L):
        z3.add(time[l] >= 0, time[l] < T)
        if l in G_1:
示例#22
0
class Oracle(ABC):
    """
    An oracle is a dict from state_ids to values (not neccessarily probabilities since o.w. the eq system does not always have a solution).

    This is an abstract base class.
    Concrete sub-classes must overwrite `initialize`.

    Attributes:
        state_graph (StateGraph): the associated state graph
        default_value (Fraction): The default value is the oracle value returned if the given state_id is not a key of the oracle
        statistics (Statistics): access to the global statistics
        settings (Settings): all settings
        solver (Solver): a solver for the equation system
        oracle_states (Set[StateId]): states in this oracle
        oracle (Dict[StateId, z3.ExprRef]): the oracle's internal value dict
    """
    def __init__(self, state_graph: StateGraph, default_value: Fraction,
                 statistics: Statistics, settings: Settings,
                 model_type: PrismModelType):

        self.state_graph = state_graph
        self.statistics = statistics
        self.settings = settings
        self.model_type = model_type

        if default_value < 0:
            raise ValueError("Oracle values must be greater or equal to 0")

        self.default_value = RealVal(default_value)

        self.solver = Solver()
        self.solver_mdp = Optimize()

        # The way we refine the Oracle depends on the model type
        if model_type == PrismModelType.DTMC:
            self.refine_oracle = self.refine_oracle_mc

        elif model_type == PrismModelType.MDP:
            self.refine_oracle = self.refine_oracle_mdp

        else:
            raise Exception("Oracle: Unsupported model type")

        self.oracle_states: Set[StateId] = set()

        self.oracle: Dict[StateId, z3.ExprRef] = dict()

        # self.save_oracle_on_disk()

    def _ensure_value_in_oracle(self, state_id: StateId):
        """
        Used to override standard behaviour. Takes a state id, ensures that self.oracle contains this value.
        :param state_id:
        :return:
        """
        pass

    def get_oracle_value(self, state_id: StateId) -> z3.ExprRef:
        if state_id not in self.oracle:
            self._ensure_value_in_oracle(state_id)
        return self.oracle.get(state_id, self.default_value)

    def refine_oracle_mc(self, visited_states: Set[StateId]) -> Set[StateId]:

        self.statistics.inc_refine_oracle_counter()
        # First ensure progress
        if visited_states <= self.oracle_states:
            # Ensure progress by adding all non-target successors of states in oracle_states to the set
            self.oracle_states = self.oracle_states.union({
                succ_id
                for state_id in self.oracle_states for succ_id, prob in
                self.state_graph.get_filtered_successors(state_id)
                if succ_id != -1
            })

        else:
            self.oracle_states = self.oracle_states.union(visited_states)

        # TODO: A lot of optimization potential
        self.solver.push()

        # We need a variable for every oracle state
        variables = {
            state_id: Real("x_%s" % state_id)
            for state_id in self.oracle_states
        }

        # Set up EQ - System
        for state_id in self.oracle_states:
            self.solver.add(variables[state_id] == Sum([
                RealVal(1) *
                prob if succ_id == -1 else  # Case succ_id target state
                (
                    variables[succ_id] * prob if succ_id in
                    self.oracle_states else  # Case succ_id oracle state
                    self.get_oracle_value(succ_id) *
                    prob)  # Case sycc_id no target and no oracle state
                for succ_id, prob in self.state_graph.get_filtered_successors(
                    state_id)
            ]))

            self.solver.add(variables[state_id] >= RealVal(0))

        #print(self.solver.assertions())

        if self.solver.check() == sat:

            m = self.solver.model()

            # update oracle
            for state_id in self.oracle_states:
                self.oracle[state_id] = m[variables[state_id]]

            logger.info("Refined oracle.")
            #logger.info(self.oracle)

            self.solver.pop()

            return self.oracle_states

        else:

            # The oracle solver is unsat. In this case, we solve the LP.
            self.solver.pop()

            self.statistics.refine_oracle_counter = self.statistics.refine_oracle_counter - 1

            return self.refine_oracle_mdp(visited_states)

    def refine_oracle_mdp(self, visited_states: Set[StateId]) -> Set[StateId]:

        self.statistics.inc_refine_oracle_counter()
        # First ensure progress
        if visited_states <= self.oracle_states:
            # Ensure progress by adding all non-target successors of states in oracle_states to the set (for every action)
            self.oracle_states = self.oracle_states.union({
                succ[0]
                for state_id in self.oracle_states for choice in
                self.state_graph.get_successors_filtered(state_id).choices
                for succ in choice.distribution if succ[0] != -1
            })

        else:
            self.oracle_states = self.oracle_states.union(visited_states)

        # TODO: A lot of optimization potential
        self.solver_mdp.push()

        # We need a variable for every oracle state
        variables = {
            state_id: Real("x_%s" % state_id)
            for state_id in self.oracle_states
        }

        # Set up EQ - System
        for state_id in self.oracle_states:
            for choice in self.state_graph.get_successors_filtered(
                    state_id).choices:
                self.solver_mdp.add(variables[state_id] >= Sum([
                    RealVal(1) *
                    prob if succ_id == -1 else  # Case succ_id target state
                    (
                        variables[succ_id] * prob if succ_id in
                        self.oracle_states else  # Case succ_id oracle state
                        self.get_oracle_value(succ_id) *
                        prob)  # Case sycc_id no target and no oracle state
                    for succ_id, prob in choice.distribution
                ]))

            self.solver_mdp.add(variables[state_id] >= RealVal(0))

        # Minimize value for initial state
        self.solver_mdp.minimize(
            variables[self.state_graph.get_initial_state_id()])

        if self.solver_mdp.check() == sat:

            m = self.solver_mdp.model()

            # update oracle
            for state_id in self.oracle_states:
                self.oracle[state_id] = m[variables[state_id]]

            logger.info("Refined oracle.")
            # logger.info(self.oracle)

            self.solver_mdp.pop()

            return self.oracle_states

        else:
            logger.error("Oracle solver unsat")
            raise RuntimeError("Oracle solver inconsistent.")

    @abstractmethod
    def initialize(self):
        """
        Stub to be overwritten by concrete oracles.
        :return:
        """
        pass

    def save_oracle_on_disk(self):
        """
        Save this oracle to disk using `save_oracle_dict` from `pric3.oracles.file_oracle`.
        """
        from pric3.oracles.file_oracle import save_oracle_dict
        save_oracle_dict(self.state_graph, self.oracle)

    def _get_prism_program(self):
        return self.state_graph.input_program.prism_program
示例#23
0
    def smt_solution(self, timeout, neg_points=None, optimize=False):
        # If halfspace's coefficients add to 1 it's
        # as simple as it gets
        normal_sum = sum(abs(x) for x in self.normal)
        if normal_sum == 0:
            return False
        elif normal_sum <= 1:
            simple = True
        else:
            simple = False

        neg_points = neg_points or []

        if optimize:
            solver = Optimize()
        else:
            solver = Solver()
            solver.set("zero_accuracy",10)
        solver.set("timeout", timeout)

        ti = self.offset
        smt_ti = Int("b")
        if ti:
            solver.add(min(0,ti) <= smt_ti, smt_ti <= max(0,ti))
            if optimize:
                # Try to minimize the independent term
                solver.minimize(smt_ti)
        else:
            solver.add(smt_ti == 0)

        variables = set()
        variables_positive = set()

        positive_x = True
        non_trivial = False
        some_consume = False
        some_produce = False

        diff_sol = smt_ti != ti
        smt_keep_sol = ti
        smt_is_sol = smt_ti

        for t_id, coeff in enumerate(self.normal):
            # SMT coefficient
            smt_coeff = Int("a%s" % t_id)
            if optimize:
                # Try to minimize the coefficient
                solver.minimize(smt_coeff)
            # SMT variable
            smt_var = Int("x%s"%t_id)

            # Add SMT varible to the set of variables
            variables.add(smt_var)
            # Add SMT varible basic constraint to the set
            variables_positive.add(smt_var >= 0)

            if coeff:
                # At least one SMT coefficient should be non zero
                non_trivial = Or(non_trivial, smt_coeff != 0)
                # At least one SMT coefficient should be different
                diff_sol = Or(diff_sol, smt_coeff != coeff)
                # Original solution with SMT variable
                smt_keep_sol += coeff * smt_var
                # SMT solution with SMT variable
                smt_is_sol += smt_coeff * smt_var
                # Keep SMT coefficient between original bundaries
                solver.add(min(0,coeff) <= smt_coeff, smt_coeff <= max(0, coeff))

                if not neg_points and not simple:
                    some_produce = Or(some_produce, smt_coeff > 0)
                    some_consume = Or(some_consume, smt_coeff < 0)
            else:
                solver.add(smt_coeff == 0)

    #This is what we want:
        if not neg_points:
            # If there is not negative info, avoid trivial solution (i.e. Not all zero)
            solver.add(simplify(non_trivial))
            if not simple:
                solver.add(simplify(some_consume))
                solver.add(simplify(some_produce))
        # A different solution (i.e. "better")
        solver.add(simplify(diff_sol))
        # If it was a solution before, keep it that way
        solver.add(simplify(ForAll(list(variables), Implies(And(Or(list(variables_positive)), smt_keep_sol <= 0), smt_is_sol <= 0))))

        # New solution shouldn't add a negative point
        for np in neg_points:
            smt_ineq_np = smt_ti
            ineq_np = ti
            for t_id, coeff in enumerate(self.normal):
                ineq_np += coeff * np[t_id]
                smt_coeff = Int("a%s"%(t_id))
                smt_ineq_np += smt_coeff * np[t_id]
            # If neg point was out of this halfspace, keep it out!
            if ineq_np > 0:
                logger.info('Adding HS SMT-NEG restriction')
                solver.add(simplify(smt_ineq_np > 0))

        sol = solver.check()
        if sol == unsat:
            ret = False
            logger.info('Z3 returns UNSAT: Cannot simplify HS without adding neg info')
        elif sol == unknown:
            ret = False
            logger.info('Z3 returns UNKNOWN: Cannot simplify HS in less than %s miliseconds', timeout)
        else:
            ret = solver.model()
        return ret
示例#24
0
class Y2021D24(object):
    _re_inp = re.compile(r'inp ([wxyz])')
    _re_add = re.compile(r'add ([wxyz]) ([wxyz]|-?\d+)')
    _re_mul = re.compile(r'mul ([wxyz]) ([wxyz]|-?\d+)')
    _re_div = re.compile(r'div ([wxyz]) ([wxyz]|-?\d+)')
    _re_mod = re.compile(r'mod ([wxyz]) ([wxyz]|-?\d+)')
    _re_eql = re.compile(r'eql ([wxyz]) ([wxyz]|-?\d+)')

    def __init__(self, file_name):
        self.solver = Optimize()

        inputs = [Int(f'model_{i}') for i in range(14)]
        self.solver.add([i >= 1 for i in inputs])
        self.solver.add([i <= 9 for i in inputs])

        # Please don't ask me to explain this. There's a common pattern in the input code that treats z like a number
        # of base 26 and the operations are either right shift or left shift on that number +- some value.
        self.solver.add(inputs[0] + 6 - 6 == inputs[13])
        self.solver.add(inputs[1] + 11 - 6 == inputs[12])
        self.solver.add(inputs[2] + 5 - 13 == inputs[11])
        self.solver.add(inputs[3] + 6 - 8 == inputs[8])
        self.solver.add(inputs[4] + 8 - 1 == inputs[5])
        self.solver.add(inputs[6] + 9 - 16 == inputs[7])
        self.solver.add(inputs[9] + 13 - 16 == inputs[10])

        my_sum = IntVal(0)
        for index in range(len(inputs)):
            my_sum = (my_sum * 10) + inputs[index]

        self.value = Int('value')
        self.solver.add(my_sum == self.value)

    def part1(self):
        self.solver.push()

        self.solver.maximize(self.value)
        self.solver.check()
        result = self.solver.model()[self.value]

        self.solver.pop()

        print("Part 1:", result)

    def part2(self):
        self.solver.push()

        self.solver.minimize(self.value)
        self.solver.check()
        result = self.solver.model()[self.value]

        self.solver.pop()

        print("Part 2:", result)
示例#25
0
# Variables
is_bomb = np.array([
    Bool("is_bomb_%s%s" % (r, c)) for (r, c) in rectangle(H, W)
]).reshape(H, W).tolist()


# Bomb placement
def at_least_one_bomb_for_each_rectangle(h, w):
    return [
        PbGe([(is_bomb[r + dr][c + dc], 1) for (dr, dc) in rectangle(h, w)], 1)
        for (r, c) in rectangle(H - h + 1, W - w + 1)
    ]


# Clauses
s = Optimize()
s.add(at_least_one_bomb_for_each_rectangle(2, 3))
s.add(at_least_one_bomb_for_each_rectangle(3, 2))

# Objective
num_bombs = Sum([If(is_bomb[r][c], 1, 0) for (r, c) in rectangle(H, W)])
min_bombs = s.minimize(num_bombs)

if s.check() == sat:
    assert s.lower(min_bombs) == 6
    print("The minimum number of bombs satisfying the constraints == %s." %
          s.lower(min_bombs))
    print(diagram(s.model()))
else:
    print("Z3 failed to find a solution.")
示例#26
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
import time
import csv
from z3 import Optimize
from z3 import *

# create a dictionary contains all the street name variables
street = {}

# create a list of list contains all the intersections
intersects = []

# track increament variable
i = 0

# Optimize API solver objective functions
opt = Optimize()

# adding integer variables
X = []

# adding constrain for each street variable
C = []

# read from the .csv file
with open("../Dataset/intersection_lane.csv") as f:
	reader = csv.reader(f, delimiter=",")
	# for each row in file:
	for row in reader:
		st1 = row[0]
		# create two new variable STREET1, STREET2
		if not st1 in street:
    def __init__(self,
                 backend_prop,
                 crosstalk_prop,
                 weight_factor=0.5,
                 measured_qubits=None):
        """CrosstalkAdaptiveSchedule initializer.

        Args:
            backend_prop (BackendProperties): backend properties object
            crosstalk_prop (dict): crosstalk properties object
                crosstalk_prop[g1][g2] specifies the conditional error rate of
                g1 when g1 and g2 are executed simultaneously.
                g1 should be a two-qubit tuple of the form (x,y) where x and y are physical
                qubit ids. g2 can be either two-qubit tuple (x,y) or single-qubit tuple (x).
                We currently ignore crosstalk between pairs of single-qubit gates.
                Gate pairs which are not specified are assumed to be crosstalk free.

                Example::

                    crosstalk_prop = {(0, 1) : {(2, 3) : 0.2, (2) : 0.15},
                                                (4, 5) : {(2, 3) : 0.1},
                                                (2, 3) : {(0, 1) : 0.05, (4, 5): 0.05}}

                The keys of the crosstalk_prop are tuples for ordered tuples for CX gates
                e.g., (0, 1) corresponding to CX 0, 1 in the hardware.
                Each key has an associated value dict which specifies the conditional error rates
                with nearby gates e.g., ``(0, 1) : {(2, 3) : 0.2, (2) : 0.15}`` means that
                CNOT 0, 1 has an error rate of 0.2 when it is executed in parallel with CNOT 2,3
                and an error rate of 0.15 when it is executed in parallel with a single qubit
                gate on qubit 2.
            weight_factor (float): weight of gate error/crosstalk terms in the objective
                :math:`weight_factor*fidelities + (1-weight_factor)*decoherence errors`.
                Weight can be varied from 0 to 1, with 0 meaning that only decoherence
                errors are optimized and 1 meaning that only crosstalk errors are optimized.
                weight_factor should be tuned per application to get the best results.
            measured_qubits (list): a list of qubits that will be measured in a particular circuit.
                This arg need not be specified for circuits which already include measure gates.
                The arg is useful when a subsequent module such as state_tomography_circuits
                inserts the measure gates. If CrosstalkAdaptiveSchedule is made aware of those
                measurements, it is included in the optimization.
        Raises:
            ImportError: if unable to import z3 solver

        """
        super().__init__()
        self.backend_prop = backend_prop
        self.crosstalk_prop = crosstalk_prop
        self.weight_factor = weight_factor
        if measured_qubits is None:
            self.input_measured_qubits = []
        else:
            self.input_measured_qubits = measured_qubits
        self.bp_u1_err = {}
        self.bp_u1_dur = {}
        self.bp_u2_err = {}
        self.bp_u2_dur = {}
        self.bp_u3_err = {}
        self.bp_u3_dur = {}
        self.bp_cx_err = {}
        self.bp_cx_dur = {}
        self.bp_t1_time = {}
        self.bp_t2_time = {}
        self.gate_id = {}
        self.gate_start_time = {}
        self.gate_duration = {}
        self.gate_fidelity = {}
        self.overlap_amounts = {}
        self.overlap_indicator = {}
        self.qubit_lifetime = {}
        self.dag_overlap_set = {}
        self.xtalk_overlap_set = {}
        self.opt = Optimize()
        self.measured_qubits = []
        self.measure_start = None
        self.last_gate_on_qubit = None
        self.first_gate_on_qubit = None
        self.fidelity_terms = []
        self.coherence_terms = []
        self.model = None
        self.dag = None
        self.parse_backend_properties()
示例#29
0
    def smt_solution(self, timeout, optimize=False):
        if optimize:
            solver = Optimize()
        else:
            solver = Solver()
            solver.set("zero_accuracy",10)
        solver.set("timeout", timeout)


        non_trivial = False
        diff_sol = False
        smt_keep_sol = True # a.k.a A1
        smt_is_sol = True # a.k.a A2

        some_consume = False
        some_produce = False
        variables = set()
        variables_positive = set()
        for p_id, place in enumerate(self.facets):
            ti = place.offset
            smt_ti = Int("b%s" % p_id)

            if ti:
                solver.add(min(0,ti) <= smt_ti, smt_ti <= max(0, ti))
            else:
                solver.add(smt_ti == 0)


            facet_non_trivial = False
            facet_diff_sol = False
            smt_facet_eval = ti
            smt_facet_sol = ti

            # If halfspace's coefficients add to 1 it's
            # as simple as it gets
            simple = sum(abs(x) for x in place.normal) <= 1
            # do_cons_prod indicates if the place has incoming and outgoing transitions
            do_cons_prod = False
            consume = produce = 0
            for coeff in place.normal:
                if coeff > 0:
                    produce = 1
                elif coeff < 0:
                    consume = 1
                if consume * produce:
                    do_cons_prod = True
                    break

            do_cons_prod = reduce(lambda x,y:x*y, [x + 1 for x in place.normal]) < 1

            for t_id, coeff in enumerate(place.normal):
                # SMT coefficient
                smt_coeff = Int("a%s,%s" % (p_id, t_id))
                if optimize:
                    # Try to minimize the coefficient
                    solver.minimize(smt_coeff)
                # SMT variable
                smt_var = Int("x%s" % t_id)

                # Add SMT varible to the set of variables
                variables.add(smt_var)
                # Add SMT varible basic constraint to the set
                variables_positive.add(smt_var >= 0)
                if coeff:
                    # At least one SMT coefficient should be non zero
                    facet_non_trivial = Or(facet_non_trivial, smt_coeff != 0)
                    # At least one SMT coefficient should be different
                    facet_diff_sol = Or(facet_diff_sol, smt_coeff != coeff)
                    # Original solution with SMT variable
                    smt_facet_eval += coeff * smt_var
                    # SMT solution with SMT variable
                    smt_facet_sol += smt_coeff * smt_var
                    # Keep SMT coefficient between original bundaries
                    solver.add(min(0,coeff) <= smt_coeff, smt_coeff <= max(0, coeff))

                    if not self.neg_points and not simple and do_cons_prod:
                        some_produce = Or(some_produce, smt_coeff > 0)
                        some_consume = Or(some_consume, smt_coeff < 0)
                else:
                    # Keep zero coefficients unchanged
                    solver.add(smt_coeff == 0)
            if not self.neg_points:
                # Avoid trivial solution (i.e. all zeros as coeff)
                non_trivial = Or(non_trivial, facet_non_trivial)
            # Solution of smt must be different
            diff_sol = Or(diff_sol, facet_diff_sol)
            # If point is in old-solution should be in smt-solution
            smt_keep_sol = And(smt_keep_sol, smt_facet_eval <= 0)
            # Solutions shoul be a solution
            smt_is_sol = And(smt_is_sol, smt_facet_sol <= 0)

            if not self.neg_points and not simple and do_cons_prod:
                solver.add(simplify(some_consume))
                solver.add(simplify(some_produce))

            if optimize:
                # Try to minimize the independent term
                solver.minimize(smt_ti)

    # This is what we want:
        if not self.neg_points:
            # If there is not negative info, avoid trivial solution (i.e. Not all zero)
            solver.add(simplify(non_trivial))
        # A different solution (i.e. "better")
        solver.add(simplify(diff_sol))
        # If it was a solution before, keep it that way
        solver.add(simplify(ForAll(list(variables), Implies(And(Or(list(variables_positive)), smt_keep_sol), smt_is_sol))))

        # Negative point shouldn't be a solution
        for np in self.neg_points:
            smt_np = False
            for p_id, place in enumerate(self.facets):
                place_at_np = Int("b%s" % p_id)
                for t_id, coeff in enumerate(place.normal):
                    # If coefficient was zero, it will remain zero
                    if coeff and np[t_id]:
                        smt_coeff = Int("a%s,%s" % (p_id, t_id))
                        place_at_np = place_at_np + smt_coeff * np[t_id]

                smt_np = Or(smt_np, place_at_np > 0)
            # Keep out (NOTE halfspaces are Ax + b <= 0)
            solver.add(simplify(smt_np))

        sol = solver.check()
        if sol == unsat:
            ret = False
            logger.info('Z3 returns UNSAT: Cannot reduce without adding neg info')
        elif sol == unknown:
            ret = False
            logger.info('Z3 returns UNKNOWN: Cannot reduce in less than %s miliseconds', timeout)
        else:
            ret = solver.model()
        return ret
class CrosstalkAdaptiveSchedule(TransformationPass):
    """Crosstalk mitigation through adaptive instruction scheduling."""
    def __init__(self,
                 backend_prop,
                 crosstalk_prop,
                 weight_factor=0.5,
                 measured_qubits=None):
        """CrosstalkAdaptiveSchedule initializer.

        Args:
            backend_prop (BackendProperties): backend properties object
            crosstalk_prop (dict): crosstalk properties object
                crosstalk_prop[g1][g2] specifies the conditional error rate of
                g1 when g1 and g2 are executed simultaneously.
                g1 should be a two-qubit tuple of the form (x,y) where x and y are physical
                qubit ids. g2 can be either two-qubit tuple (x,y) or single-qubit tuple (x).
                We currently ignore crosstalk between pairs of single-qubit gates.
                Gate pairs which are not specified are assumed to be crosstalk free.

                Example::

                    crosstalk_prop = {(0, 1) : {(2, 3) : 0.2, (2) : 0.15},
                                                (4, 5) : {(2, 3) : 0.1},
                                                (2, 3) : {(0, 1) : 0.05, (4, 5): 0.05}}

                The keys of the crosstalk_prop are tuples for ordered tuples for CX gates
                e.g., (0, 1) corresponding to CX 0, 1 in the hardware.
                Each key has an associated value dict which specifies the conditional error rates
                with nearby gates e.g., ``(0, 1) : {(2, 3) : 0.2, (2) : 0.15}`` means that
                CNOT 0, 1 has an error rate of 0.2 when it is executed in parallel with CNOT 2,3
                and an error rate of 0.15 when it is executed in parallel with a single qubit
                gate on qubit 2.
            weight_factor (float): weight of gate error/crosstalk terms in the objective
                :math:`weight_factor*fidelities + (1-weight_factor)*decoherence errors`.
                Weight can be varied from 0 to 1, with 0 meaning that only decoherence
                errors are optimized and 1 meaning that only crosstalk errors are optimized.
                weight_factor should be tuned per application to get the best results.
            measured_qubits (list): a list of qubits that will be measured in a particular circuit.
                This arg need not be specified for circuits which already include measure gates.
                The arg is useful when a subsequent module such as state_tomography_circuits
                inserts the measure gates. If CrosstalkAdaptiveSchedule is made aware of those
                measurements, it is included in the optimization.
        Raises:
            ImportError: if unable to import z3 solver

        """
        super().__init__()
        self.backend_prop = backend_prop
        self.crosstalk_prop = crosstalk_prop
        self.weight_factor = weight_factor
        if measured_qubits is None:
            self.input_measured_qubits = []
        else:
            self.input_measured_qubits = measured_qubits
        self.bp_u1_err = {}
        self.bp_u1_dur = {}
        self.bp_u2_err = {}
        self.bp_u2_dur = {}
        self.bp_u3_err = {}
        self.bp_u3_dur = {}
        self.bp_cx_err = {}
        self.bp_cx_dur = {}
        self.bp_t1_time = {}
        self.bp_t2_time = {}
        self.gate_id = {}
        self.gate_start_time = {}
        self.gate_duration = {}
        self.gate_fidelity = {}
        self.overlap_amounts = {}
        self.overlap_indicator = {}
        self.qubit_lifetime = {}
        self.dag_overlap_set = {}
        self.xtalk_overlap_set = {}
        self.opt = Optimize()
        self.measured_qubits = []
        self.measure_start = None
        self.last_gate_on_qubit = None
        self.first_gate_on_qubit = None
        self.fidelity_terms = []
        self.coherence_terms = []
        self.model = None
        self.dag = None
        self.parse_backend_properties()

    def powerset(self, iterable):
        """
        Finds the set of all subsets of the given iterable
        This function is used to generate constraints for the Z3 optimization
        """
        l_s = list(iterable)
        return chain.from_iterable(
            combinations(l_s, r) for r in range(len(l_s) + 1))

    def parse_backend_properties(self):
        """
        This function assumes that gate durations and coherence times
        are in seconds in backend.properties()
        This function converts gate durations and coherence times to
        nanoseconds.
        """
        backend_prop = self.backend_prop
        for qid in range(len(backend_prop.qubits)):
            self.bp_t1_time[qid] = int(backend_prop.t1(qid) * 10**9)
            self.bp_t2_time[qid] = int(backend_prop.t2(qid) * 10**9)
            self.bp_u1_dur[qid] = int(backend_prop.gate_length('u1',
                                                               qid)) * 10**9
            u1_err = backend_prop.gate_error('u1', qid)
            if u1_err == 1.0:
                u1_err = 0.9999
            self.bp_u1_err = round(u1_err, NUM_PREC)
            self.bp_u2_dur[qid] = int(backend_prop.gate_length('u2',
                                                               qid)) * 10**9
            u2_err = backend_prop.gate_error('u2', qid)
            if u2_err == 1.0:
                u2_err = 0.9999
            self.bp_u2_err = round(u2_err, NUM_PREC)
            self.bp_u3_dur[qid] = int(backend_prop.gate_length('u3',
                                                               qid)) * 10**9
            u3_err = backend_prop.gate_error('u3', qid)
            if u3_err == 1.0:
                u3_err = 0.9999
            self.bp_u3_err = round(u3_err, NUM_PREC)
        for ginfo in backend_prop.gates:
            if ginfo.gate == 'cx':
                q_0 = ginfo.qubits[0]
                q_1 = ginfo.qubits[1]
                cx_tup = (min(q_0, q_1), max(q_0, q_1))
                self.bp_cx_dur[cx_tup] = int(
                    backend_prop.gate_length('cx', cx_tup)) * 10**9
                cx_err = backend_prop.gate_error('cx', cx_tup)
                if cx_err == 1.0:
                    cx_err = 0.9999
                self.bp_cx_err[cx_tup] = round(cx_err, NUM_PREC)

    def cx_tuple(self, gate):
        """
        Representation for two-qubit gate
        Note: current implementation assumes that the CX error rates and
        crosstalk behavior are independent of gate direction
        """
        physical_q_0 = gate.qargs[0].index
        physical_q_1 = gate.qargs[1].index
        r_0 = min(physical_q_0, physical_q_1)
        r_1 = max(physical_q_0, physical_q_1)
        return (r_0, r_1)

    def singleq_tuple(self, gate):
        """
        Representation for single-qubit gate
        """
        physical_q_0 = gate.qargs[0].index
        tup = (physical_q_0, )
        return tup

    def gate_tuple(self, gate):
        """
        Representation for gate
        """
        if len(gate.qargs) == 2:
            return self.cx_tuple(gate)
        else:
            return self.singleq_tuple(gate)

    def assign_gate_id(self, dag):
        """
        ID for each gate
        """
        idx = 0
        for gate in dag.gate_nodes():
            self.gate_id[gate] = idx
            idx += 1

    def extract_dag_overlap_sets(self, dag):
        """
        Gate A, B are overlapping if
        A is neither a descendant nor an ancestor of B.
        Currenty overlaps (A,B) are considered when A is a 2q gate and
        B is either 2q or 1q gate.
        """
        for gate in dag.two_qubit_ops():
            overlap_set = []
            descendants = dag.descendants(gate)
            ancestors = dag.ancestors(gate)
            for tmp_gate in dag.gate_nodes():
                if tmp_gate == gate:
                    continue
                if tmp_gate in descendants:
                    continue
                if tmp_gate in ancestors:
                    continue
                overlap_set.append(tmp_gate)
            self.dag_overlap_set[gate] = overlap_set

    def is_significant_xtalk(self, gate1, gate2):
        """
        Given two conditional gate error rates
        check if there is high crosstalk by comparing with independent error rates.
        """
        gate1_tup = self.gate_tuple(gate1)
        if len(gate2.qargs) == 2:
            gate2_tup = self.gate_tuple(gate2)
            independent_err_g_1 = self.bp_cx_err[gate1_tup]
            independent_err_g_2 = self.bp_cx_err[gate2_tup]
            rg_1 = self.crosstalk_prop[gate1_tup][
                gate2_tup] / independent_err_g_1
            rg_2 = self.crosstalk_prop[gate2_tup][
                gate1_tup] / independent_err_g_2
            if rg_1 > TWOQ_XTALK_THRESH or rg_2 > TWOQ_XTALK_THRESH:
                return True
        else:
            gate2_tup = self.gate_tuple(gate2)
            independent_err_g_1 = self.bp_cx_err[gate1_tup]
            rg_1 = self.crosstalk_prop[gate1_tup][
                gate2_tup] / independent_err_g_1
            if rg_1 > ONEQ_XTALK_THRESH:
                return True
        return False

    def extract_crosstalk_relevant_sets(self):
        """
        Extract the set of program gates which potentially have crosstalk noise
        """
        for gate in self.dag_overlap_set:
            self.xtalk_overlap_set[gate] = []
            tup_g = self.gate_tuple(gate)
            if tup_g not in self.crosstalk_prop:
                continue
            for par_g in self.dag_overlap_set[gate]:
                tup_par_g = self.gate_tuple(par_g)
                if tup_par_g in self.crosstalk_prop[tup_g]:
                    if self.is_significant_xtalk(gate, par_g):
                        if par_g not in self.xtalk_overlap_set[gate]:
                            self.xtalk_overlap_set[gate].append(par_g)

    def create_z3_vars(self):
        """
        Setup the variables required for Z3 optimization
        """
        for gate in self.dag.gate_nodes():
            t_var_name = 't_' + str(self.gate_id[gate])
            d_var_name = 'd_' + str(self.gate_id[gate])
            f_var_name = 'f_' + str(self.gate_id[gate])
            self.gate_start_time[gate] = Real(t_var_name)
            self.gate_duration[gate] = Real(d_var_name)
            self.gate_fidelity[gate] = Real(f_var_name)
        for gate in self.xtalk_overlap_set:
            self.overlap_indicator[gate] = {}
            self.overlap_amounts[gate] = {}
        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 g_1 in self.overlap_indicator[g_2]:
                    self.overlap_indicator[g_1][g_2] = self.overlap_indicator[
                        g_2][g_1]
                    self.overlap_amounts[g_1][g_2] = self.overlap_amounts[g_2][
                        g_1]
                else:
                    # Indicator variable for overlap of g_1 and g_2
                    var_name1 = 'olp_ind_' + str(
                        self.gate_id[g_1]) + '_' + str(self.gate_id[g_2])
                    self.overlap_indicator[g_1][g_2] = Bool(var_name1)
                    var_name2 = 'olp_amnt_' + str(
                        self.gate_id[g_1]) + '_' + str(self.gate_id[g_2])
                    self.overlap_amounts[g_1][g_2] = Real(var_name2)
        active_qubits_list = []
        for gate in self.dag.gate_nodes():
            for q in gate.qargs:
                active_qubits_list.append(q.index)
        for active_qubit in list(set(active_qubits_list)):
            q_var_name = 'l_' + str(active_qubit)
            self.qubit_lifetime[active_qubit] = Real(q_var_name)

        meas_q = []
        for node in self.dag.op_nodes():
            if isinstance(node.op, Measure):
                meas_q.append(node.qargs[0].index)

        self.measured_qubits = list(
            set(self.input_measured_qubits).union(set(meas_q)))
        self.measure_start = Real('meas_start')

    def basic_bounds(self):
        """
        Basic variable bounds for optimization
        """
        for gate in self.gate_start_time:
            self.opt.add(self.gate_start_time[gate] >= 0)
        for gate in self.gate_duration:
            q_0 = gate.qargs[0].index
            if isinstance(gate.op, U1Gate):
                dur = self.bp_u1_dur[q_0]
            elif isinstance(gate.op, U2Gate):
                dur = self.bp_u2_dur[q_0]
            elif isinstance(gate.op, U3Gate):
                dur = self.bp_u3_dur[q_0]
            elif isinstance(gate.op, CXGate):
                dur = self.bp_cx_dur[self.cx_tuple(gate)]
            self.opt.add(self.gate_duration[gate] == dur)

    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)

    def fidelity_constraints(self):
        """
        Set gate fidelity based on gate overlap conditions
        """
        for gate in self.gate_start_time:
            q_0 = gate.qargs[0].index
            no_xtalk = False
            if gate not in self.xtalk_overlap_set:
                no_xtalk = True
            elif not self.xtalk_overlap_set[gate]:
                no_xtalk = True
            if no_xtalk:
                if isinstance(gate.op, U1Gate):
                    fid = math.log(1.0)
                elif isinstance(gate.op, U2Gate):
                    fid = math.log(1.0 - self.bp_u2_err[q_0])
                elif isinstance(gate.op, U3Gate):
                    fid = math.log(1.0 - self.bp_u3_err[q_0])
                elif isinstance(gate.op, CXGate):
                    fid = math.log(1.0 - self.bp_cx_err[self.cx_tuple(gate)])
                self.opt.add(self.gate_fidelity[gate] == round(fid, NUM_PREC))
            else:
                comb = list(self.powerset(self.xtalk_overlap_set[gate]))
                xtalk_set = set(self.xtalk_overlap_set[gate])
                for item in comb:
                    on_set = item
                    off_set = [i for i in xtalk_set if i not in on_set]
                    clauses = []
                    for tmpg in on_set:
                        clauses.append(self.overlap_indicator[gate][tmpg])
                    for tmpg in off_set:
                        clauses.append(Not(self.overlap_indicator[gate][tmpg]))
                    err = 0
                    if not on_set:
                        err = self.bp_cx_err[self.cx_tuple(gate)]
                    elif len(on_set) == 1:
                        on_gate = on_set[0]
                        err = self.crosstalk_prop[self.gate_tuple(gate)][
                            self.gate_tuple(on_gate)]
                    else:
                        err_list = []
                        for on_gate in on_set:
                            tmp_prop = self.crosstalk_prop[self.gate_tuple(
                                gate)]
                            err_list.append(tmp_prop[self.gate_tuple(on_gate)])
                        err = max(err_list)
                    if err == 1.0:
                        err = 0.999999
                    val = round(math.log(1.0 - err), NUM_PREC)
                    self.opt.add(
                        Implies(And(*clauses),
                                self.gate_fidelity[gate] == val))

    def coherence_constraints(self):
        """
        Set decoherence errors based on qubit lifetimes
        """
        self.last_gate_on_qubit = {}
        for gate in self.dag.topological_op_nodes():
            if isinstance(gate.op, Measure):
                continue
            if isinstance(gate.op, Barrier):
                continue
            if len(gate.qargs) == 1:
                q_0 = gate.qargs[0].index
                self.last_gate_on_qubit[q_0] = gate
            else:
                q_0 = gate.qargs[0].index
                q_1 = gate.qargs[1].index
                self.last_gate_on_qubit[q_0] = gate
                self.last_gate_on_qubit[q_1] = gate

        self.first_gate_on_qubit = {}
        for gate in self.dag.topological_op_nodes():
            if len(gate.qargs) == 1:
                q_0 = gate.qargs[0].index
                if q_0 not in self.first_gate_on_qubit:
                    self.first_gate_on_qubit[q_0] = gate
            else:
                q_0 = gate.qargs[0].index
                q_1 = gate.qargs[1].index
                if q_0 not in self.first_gate_on_qubit:
                    self.first_gate_on_qubit[q_0] = gate
                if q_1 not in self.first_gate_on_qubit:
                    self.first_gate_on_qubit[q_1] = gate

        for q in self.last_gate_on_qubit:
            g_last = self.last_gate_on_qubit[q]
            g_first = self.first_gate_on_qubit[q]
            finish_time = self.gate_start_time[g_last] + self.gate_duration[
                g_last]
            start_time = self.gate_start_time[g_first]
            if q in self.measured_qubits:
                self.opt.add(self.measure_start >= finish_time)
                self.opt.add(self.qubit_lifetime[q] == self.measure_start -
                             start_time)
            else:
                # All qubits get measured simultaneously whether or not they need a measurement
                self.opt.add(self.measure_start >= finish_time)
                self.opt.add(self.qubit_lifetime[q] == finish_time -
                             start_time)

    def objective_function(self):
        """
        Objective function is a weighted combination of gate errors and decoherence errors
        """
        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(Sum(all_terms))

    def r2f(self, val):
        """
        Convert Z3 Real to Python float
        """
        return float(val.as_decimal(16).rstrip('?'))

    def extract_solution(self):
        """
        Extract gate start and finish times from Z3 solution
        """
        self.model = self.opt.model()
        result = {}
        for tmpg in self.gate_start_time:
            start = self.r2f(self.model[self.gate_start_time[tmpg]])
            dur = self.r2f(self.model[self.gate_duration[tmpg]])
            result[tmpg] = (start, start + dur)
        return result

    def solve_optimization(self):
        """
        Setup and solve a Z3 optimization for finding the best schedule
        """
        self.opt = Optimize()
        self.create_z3_vars()
        self.basic_bounds()
        self.scheduling_constraints()
        self.fidelity_constraints()
        self.coherence_constraints()
        self.objective_function()
        # Solve step
        self.opt.check()
        # Extract the schedule computed by Z3
        result = self.extract_solution()
        return result

    def check_dag_dependency(self, gate1, gate2):
        """
        gate2 is a DAG dependent of gate1 if it is a descendant of gate1
        """
        return gate2 in self.dag.descendants(gate1)

    def check_xtalk_dependency(self, t_1, t_2):
        """
        Check if two gates have a crosstalk dependency.
        We do not consider crosstalk between pairs of single qubit gates.
        """
        g_1 = t_1[0]
        s_1 = t_1[1]
        f_1 = t_1[2]
        g_2 = t_2[0]
        s_2 = t_2[1]
        f_2 = t_2[2]
        if len(g_1.qargs) == 1 and len(g_2.qargs) == 1:
            return False, ()
        if s_2 <= f_1 and s_1 <= f_2:
            # Z3 says it's ok to overlap these gates,
            # so no xtalk dependency needs to be checked
            return False, ()
        else:
            # Assert because we are iterating in Z3 gate start time order,
            # so if two gates are not overlapping, then the second gate has to
            # start after the first gate finishes
            assert s_2 >= f_1
            # Not overlapping, but we care about this dependency
            if len(g_1.qargs) == 2 and len(g_2.qargs) == 2:
                if g_2 in self.xtalk_overlap_set[g_1]:
                    cx1 = self.cx_tuple(g_1)
                    cx2 = self.cx_tuple(g_2)
                    barrier = tuple(sorted([cx1[0], cx1[1], cx2[0], cx2[1]]))
                    return True, barrier
            elif len(g_1.qargs) == 1 and len(g_2.qargs) == 2:
                if g_1 in self.xtalk_overlap_set[g_2]:
                    singleq = self.gate_tuple(g_1)
                    cx1 = self.cx_tuple(g_2)
                    print(singleq, cx1)
                    barrier = tuple(sorted([singleq, cx1[0], cx1[1]]))
                    return True, barrier
            elif len(g_1.qargs) == 2 and len(g_2.qargs) == 1:
                if g_2 in self.xtalk_overlap_set[g_1]:
                    singleq = self.gate_tuple(g_2)
                    cx1 = self.cx_tuple(g_1)
                    barrier = tuple(sorted([singleq, cx1[0], cx1[1]]))
                    return True, barrier
            # Not overlapping, and we don't care about xtalk between these two gates
            return False, ()

    def filter_candidates(self, candidates, layer, layer_id, triplet):
        """
        For a gate G and layer L,
        L is a candidate layer for G if no gate in L has a DAG dependency with G,
        and if Z3 allows gates in L and G to overlap.
        """
        curr_gate = triplet[0]
        for prev_triplet in layer:
            prev_gate = prev_triplet[0]
            is_dag_dep = self.check_dag_dependency(prev_gate, curr_gate)
            is_xtalk_dep, _ = self.check_xtalk_dependency(
                prev_triplet, triplet)
            if is_dag_dep or is_xtalk_dep:
                # If there is a DAG dependency, we can't insert in any previous layer
                # If there is Xtalk dependency, we can (in general) insert in previous layers,
                # but since we are iterating in the order of gate start times,
                # we should only insert this gate in subsequent layers
                for i in range(layer_id + 1):
                    if i in candidates:
                        candidates.remove(i)
            return candidates

    def find_layer(self, layers, triplet):
        """
        Find the appropriate layer for a gate
        """
        candidates = list(range(len(layers)))
        for i, layer in enumerate(layers):
            candidates = self.filter_candidates(candidates, layer, i, triplet)
        if not candidates:
            return len(layers)
            # Open a new layer
        else:
            return max(candidates)
            # Latest acceptable layer, right-alignment

    def generate_barriers(self, layers):
        """
        For each gate g, see if a barrier is required to serialize it with
        some previously processed gate
        """
        barriers = []
        for i, layer in enumerate(layers):
            barriers.append(set())
            if i == 0:
                continue
            for t_2 in layer:
                for j in range(i):
                    prev_layer = layers[j]
                    for t_1 in prev_layer:
                        is_dag_dep = self.check_dag_dependency(t_1[0], t_2[0])
                        is_xtalk_dep, curr_barrier = self.check_xtalk_dependency(
                            t_1, t_2)
                        if is_dag_dep:
                            # Don't insert a barrier since there is a DAG dependency
                            continue
                        if is_xtalk_dep:
                            # Insert a barrier for this layer
                            barriers[-1].add(curr_barrier)
        return barriers

    def create_updated_dag(self, layers, barriers):
        """
        Given a set of layers and barries, construct a new dag
        """
        new_dag = DAGCircuit()
        for qreg in self.dag.qregs.values():
            new_dag.add_qreg(qreg)
        for creg in self.dag.cregs.values():
            new_dag.add_creg(creg)
        canonical_register = new_dag.qregs['q']
        for i, layer in enumerate(layers):
            curr_barriers = barriers[i]
            for b in curr_barriers:
                current_qregs = []
                for idx in b:
                    current_qregs.append(canonical_register[idx])
                new_dag.apply_operation_back(Barrier(len(b)), current_qregs,
                                             [])
            for triplet in layer:
                gate = triplet[0]
                new_dag.apply_operation_back(gate.op, gate.qargs, gate.cargs)

        for node in self.dag.op_nodes():
            if isinstance(node.op, Measure):
                new_dag.apply_operation_back(node.op, node.qargs, node.cargs)

        return new_dag

    def enforce_schedule_on_dag(self, input_gate_times):
        """
        Z3 outputs start times for each gate.
        Some gates need to be serialized to implement the Z3 schedule.
        This function inserts barriers to implement those serializations
        """
        gate_times = []
        for key in input_gate_times:
            gate_times.append(
                (key, input_gate_times[key][0], input_gate_times[key][1]))
        # Sort gates by start time
        sorted_gate_times = sorted(gate_times, key=operator.itemgetter(1))
        layers = []
        # Construct a set of layers. Each layer has a set of gates that
        # are allowed to fire in parallel according to Z3
        for triplet in sorted_gate_times:
            layer_idx = self.find_layer(layers, triplet)
            if layer_idx == len(layers):
                layers.append([triplet])
            else:
                layers[layer_idx].append(triplet)
        # Insert barries if necessary to enforce the above layers
        barriers = self.generate_barriers(layers)
        new_dag = self.create_updated_dag(layers, barriers)
        return new_dag

    def reset(self):
        """
        Reset variables
        """
        self.gate_id = {}
        self.gate_start_time = {}
        self.gate_duration = {}
        self.gate_fidelity = {}
        self.overlap_amounts = {}
        self.overlap_indicator = {}
        self.qubit_lifetime = {}
        self.dag_overlap_set = {}
        self.xtalk_overlap_set = {}
        self.measured_qubits = []
        self.measure_start = None
        self.last_gate_on_qubit = None
        self.first_gate_on_qubit = None
        self.fidelity_terms = []
        self.coherence_terms = []
        self.model = None

    def run(self, dag):
        """
        Main scheduling function
        """
        if not HAS_Z3:
            raise TranspilerError(
                'z3-solver is required to use CrosstalkAdaptiveSchedule. '
                'To install, run "pip install z3-solver".')

        self.dag = dag

        # process input program
        self.assign_gate_id(self.dag)
        self.extract_dag_overlap_sets(self.dag)
        self.extract_crosstalk_relevant_sets()

        # setup and solve a Z3 optimization
        z3_result = self.solve_optimization()

        # post-process to insert barriers
        new_dag = self.enforce_schedule_on_dag(z3_result)
        self.reset()
        return new_dag
示例#31
0
import time
import csv
from z3 import Optimize
from z3 import *

# create a dictionary contains all the street name variables
street = {}

# create a list of list contains all the intersections
intersects = []

# track increament variable
i = 0

# Optimize API solver objective functions
opt = Optimize()

# adding integer variables
X = []

# adding constrain for each street variable
C = []

# read from the .csv file
with open("../Dataset/intersection_lane.csv") as f:
    reader = csv.reader(f, delimiter=",")
    # for each row in file:
    for row in reader:
        st1 = row[0]
        # create two new variable STREET1, STREET2
        if not st1 in street:
def geometry_free_solve_(ddn1, ddn2, ws, station_data, sta1, sta2, prn1, prn2, ticks):
    lambda_1 = lambda_1s[prn1[0]]
    lambda_2 = lambda_2s[prn1[0]]

    # Φ_i - R_i = B_i + err  with B_i = b_i + λ_1*N_1 - λ_2*N_2
    B_i = bias(tec.geometry_free)
    
    sol = Optimize()
#    sol = Solver()
    errs = Reals('err_11 err_12 err_21 err_22')
    n1s = Ints('n1_11 n1_12 n1_21 n1_22')
    n2s = Ints('n2_11 n2_12 n2_21 n2_22')

    sol.add(n1s[0] - n1s[1] - n1s[2] + n1s[3] == ddn1)
    sol.add(n2s[0] - n2s[1] - n2s[2] + n2s[3] == ddn2)

    for i, (sta, prn) in enumerate(product([sta1, sta2], [prn1, prn2])):
        sol.add(n1s[i] - n2s[i] == ws[i])
        B_i_samples = []
        for tick in ticks:
            B_i_samples.append( B_i(station_data[sta][prn][tick])[0] )
        B_i_avg = numpy.mean(B_i_samples)
#        B_i_avg = B_i_samples[0]
        print(B_i_avg, numpy.std(B_i_samples))
        sol.add(lambda_1 * ToReal(n1s[i]) - lambda_2 * ToReal(n2s[i]) + errs[i] > B_i_avg)
        sol.add(lambda_1 * ToReal(n1s[i]) - lambda_2 * ToReal(n2s[i]) - errs[i] < B_i_avg)
    """
        sol.add(errs[0] < .9)
        sol.add(errs[1] < .9)
        sol.add(errs[2] < .9)
        sol.add(errs[3] < .9)
    """
    #sol.add(errs[0] + errs[1] + errs[2] + errs[3] < 17)
    objective = sol.minimize(errs[0] + errs[1] + errs[2] + errs[3])
    if sol.check() != sat:
        return None
    sol.lower(objective)
    if sol.check() != sat:
        return None
#    sol.add(errs[0] + errs[1] + errs[2] + errs[3] < 2)
    # can't do L2 norm with z3, L1 will have to do...
#    sol.(errs[0] + errs[1] + errs[2] + errs[3])

    
    return (
        [sol.model()[n1s[i]].as_long() for i in range(4)],
        [sol.model()[n2s[i]].as_long() for i in range(4)],
        [frac_to_float(sol.model()[errs[i]]) for i in range(4)],
    )
def dd_solve_(dd, vr1s1, vr1s2, vr2s1, vr2s2, wavelength, ionosphere=False):
    sol = Optimize()
    r1s1, r1s2, r2s1, r2s2 = Ints('r1s1 r1s2 r2s1 r2s2')
#    err = Real('err')
    err1, err2, err3, err4 = Reals('err1 err2 err3 err4')
#    sol.add(err > 0)

    if ionosphere:
        ion = Real('ion')
        sol.add(ion > 0)
        sol.add(ion < 25)
    else:
        ion = 0

    sol.add(r1s1 - r1s2 - r2s1 + r2s2 == dd)

    sol.add(ToReal(r1s1)*wavelength + err1 > vr1s1 - ion)
    sol.add(ToReal(r1s1)*wavelength - err1 < vr1s1 - ion)

    sol.add(ToReal(r1s2)*wavelength + err2 > vr1s2 - ion)
    sol.add(ToReal(r1s2)*wavelength - err2 < vr1s2 - ion)

    sol.add(ToReal(r2s1)*wavelength + err3 > vr2s1 - ion)
    sol.add(ToReal(r2s1)*wavelength - err3 < vr2s1 - ion)

    sol.add(ToReal(r2s2)*wavelength + err4 > vr2s2 - ion)
    sol.add(ToReal(r2s2)*wavelength - err4 < vr2s2 - ion)

    objective = sol.minimize(err1 + err2 + err3 + err4)

    if sol.check() != sat:
        return None
    
    sol.lower(objective)
    if sol.check() != sat:
        return None

    return (
        [sol.model()[r].as_long() for r in [r1s1, r1s2, r2s1, r2s2]],
        [frac_to_float(sol.model()[err]) for err in [err1, err2, err3, err4]],
        frac_to_float(sol.model()[ion]) if ionosphere else 0
    )
示例#34
0
    def from_model(model):
        start_over()
        context = Context()
        context.load_metamodel()
        context.load_model(model)

        solver = Optimize()

        generate_meta_constraints()
        generate_config_constraints()

        solver.add(*get_all_meta_facts())
        solver.add(*get_all_config_facts())

        context.declare(INTEGRITY_VARIABLES)
        context.declare_helper_functions()

        for each_constraint in INTEGRITY_CONSTRAINTS:
            solver.add(context.evaluate(each_constraint))

        for each_running_service in model.goals.services:
            constraint = RUNNING_SERVICE.format(each_running_service.name)
            solver.add(context.evaluate(constraint))

        for each_constraint in model.constraints:
            solver.add(context.evaluate(each_constraint))

        for each_constraint in context.value_constraints:
            solver.add(context.evaluate(each_constraint))

        #print solver.sexpr()
        return Z3Problem(model, context, solver)
示例#35
0
from z3 import Optimize, Real, If

x = Real('x')
y = Real('y')
z = Real('z')


def z3abs(obj):
    return If(x > 0, x, -x)

optimizer = Optimize()
# optimizer.add(x>0.0)
# optimizer.add(y>0.0)
optimizer.add(x*x+y*y==1.0)
optimizer.add_soft(z == x+y)
optimizer.maximize(z)
result = optimizer.check()

print(optimizer.model())