def test_constant(self): b1 = Bool(True) b2 = Bool(False) r1 = Real(5.5) r2 = Real(5) r3 = Real(-5.5) i1 = Int(4) i2 = Int(-4) b1_string = self.print_to_string(b1) b2_string = self.print_to_string(b2) self.assertEqual(b1_string, "true") self.assertEqual(b2_string, "false") r1_string = self.print_to_string(r1) r2_string = self.print_to_string(r2) r3_string = self.print_to_string(r3) self.assertEqual(r1_string, "(/ 11 2)") self.assertEqual(r2_string, "5.0") self.assertEqual(r3_string, "(- (/ 11 2))") i1_string = self.print_to_string(i1) i2_string = self.print_to_string(i2) self.assertEqual(i1_string, "4") self.assertEqual(i2_string, "(- 4)")
def test_substitute_memoization(self): a = Symbol("A", BOOL) b = Symbol("B", BOOL) f = And(a, b) g = f.substitute({a:Bool(True)}) h = f.substitute({a:Bool(False)}) self.assertNotEqual(h, g)
def test_substitution_on_quantifiers(self): x, y = FreshSymbol(), FreshSymbol() # y /\ Forall x. x /\ y. f = And(y, ForAll([x], And(x, y))) subs = {y: Bool(True)} f_subs = substitute(f, subs).simplify() self.assertEqual(f_subs, ForAll([x], x)) subs = {x: Bool(True)} f_subs = substitute(f, subs).simplify() self.assertEqual(f_subs, f)
def test_constant(self): b1 = Bool(True) b2 = Bool(False) r1 = Real(5.5) r2 = Real(5) r3 = Real(-5.5) i1 = Int(4) i2 = Int(-4) self.assertEqual(b1.to_smtlib(daggify=True), "true") self.assertEqual(b2.to_smtlib(daggify=True), "false") self.assertEqual(r1.to_smtlib(daggify=True), "(/ 11 2)") self.assertEqual(r2.to_smtlib(daggify=True), "5.0") self.assertEqual(r3.to_smtlib(daggify=True), "(- (/ 11 2))") self.assertEqual(i1.to_smtlib(daggify=True), "4") self.assertEqual(i2.to_smtlib(daggify=True), "(- 4)") self.assertEqual(b1.to_smtlib(daggify=False), "true") self.assertEqual(b2.to_smtlib(daggify=False), "false") self.assertEqual(r1.to_smtlib(daggify=False), "(/ 11 2)") self.assertEqual(r2.to_smtlib(daggify=False), "5.0") self.assertEqual(r3.to_smtlib(daggify=False), "(- (/ 11 2))") self.assertEqual(i1.to_smtlib(daggify=False), "4") self.assertEqual(i2.to_smtlib(daggify=False), "(- 4)")
def walk_constant(self, value, v_type): if self.bool_mode: return (Real(value) if v_type == REAL else self.pool.bool_test( Decision(Bool(value)))) else: assert v_type != BOOL return self.pool.terminal(self.pool.algebra.real(float(value)))
def efsmt(y, phi, logic=AUTO, maxloops=None, esolver_name=None, fsolver_name=None, verbose=False): """Solves exists x. forall y. phi(x, y)""" y = set(y) x = phi.get_free_variables() - y with Solver(logic=logic, name=esolver_name) as esolver: esolver.add_assertion(Bool(True)) loops = 0 while maxloops is None or loops <= maxloops: loops += 1 eres = esolver.solve() if not eres: return False else: tau = {v: esolver.get_value(v) for v in x} sub_phi = phi.substitute(tau).simplify() if verbose: print("%d: Tau = %s" % (loops, tau)) fmodel = get_model(Not(sub_phi), logic=logic, solver_name=fsolver_name) if fmodel is None: return tau else: sigma = {v: fmodel[v] for v in y} sub_phi = phi.substitute(sigma).simplify() if verbose: print("%d: Sigma = %s" % (loops, sigma)) esolver.add_assertion(sub_phi) raise SolverReturnedUnknownResultError
def test_create_and_solve(self): solver = Solver(logic=QF_BOOL) varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) g = f.substitute({varB: varA}) solver.add_assertion(g) res = solver.solve() self.assertFalse(res, "Formula was expected to be UNSAT") h = And(g, Bool(False)) simp_h = h.simplify() self.assertEqual(simp_h, Bool(False))
def test_basic_solving(self): solver = self.bdd_solver f = And(self.x, Not(self.y)) solver.add_assertion(f) self.assertTrue(solver.solve()) model = solver.get_model() self.assertEqual(model[self.x], Bool(True)) self.assertEqual(model[self.y], Bool(False)) self.assertFalse(solver.get_py_value(self.y)) solver.push() solver.add_assertion(Not(self.x)) self.assertFalse(solver.solve()) solver.pop() self.assertTrue(solver.solve())
def export_goals(self, formula): ex = self.export_expr if formula.is_not() and self.extract_universal(formula.args()[0])[0]: formula = formula.arg(0) uvars, inner = self.extract_universal(formula) if inner.is_equals() or inner.is_iff(): goal = formula elif inner.is_implies(): goal = formula if (not inner.arg(1).is_equals()) and ( not inner.arg(1).is_iff()): ForAll( uvars, Implies(inner.arg(0), Iff(inner.arg(1), Bool(True)))) else: goal = ForAll(uvars, Iff(inner, Bool(True))) yield SExpression(['prove', ex(goal)])
def compute_volume_pa(domain, support, weight, convex_backend=None): # noinspection PyCallingNonCallable solver = WMI(support, weight, convex_backend=convex_backend) return solver.computeWMI( Bool(True), mode=WMI.MODE_PA, domA=set(domain.get_bool_symbols()), domX=set(domain.get_real_symbols()), )[0]
def exec(self, instr: Instruction, state): assert state.PC.is_constant( ), "this symexec implementation can only deal with constant PCs" method = 'exec_' + instr.__class__.__name__ ret = getattr(self, method)(instr, state) if isinstance(ret, MachineState): st_next, pc_next = ret, (Bool(True), BVAdd(ret.PC, self.pc_inc), None) else: st_next, pc_next = ret[0], (ret[1][0], ret[1][1], BVAdd(ret[0].PC, self.pc_inc)) if self.track_taint: self.taint_diff(state, st_next, instr) return st_next, pc_next
def test_misc(self): bool_list = [ And(self.x, self.y), Or(self.x, self.y), Not(self.x), self.x, Equals(self.p, self.q), GE(self.p, self.q), LE(self.p, self.q), GT(self.p, self.q), LT(self.p, self.q), Bool(True), Ite(self.x, self.y, self.x) ] # TODO: FORALL EXISTS real_list = [ self.r, Real(4), Plus(self.r, self.s), Plus(self.r, Real(2)), Minus(self.s, self.r), Times(self.r, Real(1)), Div(self.r, Real(1)), Ite(self.x, self.r, self.s), ] int_list = [ self.p, Int(4), Plus(self.p, self.q), Plus(self.p, Int(2)), Minus(self.p, self.q), Times(self.p, Int(1)), Ite(self.x, self.p, self.q), ] for f in bool_list: t = self.tc.walk(f) self.assertEqual(t, BOOL, f) for f in real_list: t = self.tc.walk(f) self.assertEqual(t, REAL, f) for f in int_list: t = self.tc.walk(f) self.assertEqual(t, INT, f)
def complete_model(self, symbols): undefined_symbols = (s for s in symbols if s not in self.assignment) for s in undefined_symbols: if not s.is_symbol(): raise TypeError("Was expecting a symbol but got %s" % s) if s.is_symbol(BOOL): value = Bool(False) elif s.is_symbol(REAL): value = Real(0) elif s.is_symbol(INT): value = Int(0) else: raise TypeError("Unhandled type for %s: %s" % (s, s.symbol_type())) self.assignment[s] = value
def run_pa(density, n_bins, log_path): formula = density.support weight = density.weight CACHE = False #log_path = join(output_folder, f"{name}-gt-PA.json") if not isfile(log_path): print("Running WMI-PA") wmipa = WMI(density.support, density.weight) Z_pa, _ = wmipa.computeWMI(Bool(True), mode=WMI.MODE_PA, cache=CACHE) gt_marginals = {} for xvar in density.domain.get_real_symbols(): x = xvar.symbol_name() gt_marginals[x] = [] low, up = density.domain.var_domains[x] slices = [(i / n_bins) * (up - low) + low for i in range(0, n_bins + 1)] for i in range(len(slices) - 1): l, u = slices[i], slices[i + 1] gt_q = And(LE(Real(l), xvar), LE(xvar, Real(u))) gt_vol, _ = wmipa.computeWMI(gt_q, mode=WMI.MODE_PA, cache=CACHE) gt_marginals[x].append((l, u, gt_vol / Z_pa)) with open(log_path, 'w') as log_file: json.dump(gt_marginals, log_file, indent=2) else: print(f"Found {log_path}") with open(log_path, 'r') as log_file: gt_marginals = json.load(log_file) return gt_marginals
def is_path_circuit(f, path, c, sign=None): edges = list(zip(c, c[1:] + [c[0]])) k = len(c) + 1 inds = path_indices(path) if any(i not in inds for i in c): return Bool(False) if sign == -1: # an odd number of edges are negative return Or([ And([edge(f, path[inds.index(j)], j, i, -1) for j, i in ls] + [ edge(f, path[inds.index(j)], j, i, +1) for j, i in edges if (j, i) not in ls ]) for m in range(1, k + 1, 2) for ls in combinations(edges, m) ]) if sign == +1: # an even number of edges are negative return Or([ And([edge(f, path[inds.index(j)], j, i, -1) for j, i in ls] + [ edge(f, path[inds.index(j)], j, i, +1) for j, i in edges if (j, i) not in ls ]) for m in range(0, k + 1, 2) for ls in combinations(edges, m) ]) # all edges exist return And([Not(edge(f, path[inds.index(j)], j, i, 0)) for j, i in edges])
def test_bv_sle_constants(self): f = BVSLE(BV(10, 32), BV(2**32 - 1, 32)) self.check_equal_and_valid(f, Bool(False))
def test_bv_sle_eq(self): x, y = (Symbol(name, BVType(32)) for name in "xy") f = BVSLE(BVMul(x, y), BVMul(x, y)) self.check_equal_and_valid(f, Bool(True))
def test_bv_ule_constants(self): f = BVULE(BVZero(32), BVOne(32)) self.check_equal_and_valid(f, Bool(True))
def test_bv_zero_ule(self): x = Symbol("x", BVType(32)) f = BVULE(BVZero(32), x) self.check_equal_and_valid(f, Bool(True))
def test_bv_ult_zero(self): x = Symbol("x", BVType(32)) f = BVULT(x, BVZero(32)) self.check_equal_and_valid(f, Bool(False))
def test_bv_ult_eq(self): x, y = (Symbol(name, BVType(32)) for name in "xy") f = BVULT(BVMul(x, y), BVMul(x, y)) self.check_equal_and_valid(f, Bool(False))
def exec_Jump(self, instr: Jump, st): if instr.offset >= 0: pc = BVAdd(st.PC, BitVecVal(instr.offset + 1, 16)) else: pc = BVSub(st.PC, BitVecVal(-instr.offset - 1, 16)) return st, (Bool(True), pc)
def safeRL_callSMT(action, start_pos_x, start_pos_y, dynamical_parameters, image, bird_param): flapup_paths = None godown_paths = None smt_result = 0 path_depth = 8 if (action == 1): #========================================================================================================== # properties for safe flap up action #---------------------------------------------------------------------------------------------------------- #property 1: safe_upper_height is the safe max altitude of the bird, depending upon the game safe_max_height = 70 safety_prop_1 = GE(Int(dynamical_parameters['pos_y']), Int(safe_max_height)) #property 2:if there is no escape path if it takes action flap, then do not take it. # number_of_ states to check for safe movement depends upon the game speed, bird vel etc. path_list = [] temp_dynamical_parameters = {} temp_dynamical_parameters['pos_x'], temp_dynamical_parameters[ 'pos_y'], temp_dynamical_parameters['vel_y'] = predict_next_steps( dynamical_parameters['pos_x'], dynamical_parameters['pos_y'], dynamical_parameters['vel_y'], action, dynamical_parameters) path = [(temp_dynamical_parameters['pos_x'], temp_dynamical_parameters['pos_y'])] action_ctr = 1 flapup_paths = recursive_path_generator( temp_dynamical_parameters['pos_x'], temp_dynamical_parameters['pos_y'], temp_dynamical_parameters['vel_y'], action_ctr, dynamical_parameters, path_list, path_depth, path=path) is_flap_up_path_clear = is_path_safe(image, flapup_paths, bird_param['w'], bird_param['h'], action) safety_prop_2 = (Bool(is_flap_up_path_clear)) #---------------------------------------------------------------------------------------------------------- #property 3: Safe vertical distance of bird from pipe - when it goes through the pipe # min distance between pipe and bird. safe_v_pipe_dist = 15 bird_epsilon = 10 is_upper_pipe_far = is_safe_from_upper_pipe( image, start_pos_x, start_pos_y, (bird_param['w'] + bird_epsilon), (bird_param['h'] + bird_epsilon), safe_v_pipe_dist) safety_prop_3 = (Bool(is_upper_pipe_far)) #---------------------------------------------------------------------------------------------------------- #print(" Before smt ", datetime.datetime.now().strftime("%H:%M:%S.%f")[:-3]) properties_for_flap_action = And(safety_prop_1, safety_prop_2, safety_prop_3) res = is_valid(properties_for_flap_action, solver_name="z3") #print("flap :", properties_for_flap_action, " " , res) if res: smt_result = 1 if (action == 0): #---------------------------------------------------------------------------------------------------------- # properties for safe no action #---------------------------------------------------------------------------------------------------------- #property : safe_min_height is the min altitude of the bird #safe_min_height value depends on the game. Its hardcoded to 500 for this game. safe_min_height = 300 safety_prop_10 = LE(Int(dynamical_parameters['pos_y']), Int(safe_min_height)) #property :if there is no escape path if it takes action no flap, then do not take it. # number_of_ states to check for safe movement depends upon the game speed, bird vel etc. #next_possible_actions = down_action_sequence_for_path(path_depth) #godown_paths = path_generator (start_pos_x, start_pos_y + 20,dynamical_parameters, next_possible_actions) path_list = [] temp_dynamical_parameters = {} temp_dynamical_parameters['pos_x'], temp_dynamical_parameters[ 'pos_y'], temp_dynamical_parameters['vel_y'] = predict_next_steps( dynamical_parameters['pos_x'], dynamical_parameters['pos_y'], dynamical_parameters['vel_y'], action, dynamical_parameters) path = [(temp_dynamical_parameters['pos_x'], temp_dynamical_parameters['pos_y'])] action_ctr = 1 godown_paths = recursive_path_generator( temp_dynamical_parameters['pos_x'], temp_dynamical_parameters['pos_y'], temp_dynamical_parameters['vel_y'], action_ctr, dynamical_parameters, path_list, path_depth, path=path) #print(" godown_paths : ", godown_paths) is_go_down_clear = is_path_safe(image, godown_paths, bird_param['w'], bird_param['h'], action) safety_prop_11 = (Bool(is_go_down_clear)) #---------------------------------------------------------------------------------------------------------- #property 3: Safe vertical distance of bird from pipe - when it goes through the pipe # min distance between pipe and bird. safe_v_pipe_dist = 15 bird_epsilon = 10 is_lower_pipe_far = is_safe_from_lower_pipe( image, start_pos_x, start_pos_y, (bird_param['w'] + bird_epsilon), (bird_param['h'] + bird_epsilon), safe_v_pipe_dist) safety_prop_12 = (Bool(is_lower_pipe_far)) #---------------------------------------------------------------------------------------------------------- properties_for_no_action = And(safety_prop_10, safety_prop_11, safety_prop_12) res = is_valid(properties_for_no_action, solver_name="z3") #print("down :", properties_for_no_action, " " , res) if res: smt_result = 2 return smt_result, flapup_paths, godown_paths
def _compute_WMI_PA(self, formula, weights): """Computes WMI using the Predicate Abstraction (PA) algorithm. Args: formula (FNode): The formula on whick to compute WMI. weights (Weight): The corresponding weight. Returns: real: The final volume of the integral computed by summing up all the integrals' results. int: The number of problems that have been computed. """ problems = [] boolean_variables = get_boolean_variables(formula) if len(boolean_variables) == 0: # Enumerate partial TA over theory atoms lab_formula, pa_vars, labels = self.label_formula(formula, formula.get_atoms()) # Predicate abstraction on LRA atoms with minimal models for assignments in self._compute_WMI_PA_no_boolean(lab_formula, pa_vars, labels): problem = self._create_problem(assignments, weights) problems.append(problem) else: solver = Solver(name="msat") converter = solver.converter solver.add_assertion(formula) boolean_models = [] # perform AllSAT on the Boolean variables mathsat.msat_all_sat( solver.msat_env(), [converter.convert(v) for v in boolean_variables], lambda model : WMI._callback(model, converter, boolean_models)) logger.debug("n_boolean_models: {}".format(len(boolean_models))) # for each boolean assignment mu^A of F for model in boolean_models: atom_assignments = {} boolean_assignments = WMI._get_assignments(model) atom_assignments.update(boolean_assignments) subs = {k : Bool(v) for k, v in boolean_assignments.items()} f_next = formula # iteratively simplify F[A<-mu^A], getting (possibily part.) mu^LRA while True: f_before = f_next f_next = simplify(substitute(f_before, subs)) lra_assignments, over = WMI._parse_lra_formula(f_next) subs = {k : Bool(v) for k, v in lra_assignments.items()} atom_assignments.update(lra_assignments) if over or lra_assignments == {}: break if not over: # predicate abstraction on LRA atoms with minimal models lab_formula, pa_vars, labels = self.label_formula(f_next, f_next.get_atoms()) expressions = [] for k, v in atom_assignments.items(): if k.is_theory_relation(): if v: expressions.append(k) else: expressions.append(Not(k)) lab_formula = And([lab_formula] + expressions) for assignments in self._compute_WMI_PA_no_boolean(lab_formula, pa_vars, labels, atom_assignments): problem = self._create_problem(assignments, weights) problems.append(problem) else: # integrate over mu^A & mu^LRA problem = self._create_problem(atom_assignments, weights) problems.append(problem) results, cached = self.integrator.integrate_batch(problems, self.cache) volume = fsum(results) return volume, len(problems)-cached, cached
mpmi = MP2WMI(density.support, density.weight, smt_solver=args.smt_solver, n_processes=nproc) logging.info("Solver inited") Z, _ = mpmi.compute_volumes(cache=True) logging.info("Volume computed") t2 = time.perf_counter() elif args.solver == "pa": logging.info("using pa") # pa t1 = time.perf_counter() wmipa = WMI(density.support, density.weight) Z, _ = wmipa.computeWMI(Bool(True), mode=WMI.MODE_PA) t2 = time.perf_counter() elif args.solver == "xsdd": logging.info("using xsdd") # xsdd t1 = time.perf_counter() xsdd = XsddEngine(density.domain, density.support, density.weight, factorized=False, algebra=PyXaddAlgebra(), ordered=False) Z = xsdd.compute_volume(add_bounds=False) t2 = time.perf_counter()
def path_condition(self): pcs = [cond for cond in self.path_conditions if not cond.is_constant()] if len(pcs) == 0: return Bool(True) else: return reduce(And, pcs)
def BoolV(self, ast): return Bool(ast.args[0])
def main(): # Given variables ================================================= I = int(input()) J = int(input()) K = int(input()) T_MAX = int(input()) array_1D = Symbol("1D", ArrayType(INT, INT)) array_2D = Symbol("2D", ArrayType(INT, ArrayType(INT, INT))) # T[j][k] # Earliest start execution time of service k on server j ''' T = Symbol("T", ArrayType(INT, ArrayType(INT, INT))) for j in range(0, J): T_row = array_1D k = 0 for val in [int(x) for x in input().split()]: # print(symbol_name("T", j, k), " -> ", str(val)) T_row = T_row.Store(Int(k), Int(val)) k = k + 1 T = T.Store(Int(j), T_row) ''' T = Symbol("T", ArrayType(INT, ArrayType(INT, ArrayType(INT, INT)))) for i in range(0, I): T_mat = array_2D for j in range(0, J): T_mat_row = array_1D k = 0 for val in [int(x) for x in input().split()]: # print(symbol_name("T", j, k), " -> ", str(val)) T_mat_row = T_mat_row.Store(Int(k), Int(val)) k = k + 1 T_mat = T_mat.Store(Int(j), T_mat_row) T = T.Store(Int(i), T_mat) # C[j][k] # The computation time of service k on server j C = Symbol("C", ArrayType(INT, ArrayType(INT, INT))) for j in range(0, J): C_row = array_1D k = 0 for val in [int(x) for x in input().split()]: # print(symbol_name("C", j, k), " -> ", str(val)) C_row = C_row.Store(Int(k), Int(val)) k = k + 1 C = C.Store(Int(j), C_row) # Tv[j][j'][k] # the transmission time (delivery) of service k from server j to server j' Tv = Symbol("Tv", ArrayType(INT, ArrayType(INT, ArrayType(INT, INT)))) for j in range(0, J): Tv_mat = array_2D for jj in range(0, J): Tv_mat_row = array_1D k = 0 for val in [int(x) for x in input().split()]: # print(symbol_name("Tv", j, jj, k), " -> ", str(val)) Tv_mat_row = Tv_mat_row.Store(Int(k), Int(val)) k = k + 1 Tv_mat = Tv_mat.Store(Int(jj), Tv_mat_row) Tv = Tv.Store(Int(j), Tv_mat) # D[i][k] # Vehicle i's reception deadline for service k # valid[i][k] == -1 iff vehicle i doesn't demand service k D = Symbol("D", ArrayType(INT, ArrayType(INT, INT))) valid = [] for i in range(0, I): D_row = array_1D k = 0 valid.append([]) for val in [int(x) for x in input().split()]: # print(symbol_name("D", i, k), " -> ", str(val)) D_row = D_row.Store(Int(k), Int(val)) k = k + 1 if (val == -1): valid[-1].append(False) else: valid[-1].append(True) D = D.Store(Int(i), D_row) # F[i][k] # The required freshness of vehicle i for service k F = Symbol("F", ArrayType(INT, ArrayType(INT, INT))) for i in range(0, I): F_row = array_1D k = 0 for val in [int(x) for x in input().split()]: # print(symbol_name("F", i, k), " -> ", str(val)) F_row = F_row.Store(Int(k), Int(val)) k = k + 1 F = F.Store(Int(i), F_row) # R[i][j][t] # if vehicle i is in the communication of server j at time t ''' R = Symbol("R", ArrayType(INT, ArrayType(INT, ArrayType(INT, INT)))) for i in range(0, I): R_mat = array_2D for j in range(0, J): R_mat_row = array_1D t = 0 for val in [int(x) for x in input().split()]: # print(symbol_name("R", i, j, t), " -> ", str(val)) R_mat_row = R_mat_row.Store(Int(t), Int(val)) t = t + 1 R_mat = R_mat.Store(Int(j), R_mat_row) R = R.Store(Int(i), R_mat) ''' R = Symbol("R", ArrayType(INT, ArrayType(INT, INT))) for i in range(0, I): R_mat = array_1D R_it = input().split(',') t = 0 for r in R_it: cum_t = int(r.split()[0]) cur_j = int(r.split()[1]) for _ in range(cum_t): R_mat = R_mat.Store(Int(t), Int(cur_j)) t += 1 R = R.Store(Int(i), R_mat) # M[k] # the required memory size (delivery) of service k M = [int(x) for x in input().split()] # M_bar[j] # the memory size of server j M_bar = [int(x) for x in input().split()] start_time = time.time() # Decision variables ================================================= class DV: # Decision variable def __init__(self, i, k): self.i_int = i self.k_int = k self.i = Int(i) self.k = Int(k) self.e = Symbol(symbol_name("e", i, k), INT) self.d = Symbol(symbol_name("d", i, k), INT) self.s = Symbol(symbol_name("s", i, k), INT) self.t = Symbol(symbol_name("t", i, k), INT) DV_set = set() for i in range(0, I): for k in range(0, K): if valid[i][k]: DV_set.add(DV(i, k)) # Constraints ================================================= # Variable domain domain = And( [And(GE(dv.e, Int(0)), LT(dv.e, Int(J))) for dv in DV_set] + [And(GE(dv.d, Int(0)), LT(dv.d, Int(J))) for dv in DV_set] + [And(GE(dv.s, Int(0)), LT(dv.s, Int(T_MAX))) for dv in DV_set] + [And(GE(dv.t, Int(0)), LT(dv.t, Int(T_MAX))) for dv in DV_set]) # Execution constraint eq1 = And([ Or(dv1.s + C.Select(dv1.e).Select(dv1.k) <= dv2.s, dv1.s >= dv2.s + C.Select(dv2.e).Select(dv2.k), And(dv1.k.Equals(dv2.k), dv1.s.Equals(dv2.s))) for (dv1, dv2) in itertools.combinations(DV_set, 2) ]) # Timing constraint #eq2 = And([T.Select(dv.e).Select(dv.k) <= dv.s for dv in DV_set]) eq2 = And( [T.Select(dv.i).Select(dv.e).Select(dv.k) <= dv.s for dv in DV_set]) eq3 = And([ dv.s + C.Select(dv.e).Select(dv.k) + Tv.Select(dv.e).Select(dv.d).Select(dv.k) <= dv.t for dv in DV_set ]) eq4 = And([dv.t <= D.Select(dv.i).Select(dv.k) for dv in DV_set]) eq5 = And([dv.t <= dv.s + F.Select(dv.i).Select(dv.k) for dv in DV_set]) #eq3_1 = And([Tv.Select(dv.e).Select(dv.d).Select(dv.k) >= 0]) # Pinpoint constraint #eq6 = And([R.Select(dv.i).Select(dv.d).Select(dv.t).Equals(Int(1)) for dv in DV_set]) eq6 = And([R.Select(dv.i).Select(dv.t).Equals(dv.d) for dv in DV_set]) # Memory constraint eq7 = And(Bool(True)) memory_sums = [] # for objective function for t in range(0, T_MAX): memory_sums.append(Int(0)) for j in range(0, J): memory_sum = Int(0) # for a single server at time t for dv in DV_set: indicator = Symbol( symbol_name("ind", j, t, dv.i_int, dv.k_int), INT) existence_formula = And( dv.d.Equals(j), t >= dv.s + C.Select(dv.e).Select(dv.k) + Tv.Select(dv.e).Select(dv.d).Select(dv.k), t < dv.t) # print(existence_formula.Iff(indicator.Equals(1))) eq7 = eq7.And(Not(existence_formula).Iff(indicator.Equals(0))) eq7 = eq7.And(existence_formula.Iff(indicator.Equals(1))) memory_sum += M[dv.k_int] * indicator eq7 = eq7.And(memory_sum <= M_bar[j]) memory_sums[-1] += memory_sum # print(memory_sum) # print(eq7) # print(memory_sums[0]) # memory_sums[t] == the sum of memory usage of all server at time t # # Decision version # # Objective constraint # obj = Max(memory_sums) <= 4 # model = get_model(And(domain, eq1, eq2, eq3, eq4, eq5, eq6, eq7, obj)) # print(model) # Optimization version # Minimize the maximum memory used constraints = And(domain, eq1, eq2, eq3, eq4, eq5, eq6, eq7) if (not is_sat(And(constraints, Max(memory_sums) <= sum(M_bar)), solver_name="z3")): print("Unsat") else: if (is_sat(And(constraints, Max(memory_sums) <= 0), solver_name="z3")): print(f"Objective value = 0") #print(get_model(And(constraints, Max(memory_sums) <= 0))) else: l = 1 r = sum(M_bar) + 1 while l < r: # print(f"{l}, {r}") m = int((l + r) / 2) if is_sat(And(constraints, Max(memory_sums) <= m), solver_name="z3"): # print(m) r = m else: l = m + 1 print(f"Objective value = {l}") #print(get_model(And(constraints, Max(memory_sums) <= m))) # print(is_sat(And(domain, eq1, eq2, eq3, eq4, eq5, eq6, eq7, obj))) running_time = time.time() - start_time outfile = open("time.out", "a") outfile.write(f"{running_time}") outfile.write("\n")
def test_substitute_to_real(self): p = Symbol("p", INT) f = LT(ToReal(p), Real(0)) new_f = f.substitute({p: Real(1)}).simplify() self.assertEqual(new_f, Bool(False))
def test_function_smtlib_print(self): f_t = FunctionType(BOOL, [BOOL]) f0 = Symbol('f 0', f_t) f0_of_false = Function(f0, [Bool(False)]) s = to_smtlib(f0_of_false, False) self.assertEqual(s, '(|f 0| false)')