funcprops 0.1.0__py3-none-any.whl
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.
- funcprops/__init__.py +234 -0
- funcprops/_semialg.py +246 -0
- funcprops/api.py +70 -0
- funcprops/branchcuts/__init__.py +141 -0
- funcprops/branchcuts/computation.py +664 -0
- funcprops/branchcuts/core.py +1204 -0
- funcprops/branchcuts/post_simplify.py +461 -0
- funcprops/conditions.py +124 -0
- funcprops/data/catalogue.json +127449 -0
- funcprops/data/dlmf_audit.json +3382 -0
- funcprops/dlmf.py +29 -0
- funcprops/engine.py +324 -0
- funcprops/exceptions.py +29 -0
- funcprops/proof_cache.py +373 -0
- funcprops/real_analysis/__init__.py +52 -0
- funcprops/real_analysis/advanced_convexity.py +217 -0
- funcprops/real_analysis/boundedness.py +168 -0
- funcprops/real_analysis/common.py +244 -0
- funcprops/real_analysis/convexity.py +698 -0
- funcprops/real_analysis/differentiability.py +112 -0
- funcprops/real_analysis/domain.py +188 -0
- funcprops/real_analysis/mapping.py +374 -0
- funcprops/real_analysis/monotonic_certificates.py +867 -0
- funcprops/real_analysis/monotonicity.py +673 -0
- funcprops/real_analysis/oscillation.py +151 -0
- funcprops/real_analysis/piecewise.py +174 -0
- funcprops/real_analysis/range.py +552 -0
- funcprops/real_analysis/sign.py +561 -0
- funcprops/real_analysis/smoothness.py +268 -0
- funcprops/real_analysis/special_functions.py +515 -0
- funcprops/real_analysis/structural_properties.py +558 -0
- funcprops/real_analysis/zeros.py +327 -0
- funcprops/registry.py +274 -0
- funcprops/results.py +239 -0
- funcprops/singularities.py +1767 -0
- funcprops/stratification.py +494 -0
- funcprops/sympy_compare.py +63 -0
- funcprops/transcendental/__init__.py +140 -0
- funcprops/transcendental/algebraize.py +201 -0
- funcprops/transcendental/analytic.py +261 -0
- funcprops/transcendental/complex_roots.py +542 -0
- funcprops/transcendental/exp_fourier.py +221 -0
- funcprops/transcendental/extrema.py +821 -0
- funcprops/transcendental/periodic.py +222 -0
- funcprops/transcendental/proof.py +104 -0
- funcprops/transcendental/real_interval.py +128 -0
- funcprops/transcendental/real_sign.py +117 -0
- funcprops/transcendental/reduce.py +288 -0
- funcprops/transcendental/roots.py +1380 -0
- funcprops/transcendental/zero_geometry.py +1197 -0
- funcprops/verification.py +410 -0
- funcprops-0.1.0.dist-info/METADATA +208 -0
- funcprops-0.1.0.dist-info/RECORD +56 -0
- funcprops-0.1.0.dist-info/WHEEL +5 -0
- funcprops-0.1.0.dist-info/licenses/LICENSE +674 -0
- funcprops-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
"""Independent, conservative replay checks for exact property certificates.
|
|
2
|
+
|
|
3
|
+
Verifiers return True only when the certificate's stated conclusion can be
|
|
4
|
+
re-established from its payload and current proof primitives. False means the
|
|
5
|
+
certificate is internally inconsistent or unsupported; verifiers never turn an
|
|
6
|
+
unknown symbolic comparison into success.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import sympy as sp
|
|
12
|
+
from sympy import S
|
|
13
|
+
|
|
14
|
+
from .exceptions import SYMBOLIC_QUERY_ERRORS
|
|
15
|
+
from .results import Monotonicity, Sign
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _truth(q):
|
|
19
|
+
if q in (True, S.true):
|
|
20
|
+
return True
|
|
21
|
+
if q in (False, S.false):
|
|
22
|
+
return False
|
|
23
|
+
try:
|
|
24
|
+
z = sp.simplify(q)
|
|
25
|
+
if z is S.true:
|
|
26
|
+
return True
|
|
27
|
+
if z is S.false:
|
|
28
|
+
return False
|
|
29
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
30
|
+
pass
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def verify_monotonic_decomposition(cert):
|
|
35
|
+
from .real_analysis.monotonic_certificates import MonotonicDecomposition
|
|
36
|
+
|
|
37
|
+
if not isinstance(cert, MonotonicDecomposition):
|
|
38
|
+
return False
|
|
39
|
+
try:
|
|
40
|
+
return sp.simplify(cert.reconstruct() - cert.expression) == 0
|
|
41
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def verify_monotonic_partition(expr, var, cert):
|
|
46
|
+
from .proof_cache import property_proof_context
|
|
47
|
+
from .real_analysis.monotonic_certificates import MonotonicPartition
|
|
48
|
+
|
|
49
|
+
if not isinstance(cert, MonotonicPartition):
|
|
50
|
+
return False
|
|
51
|
+
expr = sp.sympify(expr)
|
|
52
|
+
var = sp.sympify(var)
|
|
53
|
+
ctx = property_proof_context(expr, var, domain=cert.domain)
|
|
54
|
+
try:
|
|
55
|
+
d = ctx.derivative(1, factored=True)
|
|
56
|
+
if cert.derivative is not None and sp.simplify(d - cert.derivative) != 0:
|
|
57
|
+
return False
|
|
58
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
59
|
+
return False
|
|
60
|
+
if cert.indexed is not None:
|
|
61
|
+
return bool(cert.indexed.boundary_geometry)
|
|
62
|
+
for cell in cert.cells:
|
|
63
|
+
if not isinstance(cell.interval, sp.Set):
|
|
64
|
+
return False
|
|
65
|
+
sg = property_proof_context(d, var, domain=cell.interval).sign(
|
|
66
|
+
domain=cell.interval
|
|
67
|
+
)
|
|
68
|
+
if cell.direction is Monotonicity.STRICTLY_INCREASING and sg not in (
|
|
69
|
+
Sign.POSITIVE,
|
|
70
|
+
Sign.NONNEGATIVE,
|
|
71
|
+
):
|
|
72
|
+
return False
|
|
73
|
+
if cell.direction is Monotonicity.STRICTLY_DECREASING and sg not in (
|
|
74
|
+
Sign.NEGATIVE,
|
|
75
|
+
Sign.NONPOSITIVE,
|
|
76
|
+
):
|
|
77
|
+
return False
|
|
78
|
+
if cell.direction is Monotonicity.NONDECREASING and sg not in (
|
|
79
|
+
Sign.POSITIVE,
|
|
80
|
+
Sign.NONNEGATIVE,
|
|
81
|
+
Sign.ZERO,
|
|
82
|
+
):
|
|
83
|
+
return False
|
|
84
|
+
if cell.direction is Monotonicity.NONINCREASING and sg not in (
|
|
85
|
+
Sign.NEGATIVE,
|
|
86
|
+
Sign.NONPOSITIVE,
|
|
87
|
+
Sign.ZERO,
|
|
88
|
+
):
|
|
89
|
+
return False
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def verify_zero_geometry(cert):
|
|
94
|
+
from .transcendental.zero_geometry import IndexedZero, ZeroGeometryCertificate
|
|
95
|
+
|
|
96
|
+
if not isinstance(cert, ZeroGeometryCertificate):
|
|
97
|
+
return False
|
|
98
|
+
if not isinstance(cert.support, sp.Set):
|
|
99
|
+
return False
|
|
100
|
+
if cert.derivative_order < 0:
|
|
101
|
+
return False
|
|
102
|
+
for z in cert.indexed_family:
|
|
103
|
+
if not isinstance(z, IndexedZero):
|
|
104
|
+
return False
|
|
105
|
+
if z.family != cert.family or z.derivative_order != cert.derivative_order:
|
|
106
|
+
return False
|
|
107
|
+
for o in cert.orderings:
|
|
108
|
+
if o.relation not in ("<", "<=", ">", ">="):
|
|
109
|
+
return False
|
|
110
|
+
return all(inter.pattern for inter in cert.interlacings)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def verify_convexity_certificate(expr, var, cert):
|
|
114
|
+
from .proof_cache import property_proof_context
|
|
115
|
+
from .real_analysis.advanced_convexity import ConvexityCertificate
|
|
116
|
+
|
|
117
|
+
if not isinstance(cert, ConvexityCertificate):
|
|
118
|
+
return False
|
|
119
|
+
if cert.modulus is None:
|
|
120
|
+
return bool(cert.method and cert.classification is not None)
|
|
121
|
+
if cert.modulus.is_positive is not True:
|
|
122
|
+
return False
|
|
123
|
+
d2 = property_proof_context(expr, var, domain=cert.domain).derivative(2)
|
|
124
|
+
concave = cert.classification.name.endswith("CONCAVE")
|
|
125
|
+
target = sp.simplify((-d2 if concave else d2) - cert.modulus)
|
|
126
|
+
sg = property_proof_context(target, var, domain=cert.domain).sign(
|
|
127
|
+
domain=cert.domain
|
|
128
|
+
)
|
|
129
|
+
return sg in (Sign.ZERO, Sign.NONNEGATIVE, Sign.POSITIVE)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def verify_extremum_ordering_theorem(cert):
|
|
133
|
+
from .transcendental.extrema import ExtremumOrderingTheorem
|
|
134
|
+
|
|
135
|
+
if not isinstance(cert, ExtremumOrderingTheorem):
|
|
136
|
+
return False
|
|
137
|
+
if cert.magnitude_direction not in ("increasing", "decreasing"):
|
|
138
|
+
return False
|
|
139
|
+
if not cert.family or not cert.source:
|
|
140
|
+
return False
|
|
141
|
+
return cert.proof is not None
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def verify_indexed_tail_inversion(cert):
|
|
145
|
+
from .transcendental.zero_geometry import (
|
|
146
|
+
IndexedTailInversionCertificate,
|
|
147
|
+
IndexedZero,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
if not isinstance(cert, IndexedTailInversionCertificate):
|
|
151
|
+
return False
|
|
152
|
+
if cert.direction not in ("left", "right"):
|
|
153
|
+
return False
|
|
154
|
+
if not isinstance(cert.zero_template, IndexedZero):
|
|
155
|
+
return False
|
|
156
|
+
if cert.zero_template.family != cert.family:
|
|
157
|
+
return False
|
|
158
|
+
if cert.integer_bracket is not None:
|
|
159
|
+
b = cert.integer_bracket
|
|
160
|
+
try:
|
|
161
|
+
if (sp.simplify(b.upper - b.lower)).is_negative is True:
|
|
162
|
+
return False
|
|
163
|
+
if (
|
|
164
|
+
getattr(b, "exact", False)
|
|
165
|
+
and sp.simplify(cert.first_index - b.lower) != 0
|
|
166
|
+
):
|
|
167
|
+
return False
|
|
168
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
169
|
+
return False
|
|
170
|
+
return True
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def verify_certificate(cert, *, expr=None, var=None):
|
|
174
|
+
"""Dispatch a supported certificate to its replay verifier."""
|
|
175
|
+
from .real_analysis.advanced_convexity import ConvexityCertificate
|
|
176
|
+
from .real_analysis.monotonic_certificates import (
|
|
177
|
+
MonotonicDecomposition,
|
|
178
|
+
MonotonicPartition,
|
|
179
|
+
)
|
|
180
|
+
from .real_analysis.structural_properties import (
|
|
181
|
+
HomogeneityResult,
|
|
182
|
+
PeriodicityResult,
|
|
183
|
+
SymmetryResult,
|
|
184
|
+
)
|
|
185
|
+
from .transcendental.extrema import (
|
|
186
|
+
ExtremumFamilyCertificate,
|
|
187
|
+
ExtremumOrderingTheorem,
|
|
188
|
+
ExtremumRange,
|
|
189
|
+
)
|
|
190
|
+
from .transcendental.roots import RootCertificate
|
|
191
|
+
from .transcendental.zero_geometry import (
|
|
192
|
+
CertifiedIntegerBracket,
|
|
193
|
+
IndexedTailInversionCertificate,
|
|
194
|
+
ZeroGeometryCertificate,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if isinstance(cert, MonotonicDecomposition):
|
|
198
|
+
return verify_monotonic_decomposition(cert)
|
|
199
|
+
if isinstance(cert, MonotonicPartition):
|
|
200
|
+
if expr is None or var is None:
|
|
201
|
+
raise ValueError("expr and var are required for MonotonicPartition replay")
|
|
202
|
+
return verify_monotonic_partition(expr, var, cert)
|
|
203
|
+
if isinstance(cert, ConvexityCertificate):
|
|
204
|
+
if expr is None or var is None:
|
|
205
|
+
raise ValueError("expr and var are required for convexity replay")
|
|
206
|
+
return verify_convexity_certificate(expr, var, cert)
|
|
207
|
+
if isinstance(cert, ZeroGeometryCertificate):
|
|
208
|
+
return verify_zero_geometry(cert)
|
|
209
|
+
if isinstance(cert, RootCertificate):
|
|
210
|
+
return verify_root_certificate(cert)
|
|
211
|
+
if isinstance(cert, ExtremumFamilyCertificate):
|
|
212
|
+
return verify_extremum_family_certificate(cert)
|
|
213
|
+
if isinstance(cert, ExtremumRange):
|
|
214
|
+
return verify_extremum_range(cert)
|
|
215
|
+
if isinstance(cert, ExtremumOrderingTheorem):
|
|
216
|
+
return verify_extremum_ordering_theorem(cert)
|
|
217
|
+
if isinstance(cert, CertifiedIntegerBracket):
|
|
218
|
+
return verify_integer_bracket(cert)
|
|
219
|
+
if isinstance(cert, IndexedTailInversionCertificate):
|
|
220
|
+
return verify_indexed_tail_inversion(cert)
|
|
221
|
+
if isinstance(cert, PeriodicityResult):
|
|
222
|
+
if expr is None or var is None:
|
|
223
|
+
raise ValueError("expr and var are required for periodicity replay")
|
|
224
|
+
return verify_periodicity_result(expr, var, cert)
|
|
225
|
+
if isinstance(cert, SymmetryResult):
|
|
226
|
+
if expr is None or var is None:
|
|
227
|
+
raise ValueError("expr and var are required for symmetry replay")
|
|
228
|
+
return verify_symmetry_result(expr, var, cert)
|
|
229
|
+
if isinstance(cert, HomogeneityResult):
|
|
230
|
+
if expr is None:
|
|
231
|
+
raise ValueError("expr is required for homogeneity replay")
|
|
232
|
+
return verify_homogeneity_result(expr, cert)
|
|
233
|
+
raise TypeError(f"unsupported certificate type: {type(cert).__name__}")
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def verify_root_certificate(cert):
|
|
237
|
+
from .transcendental.roots import RootCertificate
|
|
238
|
+
|
|
239
|
+
if not isinstance(cert, RootCertificate):
|
|
240
|
+
return False
|
|
241
|
+
if not isinstance(cert.domain, sp.Set):
|
|
242
|
+
return False
|
|
243
|
+
try:
|
|
244
|
+
if cert.root_count is not None and cert.root_count is not sp.oo:
|
|
245
|
+
n = sp.sympify(cert.root_count)
|
|
246
|
+
if n.is_integer is False or n.is_nonnegative is False:
|
|
247
|
+
return False
|
|
248
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
249
|
+
return False
|
|
250
|
+
return bool(cert.method)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def verify_extremum_family_certificate(cert):
|
|
254
|
+
from .transcendental.extrema import ExtremumFamilyCertificate
|
|
255
|
+
|
|
256
|
+
if not isinstance(cert, ExtremumFamilyCertificate):
|
|
257
|
+
return False
|
|
258
|
+
if not cert.family:
|
|
259
|
+
return False
|
|
260
|
+
if not all(verify_zero_geometry(g) for g in cert.critical_geometry):
|
|
261
|
+
return False
|
|
262
|
+
return all(getattr(e, "family", cert.family) == cert.family for e in cert.extrema)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def verify_extremum_range(cert):
|
|
266
|
+
from .transcendental.extrema import ExtremumRange
|
|
267
|
+
|
|
268
|
+
if not isinstance(cert, ExtremumRange):
|
|
269
|
+
return False
|
|
270
|
+
try:
|
|
271
|
+
d = sp.simplify(sp.sympify(cert.upper) - sp.sympify(cert.lower))
|
|
272
|
+
if d.is_negative is True:
|
|
273
|
+
return False
|
|
274
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
275
|
+
return False
|
|
276
|
+
return not (
|
|
277
|
+
cert.complete and (cert.lower_attained is None or cert.upper_attained is None)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def verify_integer_bracket(cert):
|
|
282
|
+
from .transcendental.zero_geometry import CertifiedIntegerBracket
|
|
283
|
+
|
|
284
|
+
if not isinstance(cert, CertifiedIntegerBracket):
|
|
285
|
+
return False
|
|
286
|
+
try:
|
|
287
|
+
d = sp.simplify(cert.upper - cert.lower)
|
|
288
|
+
if d.is_negative is True:
|
|
289
|
+
return False
|
|
290
|
+
if cert.lower.is_integer is False or cert.upper.is_integer is False:
|
|
291
|
+
return False
|
|
292
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
293
|
+
return False
|
|
294
|
+
return True
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def verify_periodicity_result(expr, var, cert):
|
|
298
|
+
from .real_analysis.structural_properties import PeriodicityResult
|
|
299
|
+
from .results import Periodicity
|
|
300
|
+
|
|
301
|
+
if not isinstance(cert, PeriodicityResult):
|
|
302
|
+
return False
|
|
303
|
+
expr = sp.sympify(expr)
|
|
304
|
+
var = sp.sympify(var)
|
|
305
|
+
if cert.classification is Periodicity.CONSTANT:
|
|
306
|
+
return not expr.has(var)
|
|
307
|
+
if cert.classification is Periodicity.PERIODIC:
|
|
308
|
+
if cert.period is None:
|
|
309
|
+
return False
|
|
310
|
+
if (
|
|
311
|
+
cert.period.is_positive is not True
|
|
312
|
+
and "conditional-affine-frequency" not in cert.evidence
|
|
313
|
+
):
|
|
314
|
+
return False
|
|
315
|
+
try:
|
|
316
|
+
if sp.simplify(expr.subs(var, var + cert.period) - expr) == 0:
|
|
317
|
+
return True
|
|
318
|
+
if "conditional-affine-frequency" in cert.evidence and expr.func in (
|
|
319
|
+
sp.sin,
|
|
320
|
+
sp.cos,
|
|
321
|
+
sp.tan,
|
|
322
|
+
sp.cot,
|
|
323
|
+
):
|
|
324
|
+
a = sp.simplify(sp.diff(expr.args[0], var))
|
|
325
|
+
return not a.has(var) and cert.conditions == sp.Ne(a, 0)
|
|
326
|
+
return False
|
|
327
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
328
|
+
return False
|
|
329
|
+
if cert.classification is Periodicity.APERIODIC:
|
|
330
|
+
try:
|
|
331
|
+
return (
|
|
332
|
+
bool(expr.is_polynomial(var) and sp.Poly(expr, var).degree() > 0)
|
|
333
|
+
or "incommensurate-component-periods" in cert.evidence
|
|
334
|
+
)
|
|
335
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
336
|
+
return "incommensurate-component-periods" in cert.evidence
|
|
337
|
+
return cert.classification.value == "unknown"
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def verify_symmetry_result(expr, var, cert):
|
|
341
|
+
from .real_analysis.structural_properties import SymmetryResult
|
|
342
|
+
from .results import Symmetry
|
|
343
|
+
|
|
344
|
+
if not isinstance(cert, SymmetryResult):
|
|
345
|
+
return False
|
|
346
|
+
expr = sp.sympify(expr)
|
|
347
|
+
var = sp.sympify(var)
|
|
348
|
+
c = sp.sympify(cert.center)
|
|
349
|
+
try:
|
|
350
|
+
ref = sp.simplify(expr.subs(var, 2 * c - var))
|
|
351
|
+
ev = sp.simplify(ref - expr) == 0
|
|
352
|
+
od = sp.simplify(ref + expr) == 0
|
|
353
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
354
|
+
return False
|
|
355
|
+
if cert.classification is Symmetry.BOTH:
|
|
356
|
+
return ev and od
|
|
357
|
+
if cert.classification is Symmetry.EVEN:
|
|
358
|
+
return ev
|
|
359
|
+
if cert.classification is Symmetry.ODD:
|
|
360
|
+
return od
|
|
361
|
+
if cert.classification is Symmetry.CENTRAL:
|
|
362
|
+
try:
|
|
363
|
+
return sp.simplify(ref + expr - 2 * cert.central_value) == 0
|
|
364
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
365
|
+
return False
|
|
366
|
+
if cert.classification is Symmetry.NEITHER:
|
|
367
|
+
return not ev and not od
|
|
368
|
+
return True
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def _substitute_equalities(expr, assumptions):
|
|
372
|
+
repl = {}
|
|
373
|
+
atoms = assumptions.args if isinstance(assumptions, sp.And) else (assumptions,)
|
|
374
|
+
for a in atoms:
|
|
375
|
+
if isinstance(a, sp.Equality):
|
|
376
|
+
if getattr(a.lhs, "is_Symbol", False) and not a.rhs.has(a.lhs):
|
|
377
|
+
repl[a.lhs] = a.rhs
|
|
378
|
+
elif getattr(a.rhs, "is_Symbol", False) and not a.lhs.has(a.rhs):
|
|
379
|
+
repl[a.rhs] = a.lhs
|
|
380
|
+
return sp.simplify(expr.xreplace(repl)) if repl else sp.simplify(expr)
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def verify_homogeneity_result(expr, cert):
|
|
384
|
+
from .real_analysis.structural_properties import HomogeneityResult
|
|
385
|
+
from .results import Homogeneity
|
|
386
|
+
|
|
387
|
+
if not isinstance(cert, HomogeneityResult):
|
|
388
|
+
return False
|
|
389
|
+
expr = sp.sympify(expr)
|
|
390
|
+
assumptions = getattr(cert, "assumptions", S.true)
|
|
391
|
+
if cert.classification is not Homogeneity.HOMOGENEOUS:
|
|
392
|
+
return True
|
|
393
|
+
if cert.degree is None:
|
|
394
|
+
reduced = _substitute_equalities(expr, assumptions)
|
|
395
|
+
return reduced == 0 or not any(reduced.has(v) for v in cert.variables)
|
|
396
|
+
t = sp.Dummy("_verify_scale", positive=True)
|
|
397
|
+
try:
|
|
398
|
+
scaled = expr.xreplace(
|
|
399
|
+
{
|
|
400
|
+
v: t**w * v
|
|
401
|
+
for v, w in zip(
|
|
402
|
+
cert.variables,
|
|
403
|
+
cert.weights or (S.One,) * len(cert.variables),
|
|
404
|
+
strict=False,
|
|
405
|
+
)
|
|
406
|
+
}
|
|
407
|
+
)
|
|
408
|
+
return _substitute_equalities(scaled - t**cert.degree * expr, assumptions) == 0
|
|
409
|
+
except SYMBOLIC_QUERY_ERRORS:
|
|
410
|
+
return False
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: funcprops
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Symbolic global function properties backed by SymPy
|
|
5
|
+
Author-email: Bhuvanesh Bhatt <bhuvaneshbhatt@gmail.com>
|
|
6
|
+
License-Expression: GPL-3.0-only
|
|
7
|
+
Project-URL: Homepage, https://github.com/BhuvaneshBhatt/funcprops
|
|
8
|
+
Project-URL: Documentation, https://github.com/BhuvaneshBhatt/funcprops#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/BhuvaneshBhatt/funcprops
|
|
10
|
+
Keywords: sympy,symbolic mathematics,symbolic computation,function analysis,function properties,real analysis,complex analysis,domains,ranges,zeros,root isolation,monotonicity,convexity,continuity,differentiability,smoothness,singularities,branch cuts,injectivity,surjectivity,bijectivity,sign analysis,semialgebraic,certified computation,exact computation
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: sympy>=1.14
|
|
18
|
+
Requires-Dist: mpmath>=1.3
|
|
19
|
+
Requires-Dist: semialg>=1.0.0
|
|
20
|
+
Provides-Extra: test
|
|
21
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
22
|
+
Requires-Dist: hypothesis>=6; extra == "test"
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
25
|
+
Requires-Dist: hypothesis>=6; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff>=0.8; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# funcprops
|
|
30
|
+
|
|
31
|
+
`funcprops` is a SymPy-backed package for global function properties.
|
|
32
|
+
It combines a conditional function property registry, exact semialgebraic reasoning from the semialgebraic geometry package `semialg`, transcendental interval analysis, special-function zero geometry, and branch-cut/singularity analysis.
|
|
33
|
+
|
|
34
|
+
The package is careful: parameter conditions are retained instead of guessed, piecewise branches are analyzed on their effective domains, incomplete numerical searches are never promoted to exact proofs, and undecidable comparisons remain unknown.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install funcprops
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The core runtime requires SymPy, mpmath, and semialg 1.0.0 or newer.
|
|
43
|
+
|
|
44
|
+
## Quick start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
import sympy as sp
|
|
48
|
+
from funcprops import (
|
|
49
|
+
function_analytic,
|
|
50
|
+
function_branchcuts,
|
|
51
|
+
function_continuous,
|
|
52
|
+
function_convexity,
|
|
53
|
+
function_domain,
|
|
54
|
+
function_homogeneity,
|
|
55
|
+
function_meromorphic,
|
|
56
|
+
function_monotonicity,
|
|
57
|
+
function_periodicity,
|
|
58
|
+
function_poles,
|
|
59
|
+
function_range,
|
|
60
|
+
function_symmetry,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
x, y = sp.symbols("x y", real=True)
|
|
64
|
+
z = sp.Symbol("z")
|
|
65
|
+
|
|
66
|
+
function_domain(sp.sqrt(x - 1), x)
|
|
67
|
+
# x >= 1
|
|
68
|
+
|
|
69
|
+
function_range(x**2, x, y)
|
|
70
|
+
# y >= 0
|
|
71
|
+
|
|
72
|
+
function_monotonicity(sp.exp(x), x)
|
|
73
|
+
# Monotonicity.STRICTLY_INCREASING
|
|
74
|
+
|
|
75
|
+
function_convexity(x**2, x)
|
|
76
|
+
# Convexity.STRONGLY_CONVEX
|
|
77
|
+
|
|
78
|
+
function_periodicity(sp.sin(2 * x) + sp.cos(3 * x), x, details=True).period
|
|
79
|
+
# 2*pi
|
|
80
|
+
|
|
81
|
+
function_symmetry((x - 2) ** 2, x, center=None, details=True).center
|
|
82
|
+
# 2
|
|
83
|
+
|
|
84
|
+
function_homogeneity(x**2 + y**4, (x, y), weights=(2, 1), details=True).degree
|
|
85
|
+
# 4
|
|
86
|
+
|
|
87
|
+
function_branchcuts(sp.log(1 - z), z)
|
|
88
|
+
# structural pullback of the principal logarithm cut
|
|
89
|
+
|
|
90
|
+
function_poles(sp.sin(z) / z**3, z)[0].multiplicity
|
|
91
|
+
# 2
|
|
92
|
+
|
|
93
|
+
function_analytic(sp.log(z), z, domain=sp.S.Complexes)
|
|
94
|
+
# Analyticity.ANALYTIC on the principal branch's natural domain
|
|
95
|
+
|
|
96
|
+
function_meromorphic(sp.log(z), z)
|
|
97
|
+
# Meromorphicity.NOT_MEROMORPHIC
|
|
98
|
+
|
|
99
|
+
function_continuous(sp.Abs(x), x)
|
|
100
|
+
# Continuity.CONTINUOUS
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Property model
|
|
104
|
+
|
|
105
|
+
API functions return exact classifications when the available proof machinery is sufficient. `PropertyResult` and `ConditionalValue` are the common representation for parameter strata across real and complex properties, so unresolved guards are preserved instead of being collapsed into a single answer. `PropertyResult.as_piecewise()` provides a Piecewise-style view when useful.
|
|
106
|
+
|
|
107
|
+
Three-valued reasoning is used throughout proof-oriented code. An undecidable set relation, domain implication, branch-locus intersection, or symbolic comparison is not treated as false merely because Python cannot decide it.
|
|
108
|
+
|
|
109
|
+
## Real-domain analysis
|
|
110
|
+
|
|
111
|
+
`funcprops` owns the property vocabulary. For semialgebraic functions on semialgebraic real domains `funcprops` delegates exact domain, range, sign, monotonicity, convexity, smoothness, and mapping-property problems to `semialg`, while retaining stronger exact `funcprops` results when they are already certified. A shared sign engine is the main inequality proof primitive: derivative signs feed monotonicity and convexity, while relation queries reduce comparisons to the sign of a difference. Transcendental expressions are handled compositionally using primitive facts, exact domain restrictions, periodic reductions, derivative geometry, and certified interval reasoning.
|
|
112
|
+
|
|
113
|
+
Mixed variable/parameter domains are split once by the shared stratification layer and each variable-domain branch is analyzed independently. Finite `Piecewise` expressions likewise use one effective-branch representation. Consumers add only the interface conditions their property requires: monotonicity checks jump direction, convexity checks continuity and derivative ordering, and sign and boundedness combine exact branch classifications.
|
|
114
|
+
|
|
115
|
+
The main real-analysis APIs include:
|
|
116
|
+
|
|
117
|
+
- `function_domain()` and `function_range()`;
|
|
118
|
+
- `function_sign()`;
|
|
119
|
+
- `function_boundedness()`;
|
|
120
|
+
- `function_monotonicity()`;
|
|
121
|
+
- `function_oscillation()`;
|
|
122
|
+
- `function_convexity()` with normalized `ConvexityCertificate` evidence;
|
|
123
|
+
- `function_injective()`, `function_surjective()`, and `function_bijective()`;
|
|
124
|
+
- `function_continuous()`, `function_differentiability()`, `function_smoothness()`, and `function_analytic()`;
|
|
125
|
+
- `function_periodicity()`, `function_symmetry()`, and `function_homogeneity()`.
|
|
126
|
+
|
|
127
|
+
Multivariate APIs normalize variable collections explicitly rather than treating a tuple as one symbolic atom. Constant-Hessian convexity and affine mapping cases are handled exactly; unsupported nonlinear multivariate mapping questions give unknown.
|
|
128
|
+
|
|
129
|
+
## Monotonic partitions and exact inverse solving
|
|
130
|
+
|
|
131
|
+
`MonotonicPartition` is the shared exact interval representation used by monotonicity, range, injectivity, inverse solving, oscillation, and extrema. Finite partitions retain exact critical points, endpoint limits, and endpoint attainment. Infinite oscillatory partitions retain indexed zero geometry without guessing an unsupported increasing/decreasing phase.
|
|
132
|
+
|
|
133
|
+
`solve_monotonic_inverse()` first attempts a whole-domain exact solve. If that is insufficient, it uses monotonic cells and exact image pruning. On a strict finite cell, an unresolved symbolic inverse can still be completed by certified endpoint signs and a rational isolating interval. `certified_monotonic_inverse()` is the explicit certification-oriented spelling of the same reusable primitive. The same partition can be passed explicitly to consumers or reused through the bounded proof cache.
|
|
134
|
+
|
|
135
|
+
## Certified real-root backends
|
|
136
|
+
|
|
137
|
+
Real root isolation is domain-cell aware: denominator zeros, logarithm boundaries, noninteger-power branch boundaries, Piecewise switch points, and other exact domain boundaries split the problem before any interval certificate is constructed. Identically-zero interval cells are retained as ordinary parts of the mathematical zero set.
|
|
138
|
+
|
|
139
|
+
For finite elementary cells, an outward-rounded interval evaluator can prove that zero is excluded from the function image, or from the derivative image. The latter certifies strict monotonicity even when symbolic monotonicity is unresolved. Point signs use `robust_real_sign()`, which combines exact SymPy sign reasoning with an audited exp/log interval fallback to avoid overflow and underflow.
|
|
140
|
+
|
|
141
|
+
`exponential_fourier_count()` provides a restricted derivative-sequence root counter for real exponential polynomials. After multiplication by a positive exponential factor, each derivative step removes the lowest exponential term. When every derivative root and endpoint/critical sign is exact, recursive Rolle/monotonicity reasoning certifies the number of distinct roots on the requested interval.
|
|
142
|
+
|
|
143
|
+
## Certified complex root isolation
|
|
144
|
+
|
|
145
|
+
`function_complex_zeros` isolates zeros in finite complex rectangles. It uses exact complex solving when available and otherwise a validated argument-principle contour: structural holomorphy certification, adaptive complex-interval boundary enclosures that exclude zero, winding-number counting, and count-preserving rational rectangle subdivision. Uncertified numerical winding estimates remain diagnostic only.
|
|
146
|
+
|
|
147
|
+
## Zero geometry and oscillatory extrema
|
|
148
|
+
|
|
149
|
+
Special-function zeros are represented symbolically when closed forms are not available. `IndexedZero`, `ZeroOrdering`, `ZeroInterlacing`, and `ZeroGeometryCertificate` describe exact support, simplicity, ordering, interlacing, and completeness information.
|
|
150
|
+
|
|
151
|
+
Derivative-zero geometry feeds interval decomposition. A finite exact root set produces concrete cells; a complete infinite family can produce an indexed alternating-cell structure. This allows exact reasoning about Airy, Bessel, and classical orthogonal-polynomial behavior without truncating an infinite zero sequence numerically.
|
|
152
|
+
|
|
153
|
+
`IndexedExtremumValue` and `ExtremumEnvelope` represent exact critical values and infinite extremum families. `symbolic_extremum_range()` combines them with exact endpoint values or limits. For supported Airy and Bessel families, analytic ordering theorems reduce infinite extremum envelopes to finite exact candidates.
|
|
154
|
+
|
|
155
|
+
`IndexedTailIndex` and indexed-tail inversion represent the least zero/extremum index entering a semi-infinite domain. Same-family cutoffs and certified interlacing can reduce the symbolic selector to an ordinary integer; otherwise it remains exact as a symbolic set-theoretic minimum.
|
|
156
|
+
|
|
157
|
+
## Periodicity, symmetry, and homogeneity
|
|
158
|
+
|
|
159
|
+
Periodicity propagates exact common periods through commensurate sums, products, and compositions. Parameter-dependent affine frequencies retain their nonzero frequency condition, and a returned period is not called fundamental unless minimality is established.
|
|
160
|
+
|
|
161
|
+
Symmetry supports a specified reflection center as well as exact center discovery for supported polynomial and affine-trigonometric forms. Detail results can retain families of equivalent even/odd centers and central point symmetry.
|
|
162
|
+
|
|
163
|
+
Homogeneity supports ordinary and weighted multivariate scaling. Polynomial analysis preserves exact parameter strata when coefficients determine which weighted-degree blocks survive, including the identically zero case.
|
|
164
|
+
|
|
165
|
+
## Singularities and branch cuts
|
|
166
|
+
|
|
167
|
+
`function_singularity_analysis()` performs condition-aware structural traversal of poles, removable singularities, essential singularities, branch points, branch cuts, definition cuts, and discontinuities. Piecewise guards and parameter guards are retained. Unknown primitive heads are recorded instead of silently treated as regular.
|
|
168
|
+
|
|
169
|
+
`function_branchcuts()` provides inexpensive structural pullback of principal cuts. Boundary-value and jump computations are available under `funcprops.branchcuts`.
|
|
170
|
+
|
|
171
|
+
Real analyticity and complex holomorphy are kept distinct from meromorphicity. For example, the principal logarithm is locally holomorphic on its natural complex domain but is not meromorphic on the complex plane because of its branch structure.
|
|
172
|
+
|
|
173
|
+
## Special-function property registry
|
|
174
|
+
|
|
175
|
+
The conditional registry contains SymPy/mpmath family metadata from an audited property catalogue. Catalogue values and guards are stored in deterministic SymPy constructor syntax, so rule loading does not depend on a second expression grammar. Concrete SymPy overloads are matched before guards are instantiated, and more-specific rules take precedence over generic ones. Literal pattern failures do not count as matches.
|
|
176
|
+
|
|
177
|
+
Selected special-function facts are cross-checked against the NIST Digital Library of Mathematical Functions (DLMF). The audit distinguishes direct formula-backed facts from derived wrapper/helper facts and from merely related DLMF material. The machine-readable manifest is `src/funcprops/data/dlmf_audit.json`.
|
|
178
|
+
|
|
179
|
+
## Proof cache and certificate replay
|
|
180
|
+
|
|
181
|
+
Reusable proof primitives are coordinated through a lazy `PropertyProofContext`. Constructing a context does no mathematical work. Independent bounded LRU caches hold raw and factored derivatives, natural domains, sign results, endpoint limits, zero geometry, singularity analyses, and monotonic partitions.
|
|
182
|
+
|
|
183
|
+
Cache-key normalization is intentionally inexpensive and syntactic; it does not run quantifier elimination or expensive logical simplification simply to form a key. Raw and factored derivatives use separate cache slots so callers that need only a derivative do not pay for factorization.
|
|
184
|
+
|
|
185
|
+
Certificates can be replayed with `verify_certificate()` and specialized verifiers. Convexity uses one `ConvexityCertificate` shape for ordinary, strict, and strong classifications; strong certificates additionally carry the certified modulus. Replay is conservative: an undecidable comparison never counts as a successful verification.
|
|
186
|
+
|
|
187
|
+
## Documentation
|
|
188
|
+
|
|
189
|
+
- [Function property reference](https://github.com/BhuvaneshBhatt/funcprops/blob/main/docs/properties/index.md) — comprehensive definitions, API contracts, examples, applications, proof strategies, and limitations for every public `function_*` query.
|
|
190
|
+
- [Function properties tutorial notebook](https://github.com/BhuvaneshBhatt/funcprops/blob/main/docs/notebooks/function-properties-tour.ipynb) — an executable tour built from the same tested examples as the reference documentation.
|
|
191
|
+
- [Architecture](https://github.com/BhuvaneshBhatt/funcprops/blob/main/docs/architecture.md)
|
|
192
|
+
- [DLMF audit methodology](https://github.com/BhuvaneshBhatt/funcprops/blob/main/docs/dlmf_audit.md)
|
|
193
|
+
- [Source repository](https://github.com/BhuvaneshBhatt/funcprops)
|
|
194
|
+
|
|
195
|
+
## Development
|
|
196
|
+
|
|
197
|
+
Run the test suite against the source tree with:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
PYTHONPATH=src pytest
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The package intentionally keeps exact fast paths ahead of heavier partition, root-isolation, or semialgebraic machinery. Refactors should preserve that order unless a benchmark and correctness argument justify changing it.
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
funcprops is licensed under the GNU General Public License version 3 only
|
|
208
|
+
(`GPL-3.0-only`). See [LICENSE](https://github.com/BhuvaneshBhatt/funcprops/blob/main/LICENSE).
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
funcprops/__init__.py,sha256=gzGoGBBiTD-uo_-GfL9X_trGYAOGCxCw9hHEySHraek,6832
|
|
2
|
+
funcprops/_semialg.py,sha256=04IlXW1SLas-qqRNpU7OSd-s3i8nOqyzefJW65F8Q0g,8169
|
|
3
|
+
funcprops/api.py,sha256=oD4W_-kiuZzVt6kdNUuHG9m0SWMlfxQSXsQ4cRwbp2c,2205
|
|
4
|
+
funcprops/conditions.py,sha256=d0ni0VVlksAfzle_wFdYK5eDRcWWJGZGvH-niUjo9H0,2377
|
|
5
|
+
funcprops/dlmf.py,sha256=NAwz49M80Zi7hP2w3Z_rzyJU4wkmpPU7Z9DhLuLVn9A,778
|
|
6
|
+
funcprops/engine.py,sha256=Z0uJ7J8Qdf-cfUwqDlF9LTNGDkArqq1r6QrNJqXOVk0,10468
|
|
7
|
+
funcprops/exceptions.py,sha256=ZejGRT6XaGtH6Ix1jeG8QeEG6unkNbrO0pVrb83elSs,1220
|
|
8
|
+
funcprops/proof_cache.py,sha256=ZSjiKRvexNcgzq0e15mkBs7XsGjsUcnn7aFSh_rm2iI,11912
|
|
9
|
+
funcprops/registry.py,sha256=1EuQ3vn36vFbRHqXIW6BXfvcpRmkJqcQxR6gb_Sg3Mc,8504
|
|
10
|
+
funcprops/results.py,sha256=h22ulm7AQwACPI8UsTaJTOwAFCcTMNf_2QS44Z4aQJo,6486
|
|
11
|
+
funcprops/singularities.py,sha256=bu_TOlvB__gJ1OqnTSLaSDUtanpTCs-oUNZ63fPM_4Y,62140
|
|
12
|
+
funcprops/stratification.py,sha256=DdqOEXf4cJabneX5UwdxLrhuglYlrezD9KbafZ9SXRI,17448
|
|
13
|
+
funcprops/sympy_compare.py,sha256=j2zRRJPQLwmfgyUBWHECqPe0BIGbTKxCTImjpaC-rpM,1879
|
|
14
|
+
funcprops/verification.py,sha256=obC7qJPaVBHwiXDwDKuUtQvcsdBmnvHD1PiEu55-7jM,14278
|
|
15
|
+
funcprops/branchcuts/__init__.py,sha256=xsZ-PXkvLe5MuiaCln3LaVp6x81dZ3PrFwzNwyoQufM,4171
|
|
16
|
+
funcprops/branchcuts/computation.py,sha256=rxJRC198IMhdjLMmurcU4RjoHWPs2Hppf3ShiXsHkXU,21800
|
|
17
|
+
funcprops/branchcuts/core.py,sha256=ZEBdt_xyuZlHA6syzaSz6NxxH9LZ_Vd1eRSgDeIAiAs,33469
|
|
18
|
+
funcprops/branchcuts/post_simplify.py,sha256=_dGDGasbrm3OjFnFZaYXtLPeBV5gR-NnlZqFv5JKoBo,14633
|
|
19
|
+
funcprops/data/catalogue.json,sha256=Ycj8Gu5lX8tU4lySrNPxVJd4iF9scANpectCh2qE3PI,5269115
|
|
20
|
+
funcprops/data/dlmf_audit.json,sha256=HlK_-uIcJgwtFmmyflFW_LaYsauXt64WEjYTTc1rdU0,92775
|
|
21
|
+
funcprops/real_analysis/__init__.py,sha256=zi8cTlFhDs9qxHA5-EdGx_Vr4qXrHoJdr9Sxcrc1ryo,1595
|
|
22
|
+
funcprops/real_analysis/advanced_convexity.py,sha256=fCQNcoiYx39UUbwSM-LzRLVYheGxoEhi33YDbzgATgs,8320
|
|
23
|
+
funcprops/real_analysis/boundedness.py,sha256=MmFnkzVfKzHPxRrDItJfJj-Q44kIWryJuvWlNuXliVU,6561
|
|
24
|
+
funcprops/real_analysis/common.py,sha256=8e01kciN91APhn1HAumh-i_M1p_xuF-SGja0Fyv-iEE,9288
|
|
25
|
+
funcprops/real_analysis/convexity.py,sha256=Q5witapGOuv2HisK3rC0JDyY7wJyNDMQvi9qn3ndgE4,24439
|
|
26
|
+
funcprops/real_analysis/differentiability.py,sha256=2ba3b5hGxZbcV0AB2HreoNs7VGJbFc1lrzTG2poHdaU,4268
|
|
27
|
+
funcprops/real_analysis/domain.py,sha256=HZyAUV9l5tlIMew5OAAVAxsDs1jtGe_ox66D-7RNM_A,7593
|
|
28
|
+
funcprops/real_analysis/mapping.py,sha256=YHBrM5fXQaFbRdIbAwLaVZV4lPXqf-yXAra0dlpThRw,13841
|
|
29
|
+
funcprops/real_analysis/monotonic_certificates.py,sha256=nsF-QhTSINg8TGCtLHwmJFIES_WMATPFidAjMyKYFnM,29458
|
|
30
|
+
funcprops/real_analysis/monotonicity.py,sha256=r_nlgYcgPQ1-G6MtvR4IWLaVXvHrzByiCGiVxXJsvhs,25145
|
|
31
|
+
funcprops/real_analysis/oscillation.py,sha256=qXayFA7-iPW6iUqd179LXz1nFM5HEh_cO9kodcL0iGw,5133
|
|
32
|
+
funcprops/real_analysis/piecewise.py,sha256=DJSqxt71M437-Skv4P2mrrB4jXuXiEZQZ43_66lUQt4,6413
|
|
33
|
+
funcprops/real_analysis/range.py,sha256=QdVRVryF590_c0TLJG7e0mPbV7tm0kz4YIOsqrY6fD4,20158
|
|
34
|
+
funcprops/real_analysis/sign.py,sha256=trRj15zD85s5FS6qL65M3AGBs9TpzQIsvT05m4jxURs,19146
|
|
35
|
+
funcprops/real_analysis/smoothness.py,sha256=1dDf7UOWJmMRuIIc-dHmNzQ5ohFZg5FLpEABv_0BRS4,9118
|
|
36
|
+
funcprops/real_analysis/special_functions.py,sha256=yAmQFoqQ0Zt1JStuvzKKXr_tjIAvF47CZ6oAKvRKVBg,16644
|
|
37
|
+
funcprops/real_analysis/structural_properties.py,sha256=GyxqxH2hqidjJIRvMuML__0NUB2ftCwUiNFJ28lDQ1I,20110
|
|
38
|
+
funcprops/real_analysis/zeros.py,sha256=dUUAln-YW72kYM9cqsPkSmMRL2QmYI6ueAKeFK1Nflc,11057
|
|
39
|
+
funcprops/transcendental/__init__.py,sha256=TiNrrKrpZBwlmVty2paqsAS7LzW41qYThTLesMyNfyM,3648
|
|
40
|
+
funcprops/transcendental/algebraize.py,sha256=VmKAWKKS4vYbv6qV1vE5bdqGW3qhg2947hADGmAJGns,6032
|
|
41
|
+
funcprops/transcendental/analytic.py,sha256=DZ22HGn-aZ3VCy50yARmOmOF8lzIhGf-9ACuers7_xI,7973
|
|
42
|
+
funcprops/transcendental/complex_roots.py,sha256=Ks3dWVmr84-fTzFziiZaO9y9OKz6nv3xzDfbCS0hz9o,15974
|
|
43
|
+
funcprops/transcendental/exp_fourier.py,sha256=C_U5s18U89PmwJU1pFQWNr_IF80ZkLQHVuKEVco2ywI,6977
|
|
44
|
+
funcprops/transcendental/extrema.py,sha256=fg1z3G6zRkA2Wsnp-aFNXulff5vC9ajJmn5SPX2XF7I,29285
|
|
45
|
+
funcprops/transcendental/periodic.py,sha256=E83TmL_hR_YfgvH5ovji66ZpTxqvHMsYXBEEcZ75InQ,7276
|
|
46
|
+
funcprops/transcendental/proof.py,sha256=UbAcJgdK17VxTElCHzKlAMwKduoC25TGxxosRvGLG0g,3050
|
|
47
|
+
funcprops/transcendental/real_interval.py,sha256=dV8m4q1O0pnNgAJKke1erd4l3b9NUIpc9meLzsvuD5g,3765
|
|
48
|
+
funcprops/transcendental/real_sign.py,sha256=gS-WLexzlw2txLJktgqUg0A3jptKWCeFWrTK-5g6ViY,3702
|
|
49
|
+
funcprops/transcendental/reduce.py,sha256=AmC1fEZRVE015xT2x2trrIIMX3ljXhdGMQhQm577lcU,9593
|
|
50
|
+
funcprops/transcendental/roots.py,sha256=HXVT_OOWdGdD5nkrDIkoOB5jUQ7gZeGEZTJTvUvzfiE,48303
|
|
51
|
+
funcprops/transcendental/zero_geometry.py,sha256=oCKOor-UEYnWb_LhMeIkI9vJ5UF5fpsdo-TG0iq6Gs4,38801
|
|
52
|
+
funcprops-0.1.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
53
|
+
funcprops-0.1.0.dist-info/METADATA,sha256=YfrjmYtndK-6rDh9nnqcuML8D1K27pFcUnMimcUAzKA,14263
|
|
54
|
+
funcprops-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
55
|
+
funcprops-0.1.0.dist-info/top_level.txt,sha256=jk186mdxNzdJCigjKQx_lwqvKSd2CrSWAQZWWlWrDsw,10
|
|
56
|
+
funcprops-0.1.0.dist-info/RECORD,,
|