mapFolding 0.8.5__py3-none-any.whl → 0.9.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.
- mapFolding/__init__.py +66 -18
- mapFolding/basecamp.py +32 -17
- mapFolding/beDRY.py +3 -3
- mapFolding/oeis.py +121 -25
- mapFolding/someAssemblyRequired/__init__.py +48 -27
- mapFolding/someAssemblyRequired/_theTypes.py +11 -15
- mapFolding/someAssemblyRequired/_tool_Make.py +40 -12
- mapFolding/someAssemblyRequired/_tool_Then.py +59 -25
- mapFolding/someAssemblyRequired/_toolboxAntecedents.py +151 -276
- mapFolding/someAssemblyRequired/_toolboxContainers.py +185 -51
- mapFolding/someAssemblyRequired/_toolboxPython.py +165 -44
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +141 -20
- mapFolding/someAssemblyRequired/toolboxNumba.py +93 -52
- mapFolding/someAssemblyRequired/transformationTools.py +228 -138
- mapFolding/syntheticModules/numbaCount_doTheNeedful.py +0 -1
- mapFolding/theSSOT.py +147 -55
- mapFolding/toolboxFilesystem.py +1 -1
- mapfolding-0.9.0.dist-info/METADATA +177 -0
- mapfolding-0.9.0.dist-info/RECORD +46 -0
- tests/__init__.py +44 -0
- tests/conftest.py +75 -7
- tests/test_computations.py +90 -9
- tests/test_filesystem.py +32 -33
- tests/test_other.py +0 -1
- tests/test_tasks.py +2 -2
- mapFolding/noHomeYet.py +0 -32
- mapFolding/someAssemblyRequired/newInliner.py +0 -22
- mapfolding-0.8.5.dist-info/METADATA +0 -190
- mapfolding-0.8.5.dist-info/RECORD +0 -48
- {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/WHEEL +0 -0
- {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.8.5.dist-info → mapfolding-0.9.0.dist-info}/top_level.txt +0 -0
mapFolding/__init__.py
CHANGED
|
@@ -1,45 +1,93 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Map folding enumeration and counting algorithms with optimization capabilities.
|
|
2
|
+
Map folding enumeration and counting algorithms with advanced optimization capabilities.
|
|
3
3
|
|
|
4
|
-
This package implements algorithms to count and enumerate the
|
|
4
|
+
This package implements algorithms to count and enumerate the distinct ways
|
|
5
5
|
a rectangular map can be folded, based on the mathematical problem described
|
|
6
6
|
in Lunnon's 1971 paper. It provides multiple layers of functionality, from
|
|
7
|
-
high-level user interfaces to
|
|
7
|
+
high-level user interfaces to sophisticated algorithmic optimizations and code
|
|
8
8
|
transformation tools.
|
|
9
9
|
|
|
10
10
|
Core modules:
|
|
11
11
|
- basecamp: Public API with simplified interfaces for end users
|
|
12
12
|
- theDao: Core computational algorithm using a functional state-transformation approach
|
|
13
13
|
- beDRY: Core utility functions implementing consistent data handling, validation, and
|
|
14
|
-
|
|
14
|
+
resource management across the package's computational assembly-line
|
|
15
15
|
- theSSOT: Single Source of Truth for configuration, types, and state management
|
|
16
16
|
- toolboxFilesystem: Cross-platform file management services for storing and retrieving
|
|
17
|
-
|
|
17
|
+
computation results with robust error handling and fallback mechanisms
|
|
18
18
|
- oeis: Interface to the Online Encyclopedia of Integer Sequences for known results
|
|
19
19
|
|
|
20
20
|
Extended functionality:
|
|
21
21
|
- someAssemblyRequired: Code transformation framework that optimizes the core algorithm
|
|
22
|
-
|
|
22
|
+
through AST manipulation, dataclass transformation, and compilation techniques
|
|
23
|
+
- The system converts readable code into high-performance implementations through
|
|
24
|
+
a systematic analysis and transformation pipeline
|
|
25
|
+
- Provides tools to "shatter" complex dataclasses into primitive components,
|
|
26
|
+
enabling compatibility with Numba and other optimization frameworks
|
|
27
|
+
- Creates specialized implementations tailored for specific input parameters
|
|
28
|
+
|
|
29
|
+
Testing and extension:
|
|
30
|
+
- tests: Comprehensive test suite designed for both verification and extension
|
|
31
|
+
- Provides fixtures and utilities that simplify testing of custom implementations
|
|
32
|
+
- Enables users to validate their own recipes and job configurations with minimal code
|
|
33
|
+
- Offers standardized testing patterns that maintain consistency across the codebase
|
|
34
|
+
- See tests/__init__.py for detailed documentation on extending the test suite
|
|
23
35
|
|
|
24
36
|
Special directories:
|
|
25
37
|
- .cache/: Stores cached data from external sources like OEIS to improve performance
|
|
26
38
|
- syntheticModules/: Contains dynamically generated, optimized implementations of the
|
|
27
|
-
|
|
39
|
+
core algorithm created by the code transformation framework
|
|
28
40
|
- reference/: Historical implementations and educational resources for algorithm exploration
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
- reference/jobsCompleted/: Contains successful computations for previously unknown values,
|
|
42
|
+
including first-ever calculations for 2x19 and 2x20 maps (OEIS A001415)
|
|
31
43
|
|
|
32
|
-
This package
|
|
44
|
+
This package balances algorithm readability and understandability with
|
|
33
45
|
high-performance computation capabilities, allowing users to compute map folding
|
|
34
|
-
totals for larger dimensions than previously feasible
|
|
46
|
+
totals for larger dimensions than previously feasible while also providing
|
|
47
|
+
a foundation for exploring advanced code transformation techniques.
|
|
35
48
|
"""
|
|
36
|
-
from mapFolding.basecamp import countFolds
|
|
37
|
-
from mapFolding.oeis import clearOEIScache, getOEISids, OEIS_for_n, oeisIDfor_n
|
|
38
49
|
|
|
39
50
|
__all__ = [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
'clearOEIScache',
|
|
52
|
+
'countFolds',
|
|
53
|
+
'getOEISids',
|
|
54
|
+
'OEIS_for_n',
|
|
55
|
+
'oeisIDfor_n',
|
|
45
56
|
]
|
|
57
|
+
|
|
58
|
+
from mapFolding.theSSOT import (
|
|
59
|
+
Array1DElephino,
|
|
60
|
+
Array1DFoldsTotal,
|
|
61
|
+
Array1DLeavesTotal,
|
|
62
|
+
Array3D,
|
|
63
|
+
ComputationState,
|
|
64
|
+
DatatypeElephino,
|
|
65
|
+
DatatypeFoldsTotal,
|
|
66
|
+
DatatypeLeavesTotal,
|
|
67
|
+
NumPyElephino,
|
|
68
|
+
NumPyFoldsTotal,
|
|
69
|
+
NumPyIntegerType,
|
|
70
|
+
NumPyLeavesTotal,
|
|
71
|
+
raiseIfNoneGitHubIssueNumber3,
|
|
72
|
+
The,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
from mapFolding.theDao import countInitialize, doTheNeedful
|
|
76
|
+
|
|
77
|
+
from mapFolding.beDRY import (
|
|
78
|
+
outfitCountFolds,
|
|
79
|
+
setProcessorLimit,
|
|
80
|
+
validateListDimensions,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
from mapFolding.toolboxFilesystem import (
|
|
84
|
+
getPathFilenameFoldsTotal,
|
|
85
|
+
getPathRootJobDEFAULT,
|
|
86
|
+
saveFoldsTotal,
|
|
87
|
+
saveFoldsTotalFAILearly,
|
|
88
|
+
writeStringToHere,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
from mapFolding.basecamp import countFolds
|
|
92
|
+
|
|
93
|
+
from mapFolding.oeis import clearOEIScache, getFoldsTotalKnown, getOEISids, OEIS_for_n, oeisIDfor_n
|
mapFolding/basecamp.py
CHANGED
|
@@ -13,9 +13,16 @@ implementation, and optional persistence of results.
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
from collections.abc import Sequence
|
|
16
|
-
from mapFolding
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
from mapFolding import (
|
|
17
|
+
ComputationState,
|
|
18
|
+
getPathFilenameFoldsTotal,
|
|
19
|
+
outfitCountFolds,
|
|
20
|
+
saveFoldsTotal,
|
|
21
|
+
saveFoldsTotalFAILearly,
|
|
22
|
+
setProcessorLimit,
|
|
23
|
+
The,
|
|
24
|
+
validateListDimensions,
|
|
25
|
+
)
|
|
19
26
|
from os import PathLike
|
|
20
27
|
from pathlib import PurePath
|
|
21
28
|
|
|
@@ -24,18 +31,27 @@ def countFolds(listDimensions: Sequence[int]
|
|
|
24
31
|
, computationDivisions: int | str | None = None
|
|
25
32
|
, CPUlimit: int | float | bool | None = None
|
|
26
33
|
) -> int:
|
|
27
|
-
"""
|
|
34
|
+
"""
|
|
35
|
+
Count the total number of possible foldings for a given map dimensions.
|
|
36
|
+
|
|
37
|
+
This function serves as the main public interface to the map folding algorithm,
|
|
38
|
+
handling all parameter validation, computation state management, and result
|
|
39
|
+
persistence in a user-friendly way.
|
|
28
40
|
|
|
29
|
-
Parameters
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
listDimensions: List of integers representing the dimensions of the map to be folded.
|
|
44
|
+
pathLikeWriteFoldsTotal (None): Path, filename, or pathFilename to write the total fold count to.
|
|
45
|
+
If a directory is provided, creates a file with a default name based on map dimensions.
|
|
46
|
+
computationDivisions (None):
|
|
47
|
+
Whether and how to divide the computational work. See notes for details.
|
|
48
|
+
CPUlimit (None): This is only relevant if there are `computationDivisions`: whether and how to limit the CPU usage. See notes for details.
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
foldsTotal: Total number of distinct ways to fold a map of the given dimensions.
|
|
38
52
|
|
|
53
|
+
Notes
|
|
54
|
+
-----
|
|
39
55
|
Computation divisions:
|
|
40
56
|
- None: no division of the computation into tasks; sets task divisions to 0
|
|
41
57
|
- int: direct set the number of task divisions; cannot exceed the map's total leaves
|
|
@@ -51,7 +67,8 @@ def countFolds(listDimensions: Sequence[int]
|
|
|
51
67
|
- Integer `<= -1`: Subtract the absolute value from total CPUs.
|
|
52
68
|
|
|
53
69
|
N.B.: You probably don't want to divide the computation into tasks.
|
|
54
|
-
|
|
70
|
+
|
|
71
|
+
If you want to compute a large `foldsTotal`, dividing the computation into tasks is usually a bad idea. Dividing the algorithm into tasks is inherently inefficient: efficient division into tasks means there would be no overlap in the work performed by each task. When dividing this algorithm, the amount of overlap is between 50% and 90% by all tasks: at least 50% of the work done by every task must be done by _all_ tasks. If you improve the computation time, it will only change by -10 to -50% depending on (at the very least) the ratio of the map dimensions and the number of leaves. If an undivided computation would take 10 hours on your computer, for example, the computation will still take at least 5 hours but you might reduce the time to 9 hours. Most of the time, however, you will increase the computation time. If logicalCores >= leavesTotal, it will probably be faster. If logicalCores <= 2 * leavesTotal, it will almost certainly be slower for all map dimensions.
|
|
55
72
|
"""
|
|
56
73
|
mapShape: tuple[int, ...] = validateListDimensions(listDimensions)
|
|
57
74
|
concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
|
|
@@ -63,9 +80,7 @@ def countFolds(listDimensions: Sequence[int]
|
|
|
63
80
|
else:
|
|
64
81
|
pathFilenameFoldsTotal = None
|
|
65
82
|
|
|
66
|
-
|
|
67
|
-
computationStateComplete: ComputationState = dispatcherCallableProxy(computationStateInitialized)
|
|
68
|
-
# computationStateComplete: ComputationState = The.dispatcher(computationStateInitialized)
|
|
83
|
+
computationStateComplete: ComputationState = The.dispatcher(computationStateInitialized)
|
|
69
84
|
|
|
70
85
|
computationStateComplete.getFoldsTotal()
|
|
71
86
|
|
mapFolding/beDRY.py
CHANGED
|
@@ -19,7 +19,7 @@ These utilities form a stable internal API that other modules depend on, particu
|
|
|
19
19
|
produce optimized implementations.
|
|
20
20
|
"""
|
|
21
21
|
from collections.abc import Sequence
|
|
22
|
-
from mapFolding
|
|
22
|
+
from mapFolding import ComputationState, NumPyIntegerType
|
|
23
23
|
from numpy import dtype as numpy_dtype, int64 as numpy_int64, ndarray
|
|
24
24
|
from sys import maxsize as sysMaxsize
|
|
25
25
|
from typing import Any
|
|
@@ -165,7 +165,7 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
|
|
|
165
165
|
connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex + cumulativeProduct[indexDimension]
|
|
166
166
|
return connectionGraph
|
|
167
167
|
|
|
168
|
-
def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[
|
|
168
|
+
def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[NumPyIntegerType]) -> ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]:
|
|
169
169
|
"""
|
|
170
170
|
Create a properly typed connection graph for the map folding algorithm.
|
|
171
171
|
|
|
@@ -193,7 +193,7 @@ def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: ty
|
|
|
193
193
|
connectionGraph = connectionGraph.astype(datatype)
|
|
194
194
|
return connectionGraph
|
|
195
195
|
|
|
196
|
-
def makeDataContainer(shape: int | tuple[int, ...], datatype: type[
|
|
196
|
+
def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerType]) -> ndarray[Any, numpy_dtype[NumPyIntegerType]]:
|
|
197
197
|
"""
|
|
198
198
|
Create a typed NumPy array container with initialized values.
|
|
199
199
|
|
mapFolding/oeis.py
CHANGED
|
@@ -2,26 +2,30 @@
|
|
|
2
2
|
Interface to The Online Encyclopedia of Integer Sequences (OEIS) for map folding sequences.
|
|
3
3
|
|
|
4
4
|
This module provides a comprehensive interface for accessing and utilizing integer sequences
|
|
5
|
-
from the OEIS that relate to map folding problems. It
|
|
5
|
+
from the OEIS that relate to map folding problems. It serves as the bridge between
|
|
6
|
+
mathematical sequence definitions and the computational algorithm, implementing:
|
|
6
7
|
|
|
7
|
-
1.
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
8
|
+
1. Retrieval of sequence data from OEIS with local caching for performance optimization.
|
|
9
|
+
2. Mapping of sequence indices to corresponding map shapes based on sequence definitions.
|
|
10
|
+
3. Command-line and programmatic interfaces for sequence lookups and validation.
|
|
11
|
+
4. Computation of sequence terms not available in the OEIS database.
|
|
11
12
|
|
|
12
13
|
The module maintains a registry of implemented OEIS sequences (A001415-A001418, A195646)
|
|
13
|
-
with their metadata, known values, and functions
|
|
14
|
+
with their metadata, known values, and conversion functions between sequence indices and
|
|
14
15
|
map dimensions. This allows the package to validate results against established mathematical
|
|
15
|
-
literature
|
|
16
|
+
literature while also extending sequences beyond their currently known terms.
|
|
17
|
+
|
|
18
|
+
Each sequence is carefully mapped to its corresponding map folding problem, enabling
|
|
19
|
+
seamless integration between the mathematical definition in OEIS and the computational
|
|
20
|
+
implementation in the package.
|
|
16
21
|
"""
|
|
17
22
|
from collections.abc import Callable
|
|
18
23
|
from datetime import datetime, timedelta
|
|
19
|
-
from
|
|
20
|
-
from mapFolding
|
|
24
|
+
from functools import cache
|
|
25
|
+
from mapFolding import writeStringToHere, The
|
|
21
26
|
from pathlib import Path
|
|
22
27
|
from typing import Any, Final, TYPE_CHECKING
|
|
23
28
|
import argparse
|
|
24
|
-
import pathlib
|
|
25
29
|
import random
|
|
26
30
|
import sys
|
|
27
31
|
import time
|
|
@@ -36,9 +40,6 @@ else:
|
|
|
36
40
|
|
|
37
41
|
cacheDays = 30
|
|
38
42
|
|
|
39
|
-
"""
|
|
40
|
-
Section: make `settingsOEIS`"""
|
|
41
|
-
|
|
42
43
|
pathCache: Path = The.pathPackage / ".cache"
|
|
43
44
|
|
|
44
45
|
class SettingsOEIS(TypedDict):
|
|
@@ -159,7 +160,28 @@ def _parseBFileOEIS(OEISbFile: str, oeisID: str) -> dict[int, int]:
|
|
|
159
160
|
OEISsequence[n] = aOFn
|
|
160
161
|
return OEISsequence
|
|
161
162
|
|
|
162
|
-
def getOEISofficial(pathFilenameCache:
|
|
163
|
+
def getOEISofficial(pathFilenameCache: Path, url: str) -> None | str:
|
|
164
|
+
"""
|
|
165
|
+
Retrieve OEIS sequence data from cache or online source.
|
|
166
|
+
|
|
167
|
+
This function implements a caching strategy for OEIS sequence data, first checking
|
|
168
|
+
if a local cached copy exists and is not expired. If a valid cache exists, it returns
|
|
169
|
+
the cached content; otherwise, it fetches the data from the OEIS website and
|
|
170
|
+
writes it to the cache for future use.
|
|
171
|
+
|
|
172
|
+
Parameters:
|
|
173
|
+
pathFilenameCache: Path to the local cache file.
|
|
174
|
+
url: URL to retrieve the OEIS sequence data from if cache is invalid or missing.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
oeisInformation: The retrieved OEIS sequence information as a string, or None if
|
|
178
|
+
the information could not be retrieved.
|
|
179
|
+
|
|
180
|
+
Notes:
|
|
181
|
+
The cache expiration period is controlled by the global `cacheDays` variable.
|
|
182
|
+
If the function fails to retrieve data from both cache and online source,
|
|
183
|
+
it will return None and issue a warning.
|
|
184
|
+
"""
|
|
163
185
|
tryCache: bool = False
|
|
164
186
|
if pathFilenameCache.exists():
|
|
165
187
|
fileAge: timedelta = datetime.now() - datetime.fromtimestamp(pathFilenameCache.stat().st_mtime)
|
|
@@ -173,6 +195,7 @@ def getOEISofficial(pathFilenameCache: pathlib.Path, url: str) -> None | str:
|
|
|
173
195
|
tryCache = False
|
|
174
196
|
|
|
175
197
|
if not tryCache:
|
|
198
|
+
# Change http handling #13
|
|
176
199
|
httpResponse: urllib.response.addinfourl = urllib.request.urlopen(url)
|
|
177
200
|
oeisInformation = httpResponse.read().decode('utf-8')
|
|
178
201
|
writeStringToHere(oeisInformation, pathFilenameCache)
|
|
@@ -186,6 +209,7 @@ def getOEISidValues(oeisID: str) -> dict[int, int]:
|
|
|
186
209
|
"""
|
|
187
210
|
Retrieves the specified OEIS sequence as a dictionary mapping integer indices
|
|
188
211
|
to their corresponding values.
|
|
212
|
+
|
|
189
213
|
This function checks for a cached local copy of the sequence data, using it if
|
|
190
214
|
it has not expired. Otherwise, it fetches the sequence data from the OEIS
|
|
191
215
|
website and writes it to the cache. The parsed data is returned as a dictionary
|
|
@@ -195,7 +219,7 @@ def getOEISidValues(oeisID: str) -> dict[int, int]:
|
|
|
195
219
|
oeisID: The identifier of the OEIS sequence to retrieve.
|
|
196
220
|
Returns:
|
|
197
221
|
OEISsequence: A dictionary where each key is an integer index, `n`, and each
|
|
198
|
-
value is the corresponding
|
|
222
|
+
value is the corresponding `a(n)` from the OEIS entry.
|
|
199
223
|
Raises:
|
|
200
224
|
ValueError: If the cached or downloaded file format is invalid.
|
|
201
225
|
IOError: If there is an error reading from or writing to the local cache.
|
|
@@ -211,6 +235,27 @@ def getOEISidValues(oeisID: str) -> dict[int, int]:
|
|
|
211
235
|
return {-1: -1}
|
|
212
236
|
|
|
213
237
|
def getOEISidInformation(oeisID: str) -> tuple[str, int]:
|
|
238
|
+
"""
|
|
239
|
+
Retrieve the description and offset for an OEIS sequence.
|
|
240
|
+
|
|
241
|
+
This function fetches the metadata for a given OEIS sequence ID, including
|
|
242
|
+
its textual description and index offset value. It uses a caching mechanism
|
|
243
|
+
to avoid redundant network requests while ensuring data freshness.
|
|
244
|
+
|
|
245
|
+
Parameters:
|
|
246
|
+
oeisID: The OEIS sequence identifier to retrieve information for.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
A tuple containing:
|
|
250
|
+
- description: A string describing the sequence's mathematical meaning.
|
|
251
|
+
- offset: An integer representing the starting index of the sequence.
|
|
252
|
+
Usually 0 or 1, depending on the mathematical context.
|
|
253
|
+
|
|
254
|
+
Notes:
|
|
255
|
+
Sequence descriptions are parsed from the machine-readable format of OEIS.
|
|
256
|
+
If information cannot be retrieved, warning messages are issued and
|
|
257
|
+
fallback values are returned.
|
|
258
|
+
"""
|
|
214
259
|
oeisID = validateOEISid(oeisID)
|
|
215
260
|
pathFilenameCache: Path = pathCache / f"{oeisID}.txt"
|
|
216
261
|
url: str = f"https://oeis.org/search?q=id:{oeisID}&fmt=text"
|
|
@@ -240,6 +285,26 @@ def getOEISidInformation(oeisID: str) -> tuple[str, int]:
|
|
|
240
285
|
return description, offset
|
|
241
286
|
|
|
242
287
|
def makeSettingsOEIS() -> dict[str, SettingsOEIS]:
|
|
288
|
+
"""
|
|
289
|
+
Construct the comprehensive settings dictionary for all implemented OEIS sequences.
|
|
290
|
+
|
|
291
|
+
This function builds a complete configuration dictionary for all supported OEIS
|
|
292
|
+
sequences by retrieving and combining:
|
|
293
|
+
1. Sequence values from OEIS b-files
|
|
294
|
+
2. Sequence metadata (descriptions and offsets)
|
|
295
|
+
3. Hardcoded mapping functions and test values
|
|
296
|
+
|
|
297
|
+
The resulting dictionary provides a single authoritative source for all OEIS-related
|
|
298
|
+
configurations used throughout the package, including:
|
|
299
|
+
- Mathematical descriptions of each sequence
|
|
300
|
+
- Functions to convert between sequence indices and map dimensions
|
|
301
|
+
- Known sequence values retrieved from OEIS
|
|
302
|
+
- Testing and benchmarking reference values
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
A dictionary mapping OEIS sequence IDs to their complete settings objects,
|
|
306
|
+
containing all metadata and known values needed for computation and validation.
|
|
307
|
+
"""
|
|
243
308
|
settingsTarget: dict[str, SettingsOEIS] = {}
|
|
244
309
|
for oeisID in oeisIDsImplemented:
|
|
245
310
|
valuesKnownSherpa: dict[int, int] = getOEISidValues(oeisID)
|
|
@@ -259,8 +324,42 @@ def makeSettingsOEIS() -> dict[str, SettingsOEIS]:
|
|
|
259
324
|
settingsOEIS: dict[str, SettingsOEIS] = makeSettingsOEIS()
|
|
260
325
|
"""All values and settings for `oeisIDsImplemented`."""
|
|
261
326
|
|
|
262
|
-
|
|
263
|
-
|
|
327
|
+
@cache
|
|
328
|
+
def makeDictionaryFoldsTotalKnown() -> dict[tuple[int, ...], int]:
|
|
329
|
+
"""Returns a dictionary mapping dimension tuples to their known folding totals."""
|
|
330
|
+
dictionaryMapDimensionsToFoldsTotalKnown: dict[tuple[int, ...], int] = {}
|
|
331
|
+
|
|
332
|
+
for settings in settingsOEIS.values():
|
|
333
|
+
sequence = settings['valuesKnown']
|
|
334
|
+
|
|
335
|
+
for n, foldingsTotal in sequence.items():
|
|
336
|
+
mapShape = settings['getMapShape'](n)
|
|
337
|
+
mapShape = tuple(sorted(mapShape))
|
|
338
|
+
dictionaryMapDimensionsToFoldsTotalKnown[mapShape] = foldingsTotal
|
|
339
|
+
return dictionaryMapDimensionsToFoldsTotalKnown
|
|
340
|
+
|
|
341
|
+
def getFoldsTotalKnown(mapShape: tuple[int, ...]) -> int:
|
|
342
|
+
"""
|
|
343
|
+
Retrieve the known total number of foldings for a given map shape.
|
|
344
|
+
|
|
345
|
+
This function looks up precalculated folding totals for specific map dimensions
|
|
346
|
+
from OEIS sequences. It serves as a rapid reference for known values without
|
|
347
|
+
requiring computation, and can be used to validate algorithm results.
|
|
348
|
+
|
|
349
|
+
Parameters:
|
|
350
|
+
mapShape: A tuple of integers representing the dimensions of the map.
|
|
351
|
+
|
|
352
|
+
Returns:
|
|
353
|
+
foldingsTotal: The known total number of foldings for the given map shape,
|
|
354
|
+
or -1 if the map shape doesn't match any known values in the OEIS sequences.
|
|
355
|
+
|
|
356
|
+
Notes:
|
|
357
|
+
The function uses a cached dictionary (via makeDictionaryFoldsTotalKnown) to
|
|
358
|
+
efficiently retrieve values without repeatedly parsing OEIS data. Map shape
|
|
359
|
+
tuples are sorted internally to ensure consistent lookup regardless of dimension order.
|
|
360
|
+
"""
|
|
361
|
+
lookupFoldsTotal = makeDictionaryFoldsTotalKnown()
|
|
362
|
+
return lookupFoldsTotal.get(tuple(mapShape), -1)
|
|
264
363
|
|
|
265
364
|
def _formatHelpText() -> str:
|
|
266
365
|
"""Format standardized help text for both CLI and interactive use."""
|
|
@@ -285,35 +384,32 @@ def _formatOEISsequenceInfo() -> str:
|
|
|
285
384
|
for oeisID in oeisIDsImplemented
|
|
286
385
|
)
|
|
287
386
|
|
|
288
|
-
"""
|
|
289
|
-
Section: public functions"""
|
|
290
|
-
|
|
291
387
|
def oeisIDfor_n(oeisID: str, n: int | Any) -> int:
|
|
292
388
|
"""
|
|
293
|
-
Calculate a(n) of a sequence from "The On-Line Encyclopedia of Integer Sequences" (OEIS).
|
|
389
|
+
Calculate `a(n)` of a sequence from "The On-Line Encyclopedia of Integer Sequences" (OEIS).
|
|
294
390
|
|
|
295
391
|
Parameters:
|
|
296
392
|
oeisID: The ID of the OEIS sequence.
|
|
297
393
|
n: A non-negative integer for which to calculate the sequence value.
|
|
298
394
|
|
|
299
395
|
Returns:
|
|
300
|
-
sequenceValue: a(n) of the OEIS sequence.
|
|
396
|
+
sequenceValue: `a(n)` of the OEIS sequence.
|
|
301
397
|
|
|
302
398
|
Raises:
|
|
303
|
-
ValueError: If n is negative.
|
|
399
|
+
ValueError: If `n` is negative.
|
|
304
400
|
KeyError: If the OEIS sequence ID is not directly implemented.
|
|
305
401
|
"""
|
|
306
402
|
oeisID = validateOEISid(oeisID)
|
|
307
403
|
|
|
308
404
|
if not isinstance(n, int) or n < 0:
|
|
309
|
-
raise ValueError("`n` must be non-negative integer
|
|
405
|
+
raise ValueError(f"I received `{n = }` in the form of `{type(n) = }`, but it must be non-negative integer in the form of `{int}`.")
|
|
310
406
|
|
|
311
407
|
mapShape: tuple[int, ...] = settingsOEIS[oeisID]['getMapShape'](n)
|
|
312
408
|
|
|
313
409
|
if n <= 1 or len(mapShape) < 2:
|
|
314
410
|
offset: int = settingsOEIS[oeisID]['offset']
|
|
315
411
|
if n < offset:
|
|
316
|
-
raise ArithmeticError(f"OEIS sequence {oeisID} is not defined at n=
|
|
412
|
+
raise ArithmeticError(f"OEIS sequence {oeisID} is not defined at {n = }.")
|
|
317
413
|
foldsTotal: int = settingsOEIS[oeisID]['valuesKnown'][n]
|
|
318
414
|
return foldsTotal
|
|
319
415
|
from mapFolding.basecamp import countFolds
|
|
@@ -1,46 +1,67 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Code
|
|
2
|
+
Code Transformation Framework for Algorithm Optimization and Testing
|
|
3
3
|
|
|
4
4
|
This package implements a comprehensive framework for programmatically analyzing,
|
|
5
|
-
transforming, and generating Python code. It
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
different execution environments or specific computational tasks.
|
|
5
|
+
transforming, and generating optimized Python code. It serves as the algorithmic
|
|
6
|
+
optimization engine for the mapFolding package, enabling the conversion of readable,
|
|
7
|
+
functional implementations into highly-optimized variants with verified correctness.
|
|
9
8
|
|
|
10
|
-
Core
|
|
11
|
-
1. AST Pattern Recognition - Precisely identify and match code patterns using composable predicates
|
|
12
|
-
2. Algorithm Transformation - Convert functional state-based implementations to primitive operations
|
|
13
|
-
3. Dataclass "Shattering" - Decompose complex state objects into primitive components
|
|
14
|
-
4. Performance Optimization - Apply domain-specific optimizations for numerical computation
|
|
15
|
-
5. Code Generation - Generate specialized implementations with appropriate imports and syntax
|
|
9
|
+
## Core Architecture Components
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
1. **AST Manipulation Tools**
|
|
12
|
+
- Pattern recognition with composable predicates (ifThis)
|
|
13
|
+
- Node access with consistent interfaces (DOT)
|
|
14
|
+
- AST traversal and transformation (NodeChanger, NodeTourist)
|
|
15
|
+
- AST construction with sane defaults (Make)
|
|
16
|
+
- Node transformation operations (grab, Then)
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
2. **Container and Organization**
|
|
19
|
+
- Import tracking and management (LedgerOfImports)
|
|
20
|
+
- Function packaging with dependencies (IngredientsFunction)
|
|
21
|
+
- Module assembly with structured components (IngredientsModule)
|
|
22
|
+
- Recipe configuration for generating optimized code (RecipeSynthesizeFlow)
|
|
23
|
+
- Dataclass decomposition for compatibility (ShatteredDataclass)
|
|
24
|
+
|
|
25
|
+
3. **Optimization Pipelines**
|
|
26
|
+
- General-purpose Numba acceleration (makeNumbaFlow)
|
|
27
|
+
- Job-specific optimization for concrete parameters (makeJobNumba)
|
|
28
|
+
- Specialized component transformation (decorateCallableWithNumba)
|
|
29
|
+
|
|
30
|
+
## Integration with Testing Framework
|
|
31
|
+
|
|
32
|
+
The transformation components are extensively tested through the package's test suite,
|
|
33
|
+
which provides specialized fixtures and utilities for validating both the transformation
|
|
34
|
+
process and the resulting optimized code:
|
|
35
|
+
|
|
36
|
+
- **syntheticDispatcherFixture**: Creates and tests a complete Numba-optimized module
|
|
37
|
+
using RecipeSynthesizeFlow configuration
|
|
38
|
+
|
|
39
|
+
- **test_writeJobNumba**: Tests the job-specific optimization process with RecipeJob
|
|
40
|
+
|
|
41
|
+
These fixtures enable users to test their own custom recipes and job configurations
|
|
42
|
+
with minimal effort. See the documentation in tests/__init__.py for details on
|
|
43
|
+
extending the test suite for custom implementations.
|
|
44
|
+
|
|
45
|
+
The framework balances multiple optimization levels - from general algorithmic
|
|
46
|
+
improvements to parameter-specific optimizations - while maintaining the ability
|
|
47
|
+
to verify correctness at each transformation stage through the integrated test suite.
|
|
26
48
|
"""
|
|
49
|
+
|
|
27
50
|
from mapFolding.someAssemblyRequired._theTypes import (
|
|
28
51
|
ast_expr_Slice,
|
|
29
52
|
ast_Identifier,
|
|
30
53
|
astClassHasDOTnameNotName,
|
|
31
54
|
astClassHasDOTtarget,
|
|
55
|
+
astClassHasDOTvalue_expr,
|
|
56
|
+
astClassHasDOTvalue_exprNone,
|
|
57
|
+
astClassHasDOTtargetAttributeNameSubscript,
|
|
58
|
+
astClassHasDOTtarget_expr,
|
|
32
59
|
astClassHasDOTvalue,
|
|
33
60
|
astClassOptionallyHasDOTnameNotName,
|
|
34
|
-
astMosDef,
|
|
35
|
-
Ima_funcTypeUNEDITED,
|
|
36
|
-
Ima_targetTypeUNEDITED,
|
|
37
|
-
ImaAnnotationType,
|
|
38
|
-
ImaAnnotationTypeVar,
|
|
39
61
|
intORlist_ast_type_paramORstr_orNone,
|
|
40
62
|
intORstr_orNone,
|
|
41
63
|
list_ast_type_paramORstr_orNone,
|
|
42
64
|
str_nameDOTname,
|
|
43
|
-
TypeCertified,
|
|
44
65
|
个,
|
|
45
66
|
)
|
|
46
67
|
|
|
@@ -53,9 +74,9 @@ from mapFolding.someAssemblyRequired._toolboxPython import (
|
|
|
53
74
|
parsePathFilename2astModule,
|
|
54
75
|
)
|
|
55
76
|
|
|
56
|
-
from mapFolding.someAssemblyRequired._toolboxAntecedents import
|
|
77
|
+
from mapFolding.someAssemblyRequired._toolboxAntecedents import DOT, ifThis
|
|
57
78
|
from mapFolding.someAssemblyRequired._tool_Make import Make
|
|
58
|
-
from mapFolding.someAssemblyRequired._tool_Then import Then
|
|
79
|
+
from mapFolding.someAssemblyRequired._tool_Then import grab, Then
|
|
59
80
|
|
|
60
81
|
from mapFolding.someAssemblyRequired._toolboxContainers import (
|
|
61
82
|
IngredientsFunction,
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
"""It's still wrong, but typing information is being transmitted between functions, methods, and modules."""
|
|
2
1
|
from typing import Any, TYPE_CHECKING, TypeAlias as typing_TypeAlias, TypeVar as typing_TypeVar
|
|
3
2
|
import ast
|
|
3
|
+
# TODO understand typing.
|
|
4
4
|
|
|
5
5
|
stuPyd: typing_TypeAlias = str
|
|
6
|
-
|
|
7
6
|
if TYPE_CHECKING:
|
|
8
7
|
""" 3.12 new: ast.ParamSpec, ast.type_param, ast.TypeAlias, ast.TypeVar, ast.TypeVarTuple
|
|
9
8
|
3.11 new: ast.TryStar"""
|
|
10
9
|
astClassHasDOTnameNotName: typing_TypeAlias = ast.alias | ast.AsyncFunctionDef | ast.ClassDef | ast.FunctionDef | ast.ParamSpec | ast.TypeVar | ast.TypeVarTuple
|
|
11
|
-
|
|
10
|
+
astClassHasDOTvalue_expr: typing_TypeAlias = ast.Assign | ast.Attribute | ast.AugAssign | ast.Await | ast.DictComp | ast.Expr | ast.FormattedValue | ast.keyword | ast.MatchValue | ast.NamedExpr | ast.Starred | ast.Subscript | ast.TypeAlias | ast.YieldFrom
|
|
11
|
+
|
|
12
12
|
else:
|
|
13
13
|
astClassHasDOTnameNotName = stuPyd
|
|
14
|
-
|
|
14
|
+
astClassHasDOTvalue_expr = stuPyd
|
|
15
15
|
|
|
16
|
+
astClassHasDOTtargetAttributeNameSubscript: typing_TypeAlias = ast.AnnAssign | ast.AugAssign
|
|
17
|
+
astClassHasDOTtarget_expr: typing_TypeAlias = ast.AsyncFor | ast.comprehension | ast.For
|
|
18
|
+
astClassHasDOTtarget: typing_TypeAlias = ast.NamedExpr | astClassHasDOTtarget_expr | astClassHasDOTtargetAttributeNameSubscript
|
|
16
19
|
astClassOptionallyHasDOTnameNotName: typing_TypeAlias = ast.ExceptHandler | ast.MatchAs | ast.MatchStar
|
|
17
|
-
|
|
20
|
+
astClassHasDOTvalue_exprNone: typing_TypeAlias = ast.AnnAssign | ast.Return | ast.Yield
|
|
21
|
+
astClassHasDOTvalue: typing_TypeAlias = ast.Constant | ast.MatchSingleton | astClassHasDOTvalue_expr | astClassHasDOTvalue_exprNone
|
|
18
22
|
|
|
19
23
|
ast_expr_Slice: typing_TypeAlias = ast.expr
|
|
20
24
|
ast_Identifier: typing_TypeAlias = str
|
|
@@ -22,18 +26,10 @@ intORlist_ast_type_paramORstr_orNone: typing_TypeAlias = Any
|
|
|
22
26
|
intORstr_orNone: typing_TypeAlias = Any
|
|
23
27
|
list_ast_type_paramORstr_orNone: typing_TypeAlias = Any
|
|
24
28
|
str_nameDOTname: typing_TypeAlias = stuPyd
|
|
25
|
-
ImaAnnotationType: typing_TypeAlias = ast.Attribute | ast.Constant | ast.Name | ast.Subscript
|
|
26
|
-
ImaAnnotationTypeVar = typing_TypeVar('ImaAnnotationTypeVar', ast.Attribute, ast.Constant, ast.Name, ast.Subscript)
|
|
27
|
-
|
|
28
|
-
Ima_funcTypeUNEDITED: typing_TypeAlias = ast.Attribute | ast.Await | ast.BinOp | ast.BoolOp | ast.Call | ast.Compare | ast.Constant | ast.Dict | ast.DictComp | ast.FormattedValue | ast.GeneratorExp | ast.IfExp | ast.JoinedStr | ast.Lambda | ast.List | ast.ListComp | ast.Name | ast.NamedExpr | ast.Set | ast.SetComp | ast.Slice | ast.Starred | ast.Subscript | ast.Tuple | ast.UnaryOp | ast.Yield | ast.YieldFrom
|
|
29
|
-
Ima_targetTypeUNEDITED: typing_TypeAlias = ast.AST
|
|
30
|
-
|
|
31
|
-
# TODO understand whatever the fuck `typing.TypeVar` is _supposed_ to fucking do.
|
|
32
|
-
TypeCertified = typing_TypeVar('TypeCertified', bound = ast.AST, covariant=True)
|
|
33
|
-
astMosDef = typing_TypeVar('astMosDef', bound=astClassHasDOTnameNotName)
|
|
34
29
|
|
|
35
|
-
个 = typing_TypeVar('个', bound= ast.AST
|
|
30
|
+
个 = typing_TypeVar('个', bound= ast.AST, covariant=True)
|
|
36
31
|
|
|
32
|
+
# All ast classes by subgroup:
|
|
37
33
|
Ima_ast_boolop: typing_TypeAlias = ast.boolop | ast.And | ast.Or
|
|
38
34
|
Ima_ast_cmpop: typing_TypeAlias = ast.cmpop | ast.Eq | ast.NotEq | ast.Lt | ast.LtE | ast.Gt | ast.GtE | ast.Is | ast.IsNot | ast.In | ast.NotIn
|
|
39
35
|
Ima_ast_excepthandler: typing_TypeAlias = ast.excepthandler | ast.ExceptHandler
|