-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhypothesis_selectivity.py
More file actions
67 lines (61 loc) · 2.59 KB
/
Copy pathhypothesis_selectivity.py
File metadata and controls
67 lines (61 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env python
"""tools/hypothesis_selectivity.py — how much of the pool can a class conjecture even touch?
A class-conditioned conjecture `(cubic AND triangle-free) => B` says nothing about
a graph that is not cubic and triangle-free: on those the implication is vacuously
true. So a refutation search that walks the whole pool spends its budget where no
counterexample can exist. This measures, per surviving conjecture, the fraction of
the refutation pool that satisfies its hypothesis -- i.e. the fraction of the
search that is not wasted by construction.
"""
from __future__ import annotations
import json, os, sys, collections
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import pandas as pd
from pipeline import conjecture_lattice as cl
def main() -> int:
frames = []
for f in ["battery_bigdb", "battery_families", "battery_random",
"battery_degenerate", "seed_battery"]:
p = f"database/cache/{f}.parquet"
if os.path.exists(p):
frames.append(pd.read_parquet(p))
pool = pd.concat(frames)
pool = pool[~pool.index.duplicated(keep="first")]
n = len(pool)
print(f"pool: {n} graphs\n")
conj = json.load(open("results/cegis_results.json"))["conjectures"]
surv = cl.parse_survivors(conj)
sel = []
per_class = {}
for s in surv:
cls = [c for c in s.classes if c in pool.columns]
if not cls:
continue
mask = pd.Series(True, index=pool.index)
for c in cls:
mask &= pool[c].fillna(False).astype(bool)
frac = mask.sum() / n
sel.append((frac, tuple(sorted(s.classes))))
per_class.setdefault(tuple(sorted(cls)), frac)
sel.sort()
print(f"{len(sel)} class-conditioned survivors\n")
import statistics
fr = [f for f, _ in sel]
print(f" median fraction of pool satisfying the hypothesis: {statistics.median(fr)*100:.2f}%")
print(f" mean: {statistics.mean(fr)*100:.2f}%")
print(f" under 1% of the pool: {sum(1 for f in fr if f < 0.01)} conjectures "
f"({100*sum(1 for f in fr if f<0.01)/len(fr):.0f}%)")
print(f" under 0.1% of the pool:{sum(1 for f in fr if f < 0.001)} conjectures "
f"({100*sum(1 for f in fr if f<0.001)/len(fr):.0f}%)")
print("\n tightest hypotheses (smallest feasible region):")
seen = set()
for f, c in sel:
if c in seen:
continue
seen.add(c)
print(f" {f*100:7.3f}% ({int(f*n):6d} graphs) {' & '.join(c)}")
if len(seen) >= 12:
break
return 0
if __name__ == "__main__":
raise SystemExit(main())