def add_optimize_targets2(solver, int_dict, order_dict): # new optimize target # A*o1+(1-A)*o2 # o1 = AVG[v'(pkg)/|V(pkg)|] if v'(pkg)!=|V(pkg)| ((not installed)) # o2 = (|P|-|P'|)/|P| if p is installed, p belongs to P' A = 0.5 o1 = Real("o1") o2 = Real("o2") sum_ins = Int("sum_ins") sum_all = Int("sum_all") count_ins = Int("count_ins") sum_ins, sum_all, count_ins = 0, 0, 0 count_all = 0 for pkg in int_dict: sum_ins = If(int_dict[pkg] != len(order_dict[pkg]), sum_ins + int_dict[pkg], sum_ins) count_ins = If(int_dict[pkg] != len(order_dict[pkg]), count_ins + 1, count_ins) sum_all = If(int_dict[pkg] != len(order_dict[pkg]), sum_all + len(order_dict[pkg]), sum_all) count_all += 1 o1 = ToReal(sum_ins) / ToReal(sum_all) o2 = 1 - (ToReal(count_ins) / count_all) target = A * o1 + (1 - A) * o2 solver.maximize(target) return solver
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()
def mk_var(name, vsort): """ Create a variable of type vsort. Examples: >>> from z3 import * >>> v = mk_var('real_v', Real('x').sort()) >>> print v real_v """ if vsort.kind() == Z3_INT_SORT: v = Int(name) elif vsort.kind() == Z3_REAL_SORT: v = Real(name) elif vsort.kind() == Z3_BOOL_SORT: v = Bool(name) elif vsort.kind() == Z3_DATATYPE_SORT: v = Const(name, vsort) else: raise AssertionError,\ 'Cannot handle this sort (s: {}, {})'\ .format(vsort, vsort.kind()) return v
def __init__(self, id:int, gate:Gate, prev:OrderedDict[int,Instruction], qubit_map:Dict[int, Qubit], other_args:List=[]): # The instructions numerical identifier self.id : int = id # The gate of the instruction self.gate : Gate = gate # A name for the instruction self.name : str = str(self.gate.name) + "_" + str(self.id) # Previous instructions in the dependency graph: those instrs that this one depends on self.prev : OrderedDict[int,Instruction] = prev # Available Qubits, mapped from their indices self.qubit_map: Dict[int, Qubit] = qubit_map # Qubit indicies applied to: # This is intuitively the primary mapping from "logical" indices to real ones. # The consistency over the entire graph is maintained by the constraints. self.on_indices: OrderedDict[int, Int] = OrderedDict([(edge,Int(self.name+".edge_"+str(edge))) for edge in prev.keys()]) # Time slot to run this instruction in self.time: Int = Int(self.name + ".timeslot") # Reliability of this instruction: depends on the operation and which qubit it's assigned to self.reliability: Real = Real(self.name + ".reliability") # Other args like rotations: TODO self.other_args: List = other_args
def get_z3obj_type(d_type, name): from z3 import Bool, Int, Real if d_type.is_bool: return Bool(name) elif d_type.is_integer: return Int(name) else: return Real(name)
def run_code2inv_problem(problem_num): fname = str(problem_num) + '.c' csvname = str(problem_num) + '.csv' src_path = 'benchmarks/code2inv/c/' check_path = 'benchmarks/code2inv/smt2/' trace_path = 'benchmarks/code2inv/csv/' if problem_num in [26, 27, 31, 32, 61, 62, 72, 75, 106]: print(problem_num, 'theoretically unsolvable') return False, '', 0 start_time = time.time() consts = load_consts(problem_num, 'benchmarks/code2inv/smt2/const.txt') templateGen = TemplateGen(src_path + fname, trace_path + csvname) trainer = CLNTrainer(trace_path + csvname) invariantChecker = InvariantChecker(fname, check_path) non_loop_invariant = None if problem_num in [110, 111, 112, 113]: # non_loop_invariant = And(Real('sn') == 0, Real('i') == 1, Real('n') < 0) non_loop_invariant = And( Real('sn') == 0, Real('i') == 1, Real('n') < 1) elif problem_num in [118, 119, 122, 123]: non_loop_invariant = And( Real('sn') == 0, Real('i') == 1, Real('size') < 1) solved, inv_str = False, '' for n_template in range(10_000): cln_template = templateGen.get_next_template() if cln_template is None: break rerun = True max_epoch = 2000 restarts = 0 while not solved and rerun and restarts < 10: invariant, rerun = trainer.build_train_cln( cln_template, consts, max_epoch=max_epoch, non_loop_invariant=non_loop_invariant, pname=problem_num) try: solved, inv_str = invariantChecker.check_cln(invariant) except: # rerun if z3 throws an error rerun = True max_epoch += 1000 restarts += 1 if solved: break
def dd_solve_(dd, vr1s1, vr1s2, vr2s1, vr2s2, wavelength): sol = Solver() r1s1, r1s2, r2s1, r2s2 = Ints('r1s1 r1s2 r2s1 r2s2') err = Real('err') err1, err1, err3, err4 = Reals('err1 err2 err3 err4') # sol.add(err > 0) sol.add(r1s1 - r1s2 - r2s1 + r2s2 == dd) sol.add(ToReal(r1s1)*wavelength + err1 > vr1s1) sol.add(ToReal(r1s1)*wavelength - err1 < vr1s1) sol.add(ToReal(r1s2)*wavelength + err2 > vr1s2) sol.add(ToReal(r1s2)*wavelength - err2 < vr1s2) sol.add(ToReal(r2s1)*wavelength + err3 > vr2s1) sol.add(ToReal(r2s1)*wavelength - err3 < vr2s1) sol.add(ToReal(r2s2)*wavelength + err4 > vr2s2) sol.add(ToReal(r2s2)*wavelength - err4 < vr2s2) if sol.check() != sat: return None def minimize(): # try to push the error lower, if possible for mult in [0.5, 0.85]: while sol.check() == sat: sol.push() sol.check() err_bound = frac_to_float(sol.model()[err]) if err_bound < 0.2: # not gonna do better than that... return sol.add(err < err_bound*mult) sol.pop() sol.check() minimize() return ( [sol.model()[r].as_long() for r in [r1s1, r1s2, r2s1, r2s2]], frac_to_float(sol.model()[err]) )
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 )
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 run_code2inv_problem(i): verbose=False solved=False if i in [26, 27, 31, 32, 61, 62, 72, 75, 106]: print(i,'theoretically unsolvable') return True, 0 start_time = time.time() attempts = 0 first_time = True max_epoch = 2000 I = None while (solved == False): attempts += 1 if attempts > 10: # print('failed', i) # return False break if first_time: solved, I = fast_checker(i) if solved: break else: non_loop_invariant = None if i in [110, 111, 112, 113]: non_loop_invariant = And(Real('sn') == 0, Real('i') == 1, Real('n') < 0) elif i in [118, 119, 122, 123]: non_loop_invariant = And(Real('sn') == 0, Real('i') == 1, Real('size') < 0) solved, I = gcln_infer(i, max_epoch=max_epoch, non_loop_invariant=non_loop_invariant) first_time = False max_epoch += 1000 end_time = time.time() runtime = end_time - start_time print('Problem number:', i, 'solved?',solved, 'time:', runtime) if I is not None: print(I) return solved, runtime
def state_valuation_to_z3_check_args(state_valuation): """ Converts a state_valuation to a list of state args which is to be passed to a relative inductiveness check. :param state_valuation: The state valuation that is to be converted. :return: The list of args of the solver. """ return [ eq_no_coerce(var.variable, val) for var, val in state_valuation.items() ] compare_solver = Solver() integer_div_res = Int("Div") real_div_res = Real("RDiv") eval_result = Real("result") def z3_values_check_gt(val_1, val_2): return compare_solver.check(val_1 > val_2) == sat def z3_values_check_lt(val_1, val_2): return compare_solver.check(val_1 < val_2) == sat def z3_values_check_geq(val_1, val_2): return compare_solver.check(val_1 >= val_2) == sat
def run(self, state_id, chosen_command, delta, states_with_fixed_probabilities = set()): """ :param state_id: :param delta: :return: (1) True iff it is possible to find probabilities for the successors of the given state_id and delta. (2) If True, then it returns a dict form succ_ids to probabilities. This dict does not contain goal states. """ # TODO consider changing to None if not possible, and dict otherwise. self.statistics.inc_get_probability_counter() self.statistics.start_get_probability_timer() # First check whether we have cached the corresponding obligation res = self._obligation_cache.get_cached(state_id, chosen_command, delta) if res != False: self.statistics.stop_get_probability_timer() return (True, res) # If not, we have to ask the SMT-Solver succ_dist = self.state_graph.get_successors_filtered(state_id).by_command_index(chosen_command) succ_dist_without_target_states = [(state_id, prob) for (state_id, prob) in succ_dist if state_id != -1] # Check if there is at least one non-target state. Otherwise, repairing is not possible (smt solver would return unsat if we continued, so checking this is an optimization). if len(succ_dist_without_target_states) == 0: self.statistics.stop_get_probability_timer() return (False, None) self.opt_solver.push() vars = {} # We need a variable for each successor for (succ_id, prob) in succ_dist: if succ_id != -1: vars[succ_id] = Real("x_%s" % succ_id) # all results must of be probabilities self.opt_solver.add(vars[succ_id] >= self._realval_zero) self.opt_solver.add(vars[succ_id] <= self._realval_one) # \Phi(F)[s] = delta constraint # TODO: Type of porb is pycarl.gmp.gmp.Rational. Z3 magically deals with this self.opt_solver.add( Sum([ (vars[succ_id] if succ_id != -1 else RealVal(1)) * prob # Note: Keep in mind that you need to check whether succ is a target state for (succ_id, prob) in succ_dist ]) == delta) for (succ_id, prob) in succ_dist: if succ_id in states_with_fixed_probabilities: self.opt_solver.add(vars[succ_id] == self.obligation_queue_class.smallest_probability_for_state[succ_id]) # If we have more than one non-target successor, we have to optimize if len(succ_dist_without_target_states) > 1: # first check whether all oracle values are 0 (note that we do not have to do this if there is only one succ without target) if len(succ_dist_without_target_states) > 1 and sum([self.oracle.get_oracle_value(state_id).as_fraction() for state_id, prob in succ_dist_without_target_states]) == 0: # In this case, we require that the probability mass is distributed equally for i in range(0, len(succ_dist_without_target_states) - 1): self.opt_solver.add( vars[succ_dist_without_target_states[i][0]] == vars[succ_dist_without_target_states[i + 1][0]]) else: # First Try to solve the eq system # TODO: Do not use opt_solver for this if self._get_probabilities_by_solving_eq_system(succ_dist_without_target_states, vars): self.statistics.inc_solved_eq_system_instead_of_optimization_counter() m = self.opt_solver.model() result = { succ_id: m[vars[succ_id]] for (succ_id, prob) in succ_dist_without_target_states } # Because get_probabilities_by_solving_eq_system pushes # TODO: This is ugly # TODO: Compare solve-eq-system-time with optimization-problem-time self.opt_solver.pop() self.opt_solver.pop() self._obligation_cache.cache(state_id, chosen_command, delta, result) self.statistics.stop_get_probability_timer() return (True, result) else: self.statistics.inc_had_to_solve_optimization_problem_counter() # for each non-target-succ, we need n opt-var opt_vars = {} # For every non-target successor, we need an optimization variable for (succ_id, prob) in succ_dist_without_target_states: opt_vars[succ_id] = Real("opt_var_%s" % succ_id) # Now assert that opt_var_i = |var_i \ (var_1 + ... + var_n) - oracle(s_i) \ ( oracle(s_1) + ... + oracle(s_n ) | # for every opt_var_i for (succ_id, prob) in succ_dist_without_target_states: # opt_var is the absolute value of the ratio self.opt_solver.add( If(((vars[succ_id] * Sum([ self.oracle.get_oracle_value(succ_id_2) for (succ_id_2, prob) in succ_dist_without_target_states ])) - ((self.oracle.get_oracle_value(succ_id) * Sum([ vars[succ_id_2] for (succ_id_2, prob) in succ_dist_without_target_states ])))) < 0, opt_vars[succ_id] == (((self.oracle.get_oracle_value(succ_id) * Sum([ vars[succ_id_2] for (succ_id_2, prob) in succ_dist_without_target_states ]))) - (vars[succ_id] * Sum([ self.oracle.get_oracle_value(succ_id_2) for (succ_id_2, prob) in succ_dist_without_target_states ]))), opt_vars[succ_id] == ((vars[succ_id] * Sum([ self.oracle.get_oracle_value(succ_id_2) for (succ_id_2, prob) in succ_dist_without_target_states ])) - ((self.oracle.get_oracle_value(succ_id) * Sum([ vars[succ_id_2] for (succ_id_2, prob) in succ_dist_without_target_states ])))))) # minimize sum of opt-vars opt = self.opt_solver.minimize( Sum([ opt_vars[succ_id] for (succ_id, prob) in succ_dist_without_target_states ])) if self.opt_solver.check() == sat: # We found probabilities or the successors m = self.opt_solver.model() result = { succ_id: m[vars[succ_id]] for (succ_id, prob) in succ_dist_without_target_states } self.opt_solver.pop() self._obligation_cache.cache(state_id, chosen_command, delta, result) self.statistics.stop_get_probability_timer() return (True, result) else: # There are no such probabilities self.opt_solver.pop() self.statistics.stop_get_probability_timer() return (False, None)
from z3 import Real, Solver, Or, And p0 = [0, 0] p1 = [0, 1] p2 = [2, 1] p3 = [2, 0] p4 = p0 t1 = Real('t1') t2 = Real('t2') t3 = Real('t3') t4 = Real('t4') q1x = p0[0] + t1 * (p1[0] - p0[0]) q1y = p0[1] + t1 * (p1[1] - p0[1]) q2x = p1[0] + t2 * (p2[0] - p1[0]) q2y = p1[1] + t2 * (p2[1] - p1[1]) q3x = p2[0] + t3 * (p3[0] - p2[0]) q3y = p2[1] + t3 * (p3[1] - p2[1]) q4x = p3[0] + t4 * (p4[0] - p3[0]) q4y = p3[1] + t4 * (p4[1] - p3[1]) solver = Solver() solver.add(t1 >= 0, t2 >= 0, t3 >= 0, t4 >= 0) solver.add(t1 <= 1, t2 <= 1, t3 <= 1, t4 <= 1)
def example(): """ A simple example to demonstrate how KIP works. The program has a single variable x, initialized with x = 2. Then it enters an infinite loop that updates the value of x as x = (2*x) - 1. We want to prove the property x > 0 from this program using KIP. """ from z3 import Real #Given this program x = Real('x') I = x == 2 T = x == 2 * pre(x) - 1 #We want to prove this property P = x > 0 #First, we create a representation of the program prog = Prog( init_conds=[I], #Initial condition defs={fhash(x): T}, #Definitions of variables being updated input_vars=[], #Input variables assumes=[]) #Now, we can call KIP to prove P max_k = 5 #this is the max k iteration logger.info("We can't prove {} here yet".format(P)) r, m, k = prog.prove(P, k=max_k) logger.debug('proved: {}, k: {}'.format(r, k)) logger.debug('cex: {}'.format(m)) assert not r and not m, (r, m) P_stronger = x > 1 logger.info("But we can prove a stronger property '{}'".\ format(P_stronger)) r, m, k = prog.prove(P_stronger, k=max_k) logger.debug('proved: {}, k: {}'.format(r, k)) logger.debug('cex: {}'.format(m)) assert r and not m, (r, m) logger.info("Adding the stronger prop '{}' as known inv "\ "allows us to prove the orig prop '{}'"\ .format(P_stronger, P)) prog.add_inv(P_stronger) r, m, k = prog.prove(P, k=max_k) logger.debug('proved: {}, k: {}'.format(r, k)) logger.debug('cex: {}'.format(m)) assert r and not m, (r, m) logger.info("After removing the stronger prop '{}',"\ "we can't prove the orig '{}' anymore"\ .format(P_stronger, P)) prog.reset_invs() r, m, k = prog.prove(P, k=max_k) logger.debug('proved: {}, k: {}'.format(r, k)) logger.debug('cex: {}'.format(m)) assert not r and not m, (r, m)
def evaluate(self): """Convert symbol to either a constant or a z3 Real type object.""" if isinstance(self.value, (int, float)): return self.value else: return Real(self.show())
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.")
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 __init__(self, name: str): self.name = name self.z3 = Real(name)
def isReal(self, who): return Real(who)
def conv_safety_solve(layer2Consider,nfeatures,nfilters,filters,bias,input,activations,prevSpan,prevNumSpan,span,numSpan,pk): random.seed(time.time()) # number of clauses c = 0 # number of variables d = 0 # variables to be used for z3 variable={} if nfeatures == 1: images = np.expand_dims(input, axis=0) else: images = input if len(activations.shape) == 3: avg = np.sum(activations)/float(len(activations)*len(activations[0])*len(activations[0][0])) elif len(activations[0].shape) == 2: avg = np.sum(activations)/float(len(activations)*len(activations[0])) else: avg = 0 s = Tactic('qflra').solver() s.reset() #print("%s\n%s\n%s\n%s"%(prevSpan,prevNumSpan,span,numSpan)) toBeChanged = [] if inverseFunction == "point": if nfeatures == 1: #print("%s\n%s"%(nfeatures,prevSpan.keys())) ks = [ (0,x,y) for (x,y) in prevSpan.keys() ] else: ks = copy.deepcopy(prevSpan.keys()) toBeChanged = toBeChanged + ks elif inverseFunction == "area": for (k,x,y) in span.keys(): toBeChanged = toBeChanged + [(l,x1,y1) for l in range(nfeatures) for x1 in range(x,x+cfg.filterSize) for y1 in range(y,y+cfg.filterSize) if x1 >= 0 and y1 >= 0 and x1 < images.shape[1] and y1 < images.shape[2]] toBeChanged = list(set(toBeChanged)) for (l,x,y) in toBeChanged: variable[1,0,l+1,x,y] = Real('1_x_%s_%s_%s' % (l+1,x,y)) d += 1 if not(cfg.boundOfPixelValue == [0,0]) and (layer2Consider == 0): pstr = eval("variable[1,0,%s,%s,%s] <= %s"%(l+1,x,y,cfg.boundOfPixelValue[1])) pstr = And(eval("variable[1,0,%s,%s,%s] >= %s"%(l+1,x,y,cfg.boundOfPixelValue[0])), pstr) pstr = And(eval("variable[1,0,%s,%s,%s] != %s"%(l+1,x,y,images[l][x][y])), pstr) s.add(pstr) c += 1 maxterms = "" for (k,x,y) in span.keys(): variable[1,1,k+1,x,y] = Real('1_y_%s_%s_%s' % (k+1,x,y)) d += 1 string = "variable[1,1,%s,%s,%s] == "%(k+1,x,y) for l in range(nfeatures): for x1 in range(cfg.filterSize): for y1 in range(cfg.filterSize): if (l,x+x1,y+y1) in toBeChanged: newstr1 = " variable[1,0,%s,%s,%s] * %s + "%(l+1,x+x1,y+y1,filters[l,k][x1][y1]) elif x+x1 < images.shape[1] and y+y1 < images.shape[2] : newstr1 = " %s + "%(images[l][x+x1][y+y1] * filters[l,k][x1][y1]) string += newstr1 string += str(bias[l,k]) s.add(eval(string)) c += 1 if cfg.enumerationMethod == "line": pstr = eval("variable[1,1,%s,%s,%s] < %s" %(k+1,x,y,activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] + cfg.epsilon)) pstr = And(eval("variable[1,1,%s,%s,%s] > %s "%(k+1,x,y,activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] - cfg.epsilon)), pstr) elif cfg.enumerationMethod == "convex" or cfg.enumerationMethod == "point": if activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] >= 0: upper = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] + pk lower = -1 * (activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)]) - pk else: upper = -1 * (activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)]) + pk lower = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] - pk #if span[(k,x,y)] > 0 : # upper = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] + epsilon # lower = activations[k][x][y] - span[(k,x,y)] * numSpan[(k,x,y)] - epsilon #else: # upper = activations[k][x][y] - span[(k,x,y)] * numSpan[(k,x,y)] + epsilon # lower = activations[k][x][y] + span[(k,x,y)] * numSpan[(k,x,y)] - epsilon #if span[(k,x,y)] > 0 : # upper = activations[k][x][y] + span[(k,x,y)] + epsilon # lower = activations[k][x][y] - epsilon - span[(k,x,y)] #else: # upper = activations[k][x][y] + epsilon - span[(k,x,y)] # lower = activations[k][x][y] + span[(k,x,y)] - epsilon pstr = eval("variable[1,1,%s,%s,%s] < %s"%(k+1,x,y,upper)) pstr = And(eval("variable[1,1,%s,%s,%s] > %s"%(k+1,x,y,lower)), pstr) pstr = And(eval("variable[1,1,%s,%s,%s] != %s"%(k+1,x,y,activations[k][x][y])), pstr) s.add(pstr) c += 1 if activations[k][x][y] > 0 : maxterm = "- variable[1,1,%s,%s,%s]"%(k+1,x,y) else: maxterm = "variable[1,1,%s,%s,%s]"%(k+1,x,y) if maxterms == "": maxterms = "(%s)"%maxterm else: maxterms = " %s + (%s) "%(maxterms, maxterm) nprint("Number of variables: " + str(d)) nprint("Number of clauses: " + str(c)) p = multiprocessing.Process(target=s.check) p.start() # Wait for timeout seconds or until process finishes p.join(cfg.timeout) # If thread is still active if p.is_alive(): print "Solver running more than timeout seconds (default="+str(cfg.timeout)+"s)! Skip it" p.terminate() p.join() else: s_return = s.check() if 's_return' in locals(): if s_return == sat: inputVars = [ (l,x,y,eval("variable[1,0,"+ str(l+1) +"," + str(x) +"," + str(y)+ "]")) for (l,x,y) in toBeChanged ] cex = copy.deepcopy(images) for (l,x,y,v) in inputVars: #if cex[l][x][y] != v: print("different dimension spotted ... ") cex[l][x][y] = getDecimalValue(s.model()[v]) #print("%s %s"%(images[l][x][y],cex[l][x][y])) cex = np.squeeze(cex) #cex2 = copy.deepcopy(activations) #nextVars = [ (k,x,y,eval("variable[1,1,"+ str(k+1) +"," + str(x) +"," + str(y)+ "]")) for (k,x,y) in span.keys() ] #for (k,x,y,v) in nextVars: #if cex[l][x][y] != v: print("different dimension spotted ... ") # cex2[k][x][y] = getDecimalValue(s.model()[v]) # print("%s %s"%(activations[k][x][y],cex2[k][x][y])) nprint("satisfiable!") return (True, cex) else: nprint("unsatisfiable!") return (False, input) else: print "timeout! " return (False, input)
def _(varname): return Real(varname)
import sys from z3 import Solver, Real, sat, And import json import re x = [Real('x.%d' % i) for i in xrange(6)] d = Real('d') s = Solver() s.set(soft_timeout=1) def _(varname): return Real(varname) def avg(exprs): return reduce(lambda x, y: x + y, exprs) / len(exprs) def sqdists(exprs, mean): return map(lambda x: (x - mean)**2, exprs) def constraint(text): expr = re.sub(r'\[(.*?)\]', lambda mo: "_('%s')" % mo.groups(1), text) try: return eval(expr) except Exception, e: raise Exception("error in expr '%s': %s" % (text, e))
def real_var(self, expr): return Real(expr.id)
def test_parse_model_values(self): # model = '[r_0 = 1/8, r_1 = 9/16, /0 = [(7/16, 7/8) -> 1/2, else -> 0]]' x = Real('x') y = Real('y') s = Solver() s.add(x > 0) s.add(x < 2) s.add(y > 0) s.add(y < 100) print("s.check()", s.check()) model = s.model() print("s.model()", model) model_values = parse_model_values(model, "z3") self.assertEqual(model_values, [1, 1]) # Model used as an example ## model (1) is below threshold self.assertEqual(pass_models_to_sons(model, False, 0, 2, "z3"), ([model, None], [None, None])) self.assertEqual(pass_models_to_sons(model, False, 1, 2, "z3"), ([model, None], [None, None])) ## model (1) is above threshold self.assertEqual(pass_models_to_sons(model, False, 0, 0, "z3"), ([None, None], [model, None])) self.assertEqual(pass_models_to_sons(model, False, 1, 0, "z3"), ([None, None], [model, None])) ## model (1) is equal to threshold self.assertEqual(pass_models_to_sons(model, False, 0, 1, "z3"), ([None, None], [None, None])) self.assertEqual(pass_models_to_sons(model, False, 1, 1, "z3"), ([None, None], [None, None])) # Now as a counterexample ## model (1) is below threshold self.assertEqual(pass_models_to_sons(False, model, 0, 2, "z3"), ([None, model], [None, None])) self.assertEqual(pass_models_to_sons(False, model, 1, 2, "z3"), ([None, model], [None, None])) ## model (1) is above threshold self.assertEqual(pass_models_to_sons(False, model, 0, 0, "z3"), ([None, None], [None, model])) self.assertEqual(pass_models_to_sons(False, model, 1, 0, "z3"), ([None, None], [None, model])) ## model (1) is equal to threshold self.assertEqual(pass_models_to_sons(False, model, 0, 1, "z3"), ([None, None], [None, None])) self.assertEqual(pass_models_to_sons(False, model, 1, 1, "z3"), ([None, None], [None, None])) # Now as both, example and counterexample ## model (1) is below threshold self.assertEqual(pass_models_to_sons(model, model, 0, 2, "z3"), ([model, model], [None, None])) self.assertEqual(pass_models_to_sons(model, model, 1, 2, "z3"), ([model, model], [None, None])) ## model (1) is above threshold self.assertEqual(pass_models_to_sons(model, model, 0, 0, "z3"), ([None, None], [model, model])) self.assertEqual(pass_models_to_sons(model, model, 1, 0, "z3"), ([None, None], [model, model])) ## model (1) is equal to threshold self.assertEqual(pass_models_to_sons(model, model, 0, 1, "z3"), ([None, None], [None, None])) self.assertEqual(pass_models_to_sons(model, model, 1, 1, "z3"), ([None, None], [None, None])) x = Real('x') y = Real('y') s = Solver() s.add(x > 0) s.add(x < 2) s.add(y > 0) s.add(y < 100) s.add( eval( '((1/2)**y / (x + (1/2)**y))**2-2*((1/2)**y / (x + (1/2)**y))+1>=0.726166837943366' )) print("s.check()", s.check()) model = s.model() print("s.model()", model) model_values = parse_model_values(model, "z3") self.assertEqual(model_values, [0, 0]) r_1 = Real("r_1") r_0 = Real("r_0") s = Solver() s.add(r_0 > 0) s.add(r_0 < 1) s.add(r_1 > 0) s.add(r_1 < 1) a = [ '(r_0 - 1)**2>=0.726166837943366', '(r_0 - 1)**2<=0.907166495456634', '2*r_0*(If(r_1 > r_0, (r_1 - r_0)/(1 - r_0), 0) - 1)*(r_0 - 1)>=0.0401642685583240', '2*r_0*(If(r_1 > r_0, (r_1 - r_0)/(1 - r_0), 0) - 1)*(r_0 - 1)<=0.193169064841676', '-r_0*(2*If(r_1 > r_0, (r_1 - r_0)/(1 - r_0), 0)*r_0 - 2*If(r_1 > r_0, (r_1 - r_0)/(1 - r_0), 0) - r_0)>=0.00536401422323720', '-r_0*(2*If(r_1 > r_0, (r_1 - r_0)/(1 - r_0), 0)*r_0 - 2*If(r_1 > r_0, (r_1 - r_0)/(1 - r_0), 0) - r_0)<=0.127969319116763' ] for item in a: s.add(eval(item)) print("s.check()", s.check()) model = s.model() print("s.model()", model) model_values = parse_model_values(model, "z3") self.assertEqual(model_values, [1 / 8, 9 / 16])