#!/usr/bin/env python3 """ DAG Deep Tuning: find optimal modulus selection strategies. """ import sys, math, random, json from collections import Counter sys.path.insert(0, '/home/allaun/SilverSight/scripts') from verify_wrapping import f_k, is_sidon, sum_collisions, wrapping_criterion, certify_sidon_creation, m_difference_condition, wrapping_condition random.seed(42) # ---------- Failure Mode Analysis ---------- def analyze_failures(A, S, L1, L2): """Why does this moduli pair fail to create Sidon?""" M = L1 * L2 guaranteed, FA, reason = certify_sidon_creation(A, S, [L1, L2]) collisions = sum_collisions(A) wrap_ok, unresolved = wrapping_condition(A, S, [L1, L2]) mdiff_ok, violators = m_difference_condition(A, M) failures = [] if not wrap_ok: for (a,b,c,d),(s1,s2) in unresolved: failures.append(f" Wrap fail: {a}+{b}={a+b} and {c}+{d}={c+d} both map to s1={s1}, s2={s2} (same wrap state)") if not mdiff_ok: for T1, T2, pairs1, pairs2 in violators: failures.append(f" M-diff fail: sum {T1} (from {pairs1}) and {T2} (from {pairs2}) differ by M={M}") return failures, FA def detailed_modulus_report(A, S, max_mod=20): """Full report on every valid modulus pair.""" maxA = max(A) rows = [] for L1 in range(2, max_mod + 1): for L2 in range(L1 + 1, max_mod + 1): if math.gcd(L1, L2) != 1: continue M = L1 * L2 if not (maxA < M <= 2 * maxA): continue guaranteed, FA, _ = certify_sidon_creation(A, S, [L1, L2]) sidon = is_sidon(FA) fails, _ = analyze_failures(A, S, L1, L2) rows.append({ 'L1': L1, 'L2': L2, 'M': M, 'sidon': sidon, 'guaranteed': guaranteed, 'failures': fails, 'FA': FA }) return rows # ---------- Optimal M Strategy ---------- def analyze_optimal_M_trend(trials=500): """Trend: what M/maxA ratios work best?""" results = [] for trial in range(trials): maxA = random.randint(5, 30) n = random.randint(4, 8) A = sorted(random.sample(range(maxA + 1), min(n, maxA + 1))) S = random.randint(maxA, maxA + 10) max_mod = max(2, min(20, 2 * maxA)) for L1 in range(2, max_mod + 1): for L2 in range(L1 + 1, max_mod + 1): if math.gcd(L1, L2) != 1: continue M = L1 * L2 if not (maxA < M <= 2 * maxA): continue FA = [f_k(a, S, [L1, L2]) for a in A] sidon = is_sidon(FA) results.append({ 'maxA': maxA, 'M': M, 'ratio': M / maxA, 'sidon': sidon }) # Group by ratio buckets buckets = {} for r in results: bucket = round(r['ratio'] * 10) / 10 # 0.1 increments if bucket not in buckets: buckets[bucket] = {'total': 0, 'sidon': 0} buckets[bucket]['total'] += 1 if r['sidon']: buckets[bucket]['sidon'] += 1 print("\n=== Optimal M/maxA Ratio Analysis ===") print(f"{'Ratio':>8} {'Total':>8} {'Sidon':>8} {'Rate':>8}") print("-" * 36) for ratio in sorted(buckets.keys()): b = buckets[ratio] pct = b['sidon'] / b['total'] * 100 print(f"{ratio:>8.1f} {b['total']:>8} {b['sidon']:>8} {pct:>7.1f}%") # Best ratio range best = max(buckets.items(), key=lambda x: x[1]['sidon'] / x[1]['total']) print(f"\nBest ratio: {best[0]:.1f} ({best[1]['sidon']/best[1]['total']*100:.1f}% success)") # ---------- Modulus Size Preference ---------- def analyze_modulus_size_preference(trials=500): """Which modulus values work most often?""" mod_counts = Counter() mod_sidon = Counter() for trial in range(trials): maxA = random.randint(5, 30) n = random.randint(4, 8) A = sorted(random.sample(range(maxA + 1), min(n, maxA + 1))) S = random.randint(maxA, maxA + 10) max_mod = max(2, min(20, 2 * maxA)) for L1 in range(2, max_mod + 1): for L2 in range(L1 + 1, max_mod + 1): if math.gcd(L1, L2) != 1: continue M = L1 * L2 if not (maxA < M <= 2 * maxA): continue FA = [f_k(a, S, [L1, L2]) for a in A] sidon = is_sidon(FA) mod_counts[(L1, L2)] += 1 if sidon: mod_sidon[(L1, L2)] += 1 print("\n=== Modulus Size Preference ===") print(f"{'Moduli':>10} {'Trials':>8} {'Sidon':>8} {'Rate':>8}") print("-" * 38) sorted_mods = sorted(mod_counts.items(), key=lambda x: x[1], reverse=True) for (L1, L2), count in sorted_mods[:15]: sidon_count = mod_sidon.get((L1, L2), 0) pct = sidon_count / count * 100 print(f"[{L1:>2},{L2:>2}] {count:>8} {sidon_count:>8} {pct:>7.1f}%") # ---------- Multi-step Analysis ---------- def analyze_multi_step_needed(trials=300): """For sets that fail one-step, analyze multi-step depth.""" print("\n=== Multi-Step Analysis ===") from iteration_dag import IterationDAG, AdaptiveRule one_step_only = 0 multi_step = 0 no_path = 0 for trial in range(trials): maxA = random.randint(5, 30) n = random.randint(4, 7) A = sorted(random.sample(range(maxA + 1), min(n, maxA + 1))) S = random.randint(maxA, maxA + 10) # Check one-step mods = [] for L1 in range(2, 15): for L2 in range(L1 + 1, 15): if math.gcd(L1, L2) != 1: continue M = L1 * L2 if not (maxA < M <= 2 * maxA): continue FA = [f_k(a, S, [L1, L2]) for a in A] if is_sidon(FA): mods.append((L1, L2)) if mods: one_step_only += 1 continue # Check multi-step rule = AdaptiveRule(max_val=12) dag = IterationDAG(A, S, rule, max_steps=3, max_branch=30) dag.build() if dag.sidon_paths: multi_step += 1 else: no_path += 1 print(f" One-step success: {one_step_only}/{trials}") print(f" Multi-step only: {multi_step}/{trials}") print(f" No path found: {no_path}/{trials}") # ---------- Main ---------- if __name__ == "__main__": # Detailed failure analysis for known examples print("=" * 60) print("DEEP TUNING: FAILURE ANALYSIS") print("=" * 60) print("\n--- Sidon Example: A=[1,2,5,6], S=7 ---") rows = detailed_modulus_report([1,2,5,6], 7) for r in rows: status = "✓ SIDON" if r['sidon'] else "✗ FAIL" g = "guaranteed" if r['guaranteed'] else "not-guaranteed" print(f" [{r['L1']},{r['L2']}] M={r['M']} {status} ({g})") if r['failures']: for f in r['failures'][:2]: print(f" {f}") print("\n--- Complex Set: A=[0,1,3,8,13], S=27 ---") rows = detailed_modulus_report([0,1,3,8,13], 27) for r in rows[:8]: status = "✓ SIDON" if r['sidon'] else "✗ FAIL" print(f" [{r['L1']},{r['L2']}] M={r['M']} {status}") if r['failures']: for f in r['failures'][:3]: print(f" {f}") analyze_optimal_M_trend(300) analyze_modulus_size_preference(300) analyze_multi_step_needed(200)