diff --git a/param-tuning-experiment.py b/param-tuning-experiment.py index afdfcbde2..2758ab0b8 100644 --- a/param-tuning-experiment.py +++ b/param-tuning-experiment.py @@ -6,7 +6,7 @@ import math, random MAX_CONFLICTS = 1000 MAX_EXAMPLES = 5 -bench_dir = "C:/tmp/parameter-tuning" +bench_dir = "../z3-poly-testing/inputs/QF_NIA_small" BASE_PARAM_CANDIDATES = [ ("smt.arith.eager_eq_axioms", False), @@ -67,7 +67,7 @@ def stats_tuple(st): # -------------------------- def run_prefix_step(S, K): - S.set("smt.max_conflicts", K) + S.set("max_conflicts", K) r = S.check() return r, S.statistics() @@ -79,7 +79,7 @@ def collect_conflict_clauses_placeholder(S, limit=4): # Solver continues from its current state. def replay_prefix_on_pps(PPS_solver, clauses, param_state, budget): apply_param_state(PPS_solver, param_state) - PPS_solver.set("smt.max_conflicts", budget) + PPS_solver.set("max_conflicts", budget) asms = [] for Cj in clauses: @@ -139,6 +139,7 @@ def protocol_iteration(filepath, manager, S, PPS_solvers, PPS_states, K, eps=200 apply_param_state(S, P) # Run S with max conflicts K + print(f"[S] Running proof prefix solver with params={P} and max_conflicts={K}") r, st = run_prefix_step(S, K) # If S returns SAT or UNSAT we have a verdict @@ -149,12 +150,14 @@ def protocol_iteration(filepath, manager, S, PPS_solvers, PPS_states, K, eps=200 return # Collect subset of conflict clauses from the bounded run of S. Call these clauses C1...Cl + print(f"[S] collecting conflict clauses for replay") C_list = collect_conflict_clauses_placeholder(S) print(f"[S] collected {len(C_list)} conflict clauses for replay") # For each PPS_i, replay the proof prefix of S + print(f"[Replaying] Replaying proof prefix on PPS solvers with budget={K + eps}") best_state, best_score = replay_proof_prefixes(C_list, PPS_states, PPS_solvers, K, eps) - print(f"[Replay] best={best_state} score(conf, dec, rlim)={best_score}") + print(f"[Done replaying] best={best_state} score(conf, dec, rlim)={best_score}") if best_state != P: print(f"[Dispatch] updating best param state") @@ -183,14 +186,15 @@ def prefix_probe_thread(filepath, manager): PPS_states.append(list(BASE_PARAM_CANDIDATES)) perturbations = perturbate(BASE_PARAM_CANDIDATES) - # set up 5 parameter probe solvers PPS_0 ... PPS_4 + # set up 5 parameter probe solvers PPS_0 ... PPS_4 as new contexts on the proof prefix solver S for i in range(5): - st = perturbations[i] if i < len(perturbations) else BASE_PARAM_CANDIDATES - PPS_solver = Solver() + st = perturbations if i < len(perturbations) else BASE_PARAM_CANDIDATES + ctx = Context() + PPS_solver = S.translate(ctx) # clone S (proof prefix) into new context apply_param_state(PPS_solver, st) PPS_solvers.append(PPS_solver) PPS_states.append(st) - print(f"[Init] PPS_{i} initialized with params={st}") + print(f"[Init] PPS_{i} inherited prefix in new context with params={st}") # Reuse the same solvers each iteration iteration = 0 @@ -212,19 +216,27 @@ def main(): continue filepath = os.path.join(bench_dir, benchmark) + + # --- start prefix probing thread --- prefix_thread = threading.Thread(target=prefix_probe_thread, args=(filepath, manager)) prefix_thread.start() - # main thread can perform monitoring or waiting - while prefix_thread.is_alive(): - if manager.search_complete: - break + # --- start main solver (same formula, in parallel mode, uses cube search tree) --- + set_param("parallel.enable", True) + main_solver = solver_from_file(filepath) + main_solver.set("smt.auto_config", False) + apply_param_state(main_solver, BASE_PARAM_CANDIDATES) + print(f"[Main] Started main solver on {os.path.basename(filepath)} with parallel.enable=True") + # --- run main solver on full formula (need to enable live param injection in z3 internals) --- + r = main_solver.check() + print(f"[Main] {os.path.basename(filepath)} → {r}") + + # --- wait for prefix thread to finish --- prefix_thread.join() if manager.best_param_state: print(f"\n[GLOBAL] Best parameter state: {manager.best_param_state} with score {manager.best_score}") - if __name__ == "__main__": main()