selector-complexity 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- selector_complexity-0.1.0/PKG-INFO +11 -0
- selector_complexity-0.1.0/pyproject.toml +22 -0
- selector_complexity-0.1.0/selector_complexity/__init__.py +28 -0
- selector_complexity-0.1.0/selector_complexity/core.py +77 -0
- selector_complexity-0.1.0/selector_complexity/php.py +154 -0
- selector_complexity-0.1.0/selector_complexity/selectors.py +68 -0
- selector_complexity-0.1.0/selector_complexity/solvers.py +49 -0
- selector_complexity-0.1.0/selector_complexity.egg-info/PKG-INFO +11 -0
- selector_complexity-0.1.0/selector_complexity.egg-info/SOURCES.txt +11 -0
- selector_complexity-0.1.0/selector_complexity.egg-info/dependency_links.txt +1 -0
- selector_complexity-0.1.0/selector_complexity.egg-info/requires.txt +2 -0
- selector_complexity-0.1.0/selector_complexity.egg-info/top_level.txt +1 -0
- selector_complexity-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: selector-complexity
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Selector Complexity Framework for IPS proof complexity
|
|
5
|
+
Author-email: Carmen Esteban <carmen@research.dev>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/iafiscal1212/Selector-Complexity-Framework
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: numpy>=1.20
|
|
11
|
+
Requires-Dist: scipy>=1.7
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "selector-complexity"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Selector Complexity Framework for IPS proof complexity"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [{name = "Carmen Esteban", email = "carmen@research.dev"}]
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"numpy>=1.20",
|
|
15
|
+
"scipy>=1.7",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.urls]
|
|
19
|
+
Homepage = "https://github.com/iafiscal1212/Selector-Complexity-Framework"
|
|
20
|
+
|
|
21
|
+
[tool.setuptools.packages.find]
|
|
22
|
+
include = ["selector_complexity*"]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Selector Complexity Framework
|
|
3
|
+
==============================
|
|
4
|
+
|
|
5
|
+
Classifies tautologies by the complexity of their selector
|
|
6
|
+
families in IPS (Ideal Proof Systems).
|
|
7
|
+
|
|
8
|
+
Levels:
|
|
9
|
+
0 - Polynomial certificates, no selectors needed (e.g. PHP)
|
|
10
|
+
1 - Efficient selectors in auxiliary variables (e.g. PHP-E)
|
|
11
|
+
2+- Selectors require original variables, expensive (e.g. PHP-C)
|
|
12
|
+
|
|
13
|
+
Author: Carmen Esteban
|
|
14
|
+
License: MIT
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
__version__ = "0.1.0"
|
|
18
|
+
__author__ = "Carmen Esteban"
|
|
19
|
+
|
|
20
|
+
from selector_complexity.core import PolynomialSystem, SelectorFamily
|
|
21
|
+
from selector_complexity.php import php_axioms, phpe_axioms, phpc_axioms
|
|
22
|
+
from selector_complexity.solvers import build_matrix, find_certificate
|
|
23
|
+
from selector_complexity.selectors import (
|
|
24
|
+
build_phpe_selectors,
|
|
25
|
+
build_phpc_explicit_selectors,
|
|
26
|
+
enumerate_vc,
|
|
27
|
+
test_s_only_feasibility,
|
|
28
|
+
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""Core definitions: PolynomialSystem, SelectorFamily."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from itertools import combinations
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PolynomialSystem:
|
|
8
|
+
"""A system of polynomial equations over boolean variables."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, name, num_vars, axioms):
|
|
11
|
+
self.name = name
|
|
12
|
+
self.num_vars = num_vars
|
|
13
|
+
self.axioms = axioms
|
|
14
|
+
|
|
15
|
+
def evaluate(self, assignment):
|
|
16
|
+
values = []
|
|
17
|
+
for ax in self.axioms:
|
|
18
|
+
val = 0.0
|
|
19
|
+
for coef, monom in ax:
|
|
20
|
+
prod = coef
|
|
21
|
+
for v in monom:
|
|
22
|
+
prod *= assignment.get(v, 0)
|
|
23
|
+
val += prod
|
|
24
|
+
values.append(val)
|
|
25
|
+
return values
|
|
26
|
+
|
|
27
|
+
def is_unsatisfiable(self, max_vars=15):
|
|
28
|
+
if self.num_vars > max_vars:
|
|
29
|
+
return None
|
|
30
|
+
for bits in range(2 ** self.num_vars):
|
|
31
|
+
assignment = {v: (bits >> v) & 1 for v in range(self.num_vars)}
|
|
32
|
+
vals = self.evaluate(assignment)
|
|
33
|
+
if all(abs(v) < 1e-10 for v in vals):
|
|
34
|
+
return False
|
|
35
|
+
return True
|
|
36
|
+
|
|
37
|
+
def __repr__(self):
|
|
38
|
+
return "PolynomialSystem({}, {} vars, {} axioms)".format(
|
|
39
|
+
self.name, self.num_vars, len(self.axioms))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class SelectorFamily:
|
|
43
|
+
"""A family of selector polynomials."""
|
|
44
|
+
|
|
45
|
+
def __init__(self, selectors, var_assignments_generator):
|
|
46
|
+
self.selectors = selectors
|
|
47
|
+
self.var_gen = var_assignments_generator
|
|
48
|
+
|
|
49
|
+
def verify(self):
|
|
50
|
+
labels = list(self.selectors.keys())
|
|
51
|
+
partition_ok = exclusivity_ok = boolean_ok = total = 0
|
|
52
|
+
for assignment in self.var_gen():
|
|
53
|
+
total += 1
|
|
54
|
+
vals = {}
|
|
55
|
+
for label in labels:
|
|
56
|
+
v = sum(c * np.prod([assignment.get(var, 0) for var in m])
|
|
57
|
+
for c, m in self.selectors[label])
|
|
58
|
+
vals[label] = v
|
|
59
|
+
if all(abs(v) < 1e-10 or abs(v - 1) < 1e-10 for v in vals.values()):
|
|
60
|
+
boolean_ok += 1
|
|
61
|
+
if abs(sum(vals.values()) - 1.0) < 1e-10:
|
|
62
|
+
partition_ok += 1
|
|
63
|
+
excl = all(abs(vals[l1] * vals[l2]) < 1e-10
|
|
64
|
+
for i, l1 in enumerate(labels)
|
|
65
|
+
for l2 in labels[i+1:])
|
|
66
|
+
if excl:
|
|
67
|
+
exclusivity_ok += 1
|
|
68
|
+
return {"total": total, "partition": partition_ok,
|
|
69
|
+
"exclusivity": exclusivity_ok, "boolean": boolean_ok,
|
|
70
|
+
"all_pass": partition_ok == total == exclusivity_ok == boolean_ok}
|
|
71
|
+
|
|
72
|
+
def size(self):
|
|
73
|
+
return sum(len(p) for p in self.selectors.values())
|
|
74
|
+
|
|
75
|
+
def max_degree(self):
|
|
76
|
+
return max(max((len(m) for _, m in p), default=0)
|
|
77
|
+
for p in self.selectors.values())
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
from itertools import combinations
|
|
2
|
+
|
|
3
|
+
def php_axioms(n):
|
|
4
|
+
pigeons = list(range(1, n + 2))
|
|
5
|
+
holes = list(range(1, n + 1))
|
|
6
|
+
var_x = {}
|
|
7
|
+
idx = 0
|
|
8
|
+
for p in pigeons:
|
|
9
|
+
for h in holes:
|
|
10
|
+
var_x[(p, h)] = idx
|
|
11
|
+
idx += 1
|
|
12
|
+
num_vars = idx
|
|
13
|
+
axioms = []
|
|
14
|
+
for p in pigeons:
|
|
15
|
+
terms = []
|
|
16
|
+
hvars = [var_x[(p, h)] for h in holes]
|
|
17
|
+
for k in range(len(hvars) + 1):
|
|
18
|
+
sign = (-1.0) ** k
|
|
19
|
+
for subset in combinations(hvars, k):
|
|
20
|
+
terms.append((sign, frozenset(subset)))
|
|
21
|
+
axioms.append(terms)
|
|
22
|
+
for h in holes:
|
|
23
|
+
for i, p in enumerate(pigeons):
|
|
24
|
+
for p2 in pigeons[i + 1:]:
|
|
25
|
+
axioms.append([(1.0, frozenset([var_x[(p, h)], var_x[(p2, h)]]))])
|
|
26
|
+
for p in pigeons:
|
|
27
|
+
for j, h in enumerate(holes):
|
|
28
|
+
for h2 in holes[j + 1:]:
|
|
29
|
+
axioms.append([(1.0, frozenset([var_x[(p, h)], var_x[(p, h2)]]))])
|
|
30
|
+
return axioms, num_vars, var_x
|
|
31
|
+
|
|
32
|
+
def phpe_axioms(n):
|
|
33
|
+
pigeons = list(range(1, n + 2))
|
|
34
|
+
holes = list(range(1, n + 1))
|
|
35
|
+
var_x, var_y = {}, {}
|
|
36
|
+
idx = 0
|
|
37
|
+
for p in pigeons:
|
|
38
|
+
for h in holes:
|
|
39
|
+
var_x[(p, h)] = idx
|
|
40
|
+
idx += 1
|
|
41
|
+
for i, p in enumerate(pigeons):
|
|
42
|
+
for p2 in pigeons[i + 1:]:
|
|
43
|
+
var_y[(p, p2)] = idx
|
|
44
|
+
idx += 1
|
|
45
|
+
num_vars = idx
|
|
46
|
+
axioms = []
|
|
47
|
+
for p in pigeons:
|
|
48
|
+
terms = []
|
|
49
|
+
hvars = [var_x[(p, h)] for h in holes]
|
|
50
|
+
for k in range(len(hvars) + 1):
|
|
51
|
+
sign = (-1.0) ** k
|
|
52
|
+
for subset in combinations(hvars, k):
|
|
53
|
+
terms.append((sign, frozenset(subset)))
|
|
54
|
+
axioms.append(terms)
|
|
55
|
+
for h in holes:
|
|
56
|
+
for i, p in enumerate(pigeons):
|
|
57
|
+
for p2 in pigeons[i + 1:]:
|
|
58
|
+
axioms.append([(1.0, frozenset([var_x[(p, h)], var_x[(p2, h)]]))])
|
|
59
|
+
for p in pigeons:
|
|
60
|
+
for j, h in enumerate(holes):
|
|
61
|
+
for h2 in holes[j + 1:]:
|
|
62
|
+
axioms.append([(1.0, frozenset([var_x[(p, h)], var_x[(p, h2)]]))])
|
|
63
|
+
for i_p, p in enumerate(pigeons):
|
|
64
|
+
for p2 in pigeons[i_p + 1:]:
|
|
65
|
+
y_idx = var_y[(p, p2)]
|
|
66
|
+
for h in holes:
|
|
67
|
+
for h2 in holes:
|
|
68
|
+
if h == h2: continue
|
|
69
|
+
x1, x2 = var_x[(p, h)], var_x[(p2, h2)]
|
|
70
|
+
if h < h2:
|
|
71
|
+
axioms.append([(1.0, frozenset([x1, x2])), (-1.0, frozenset([x1, x2,
|
|
72
|
+
y_idx]))])
|
|
73
|
+
else:
|
|
74
|
+
axioms.append([(1.0, frozenset([x1, x2, y_idx]))])
|
|
75
|
+
for i_p, p in enumerate(pigeons):
|
|
76
|
+
for j_p, p2 in enumerate(pigeons[i_p + 1:], i_p + 1):
|
|
77
|
+
for p3 in pigeons[j_p + 1:]:
|
|
78
|
+
y12, y23, y13 = var_y[(p, p2)], var_y[(p2, p3)], var_y[(p, p3)]
|
|
79
|
+
axioms.append([(1.0, frozenset([y12, y23])), (-1.0, frozenset([y12, y23,
|
|
80
|
+
y13]))])
|
|
81
|
+
axioms.append([(1.0, frozenset([y13])), (-1.0, frozenset([y12, y13])),
|
|
82
|
+
(-1.0, frozenset([y23, y13])), (1.0, frozenset([y12, y23,
|
|
83
|
+
y13]))])
|
|
84
|
+
return axioms, num_vars, var_x, var_y
|
|
85
|
+
|
|
86
|
+
def phpc_axioms(n):
|
|
87
|
+
pigeons = list(range(1, n + 2))
|
|
88
|
+
holes = list(range(1, n + 1))
|
|
89
|
+
var_x, var_s = {}, {}
|
|
90
|
+
idx = 0
|
|
91
|
+
for p in pigeons:
|
|
92
|
+
for h in holes:
|
|
93
|
+
var_x[(p, h)] = idx
|
|
94
|
+
idx += 1
|
|
95
|
+
for p in pigeons:
|
|
96
|
+
for q in pigeons:
|
|
97
|
+
if p != q:
|
|
98
|
+
var_s[(p, q)] = idx
|
|
99
|
+
idx += 1
|
|
100
|
+
num_vars = idx
|
|
101
|
+
axioms = []
|
|
102
|
+
for p in pigeons:
|
|
103
|
+
terms = []
|
|
104
|
+
hvars = [var_x[(p, h)] for h in holes]
|
|
105
|
+
for k in range(len(hvars) + 1):
|
|
106
|
+
sign = (-1.0) ** k
|
|
107
|
+
for subset in combinations(hvars, k):
|
|
108
|
+
terms.append((sign, frozenset(subset)))
|
|
109
|
+
axioms.append(terms)
|
|
110
|
+
for h in holes:
|
|
111
|
+
for i, p in enumerate(pigeons):
|
|
112
|
+
for p2 in pigeons[i + 1:]:
|
|
113
|
+
axioms.append([(1.0, frozenset([var_x[(p, h)], var_x[(p2, h)]]))])
|
|
114
|
+
for p in pigeons:
|
|
115
|
+
for j, h in enumerate(holes):
|
|
116
|
+
for h2 in holes[j + 1:]:
|
|
117
|
+
axioms.append([(1.0, frozenset([var_x[(p, h)], var_x[(p, h2)]]))])
|
|
118
|
+
for p in pigeons:
|
|
119
|
+
terms = []
|
|
120
|
+
svars = [var_s[(p, q)] for q in pigeons if q != p]
|
|
121
|
+
for k in range(len(svars) + 1):
|
|
122
|
+
sign = (-1.0) ** k
|
|
123
|
+
for subset in combinations(svars, k):
|
|
124
|
+
terms.append((sign, frozenset(subset)))
|
|
125
|
+
axioms.append(terms)
|
|
126
|
+
for p in pigeons:
|
|
127
|
+
others = [q for q in pigeons if q != p]
|
|
128
|
+
for i, q in enumerate(others):
|
|
129
|
+
for q2 in others[i + 1:]:
|
|
130
|
+
axioms.append([(1.0, frozenset([var_s[(p, q)], var_s[(p, q2)]]))])
|
|
131
|
+
for q in pigeons:
|
|
132
|
+
terms = []
|
|
133
|
+
svars = [var_s[(p, q)] for p in pigeons if p != q]
|
|
134
|
+
for k in range(len(svars) + 1):
|
|
135
|
+
sign = (-1.0) ** k
|
|
136
|
+
for subset in combinations(svars, k):
|
|
137
|
+
terms.append((sign, frozenset(subset)))
|
|
138
|
+
axioms.append(terms)
|
|
139
|
+
for q in pigeons:
|
|
140
|
+
others = [p for p in pigeons if p != q]
|
|
141
|
+
for i, p in enumerate(others):
|
|
142
|
+
for p2 in others[i + 1:]:
|
|
143
|
+
axioms.append([(1.0, frozenset([var_s[(p, q)], var_s[(p2, q)]]))])
|
|
144
|
+
def succ_hole(h):
|
|
145
|
+
return (h % n) + 1
|
|
146
|
+
for p in pigeons:
|
|
147
|
+
for q in pigeons:
|
|
148
|
+
if p == q: continue
|
|
149
|
+
s_idx = var_s[(p, q)]
|
|
150
|
+
for h in holes:
|
|
151
|
+
for h2 in holes:
|
|
152
|
+
if h2 == succ_hole(h): continue
|
|
153
|
+
axioms.append([(1.0, frozenset([s_idx, var_x[(p, h)], var_x[(q, h2)]]))])
|
|
154
|
+
return axioms, num_vars, var_x, var_s
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from itertools import combinations, permutations
|
|
3
|
+
|
|
4
|
+
def build_phpe_selectors(n):
|
|
5
|
+
pigeons = list(range(1, n + 2))
|
|
6
|
+
var_y = {}
|
|
7
|
+
idx = 0
|
|
8
|
+
for i, p in enumerate(pigeons):
|
|
9
|
+
for p2 in pigeons[i + 1:]:
|
|
10
|
+
var_y[(p, p2)] = idx
|
|
11
|
+
idx += 1
|
|
12
|
+
indicators = {}
|
|
13
|
+
for p in pigeons:
|
|
14
|
+
factors = []
|
|
15
|
+
for q in pigeons:
|
|
16
|
+
if q == p: continue
|
|
17
|
+
if q < p:
|
|
18
|
+
factors.append([(1.0, frozenset([var_y[(q, p)]]))])
|
|
19
|
+
else:
|
|
20
|
+
factors.append([(1.0, frozenset()), (-1.0, frozenset([var_y[(p, q)]]))])
|
|
21
|
+
result = [(1.0, frozenset())]
|
|
22
|
+
for factor in factors:
|
|
23
|
+
new_result = []
|
|
24
|
+
for c1, m1 in result:
|
|
25
|
+
for c2, m2 in factor:
|
|
26
|
+
new_result.append((c1 * c2, m1 | m2))
|
|
27
|
+
combined = {}
|
|
28
|
+
for c, m in new_result:
|
|
29
|
+
combined[m] = combined.get(m, 0) + c
|
|
30
|
+
result = [(c, m) for m, c in combined.items() if abs(c) > 1e-15]
|
|
31
|
+
indicators[p] = result
|
|
32
|
+
return indicators, var_y
|
|
33
|
+
|
|
34
|
+
def test_s_only_feasibility(n, max_degree=3):
|
|
35
|
+
pigeons = list(range(1, n + 2))
|
|
36
|
+
var_s = {}
|
|
37
|
+
idx = 0
|
|
38
|
+
for p in pigeons:
|
|
39
|
+
for q in pigeons:
|
|
40
|
+
if p != q:
|
|
41
|
+
var_s[(p, q)] = idx
|
|
42
|
+
idx += 1
|
|
43
|
+
num_s_vars = idx
|
|
44
|
+
others = pigeons[1:]
|
|
45
|
+
cycle_assignments = []
|
|
46
|
+
for perm in permutations(others):
|
|
47
|
+
cycle = (pigeons[0],) + perm
|
|
48
|
+
assignment = {}
|
|
49
|
+
for i in range(len(cycle)):
|
|
50
|
+
p, q = cycle[i], cycle[(i + 1) % len(cycle)]
|
|
51
|
+
for p2 in pigeons:
|
|
52
|
+
for q2 in pigeons:
|
|
53
|
+
if p2 != q2:
|
|
54
|
+
assignment[var_s[(p2, q2)]] = 1 if (p2 == p and q2 == q) else 0
|
|
55
|
+
cycle_assignments.append(assignment)
|
|
56
|
+
monoms = [frozenset()]
|
|
57
|
+
for d in range(1, max_degree + 1):
|
|
58
|
+
for combo in combinations(range(num_s_vars), d):
|
|
59
|
+
monoms.append(frozenset(combo))
|
|
60
|
+
eval_matrix = np.zeros((len(cycle_assignments), len(monoms)))
|
|
61
|
+
for i, assign in enumerate(cycle_assignments):
|
|
62
|
+
for j, monom in enumerate(monoms):
|
|
63
|
+
prod = 1.0
|
|
64
|
+
for v in monom:
|
|
65
|
+
prod *= assign.get(v, 0)
|
|
66
|
+
eval_matrix[i, j] = prod
|
|
67
|
+
unique_rows = np.unique(eval_matrix, axis=0)
|
|
68
|
+
return len(unique_rows) == 1, len(cycle_assignments), len(unique_rows)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy import sparse
|
|
3
|
+
from scipy.sparse.linalg import lsqr
|
|
4
|
+
from itertools import combinations
|
|
5
|
+
|
|
6
|
+
def build_matrix(axioms, num_vars, d_max):
|
|
7
|
+
all_monoms = []
|
|
8
|
+
monom_to_idx = {}
|
|
9
|
+
for d in range(d_max + 1):
|
|
10
|
+
for combo in combinations(range(num_vars), d):
|
|
11
|
+
m = frozenset(combo)
|
|
12
|
+
monom_to_idx[m] = len(all_monoms)
|
|
13
|
+
all_monoms.append(m)
|
|
14
|
+
num_monoms = len(all_monoms)
|
|
15
|
+
rows, cols, vals = [], [], []
|
|
16
|
+
total_unknowns = 0
|
|
17
|
+
for ax in axioms:
|
|
18
|
+
deg_ax = max(len(m) for c, m in ax)
|
|
19
|
+
deg_mult = max(0, d_max - deg_ax)
|
|
20
|
+
for d in range(deg_mult + 1):
|
|
21
|
+
for combo in combinations(range(num_vars), d):
|
|
22
|
+
m_mult = frozenset(combo)
|
|
23
|
+
col = total_unknowns
|
|
24
|
+
total_unknowns += 1
|
|
25
|
+
for coef_ax, m_ax in ax:
|
|
26
|
+
m_prod = m_mult | m_ax
|
|
27
|
+
if len(m_prod) <= d_max and m_prod in monom_to_idx:
|
|
28
|
+
rows.append(monom_to_idx[m_prod])
|
|
29
|
+
cols.append(col)
|
|
30
|
+
vals.append(coef_ax)
|
|
31
|
+
if total_unknowns == 0:
|
|
32
|
+
return sparse.csr_matrix((num_monoms, 0)), np.zeros(num_monoms), num_monoms, 0
|
|
33
|
+
A = sparse.csr_matrix((vals, (rows, cols)), shape=(num_monoms, total_unknowns))
|
|
34
|
+
b = np.zeros(num_monoms)
|
|
35
|
+
b[monom_to_idx[frozenset()]] = 1.0
|
|
36
|
+
return A, b, num_monoms, total_unknowns
|
|
37
|
+
|
|
38
|
+
def find_certificate(axioms, num_vars, d_max, atol=1e-12):
|
|
39
|
+
A, b, nm, nu = build_matrix(axioms, num_vars, d_max)
|
|
40
|
+
if nu == 0:
|
|
41
|
+
return None
|
|
42
|
+
res = lsqr(A, b, atol=atol, btol=atol, iter_lim=10000)
|
|
43
|
+
x = res[0]
|
|
44
|
+
residual = np.linalg.norm(A @ x - b)
|
|
45
|
+
if residual < 1e-6:
|
|
46
|
+
size = int(np.sum(np.abs(x) > 1e-8))
|
|
47
|
+
return {"degree": d_max, "size": size, "num_monoms": nm,
|
|
48
|
+
"num_unknowns": nu, "residual": float(residual), "coefficients": x}
|
|
49
|
+
return None
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: selector-complexity
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Selector Complexity Framework for IPS proof complexity
|
|
5
|
+
Author-email: Carmen Esteban <carmen@research.dev>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/iafiscal1212/Selector-Complexity-Framework
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: numpy>=1.20
|
|
11
|
+
Requires-Dist: scipy>=1.7
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
selector_complexity/__init__.py
|
|
3
|
+
selector_complexity/core.py
|
|
4
|
+
selector_complexity/php.py
|
|
5
|
+
selector_complexity/selectors.py
|
|
6
|
+
selector_complexity/solvers.py
|
|
7
|
+
selector_complexity.egg-info/PKG-INFO
|
|
8
|
+
selector_complexity.egg-info/SOURCES.txt
|
|
9
|
+
selector_complexity.egg-info/dependency_links.txt
|
|
10
|
+
selector_complexity.egg-info/requires.txt
|
|
11
|
+
selector_complexity.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
selector_complexity
|