mapFolding 0.15.4__py3-none-any.whl → 0.16.1__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.
- easyRun/A000682.py +25 -0
- easyRun/A005316.py +21 -0
- easyRun/NOTcountingFolds.py +36 -0
- easyRun/__init__.py +0 -0
- easyRun/countFolds.py +41 -0
- easyRun/meanders.py +71 -0
- mapFolding/__init__.py +10 -55
- mapFolding/_dataPacking.py +68 -0
- mapFolding/_theSSOT.py +33 -36
- mapFolding/_theTypes.py +21 -4
- mapFolding/algorithms/daoOfMapFolding.py +1 -2
- mapFolding/algorithms/matrixMeanders.py +101 -348
- mapFolding/algorithms/matrixMeandersBeDry.py +264 -0
- mapFolding/algorithms/matrixMeandersNumPy.py +286 -0
- mapFolding/algorithms/matrixMeandersPandas.py +351 -0
- mapFolding/algorithms/oeisIDbyFormula.py +320 -76
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +92 -0
- mapFolding/basecamp.py +261 -113
- mapFolding/beDRY.py +2 -30
- mapFolding/dataBaskets.py +120 -4
- mapFolding/oeis.py +13 -33
- mapFolding/reference/A000682facts.py +1276 -0
- mapFolding/reference/A005316facts.py +985 -0
- mapFolding/reference/matrixMeandersAnalysis/__init__.py +1 -0
- mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +15 -0
- mapFolding/reference/meandersDumpingGround/A005316JavaPort.py +1 -1
- mapFolding/reference/meandersDumpingGround/A005316imperative.py +1 -1
- mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +424 -0
- mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +54 -0
- mapFolding/someAssemblyRequired/A007822/__init__.py +0 -0
- mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +197 -0
- mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +74 -0
- mapFolding/someAssemblyRequired/RecipeJob.py +4 -4
- mapFolding/someAssemblyRequired/__init__.py +9 -2
- mapFolding/someAssemblyRequired/_toolIfThis.py +4 -3
- mapFolding/someAssemblyRequired/_toolkitContainers.py +8 -8
- mapFolding/someAssemblyRequired/infoBooth.py +27 -30
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +6 -5
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +6 -4
- mapFolding/someAssemblyRequired/makingModules_count.py +294 -0
- mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +117 -0
- mapFolding/someAssemblyRequired/mapFolding/__init__.py +0 -0
- mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +220 -0
- mapFolding/someAssemblyRequired/meanders/__init__.py +0 -0
- mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +64 -0
- mapFolding/someAssemblyRequired/toolkitMakeModules.py +152 -0
- mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
- mapFolding/someAssemblyRequired/transformationTools.py +1 -0
- mapFolding/syntheticModules/A007822/__init__.py +1 -0
- mapFolding/syntheticModules/{algorithmA007822.py → A007822/algorithm.py} +2 -3
- mapFolding/syntheticModules/{algorithmA007822Numba.py → A007822/algorithmNumba.py} +3 -6
- mapFolding/syntheticModules/A007822/asynchronous.py +148 -0
- mapFolding/syntheticModules/A007822/asynchronousAnnex.py +66 -0
- mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +85 -0
- mapFolding/syntheticModules/A007822/asynchronousNumba.py +52 -0
- mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +53 -0
- mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +47 -0
- mapFolding/syntheticModules/{initializeStateA007822.py → A007822/initializeState.py} +1 -2
- mapFolding/syntheticModules/{theorem2A007822.py → A007822/theorem2.py} +1 -2
- mapFolding/syntheticModules/{theorem2A007822Numba.py → A007822/theorem2Numba.py} +6 -4
- mapFolding/syntheticModules/{theorem2A007822Trimmed.py → A007822/theorem2Trimmed.py} +1 -2
- mapFolding/syntheticModules/countParallelNumba.py +5 -2
- mapFolding/syntheticModules/daoOfMapFoldingNumba.py +4 -2
- mapFolding/syntheticModules/dataPacking.py +4 -2
- mapFolding/syntheticModules/dataPackingA007822.py +92 -26
- mapFolding/syntheticModules/meanders/__init__.py +1 -0
- mapFolding/syntheticModules/meanders/bigInt.py +62 -0
- mapFolding/syntheticModules/theorem2Numba.py +3 -2
- mapFolding/tests/conftest.py +28 -13
- mapFolding/tests/test_computations.py +69 -62
- mapFolding/tests/test_oeis.py +6 -6
- mapFolding/zCuzDocStoopid/__init__.py +4 -0
- mapFolding/zCuzDocStoopid/makeDocstrings.py +68 -0
- mapfolding-0.16.1.dist-info/METADATA +99 -0
- mapfolding-0.16.1.dist-info/RECORD +114 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/top_level.txt +1 -0
- mapFolding/someAssemblyRequired/A007822rawMaterials.py +0 -46
- mapFolding/someAssemblyRequired/makeAllModules.py +0 -764
- mapfolding-0.15.4.dist-info/METADATA +0 -78
- mapfolding-0.15.4.dist-info/RECORD +0 -78
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/WHEEL +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""addSymmetryCheckAsynchronous."""
|
|
2
|
+
from astToolkit import Be, extractFunctionDef, Grab, Make, NodeChanger, NodeTourist, parsePathFilename2astModule, Then
|
|
3
|
+
from hunterMakesPy import raiseIfNone
|
|
4
|
+
from mapFolding import packageSettings
|
|
5
|
+
from mapFolding.someAssemblyRequired import IfThis, logicalPathInfixAlgorithmDEFAULT
|
|
6
|
+
from mapFolding.someAssemblyRequired.A007822.A007822rawMaterials import (
|
|
7
|
+
A007822adjustFoldsTotal, astExprCall_filterAsymmetricFoldsDataclass, identifier_filterAsymmetricFolds,
|
|
8
|
+
identifierCounting, identifierDataclass, logicalPathInfixA007822, sourceCallableDispatcherA007822,
|
|
9
|
+
sourceCallableIdentifierA007822)
|
|
10
|
+
from mapFolding.someAssemblyRequired.makingModules_count import makeTheorem2, numbaOnTheorem2, trimTheorem2
|
|
11
|
+
from mapFolding.someAssemblyRequired.toolkitMakeModules import getModule, getPathFilename, write_astModule
|
|
12
|
+
from os import PathLike
|
|
13
|
+
from pathlib import PurePath
|
|
14
|
+
import ast
|
|
15
|
+
|
|
16
|
+
identifier_getAsymmetricFoldsTotal = 'getAsymmetricFoldsTotal'
|
|
17
|
+
identifier_initializeConcurrencyManager = 'initializeConcurrencyManager'
|
|
18
|
+
identifier_processCompletedFutures = '_processCompletedFutures'
|
|
19
|
+
|
|
20
|
+
astExprCall_initializeConcurrencyManager: ast.Expr = Make.Expr(Make.Call(Make.Name(identifier_initializeConcurrencyManager)))
|
|
21
|
+
AssignTotal2CountingIdentifier: ast.Assign = Make.Assign(
|
|
22
|
+
[Make.Attribute(Make.Name(identifierDataclass), identifierCounting, context=Make.Store())]
|
|
23
|
+
, value=Make.Call(Make.Name(identifier_getAsymmetricFoldsTotal))
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
def addSymmetryCheckAsynchronous(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
27
|
+
"""Add symmetry check to the counting function.
|
|
28
|
+
|
|
29
|
+
To do asynchronous filtering, a few things must happen.
|
|
30
|
+
1. When the algorithm finds a `groupOfFolds`, the call to `filterAsymmetricFolds` must be non-blocking.
|
|
31
|
+
2. Filtering the `groupOfFolds` into symmetric folds must start immediately, and run concurrently.
|
|
32
|
+
3. When filtering, the module must immediately discard `leafBelow` and sum the filtered folds into a global total.
|
|
33
|
+
4. Of course, the filtering must be complete before `getAsymmetricFoldsTotal` fulfills the request for the total.
|
|
34
|
+
|
|
35
|
+
Why _must_ those things happen?
|
|
36
|
+
1. Filtering takes as long as finding the `groupOfFolds`, so we can't block.
|
|
37
|
+
2. Filtering must start immediately to keep up with the finding process.
|
|
38
|
+
3. To discover A007822(27), which is currently unknown, I estimate there will be 369192702554 calls to filterAsymmetricFolds.
|
|
39
|
+
Each `leafBelow` array will be 28 * 8-bits, so if the queue has only 0.3% of the total calls in it, that is 28 GiB of data.
|
|
40
|
+
"""
|
|
41
|
+
astFunctionDef_count: ast.FunctionDef = raiseIfNone(NodeTourist(
|
|
42
|
+
findThis = Be.FunctionDef.nameIs(IfThis.isIdentifier(sourceCallableIdentifierA007822))
|
|
43
|
+
, doThat = Then.extractIt
|
|
44
|
+
).captureLastMatch(astModule))
|
|
45
|
+
|
|
46
|
+
NodeChanger(Be.Return, Then.insertThisAbove([A007822adjustFoldsTotal])).visit(astFunctionDef_count)
|
|
47
|
+
|
|
48
|
+
NodeChanger(
|
|
49
|
+
findThis=Be.AugAssign.targetIs(IfThis.isAttributeNamespaceIdentifier(identifierDataclass, identifierCounting))
|
|
50
|
+
, doThat=Then.replaceWith(astExprCall_filterAsymmetricFoldsDataclass)
|
|
51
|
+
).visit(astFunctionDef_count)
|
|
52
|
+
|
|
53
|
+
NodeChanger(
|
|
54
|
+
findThis=Be.While.testIs(IfThis.isCallIdentifier('activeLeafGreaterThan0'))
|
|
55
|
+
, doThat=Grab.orelseAttribute(Then.replaceWith([AssignTotal2CountingIdentifier]))
|
|
56
|
+
).visit(astFunctionDef_count)
|
|
57
|
+
|
|
58
|
+
NodeChanger(
|
|
59
|
+
findThis=Be.FunctionDef.nameIs(IfThis.isIdentifier(sourceCallableIdentifierA007822))
|
|
60
|
+
, doThat=Then.replaceWith(astFunctionDef_count)
|
|
61
|
+
).visit(astModule)
|
|
62
|
+
|
|
63
|
+
astFunctionDef_doTheNeedful: ast.FunctionDef = raiseIfNone(NodeTourist(
|
|
64
|
+
findThis = Be.FunctionDef.nameIs(IfThis.isIdentifier(sourceCallableDispatcher))
|
|
65
|
+
, doThat = Then.extractIt
|
|
66
|
+
).captureLastMatch(astModule))
|
|
67
|
+
|
|
68
|
+
astFunctionDef_doTheNeedful.body.insert(0, astExprCall_initializeConcurrencyManager)
|
|
69
|
+
|
|
70
|
+
NodeChanger(
|
|
71
|
+
findThis=Be.FunctionDef.nameIs(IfThis.isIdentifier(sourceCallableDispatcher))
|
|
72
|
+
, doThat=Then.replaceWith(astFunctionDef_doTheNeedful)
|
|
73
|
+
).visit(astModule)
|
|
74
|
+
|
|
75
|
+
astImportFrom = ast.ImportFrom(f'{packageSettings.identifierPackage}.{logicalPathInfix}.{moduleIdentifier}Annex'
|
|
76
|
+
, [Make.alias(identifier_filterAsymmetricFolds), Make.alias(identifier_getAsymmetricFoldsTotal), Make.alias(identifier_initializeConcurrencyManager)], 0)
|
|
77
|
+
|
|
78
|
+
astModule.body.insert(0, astImportFrom)
|
|
79
|
+
|
|
80
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
81
|
+
pathFilenameAnnex: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier + 'Annex')
|
|
82
|
+
|
|
83
|
+
write_astModule(astModule, pathFilename, packageSettings.identifierPackage)
|
|
84
|
+
del astModule
|
|
85
|
+
# ----------------- Ingredients Module Annex ------------------------------------------------------------------------------
|
|
86
|
+
ImaString = """from concurrent.futures import Future as ConcurrentFuture, ThreadPoolExecutor
|
|
87
|
+
from hunterMakesPy import raiseIfNone
|
|
88
|
+
from mapFolding import Array1DLeavesTotal
|
|
89
|
+
from queue import Empty, Queue
|
|
90
|
+
from threading import Thread
|
|
91
|
+
import numpy"""
|
|
92
|
+
|
|
93
|
+
astModule = ast.parse(ImaString)
|
|
94
|
+
del ImaString
|
|
95
|
+
|
|
96
|
+
ImaString = f"""concurrencyManager = None
|
|
97
|
+
{identifierCounting}Total: int = 0
|
|
98
|
+
processingThread = None
|
|
99
|
+
queueFutures: Queue[ConcurrentFuture[int]] = Queue()
|
|
100
|
+
"""
|
|
101
|
+
astModule.body.extend(ast.parse(ImaString).body)
|
|
102
|
+
del ImaString
|
|
103
|
+
|
|
104
|
+
ImaString = f"""def {identifier_initializeConcurrencyManager}(maxWorkers: int | None = None, {identifierCounting}: int = 0) -> None:
|
|
105
|
+
global concurrencyManager, queueFutures, {identifierCounting}Total, processingThread
|
|
106
|
+
concurrencyManager = ThreadPoolExecutor(max_workers=maxWorkers)
|
|
107
|
+
queueFutures = Queue()
|
|
108
|
+
{identifierCounting}Total = {identifierCounting}
|
|
109
|
+
processingThread = Thread(target={identifier_processCompletedFutures})
|
|
110
|
+
processingThread.start()
|
|
111
|
+
"""
|
|
112
|
+
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_initializeConcurrencyManager)))
|
|
113
|
+
del ImaString
|
|
114
|
+
|
|
115
|
+
ImaString = f"""def {identifier_processCompletedFutures}() -> None:
|
|
116
|
+
global queueFutures, {identifierCounting}Total
|
|
117
|
+
while True:
|
|
118
|
+
try:
|
|
119
|
+
claimTicket: ConcurrentFuture[int] = queueFutures.get(timeout=1)
|
|
120
|
+
if claimTicket is None:
|
|
121
|
+
break
|
|
122
|
+
{identifierCounting}Total += claimTicket.result()
|
|
123
|
+
except Empty:
|
|
124
|
+
continue
|
|
125
|
+
"""
|
|
126
|
+
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_processCompletedFutures)))
|
|
127
|
+
del ImaString
|
|
128
|
+
|
|
129
|
+
ImaString = f"""def _{identifier_filterAsymmetricFolds}(leafBelow: Array1DLeavesTotal) -> int:
|
|
130
|
+
{identifierCounting} = 0
|
|
131
|
+
leafComparison: Array1DLeavesTotal = numpy.zeros_like(leafBelow)
|
|
132
|
+
leavesTotal = leafBelow.size - 1
|
|
133
|
+
|
|
134
|
+
indexLeaf = 0
|
|
135
|
+
leafConnectee = 0
|
|
136
|
+
while leafConnectee < leavesTotal + 1:
|
|
137
|
+
leafNumber = int(leafBelow[indexLeaf])
|
|
138
|
+
leafComparison[leafConnectee] = (leafNumber - indexLeaf + leavesTotal) % leavesTotal
|
|
139
|
+
indexLeaf = leafNumber
|
|
140
|
+
leafConnectee += 1
|
|
141
|
+
|
|
142
|
+
indexInMiddle = leavesTotal // 2
|
|
143
|
+
indexDistance = 0
|
|
144
|
+
while indexDistance < leavesTotal + 1:
|
|
145
|
+
ImaSymmetricFold = True
|
|
146
|
+
leafConnectee = 0
|
|
147
|
+
while leafConnectee < indexInMiddle:
|
|
148
|
+
if leafComparison[(indexDistance + leafConnectee) % (leavesTotal + 1)] != leafComparison[(indexDistance + leavesTotal - 1 - leafConnectee) % (leavesTotal + 1)]:
|
|
149
|
+
ImaSymmetricFold = False
|
|
150
|
+
break
|
|
151
|
+
leafConnectee += 1
|
|
152
|
+
{identifierCounting} += ImaSymmetricFold
|
|
153
|
+
indexDistance += 1
|
|
154
|
+
return {identifierCounting}
|
|
155
|
+
"""
|
|
156
|
+
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), f'_{identifier_filterAsymmetricFolds}')))
|
|
157
|
+
del ImaString
|
|
158
|
+
|
|
159
|
+
ImaString = f"""
|
|
160
|
+
def {identifier_filterAsymmetricFolds}(leafBelow: Array1DLeavesTotal) -> None:
|
|
161
|
+
global concurrencyManager, queueFutures
|
|
162
|
+
queueFutures.put_nowait(raiseIfNone(concurrencyManager).submit(_{identifier_filterAsymmetricFolds}, leafBelow.copy()))
|
|
163
|
+
"""
|
|
164
|
+
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_filterAsymmetricFolds)))
|
|
165
|
+
del ImaString
|
|
166
|
+
|
|
167
|
+
ImaString = f"""
|
|
168
|
+
def {identifier_getAsymmetricFoldsTotal}() -> int:
|
|
169
|
+
global concurrencyManager, queueFutures, processingThread
|
|
170
|
+
raiseIfNone(concurrencyManager).shutdown(wait=True)
|
|
171
|
+
queueFutures.put(None)
|
|
172
|
+
raiseIfNone(processingThread).join()
|
|
173
|
+
return {identifierCounting}Total
|
|
174
|
+
"""
|
|
175
|
+
astModule.body.append(raiseIfNone(extractFunctionDef(ast.parse(ImaString), identifier_getAsymmetricFoldsTotal)))
|
|
176
|
+
del ImaString
|
|
177
|
+
|
|
178
|
+
write_astModule(astModule, pathFilenameAnnex, packageSettings.identifierPackage)
|
|
179
|
+
|
|
180
|
+
return pathFilename
|
|
181
|
+
|
|
182
|
+
def _makeA007822AsynchronousModules() -> None:
|
|
183
|
+
|
|
184
|
+
astModule = getModule(logicalPathInfix=logicalPathInfixAlgorithmDEFAULT)
|
|
185
|
+
pathFilename = addSymmetryCheckAsynchronous(astModule, 'asynchronous', None, logicalPathInfixA007822, sourceCallableDispatcherA007822)
|
|
186
|
+
|
|
187
|
+
astModule = getModule(logicalPathInfix=logicalPathInfixA007822, moduleIdentifier='asynchronous')
|
|
188
|
+
pathFilename = makeTheorem2(astModule, 'asynchronousTheorem2', None, logicalPathInfixA007822, None)
|
|
189
|
+
|
|
190
|
+
astModule = parsePathFilename2astModule(pathFilename)
|
|
191
|
+
pathFilename = trimTheorem2(astModule, 'asynchronousTrimmed', None, logicalPathInfixA007822, None)
|
|
192
|
+
|
|
193
|
+
astModule = parsePathFilename2astModule(pathFilename)
|
|
194
|
+
pathFilename = numbaOnTheorem2(astModule, 'asynchronousNumba', None, logicalPathInfixA007822, None)
|
|
195
|
+
|
|
196
|
+
if __name__ == '__main__':
|
|
197
|
+
_makeA007822AsynchronousModules()
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""addSymmetryCheck."""
|
|
2
|
+
from astToolkit import Be, Make, NodeChanger, NodeTourist, parsePathFilename2astModule, Then
|
|
3
|
+
from hunterMakesPy import raiseIfNone
|
|
4
|
+
from mapFolding import packageSettings
|
|
5
|
+
from mapFolding.someAssemblyRequired import (
|
|
6
|
+
identifierCallableSourceDEFAULT, identifierCountingDEFAULT, identifierDataclassInstanceDEFAULT, IfThis)
|
|
7
|
+
from mapFolding.someAssemblyRequired.A007822.A007822rawMaterials import (
|
|
8
|
+
A007822adjustFoldsTotal, A007822incrementCount, FunctionDef_filterAsymmetricFolds, logicalPathInfixA007822,
|
|
9
|
+
sourceCallableDispatcherA007822, sourceCallableIdentifierA007822)
|
|
10
|
+
from mapFolding.someAssemblyRequired.makingModules_count import (
|
|
11
|
+
makeDaoOfMapFoldingNumba, makeTheorem2, numbaOnTheorem2, trimTheorem2)
|
|
12
|
+
from mapFolding.someAssemblyRequired.makingModules_doTheNeedful import makeInitializeState, makeUnRePackDataclass
|
|
13
|
+
from mapFolding.someAssemblyRequired.toolkitMakeModules import (
|
|
14
|
+
getLogicalPath, getModule, getPathFilename, write_astModule)
|
|
15
|
+
from os import PathLike
|
|
16
|
+
from pathlib import PurePath
|
|
17
|
+
import ast
|
|
18
|
+
|
|
19
|
+
def addSymmetryCheck(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
|
|
20
|
+
"""Add logic to check for symmetric folds."""
|
|
21
|
+
# NOTE HEY HEY! Are you trying to figure out why there is more than one copy of `filterAsymmetricFolds`? See the TODO NOTE, below.
|
|
22
|
+
|
|
23
|
+
astFunctionDef_count: ast.FunctionDef = raiseIfNone(NodeTourist(
|
|
24
|
+
findThis = Be.FunctionDef.nameIs(IfThis.isIdentifier(identifierCallableSourceDEFAULT))
|
|
25
|
+
, doThat = Then.extractIt
|
|
26
|
+
).captureLastMatch(astModule))
|
|
27
|
+
astFunctionDef_count.name = sourceCallableIdentifierA007822
|
|
28
|
+
|
|
29
|
+
NodeChanger(Be.Return, Then.insertThisAbove([A007822adjustFoldsTotal])).visit(astFunctionDef_count)
|
|
30
|
+
|
|
31
|
+
NodeChanger(
|
|
32
|
+
findThis=Be.AugAssign.targetIs(IfThis.isAttributeNamespaceIdentifier(identifierDataclassInstanceDEFAULT, identifierCountingDEFAULT))
|
|
33
|
+
, doThat=Then.replaceWith(A007822incrementCount)
|
|
34
|
+
).visit(astFunctionDef_count)
|
|
35
|
+
|
|
36
|
+
# TODO NOTE This will insert a copy of `filterAsymmetricFolds` for each `ast.ImportFrom` in the source module. Find or make a
|
|
37
|
+
# system to replace the `Ingredients` paradigm.
|
|
38
|
+
NodeChanger(Be.ImportFrom, Then.insertThisBelow([FunctionDef_filterAsymmetricFolds])).visit(astModule)
|
|
39
|
+
|
|
40
|
+
pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
|
|
41
|
+
|
|
42
|
+
write_astModule(astModule, pathFilename, packageSettings.identifierPackage)
|
|
43
|
+
|
|
44
|
+
return pathFilename
|
|
45
|
+
|
|
46
|
+
def _makeA007822Modules() -> None:
|
|
47
|
+
astModule = getModule(logicalPathInfix='algorithms')
|
|
48
|
+
pathFilename = addSymmetryCheck(astModule, 'algorithm', None, logicalPathInfixA007822, None)
|
|
49
|
+
|
|
50
|
+
astModule = getModule(logicalPathInfix=logicalPathInfixA007822, moduleIdentifier='algorithm')
|
|
51
|
+
pathFilename: PurePath = makeDaoOfMapFoldingNumba(astModule, 'algorithmNumba', None, logicalPathInfixA007822, sourceCallableDispatcherA007822)
|
|
52
|
+
|
|
53
|
+
# NOTE I can't handle parallel right now.
|
|
54
|
+
|
|
55
|
+
astModule = getModule(logicalPathInfix=logicalPathInfixA007822, moduleIdentifier='algorithm')
|
|
56
|
+
makeInitializeState(astModule, 'initializeState', 'transitionOnGroupsOfFolds', logicalPathInfixA007822)
|
|
57
|
+
|
|
58
|
+
astModule = getModule(logicalPathInfix=logicalPathInfixA007822, moduleIdentifier='algorithm')
|
|
59
|
+
pathFilename = makeTheorem2(astModule, 'theorem2', None, logicalPathInfixA007822, None)
|
|
60
|
+
|
|
61
|
+
astModule = parsePathFilename2astModule(pathFilename)
|
|
62
|
+
pathFilename = trimTheorem2(astModule, 'theorem2Trimmed', None, logicalPathInfixA007822, None)
|
|
63
|
+
|
|
64
|
+
astModule = parsePathFilename2astModule(pathFilename)
|
|
65
|
+
pathFilename = numbaOnTheorem2(astModule, 'theorem2Numba', None, logicalPathInfixA007822, None)
|
|
66
|
+
# TODO from mapFolding.syntheticModules.dataPackingA007822 import unRePackDataclass
|
|
67
|
+
# @unRePackDataclass
|
|
68
|
+
|
|
69
|
+
# TODO Make this decorator.
|
|
70
|
+
# astImportFrom: ast.ImportFrom = Make.ImportFrom(getLogicalPath(packageSettings.identifierPackage, logicalPathInfixA007822, 'theorem2Numba'), list_alias=[Make.alias(sourceCallableIdentifierA007822)])
|
|
71
|
+
# makeUnRePackDataclass(astImportFrom, 'dataPackingA007822')
|
|
72
|
+
|
|
73
|
+
if __name__ == '__main__':
|
|
74
|
+
_makeA007822Modules()
|
|
@@ -4,9 +4,9 @@ from ast import Module
|
|
|
4
4
|
from astToolkit import identifierDotAttribute, parseLogicalPath2astModule
|
|
5
5
|
from mapFolding import (
|
|
6
6
|
DatatypeElephino as TheDatatypeElephino, DatatypeFoldsTotal as TheDatatypeFoldsTotal,
|
|
7
|
-
DatatypeLeavesTotal as TheDatatypeLeavesTotal, getPathFilenameFoldsTotal, getPathRootJobDEFAULT,
|
|
8
|
-
|
|
9
|
-
from mapFolding.someAssemblyRequired import
|
|
7
|
+
DatatypeLeavesTotal as TheDatatypeLeavesTotal, getPathFilenameFoldsTotal, getPathRootJobDEFAULT, packageSettings)
|
|
8
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
9
|
+
from mapFolding.someAssemblyRequired import identifierDataclassInstanceDEFAULT, ShatteredDataclass
|
|
10
10
|
from mapFolding.someAssemblyRequired.transformationTools import shatter_dataclassesDOTdataclass
|
|
11
11
|
from pathlib import Path, PurePosixPath
|
|
12
12
|
import dataclasses
|
|
@@ -98,7 +98,7 @@ class RecipeJobTheorem2:
|
|
|
98
98
|
"""Logical path to the dataclass module."""
|
|
99
99
|
sourceDataclassIdentifier: str = 'MapFoldingState'
|
|
100
100
|
"""Name of the source dataclass."""
|
|
101
|
-
sourceDataclassInstance: str =
|
|
101
|
+
sourceDataclassInstance: str = identifierDataclassInstanceDEFAULT
|
|
102
102
|
"""Instance identifier for the dataclass."""
|
|
103
103
|
|
|
104
104
|
sourcePathPackage: PurePosixPath | None = PurePosixPath(packageSettings.pathPackage) # noqa: RUF009
|
|
@@ -73,8 +73,15 @@ calculations through the strategic application of compiler optimization techniqu
|
|
|
73
73
|
"""
|
|
74
74
|
|
|
75
75
|
from mapFolding.someAssemblyRequired.infoBooth import (
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
dictionaryEstimatesMapFolding as dictionaryEstimatesMapFolding,
|
|
77
|
+
identifierCallableSourceDEFAULT as identifierCallableSourceDEFAULT,
|
|
78
|
+
identifierCallableSourceDispatcherDEFAULT as identifierCallableSourceDispatcherDEFAULT,
|
|
79
|
+
identifierCountingDEFAULT as identifierCountingDEFAULT,
|
|
80
|
+
identifierDataclassInstanceDEFAULT as identifierDataclassInstanceDEFAULT,
|
|
81
|
+
identifierModuleDataPackingDEFAULT as identifierModuleDataPackingDEFAULT,
|
|
82
|
+
identifierModuleSourceAlgorithmDEFAULT as identifierModuleSourceAlgorithmDEFAULT,
|
|
83
|
+
logicalPathInfixAlgorithmDEFAULT as logicalPathInfixAlgorithmDEFAULT,
|
|
84
|
+
logicalPathInfixDEFAULT as logicalPathInfixDEFAULT,
|
|
78
85
|
)
|
|
79
86
|
|
|
80
87
|
from mapFolding.someAssemblyRequired._toolIfThis import IfThis as IfThis
|
|
@@ -67,7 +67,7 @@ class IfThis(astToolkit_IfThis):
|
|
|
67
67
|
|
|
68
68
|
"""
|
|
69
69
|
return lambda node: (Be.Compare.leftIs(IfThis.isAttributeNamespaceIdentifier(namespace, identifier))(node)
|
|
70
|
-
and Be.Compare.opsIs(
|
|
70
|
+
and Be.Compare.opsIs(Be.at(0, Be.LtE))(node)
|
|
71
71
|
)
|
|
72
72
|
|
|
73
73
|
@staticmethod
|
|
@@ -94,8 +94,9 @@ class IfThis(astToolkit_IfThis):
|
|
|
94
94
|
|
|
95
95
|
"""
|
|
96
96
|
return lambda node: (Be.Compare.leftIs(IfThis.isAttributeNamespaceIdentifier(namespace, identifier))(node)
|
|
97
|
-
and Be.
|
|
98
|
-
and IfThis.isConstant_value(0)(node
|
|
97
|
+
and Be.Compare.opsIs(Be.at(0, Be.Gt))(node)
|
|
98
|
+
and Be.Compare.comparatorsIs(Be.at(0, IfThis.isConstant_value(0)))(node)
|
|
99
|
+
)
|
|
99
100
|
|
|
100
101
|
@staticmethod
|
|
101
102
|
def isIfAttributeNamespaceIdentifierGreaterThan0(namespace: str, identifier: str) -> Callable[[ast.AST], TypeIs[ast.If]]:
|
|
@@ -62,10 +62,10 @@ class ShatteredDataclass:
|
|
|
62
62
|
countingVariableName: ast.Name
|
|
63
63
|
"""AST name node representing the counting variable identifier."""
|
|
64
64
|
|
|
65
|
-
field2AnnAssign: dict[str, ast.AnnAssign | ast.Assign] = dataclasses.field(default_factory=
|
|
65
|
+
field2AnnAssign: dict[str, ast.AnnAssign | ast.Assign] = dataclasses.field(default_factory=dict[str, ast.AnnAssign | ast.Assign])
|
|
66
66
|
"""Maps field names to their corresponding AST assignment expressions for initialization."""
|
|
67
67
|
|
|
68
|
-
Z0Z_field2AnnAssign: dict[str, tuple[ast.AnnAssign | ast.Assign, str]] = dataclasses.field(default_factory=
|
|
68
|
+
Z0Z_field2AnnAssign: dict[str, tuple[ast.AnnAssign | ast.Assign, str]] = dataclasses.field(default_factory=dict[str, tuple[ast.AnnAssign | ast.Assign, str]])
|
|
69
69
|
"""Temporary mapping for field assignments with constructor type information."""
|
|
70
70
|
|
|
71
71
|
fragments4AssignmentOrParameters: ast.Tuple = dummyTuple
|
|
@@ -74,22 +74,22 @@ class ShatteredDataclass:
|
|
|
74
74
|
imports: LedgerOfImports = dataclasses.field(default_factory=LedgerOfImports)
|
|
75
75
|
"""Import records for the dataclass and its constituent field types."""
|
|
76
76
|
|
|
77
|
-
list_argAnnotated4ArgumentsSpecification: list[ast.arg] = dataclasses.field(default_factory=
|
|
77
|
+
list_argAnnotated4ArgumentsSpecification: list[ast.arg] = dataclasses.field(default_factory=list[ast.arg])
|
|
78
78
|
"""Function argument nodes with type annotations for parameter specification."""
|
|
79
79
|
|
|
80
|
-
list_keyword_field__field4init: list[ast.keyword] = dataclasses.field(default_factory=
|
|
80
|
+
list_keyword_field__field4init: list[ast.keyword] = dataclasses.field(default_factory=list[ast.keyword])
|
|
81
81
|
"""Keyword arguments for dataclass initialization using field=field format."""
|
|
82
82
|
|
|
83
|
-
listAnnotations: list[ast.expr] = dataclasses.field(default_factory=
|
|
83
|
+
listAnnotations: list[ast.expr] = dataclasses.field(default_factory=list[ast.expr])
|
|
84
84
|
"""Type annotations for each dataclass field in declaration order."""
|
|
85
85
|
|
|
86
|
-
listName4Parameters: list[ast.Name] = dataclasses.field(default_factory=
|
|
86
|
+
listName4Parameters: list[ast.Name] = dataclasses.field(default_factory=list[ast.Name])
|
|
87
87
|
"""Name nodes for each dataclass field used as function parameters."""
|
|
88
88
|
|
|
89
|
-
listUnpack: list[ast.AnnAssign] = dataclasses.field(default_factory=
|
|
89
|
+
listUnpack: list[ast.AnnAssign] = dataclasses.field(default_factory=list[ast.AnnAssign])
|
|
90
90
|
"""Annotated assignment statements to extract individual fields from dataclass instances."""
|
|
91
91
|
|
|
92
|
-
map_stateDOTfield2Name: dict[ast.AST, ast.Name] = dataclasses.field(default_factory=
|
|
92
|
+
map_stateDOTfield2Name: dict[ast.AST, ast.Name] = dataclasses.field(default_factory=dict[ast.AST, ast.Name])
|
|
93
93
|
"""Maps dataclass attribute access expressions to field name nodes for find-replace operations."""
|
|
94
94
|
|
|
95
95
|
repack: ast.Assign = dummyAssign
|
|
@@ -11,42 +11,39 @@ on empirical measurements and theoretical analysis of map folding algorithms for
|
|
|
11
11
|
specific dimensional configurations.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
dataclassInstanceIdentifierDEFAULT: str = 'state'
|
|
18
|
-
"""Default variable name for dataclass instances in generated code."""
|
|
19
|
-
|
|
20
|
-
dataPackingModuleIdentifierDEFAULT: str = 'dataPacking'
|
|
21
|
-
"""Default identifier for modules containing data packing and unpacking functions."""
|
|
22
|
-
|
|
23
|
-
logicalPathInfixDEFAULT: str = 'syntheticModules'
|
|
24
|
-
"""Default path component for organizing synthetic generated modules."""
|
|
25
|
-
|
|
26
|
-
sourceCallableDispatcherDEFAULT: str = 'doTheNeedful'
|
|
27
|
-
"""Default identifier for dispatcher functions that route computational tasks."""
|
|
28
|
-
|
|
29
|
-
sourceCallableIdentifierDEFAULT: str = 'count'
|
|
30
|
-
"""Default identifier for the core counting function in algorithms."""
|
|
14
|
+
from hunterMakesPy import identifierDotAttribute
|
|
15
|
+
from typing import Final
|
|
31
16
|
|
|
32
|
-
|
|
33
|
-
"""Default identifier for the primary counting variable in map folding computations."""
|
|
34
|
-
|
|
35
|
-
dictionaryEstimates: dict[tuple[int, ...], int] = {
|
|
17
|
+
dictionaryEstimatesMapFolding: Final[dict[tuple[int, ...], int]] = {
|
|
36
18
|
(2,2,2,2,2,2,2,2): 798148657152000,
|
|
37
19
|
(2,21): 776374224866624,
|
|
38
20
|
(3,15): 824761667826225,
|
|
39
21
|
(3,3,3,3): 85109616000000000000000000000000,
|
|
40
22
|
(8,8): 791274195985524900,
|
|
41
23
|
}
|
|
42
|
-
"""
|
|
43
|
-
Registry of computational complexity estimates for specific map dimension configurations.
|
|
24
|
+
"""Estimates of multidimensional map folding `foldsTotal`."""
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
26
|
+
identifierCallableSourceDEFAULT: Final[str] = 'count'
|
|
27
|
+
"""Default identifier for the core counting function in algorithms."""
|
|
28
|
+
|
|
29
|
+
identifierCallableSourceDispatcherDEFAULT: Final[str] = 'doTheNeedful'
|
|
30
|
+
"""Default identifier for dispatcher functions that route computational tasks."""
|
|
31
|
+
|
|
32
|
+
identifierCountingDEFAULT: Final[str] = 'groupsOfFolds'
|
|
33
|
+
"""Default identifier for the primary counting variable in map folding computations."""
|
|
34
|
+
|
|
35
|
+
identifierDataclassInstanceDEFAULT: Final[str] = 'state'
|
|
36
|
+
"""Default variable name for dataclass instances in generated code."""
|
|
37
|
+
|
|
38
|
+
identifierModuleDataPackingDEFAULT: Final[str] = 'dataPacking'
|
|
39
|
+
"""Default identifier for modules containing data packing and unpacking functions."""
|
|
40
|
+
|
|
41
|
+
identifierModuleSourceAlgorithmDEFAULT: Final[str] = 'daoOfMapFolding'
|
|
42
|
+
"""Default identifier for the algorithm source module containing the base implementation."""
|
|
43
|
+
|
|
44
|
+
logicalPathInfixAlgorithmDEFAULT: Final[identifierDotAttribute] = 'algorithms'
|
|
45
|
+
"""Default logical path component for handmade algorithms."""
|
|
46
|
+
|
|
47
|
+
logicalPathInfixDEFAULT: Final[identifierDotAttribute] = 'syntheticModules'
|
|
48
|
+
"""Default logical path component for organizing synthetic generated modules."""
|
|
48
49
|
|
|
49
|
-
The estimates represent the expected number of computational operations or fold
|
|
50
|
-
configurations for the given map dimensions, helping determine appropriate optimization
|
|
51
|
-
strategies and computational resource allocation.
|
|
52
|
-
"""
|
|
@@ -33,7 +33,8 @@ from astToolkit import (
|
|
|
33
33
|
NodeChanger, NodeTourist, Then)
|
|
34
34
|
from astToolkit.transformationTools import write_astModule
|
|
35
35
|
from hunterMakesPy import autoDecodingRLE, raiseIfNone
|
|
36
|
-
from mapFolding import getPathFilenameFoldsTotal,
|
|
36
|
+
from mapFolding import getPathFilenameFoldsTotal, packageSettings
|
|
37
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
37
38
|
from mapFolding.someAssemblyRequired import IfThis
|
|
38
39
|
from mapFolding.someAssemblyRequired.RecipeJob import RecipeJobTheorem2
|
|
39
40
|
from mapFolding.someAssemblyRequired.toolkitNumba import decorateCallableWithNumba, parametersNumbaLight, SpicesJobNumba
|
|
@@ -161,9 +162,9 @@ def move_arg2FunctionDefDOTbodyAndAssignInitialValues(ingredientsFunction: Ingre
|
|
|
161
162
|
ImaAnnAssign, elementConstructor = job.shatteredDataclass.Z0Z_field2AnnAssign[ast_arg.arg]
|
|
162
163
|
match elementConstructor:
|
|
163
164
|
case 'scalar':
|
|
164
|
-
cast('ast.Constant', cast('ast.Call', ImaAnnAssign.value).args[0]).value = int(job.state.
|
|
165
|
+
cast('ast.Constant', cast('ast.Call', ImaAnnAssign.value).args[0]).value = int(eval(f"job.state.{ast_arg.arg}")) # noqa: S307
|
|
165
166
|
case 'array':
|
|
166
|
-
dataAsStrRLE: str = autoDecodingRLE(job.state.
|
|
167
|
+
dataAsStrRLE: str = autoDecodingRLE(eval(f"job.state.{ast_arg.arg}"), assumeAddSpaces=True) # noqa: S307
|
|
167
168
|
dataAs_astExpr: ast.expr = cast('ast.Expr', ast.parse(dataAsStrRLE).body[0]).value
|
|
168
169
|
cast('ast.Call', ImaAnnAssign.value).args = [dataAs_astExpr]
|
|
169
170
|
case _:
|
|
@@ -220,7 +221,7 @@ def makeJobNumba(job: RecipeJobTheorem2, spices: SpicesJobNumba) -> None:
|
|
|
220
221
|
listIdentifiersStaticValues: list[str] = listIdentifiersStaticValuesHARDCODED
|
|
221
222
|
for identifier in listIdentifiersStaticValues:
|
|
222
223
|
findThis: Callable[[ast.AST], TypeIs[ast.Name] | bool] = IfThis.isNameIdentifier(identifier)
|
|
223
|
-
doThat: Callable[[ast.Name], ast.Constant] = Then.replaceWith(Make.Constant(int(job.state.
|
|
224
|
+
doThat: Callable[[ast.Name], ast.Constant] = Then.replaceWith(Make.Constant(int(eval(f"job.state.{identifier}")))) # noqa: S307
|
|
224
225
|
NodeChanger(findThis, doThat).visit(ingredientsCount.astFunctionDef)
|
|
225
226
|
|
|
226
227
|
ingredientsModule = IngredientsModule()
|
|
@@ -326,7 +327,7 @@ if __name__ == '__main__':
|
|
|
326
327
|
"""
|
|
327
328
|
|
|
328
329
|
if __name__ == '__main__':
|
|
329
|
-
state = transitionOnGroupsOfFolds(MapFoldingState((
|
|
330
|
+
state = transitionOnGroupsOfFolds(MapFoldingState((1,27)))
|
|
330
331
|
pathModule = PurePosixPath(packageSettings.pathPackage, 'jobs')
|
|
331
332
|
pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(state.mapShape, pathModule))
|
|
332
333
|
aJob = RecipeJobTheorem2(state, pathModule=pathModule, pathFilenameFoldsTotal=pathFilenameFoldsTotal)
|
|
@@ -8,10 +8,11 @@ from astToolkit import (
|
|
|
8
8
|
NodeTourist, parseLogicalPath2astModule, Then)
|
|
9
9
|
from astToolkit.transformationTools import removeUnusedParameters, write_astModule
|
|
10
10
|
from hunterMakesPy import autoDecodingRLE, raiseIfNone
|
|
11
|
-
from mapFolding import DatatypeLeavesTotal, getPathFilenameFoldsTotal
|
|
11
|
+
from mapFolding import DatatypeLeavesTotal, getPathFilenameFoldsTotal
|
|
12
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
12
13
|
from mapFolding.someAssemblyRequired import IfThis
|
|
13
14
|
from mapFolding.someAssemblyRequired.RecipeJob import RecipeJobTheorem2
|
|
14
|
-
from mapFolding.syntheticModules.
|
|
15
|
+
from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds
|
|
15
16
|
from pathlib import Path, PurePosixPath
|
|
16
17
|
from typing import cast, NamedTuple, TYPE_CHECKING
|
|
17
18
|
import ast
|
|
@@ -100,7 +101,8 @@ def _variableCompatibility(ingredientsFunction: IngredientsFunction, job: Recipe
|
|
|
100
101
|
# `identifier` in Augmented Assignment, or in Assignments and value is Constant.
|
|
101
102
|
NodeChanger(findThis=IfThis.isAnyOf(
|
|
102
103
|
Be.AugAssign.targetIs(IfThis.isNestedNameIdentifier(identifier))
|
|
103
|
-
, IfThis.isAllOf(
|
|
104
|
+
, IfThis.isAllOf(
|
|
105
|
+
Be.Assign.targetsIs(Be.at(0, IfThis.isNestedNameIdentifier(identifier)))
|
|
104
106
|
, Be.Assign.valueIs(Be.Constant))
|
|
105
107
|
)
|
|
106
108
|
, doThat=lambda node, annotation=annotation: Grab.valueAttribute(Then.replaceWith(Make.Call(annotation, listParameters=[node.value])))(node)
|
|
@@ -220,6 +222,6 @@ def fromMapShape(mapShape: tuple[DatatypeLeavesTotal, ...]) -> None:
|
|
|
220
222
|
makeJob(aJob)
|
|
221
223
|
|
|
222
224
|
if __name__ == '__main__':
|
|
223
|
-
mapShape = (1,
|
|
225
|
+
mapShape = (1, 3)
|
|
224
226
|
fromMapShape(mapShape)
|
|
225
227
|
|