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.
Files changed (83) hide show
  1. easyRun/A000682.py +25 -0
  2. easyRun/A005316.py +21 -0
  3. easyRun/NOTcountingFolds.py +36 -0
  4. easyRun/__init__.py +0 -0
  5. easyRun/countFolds.py +41 -0
  6. easyRun/meanders.py +71 -0
  7. mapFolding/__init__.py +10 -55
  8. mapFolding/_dataPacking.py +68 -0
  9. mapFolding/_theSSOT.py +33 -36
  10. mapFolding/_theTypes.py +21 -4
  11. mapFolding/algorithms/daoOfMapFolding.py +1 -2
  12. mapFolding/algorithms/matrixMeanders.py +101 -348
  13. mapFolding/algorithms/matrixMeandersBeDry.py +264 -0
  14. mapFolding/algorithms/matrixMeandersNumPy.py +286 -0
  15. mapFolding/algorithms/matrixMeandersPandas.py +351 -0
  16. mapFolding/algorithms/oeisIDbyFormula.py +320 -76
  17. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +92 -0
  18. mapFolding/basecamp.py +261 -113
  19. mapFolding/beDRY.py +2 -30
  20. mapFolding/dataBaskets.py +120 -4
  21. mapFolding/oeis.py +13 -33
  22. mapFolding/reference/A000682facts.py +1276 -0
  23. mapFolding/reference/A005316facts.py +985 -0
  24. mapFolding/reference/matrixMeandersAnalysis/__init__.py +1 -0
  25. mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +15 -0
  26. mapFolding/reference/meandersDumpingGround/A005316JavaPort.py +1 -1
  27. mapFolding/reference/meandersDumpingGround/A005316imperative.py +1 -1
  28. mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +424 -0
  29. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +54 -0
  30. mapFolding/someAssemblyRequired/A007822/__init__.py +0 -0
  31. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +197 -0
  32. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +74 -0
  33. mapFolding/someAssemblyRequired/RecipeJob.py +4 -4
  34. mapFolding/someAssemblyRequired/__init__.py +9 -2
  35. mapFolding/someAssemblyRequired/_toolIfThis.py +4 -3
  36. mapFolding/someAssemblyRequired/_toolkitContainers.py +8 -8
  37. mapFolding/someAssemblyRequired/infoBooth.py +27 -30
  38. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +6 -5
  39. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +6 -4
  40. mapFolding/someAssemblyRequired/makingModules_count.py +294 -0
  41. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +117 -0
  42. mapFolding/someAssemblyRequired/mapFolding/__init__.py +0 -0
  43. mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +220 -0
  44. mapFolding/someAssemblyRequired/meanders/__init__.py +0 -0
  45. mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +64 -0
  46. mapFolding/someAssemblyRequired/toolkitMakeModules.py +152 -0
  47. mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
  48. mapFolding/someAssemblyRequired/transformationTools.py +1 -0
  49. mapFolding/syntheticModules/A007822/__init__.py +1 -0
  50. mapFolding/syntheticModules/{algorithmA007822.py → A007822/algorithm.py} +2 -3
  51. mapFolding/syntheticModules/{algorithmA007822Numba.py → A007822/algorithmNumba.py} +3 -6
  52. mapFolding/syntheticModules/A007822/asynchronous.py +148 -0
  53. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +66 -0
  54. mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +85 -0
  55. mapFolding/syntheticModules/A007822/asynchronousNumba.py +52 -0
  56. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +53 -0
  57. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +47 -0
  58. mapFolding/syntheticModules/{initializeStateA007822.py → A007822/initializeState.py} +1 -2
  59. mapFolding/syntheticModules/{theorem2A007822.py → A007822/theorem2.py} +1 -2
  60. mapFolding/syntheticModules/{theorem2A007822Numba.py → A007822/theorem2Numba.py} +6 -4
  61. mapFolding/syntheticModules/{theorem2A007822Trimmed.py → A007822/theorem2Trimmed.py} +1 -2
  62. mapFolding/syntheticModules/countParallelNumba.py +5 -2
  63. mapFolding/syntheticModules/daoOfMapFoldingNumba.py +4 -2
  64. mapFolding/syntheticModules/dataPacking.py +4 -2
  65. mapFolding/syntheticModules/dataPackingA007822.py +92 -26
  66. mapFolding/syntheticModules/meanders/__init__.py +1 -0
  67. mapFolding/syntheticModules/meanders/bigInt.py +62 -0
  68. mapFolding/syntheticModules/theorem2Numba.py +3 -2
  69. mapFolding/tests/conftest.py +28 -13
  70. mapFolding/tests/test_computations.py +69 -62
  71. mapFolding/tests/test_oeis.py +6 -6
  72. mapFolding/zCuzDocStoopid/__init__.py +4 -0
  73. mapFolding/zCuzDocStoopid/makeDocstrings.py +68 -0
  74. mapfolding-0.16.1.dist-info/METADATA +99 -0
  75. mapfolding-0.16.1.dist-info/RECORD +114 -0
  76. {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/top_level.txt +1 -0
  77. mapFolding/someAssemblyRequired/A007822rawMaterials.py +0 -46
  78. mapFolding/someAssemblyRequired/makeAllModules.py +0 -764
  79. mapfolding-0.15.4.dist-info/METADATA +0 -78
  80. mapfolding-0.15.4.dist-info/RECORD +0 -78
  81. {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/WHEEL +0 -0
  82. {mapfolding-0.15.4.dist-info → mapfolding-0.16.1.dist-info}/entry_points.txt +0 -0
  83. {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, MapFoldingState,
8
- packageSettings)
9
- from mapFolding.someAssemblyRequired import dataclassInstanceIdentifierDEFAULT, ShatteredDataclass
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 = dataclassInstanceIdentifierDEFAULT
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
- dataclassInstanceIdentifierDEFAULT as dataclassInstanceIdentifierDEFAULT,
77
- sourceCallableDispatcherDEFAULT as sourceCallableDispatcherDEFAULT,
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(lambda at: Be.LtE(at[0]))(node)
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.Gt(node.ops[0])
98
- and IfThis.isConstant_value(0)(node.comparators[0]))
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=lambda: dict[str, ast.AnnAssign | ast.Assign]())
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=lambda: dict[str, tuple[ast.AnnAssign | ast.Assign, str]]())
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=lambda: list[ast.arg]())
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=lambda: list[ast.keyword]())
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=lambda: list[ast.expr]())
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=lambda: list[ast.Name]())
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=lambda: list[ast.AnnAssign]())
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=lambda: dict[ast.AST, ast.Name]())
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
- algorithmSourceModuleDEFAULT: str = 'daoOfMapFolding'
15
- """Default identifier for the algorithm source module containing the base implementation."""
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
- theCountingIdentifierDEFAULT: str = 'groupsOfFolds'
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
- Maps dimensional tuples to estimated fold counts based on empirical measurements and
46
- theoretical analysis. These estimates guide optimization decisions and resource planning
47
- for computational tasks with known dimensional parameters.
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, MapFoldingState, packageSettings
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.__dict__[ast_arg.arg])
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.__dict__[ast_arg.arg], assumeAddSpaces=True)
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.__dict__[identifier])))
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((2,4)))
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, MapFoldingState
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.initializeStateA007822 import transitionOnGroupsOfFolds
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(IfThis.isAssignAndTargets0Is(IfThis.isNameIdentifier(identifier))
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, 15)
225
+ mapShape = (1, 3)
224
226
  fromMapShape(mapShape)
225
227