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,294 @@
1
+ """Make the `count` function for an algorithm.
2
+
3
+ These transformation functions will work on at least two different algorithms. If a transformation function only works on a
4
+ specific type of algorithm, it will be in a subdirectory.
5
+ """
6
+ from astToolkit import (
7
+ astModuleToIngredientsFunction, Be, DOT, Grab, identifierDotAttribute, IngredientsFunction, IngredientsModule,
8
+ LedgerOfImports, Make, NodeChanger, NodeTourist, Then)
9
+ from astToolkit.transformationTools import inlineFunctionDef, removeUnusedParameters, write_astModule
10
+ from hunterMakesPy import raiseIfNone
11
+ from mapFolding import packageSettings
12
+ from mapFolding.someAssemblyRequired import (
13
+ identifierCallableSourceDEFAULT, identifierCountingDEFAULT, IfThis, ShatteredDataclass)
14
+ from mapFolding.someAssemblyRequired.A007822.A007822rawMaterials import astExprCall_filterAsymmetricFoldsLeafBelow
15
+ from mapFolding.someAssemblyRequired.toolkitMakeModules import findDataclass, getPathFilename
16
+ from mapFolding.someAssemblyRequired.toolkitNumba import decorateCallableWithNumba, parametersNumbaLight
17
+ from mapFolding.someAssemblyRequired.transformationTools import (
18
+ removeDataclassFromFunction, shatter_dataclassesDOTdataclass, unpackDataclassCallFunctionRepackDataclass)
19
+ from os import PathLike
20
+ from pathlib import PurePath
21
+ from typing import cast
22
+ import ast
23
+
24
+ def makeDaoOfMapFoldingNumba(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
25
+ """Generate Numba-optimized sequential implementation of map folding algorithm.
26
+
27
+ (AI generated docstring)
28
+
29
+ Creates a high-performance sequential version of the map folding algorithm by
30
+ decomposing dataclass parameters into individual primitive values, removing
31
+ dataclass dependencies that are incompatible with Numba, applying Numba
32
+ decorators for just-in-time compilation, and optionally including a dispatcher
33
+ function for dataclass integration.
34
+
35
+ The generated module provides significant performance improvements over the
36
+ original dataclass-based implementation while maintaining algorithmic correctness.
37
+ The transformation preserves all computational logic while restructuring data
38
+ access patterns for optimal Numba compilation.
39
+
40
+ Parameters
41
+ ----------
42
+ astModule : ast.Module
43
+ Source module containing the base algorithm.
44
+ moduleIdentifier : str
45
+ Name for the generated optimized module.
46
+ callableIdentifier : str | None = None
47
+ Name for the main computational function.
48
+ logicalPathInfix : PathLike[str] | PurePath | str | None = None
49
+ Directory path for organizing the generated module.
50
+ sourceCallableDispatcher : str | None = None
51
+ Optional dispatcher function for dataclass integration.
52
+
53
+ Returns
54
+ -------
55
+ pathFilename : PurePath
56
+ Filesystem path where the optimized module was written.
57
+
58
+ """
59
+ sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDEFAULT
60
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
61
+ ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
62
+
63
+ shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
64
+
65
+ ingredientsFunction.imports.update(shatteredDataclass.imports)
66
+ ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclass)
67
+ ingredientsFunction = removeUnusedParameters(ingredientsFunction)
68
+ ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
69
+
70
+ ingredientsModule = IngredientsModule(ingredientsFunction)
71
+
72
+ if sourceCallableDispatcher is not None:
73
+
74
+ ingredientsFunctionDispatcher: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableDispatcher)
75
+ ingredientsFunctionDispatcher.imports.update(shatteredDataclass.imports)
76
+ targetCallableIdentifier = ingredientsFunction.astFunctionDef.name
77
+ ingredientsFunctionDispatcher = unpackDataclassCallFunctionRepackDataclass(ingredientsFunctionDispatcher, targetCallableIdentifier, shatteredDataclass)
78
+ astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
79
+ , doThat=Then.extractIt(DOT.value)).captureLastMatch(ingredientsFunction.astFunctionDef)))
80
+ astTuple.ctx = Make.Store()
81
+
82
+ changeAssignCallToTarget = NodeChanger(
83
+ findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
84
+ , doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts))))
85
+ changeAssignCallToTarget.visit(ingredientsFunctionDispatcher.astFunctionDef)
86
+
87
+ ingredientsModule.appendIngredientsFunction(ingredientsFunctionDispatcher)
88
+
89
+ ingredientsModule.removeImportFromModule('numpy')
90
+
91
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
92
+
93
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
94
+
95
+ return pathFilename
96
+
97
+ def makeTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
98
+ """Generate module by applying optimization predicted by Theorem 2.
99
+
100
+ Parameters
101
+ ----------
102
+ astModule : ast.Module
103
+ Source module containing the base algorithm.
104
+ moduleIdentifier : str
105
+ Name for the generated theorem-optimized module.
106
+ callableIdentifier : str | None = None
107
+ Name for the optimized computational function.
108
+ logicalPathInfix : PathLike[str] | PurePath | str | None = None
109
+ Directory path for organizing the generated module.
110
+ sourceCallableDispatcher : str | None = None
111
+ Currently not implemented for this transformation.
112
+
113
+ Returns
114
+ -------
115
+ pathFilename : PurePath
116
+ Filesystem path where the theorem-optimized module was written.
117
+
118
+ Raises
119
+ ------
120
+ NotImplementedError
121
+ If `sourceCallableDispatcher` is provided.
122
+
123
+ """
124
+ sourceCallableIdentifier = identifierCallableSourceDEFAULT
125
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
126
+ ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
127
+
128
+ dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
129
+
130
+ theCountingIdentifier: identifierDotAttribute = identifierCountingDEFAULT
131
+ doubleTheCount: ast.AugAssign = Make.AugAssign(Make.Attribute(Make.Name(dataclassInstanceIdentifier), theCountingIdentifier), Make.Mult(), Make.Constant(2))
132
+
133
+ NodeChanger(
134
+ findThis = IfThis.isAllOf(
135
+ IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
136
+ , Be.While.orelseIs(lambda ImaList: ImaList))
137
+ , doThat = Grab.orelseAttribute(Grab.index(0, Then.insertThisBelow([doubleTheCount])))
138
+ ).visit(ingredientsFunction.astFunctionDef)
139
+
140
+ NodeChanger(
141
+ findThis = IfThis.isAllOf(
142
+ IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
143
+ , Be.While.orelseIs(lambda ImaList: not ImaList))
144
+ , doThat = Grab.orelseAttribute(Then.replaceWith([doubleTheCount]))
145
+ ).visit(ingredientsFunction.astFunctionDef)
146
+
147
+ NodeChanger(
148
+ findThis = IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
149
+ , doThat = Grab.testAttribute(Grab.comparatorsAttribute(Then.replaceWith([Make.Constant(4)])))
150
+ ).visit(ingredientsFunction.astFunctionDef)
151
+
152
+ insertLeaf = NodeTourist(
153
+ findThis = IfThis.isIfAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
154
+ , doThat = Then.extractIt(DOT.body)
155
+ ).captureLastMatch(ingredientsFunction.astFunctionDef)
156
+ NodeChanger(
157
+ findThis = IfThis.isIfAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
158
+ , doThat = Then.replaceWith(insertLeaf)
159
+ ).visit(ingredientsFunction.astFunctionDef)
160
+
161
+ NodeChanger(
162
+ findThis = IfThis.isAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
163
+ , doThat = Then.removeIt
164
+ ).visit(ingredientsFunction.astFunctionDef)
165
+
166
+ NodeChanger(
167
+ findThis = IfThis.isAttributeNamespaceIdentifierLessThanOrEqual0(dataclassInstanceIdentifier, 'leaf1ndex')
168
+ , doThat = Then.removeIt
169
+ ).visit(ingredientsFunction.astFunctionDef)
170
+
171
+ ingredientsModule = IngredientsModule(ingredientsFunction)
172
+
173
+ if sourceCallableDispatcher is not None:
174
+ message = 'sourceCallableDispatcher is not implemented yet'
175
+ raise NotImplementedError(message)
176
+
177
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
178
+
179
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
180
+
181
+ return pathFilename
182
+
183
+ def numbaOnTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
184
+ """Generate Numba-accelerated Theorem 2 implementation with dataclass decomposition.
185
+
186
+ (AI generated docstring)
187
+
188
+ Creates a highly optimized version of the Theorem 2 algorithm by combining the
189
+ mathematical optimizations of Theorem 2 with Numba just-in-time compilation.
190
+ The transformation includes dataclass decomposition to convert structured
191
+ parameters into primitives, removal of Python object dependencies incompatible
192
+ with Numba, application of Numba decorators for maximum performance, and type
193
+ annotation optimization for efficient compilation.
194
+
195
+ This represents the highest level of optimization available for Theorem 2
196
+ implementations, providing both mathematical efficiency through theorem
197
+ application and computational efficiency through Numba acceleration.
198
+ The result is suitable for production use in high-performance computing
199
+ environments where maximum speed is required.
200
+
201
+ Parameters
202
+ ----------
203
+ astModule : ast.Module
204
+ Source module containing the Theorem 2 implementation.
205
+ moduleIdentifier : str
206
+ Name for the generated Numba-accelerated module.
207
+ callableIdentifier : str | None = None
208
+ Name for the accelerated computational function.
209
+ logicalPathInfix : PathLike[str] | PurePath | str | None = None
210
+ Directory path for organizing the generated module.
211
+ sourceCallableDispatcher : str | None = None
212
+ Optional dispatcher function identifier (unused).
213
+
214
+ Returns
215
+ -------
216
+ pathFilename : PurePath
217
+ Filesystem path where the accelerated module was written.
218
+
219
+ """
220
+ sourceCallableIdentifier = identifierCallableSourceDEFAULT
221
+ if callableIdentifier is None:
222
+ callableIdentifier = sourceCallableIdentifier
223
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
224
+ ingredientsFunction.astFunctionDef.name = callableIdentifier
225
+
226
+ shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
227
+
228
+ ingredientsFunction.imports.update(shatteredDataclass.imports)
229
+ ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclass)
230
+ ingredientsFunction = removeUnusedParameters(ingredientsFunction)
231
+ ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
232
+
233
+ ingredientsModule = IngredientsModule(ingredientsFunction)
234
+ ingredientsModule.removeImportFromModule('numpy')
235
+
236
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
237
+
238
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
239
+
240
+ return pathFilename
241
+
242
+ def trimTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
243
+ """Generate constrained Theorem 2 implementation by removing unnecessary logic.
244
+
245
+ (AI generated docstring)
246
+
247
+ Creates a trimmed version of the Theorem 2 implementation by eliminating conditional logic that is not needed under specific
248
+ constraint assumptions. This transformation removes checks for unconstrained dimensions, simplifying the algorithm for cases
249
+ where dimensional constraints are guaranteed to be satisfied by external conditions.
250
+
251
+ The trimming operation is particularly valuable for generating lean implementations where the calling context ensures that
252
+ certain conditions will always be met, allowing the removal of defensive programming constructs that add computational
253
+ overhead without providing benefits in the constrained environment.
254
+
255
+ Parameters
256
+ ----------
257
+ astModule : ast.Module
258
+ Source module containing the Theorem 2 implementation.
259
+ moduleIdentifier : str
260
+ Name for the generated trimmed module.
261
+ callableIdentifier : str | None = None
262
+ Name for the trimmed computational function.
263
+ logicalPathInfix : PathLike[str] | PurePath | str | None = None
264
+ Directory path for organizing the generated module.
265
+ sourceCallableDispatcher : str | None = None
266
+ Optional dispatcher function identifier (unused).
267
+
268
+ Returns
269
+ -------
270
+ pathFilename : PurePath
271
+ Filesystem path where the trimmed module was written.
272
+
273
+ """
274
+ sourceCallableIdentifier = identifierCallableSourceDEFAULT
275
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
276
+ ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
277
+
278
+ dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
279
+
280
+ findThis = IfThis.isIfUnaryNotAttributeNamespaceIdentifier(dataclassInstanceIdentifier, 'dimensionsUnconstrained')
281
+ doThat = Then.removeIt
282
+ NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
283
+
284
+ ingredientsModule = IngredientsModule(ingredientsFunction)
285
+ ingredientsModule.removeImportFromModule('numpy')
286
+
287
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
288
+
289
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
290
+
291
+ return pathFilename
292
+
293
+
294
+
@@ -0,0 +1,117 @@
1
+ """Make functions that are complementary to the `count` function and are often called by `doTheNeedful`."""
2
+ from astToolkit import (
3
+ astModuleToIngredientsFunction, Be, DOT, extractFunctionDef, Grab, identifierDotAttribute, IngredientsFunction,
4
+ IngredientsModule, LedgerOfImports, Make, NodeChanger, NodeTourist, parseLogicalPath2astModule, Then)
5
+ from astToolkit.transformationTools import inlineFunctionDef, write_astModule
6
+ from hunterMakesPy import raiseIfNone
7
+ from mapFolding import packageSettings
8
+ from mapFolding.someAssemblyRequired import (
9
+ identifierCallableSourceDEFAULT, identifierCallableSourceDispatcherDEFAULT, identifierCountingDEFAULT,
10
+ identifierModuleDataPackingDEFAULT, identifierModuleSourceAlgorithmDEFAULT, IfThis, logicalPathInfixAlgorithmDEFAULT,
11
+ logicalPathInfixDEFAULT, ShatteredDataclass)
12
+ from mapFolding.someAssemblyRequired.toolkitMakeModules import findDataclass, getPathFilename
13
+ from mapFolding.someAssemblyRequired.transformationTools import (
14
+ shatter_dataclassesDOTdataclass, unpackDataclassCallFunctionRepackDataclass)
15
+ from os import PathLike
16
+ from pathlib import PurePath
17
+ from typing import cast
18
+ import ast
19
+
20
+ def makeInitializeState(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
21
+ """Generate initialization module for counting variable setup.
22
+
23
+ (AI generated docstring)
24
+
25
+ Creates a specialized module containing initialization logic for the counting variables
26
+ used in map folding computations. The generated function transforms the original
27
+ algorithm's loop conditions to use equality comparisons instead of greater-than
28
+ comparisons, optimizing the initialization phase.
29
+
30
+ This transformation is particularly important for ensuring that counting variables
31
+ are properly initialized before the main computational loops begin executing.
32
+
33
+ Parameters
34
+ ----------
35
+ astModule : ast.Module
36
+ Source module containing the base algorithm.
37
+ moduleIdentifier : str
38
+ Name for the generated initialization module.
39
+ callableIdentifier : str | None = None
40
+ Name for the initialization function.
41
+ logicalPathInfix : PathLike[str] | PurePath | str | None = None
42
+ Directory path for organizing the generated module.
43
+ sourceCallableDispatcher : str | None = None
44
+ Optional dispatcher function identifier.
45
+
46
+ Returns
47
+ -------
48
+ pathFilename : PurePath
49
+ Filesystem path where the initialization module was written.
50
+
51
+ """
52
+ sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDEFAULT
53
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
54
+ ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
55
+
56
+ dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
57
+ theCountingIdentifier: identifierDotAttribute = identifierCountingDEFAULT
58
+
59
+ findThis = IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
60
+ doThat = Grab.testAttribute(Grab.andDoAllOf([Grab.opsAttribute(Then.replaceWith([ast.Eq()])), Grab.leftAttribute(Grab.attrAttribute(Then.replaceWith(theCountingIdentifier)))]))
61
+ NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef.body[0])
62
+
63
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
64
+ write_astModule(IngredientsModule(ingredientsFunction), pathFilename, packageSettings.identifierPackage)
65
+
66
+ return pathFilename
67
+
68
+ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom, moduleIdentifier: str = identifierModuleDataPackingDEFAULT) -> None:
69
+ """Generate interface module for dataclass unpacking and repacking operations.
70
+
71
+ Parameters
72
+ ----------
73
+ astImportFrom : ast.ImportFrom
74
+ Import statement specifying the target optimized function to call.
75
+
76
+ Returns
77
+ -------
78
+ None
79
+ The generated module is written directly to the filesystem.
80
+
81
+ """
82
+ callableIdentifierHARDCODED: str = 'sequential'
83
+
84
+ algorithmSourceModule: identifierDotAttribute = identifierModuleSourceAlgorithmDEFAULT
85
+ callableIdentifier: identifierDotAttribute = callableIdentifierHARDCODED
86
+ logicalPathInfix: identifierDotAttribute = logicalPathInfixDEFAULT
87
+ logicalPathInfixAlgorithm: identifierDotAttribute = logicalPathInfixAlgorithmDEFAULT
88
+ sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDispatcherDEFAULT
89
+
90
+ logicalPathSourceModule: identifierDotAttribute = '.'.join([packageSettings.identifierPackage, logicalPathInfixAlgorithm, algorithmSourceModule]) # noqa: FLY002
91
+
92
+ ingredientsFunction: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
93
+ ingredientsFunction.astFunctionDef.name = callableIdentifier
94
+
95
+ shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
96
+
97
+ ingredientsFunction.imports.update(shatteredDataclass.imports)
98
+ ingredientsFunction.imports.addAst(astImportFrom)
99
+ targetCallableIdentifier: str = astImportFrom.names[0].name
100
+ ingredientsFunction = raiseIfNone(unpackDataclassCallFunctionRepackDataclass(ingredientsFunction, targetCallableIdentifier, shatteredDataclass))
101
+ targetFunctionDef: ast.FunctionDef = raiseIfNone(extractFunctionDef(parseLogicalPath2astModule(raiseIfNone(astImportFrom.module)), targetCallableIdentifier))
102
+ astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
103
+ , doThat=Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)))
104
+ astTuple.ctx = Make.Store()
105
+
106
+ changeAssignCallToTarget = NodeChanger(
107
+ findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
108
+ , doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts))))
109
+ changeAssignCallToTarget.visit(ingredientsFunction.astFunctionDef)
110
+
111
+ ingredientsModule = IngredientsModule(ingredientsFunction)
112
+ ingredientsModule.removeImportFromModule('numpy')
113
+
114
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
115
+
116
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
117
+
File without changes
@@ -0,0 +1,220 @@
1
+ """makeMapFoldingModules."""
2
+ from astToolkit import (
3
+ astModuleToIngredientsFunction, Be, DOT, extractClassDef, Grab, hasDOTbody, identifierDotAttribute,
4
+ IngredientsFunction, IngredientsModule, LedgerOfImports, Make, NodeChanger, NodeTourist, parseLogicalPath2astModule,
5
+ parsePathFilename2astModule, Then)
6
+ from astToolkit.transformationTools import inlineFunctionDef, removeUnusedParameters, write_astModule
7
+ from hunterMakesPy import importLogicalPath2Identifier, raiseIfNone
8
+ from mapFolding import packageSettings
9
+ from mapFolding.someAssemblyRequired import (
10
+ DeReConstructField2ast, identifierCallableSourceDEFAULT, identifierCallableSourceDispatcherDEFAULT, IfThis,
11
+ logicalPathInfixDEFAULT, ShatteredDataclass)
12
+ from mapFolding.someAssemblyRequired.makingModules_count import (
13
+ makeDaoOfMapFoldingNumba, makeTheorem2, numbaOnTheorem2, trimTheorem2)
14
+ from mapFolding.someAssemblyRequired.makingModules_doTheNeedful import makeInitializeState, makeUnRePackDataclass
15
+ from mapFolding.someAssemblyRequired.toolkitMakeModules import getLogicalPath, getModule, getPathFilename
16
+ from mapFolding.someAssemblyRequired.toolkitNumba import decorateCallableWithNumba, parametersNumbaLight
17
+ from mapFolding.someAssemblyRequired.transformationTools import (
18
+ removeDataclassFromFunction, shatter_dataclassesDOTdataclass, unpackDataclassCallFunctionRepackDataclass)
19
+ from os import PathLike
20
+ from pathlib import PurePath
21
+ from typing import Any, TYPE_CHECKING
22
+ import ast
23
+ import dataclasses
24
+
25
+ if TYPE_CHECKING:
26
+ from collections.abc import Sequence
27
+
28
+ def makeDaoOfMapFoldingParallelNumba(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
29
+ """Generate parallel implementation with concurrent execution and task division.
30
+
31
+ Parameters
32
+ ----------
33
+ astModule : ast.Module
34
+ Source module containing the base algorithm.
35
+ moduleIdentifier : str
36
+ Name for the generated parallel module.
37
+ callableIdentifier : str | None = None
38
+ Name for the core parallel counting function.
39
+ logicalPathInfix : PathLike[str] | PurePath | str | None = None
40
+ Directory path for organizing the generated module.
41
+ sourceCallableDispatcher : str | None = None
42
+ Optional dispatcher function identifier.
43
+
44
+ Returns
45
+ -------
46
+ pathFilename : PurePath
47
+ Filesystem path where the parallel module was written.
48
+
49
+ """
50
+ sourceCallableIdentifier = identifierCallableSourceDEFAULT
51
+ if callableIdentifier is None:
52
+ callableIdentifier = sourceCallableIdentifier
53
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
54
+ ingredientsFunction.astFunctionDef.name = callableIdentifier
55
+
56
+ dataclassName: ast.expr = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(ingredientsFunction.astFunctionDef))
57
+ dataclassIdentifier: str = raiseIfNone(NodeTourist(Be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName))
58
+
59
+ dataclassLogicalPathModule = None
60
+ for moduleWithLogicalPath, listNameTuples in ingredientsFunction.imports._dictionaryImportFrom.items(): # noqa: SLF001
61
+ for nameTuple in listNameTuples:
62
+ if nameTuple[0] == dataclassIdentifier:
63
+ dataclassLogicalPathModule = moduleWithLogicalPath
64
+ break
65
+ if dataclassLogicalPathModule:
66
+ break
67
+ if dataclassLogicalPathModule is None:
68
+ raise Exception # noqa: TRY002
69
+ dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
70
+ shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclassIdentifier, dataclassInstanceIdentifier)
71
+
72
+ # START add the parallel state fields to the count function ------------------------------------------------
73
+ dataclassBaseFields: tuple[dataclasses.Field[Any], ...] = dataclasses.fields(importLogicalPath2Identifier(dataclassLogicalPathModule, dataclassIdentifier)) # pyright: ignore [reportArgumentType]
74
+ dataclassIdentifierParallel: identifierDotAttribute = 'Parallel' + dataclassIdentifier
75
+ dataclassFieldsParallel: tuple[dataclasses.Field[Any], ...] = dataclasses.fields(importLogicalPath2Identifier(dataclassLogicalPathModule, dataclassIdentifierParallel)) # pyright: ignore [reportArgumentType]
76
+ onlyParallelFields: list[dataclasses.Field[Any]] = [field for field in dataclassFieldsParallel if field.name not in [fieldBase.name for fieldBase in dataclassBaseFields]]
77
+
78
+ Official_fieldOrder: list[str] = []
79
+ dictionaryDeReConstruction: dict[str, DeReConstructField2ast] = {}
80
+
81
+ dataclassClassDef: ast.ClassDef | None = extractClassDef(parseLogicalPath2astModule(dataclassLogicalPathModule), dataclassIdentifierParallel)
82
+ if not dataclassClassDef:
83
+ message = f"I could not find `{dataclassIdentifierParallel = }` in `{dataclassLogicalPathModule = }`."
84
+ raise ValueError(message)
85
+
86
+ for aField in onlyParallelFields:
87
+ Official_fieldOrder.append(aField.name)
88
+ dictionaryDeReConstruction[aField.name] = DeReConstructField2ast(dataclassLogicalPathModule, dataclassClassDef, dataclassInstanceIdentifier, aField)
89
+
90
+ shatteredDataclassParallel = ShatteredDataclass(
91
+ countingVariableAnnotation=shatteredDataclass.countingVariableAnnotation,
92
+ countingVariableName=shatteredDataclass.countingVariableName,
93
+ field2AnnAssign={**shatteredDataclass.field2AnnAssign, **{dictionaryDeReConstruction[field].name: dictionaryDeReConstruction[field].astAnnAssignConstructor for field in Official_fieldOrder}},
94
+ Z0Z_field2AnnAssign={**shatteredDataclass.Z0Z_field2AnnAssign, **{dictionaryDeReConstruction[field].name: dictionaryDeReConstruction[field].Z0Z_hack for field in Official_fieldOrder}},
95
+ list_argAnnotated4ArgumentsSpecification=shatteredDataclass.list_argAnnotated4ArgumentsSpecification + [dictionaryDeReConstruction[field].ast_argAnnotated for field in Official_fieldOrder],
96
+ list_keyword_field__field4init=shatteredDataclass.list_keyword_field__field4init + [dictionaryDeReConstruction[field].ast_keyword_field__field for field in Official_fieldOrder if dictionaryDeReConstruction[field].init],
97
+ listAnnotations=shatteredDataclass.listAnnotations + [dictionaryDeReConstruction[field].astAnnotation for field in Official_fieldOrder],
98
+ listName4Parameters=shatteredDataclass.listName4Parameters + [dictionaryDeReConstruction[field].astName for field in Official_fieldOrder],
99
+ listUnpack=shatteredDataclass.listUnpack + [Make.AnnAssign(dictionaryDeReConstruction[field].astName, dictionaryDeReConstruction[field].astAnnotation, dictionaryDeReConstruction[field].ast_nameDOTname) for field in Official_fieldOrder],
100
+ map_stateDOTfield2Name={**shatteredDataclass.map_stateDOTfield2Name, **{dictionaryDeReConstruction[field].ast_nameDOTname: dictionaryDeReConstruction[field].astName for field in Official_fieldOrder}},
101
+ )
102
+ shatteredDataclassParallel.fragments4AssignmentOrParameters = Make.Tuple(shatteredDataclassParallel.listName4Parameters, Make.Store())
103
+ shatteredDataclassParallel.repack = Make.Assign([Make.Name(dataclassInstanceIdentifier)], value=Make.Call(Make.Name(dataclassIdentifierParallel), list_keyword=shatteredDataclassParallel.list_keyword_field__field4init))
104
+ shatteredDataclassParallel.signatureReturnAnnotation = Make.Subscript(Make.Name('tuple'), Make.Tuple(shatteredDataclassParallel.listAnnotations))
105
+
106
+ shatteredDataclassParallel.imports.update(*(dictionaryDeReConstruction[field].ledger for field in Official_fieldOrder))
107
+ shatteredDataclassParallel.imports.addImportFrom_asStr(dataclassLogicalPathModule, dataclassIdentifierParallel)
108
+ shatteredDataclassParallel.imports.update(shatteredDataclass.imports)
109
+ shatteredDataclassParallel.imports.removeImportFrom(dataclassLogicalPathModule, dataclassIdentifier)
110
+
111
+ # END add the parallel state fields to the count function ------------------------------------------------
112
+
113
+ ingredientsFunction.imports.update(shatteredDataclassParallel.imports)
114
+ ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclassParallel)
115
+
116
+ # START add the parallel logic to the count function ------------------------------------------------
117
+
118
+ findThis = Be.While.testIs(Be.Compare.leftIs(IfThis.isNameIdentifier('leafConnectee')))
119
+ captureCountGapsCodeBlock: NodeTourist[ast.While, Sequence[ast.stmt]] = NodeTourist(findThis, doThat = Then.extractIt(DOT.body))
120
+ countGapsCodeBlock: Sequence[ast.stmt] = raiseIfNone(captureCountGapsCodeBlock.captureLastMatch(ingredientsFunction.astFunctionDef))
121
+
122
+ thisIsMyTaskIndexCodeBlock = ast.If(ast.BoolOp(ast.Or()
123
+ , values=[ast.Compare(ast.Name('leaf1ndex'), ops=[ast.NotEq()], comparators=[ast.Name('taskDivisions')])
124
+ , ast.Compare(Make.Mod.join([ast.Name('leafConnectee'), ast.Name('taskDivisions')]), ops=[ast.Eq()], comparators=[ast.Name('taskIndex')])])
125
+ , body=list(countGapsCodeBlock[0:-1]))
126
+
127
+ countGapsCodeBlockNew: list[ast.stmt] = [thisIsMyTaskIndexCodeBlock, countGapsCodeBlock[-1]]
128
+ NodeChanger[ast.While, hasDOTbody](findThis, doThat = Grab.bodyAttribute(Then.replaceWith(countGapsCodeBlockNew))).visit(ingredientsFunction.astFunctionDef)
129
+
130
+ # END add the parallel logic to the count function ------------------------------------------------
131
+
132
+ ingredientsFunction = removeUnusedParameters(ingredientsFunction)
133
+
134
+ ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
135
+
136
+ # START unpack/repack the dataclass function ------------------------------------------------
137
+ sourceCallableIdentifier = identifierCallableSourceDispatcherDEFAULT
138
+
139
+ unRepackDataclass: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableIdentifier)
140
+ unRepackDataclass.astFunctionDef.name = 'unRepack' + dataclassIdentifierParallel
141
+ unRepackDataclass.imports.update(shatteredDataclassParallel.imports)
142
+ NodeChanger(
143
+ findThis = Be.arg.annotationIs(Be.Name.idIs(lambda thisAttribute: thisAttribute == dataclassIdentifier)) # pyright: ignore[reportArgumentType]
144
+ , doThat = Grab.annotationAttribute(Grab.idAttribute(Then.replaceWith(dataclassIdentifierParallel)))
145
+ ).visit(unRepackDataclass.astFunctionDef)
146
+ unRepackDataclass.astFunctionDef.returns = Make.Name(dataclassIdentifierParallel)
147
+ targetCallableIdentifier: identifierDotAttribute = ingredientsFunction.astFunctionDef.name
148
+ unRepackDataclass = unpackDataclassCallFunctionRepackDataclass(unRepackDataclass, targetCallableIdentifier, shatteredDataclassParallel)
149
+
150
+ astTuple: ast.Tuple = raiseIfNone(NodeTourist[ast.Return, ast.Tuple](Be.Return, Then.extractIt(DOT.value)).captureLastMatch(ingredientsFunction.astFunctionDef)) # pyright: ignore[reportArgumentType]
151
+ astTuple.ctx = Make.Store()
152
+ changeAssignCallToTarget: NodeChanger[ast.Assign, ast.Assign] = NodeChanger(
153
+ findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
154
+ , doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
155
+ )
156
+ changeAssignCallToTarget.visit(unRepackDataclass.astFunctionDef)
157
+
158
+ ingredientsDoTheNeedful: IngredientsFunction = IngredientsFunction(
159
+ astFunctionDef = Make.FunctionDef('doTheNeedful'
160
+ , argumentSpecification=Make.arguments(list_arg=[Make.arg('state', annotation=Make.Name(dataclassIdentifierParallel)), Make.arg('concurrencyLimit', annotation=Make.Name('int'))])
161
+ , body=[Make.Assign([Make.Name('stateParallel', Make.Store())], value=Make.Call(Make.Name('deepcopy'), listParameters=[Make.Name('state')]))
162
+ , Make.AnnAssign(Make.Name('listStatesParallel', Make.Store()), annotation=Make.Subscript(value=Make.Name('list'), slice=Make.Name(dataclassIdentifierParallel))
163
+ , value=Make.Mult.join([Make.List([Make.Name('stateParallel')]), Make.Attribute(Make.Name('stateParallel'), 'taskDivisions')]))
164
+ , Make.AnnAssign(Make.Name('groupsOfFoldsTotal', Make.Store()), annotation=Make.Name('int'), value=Make.Constant(value=0))
165
+
166
+ , Make.AnnAssign(Make.Name('dictionaryConcurrency', Make.Store()), annotation=Make.Subscript(value=Make.Name('dict'), slice=Make.Tuple([Make.Name('int'), Make.Subscript(value=Make.Name('ConcurrentFuture'), slice=Make.Name(dataclassIdentifierParallel))])), value=Make.Dict())
167
+ , Make.With(items=[Make.withitem(context_expr=Make.Call(Make.Name('ProcessPoolExecutor'), listParameters=[Make.Name('concurrencyLimit')]), optional_vars=Make.Name('concurrencyManager', Make.Store()))]
168
+ , body=[Make.For(Make.Name('indexSherpa', Make.Store()), iter=Make.Call(Make.Name('range'), listParameters=[Make.Attribute(Make.Name('stateParallel'), 'taskDivisions')])
169
+ , body=[Make.Assign([Make.Name('state', Make.Store())], value=Make.Call(Make.Name('deepcopy'), listParameters=[Make.Name('stateParallel')]))
170
+ , Make.Assign([Make.Attribute(Make.Name('state'), 'taskIndex', context=Make.Store())], value=Make.Name('indexSherpa'))
171
+ , Make.Assign([Make.Subscript(Make.Name('dictionaryConcurrency'), slice=Make.Name('indexSherpa'), context=Make.Store())], value=Make.Call(Make.Attribute(Make.Name('concurrencyManager'), 'submit'), listParameters=[Make.Name(unRepackDataclass.astFunctionDef.name), Make.Name('state')]))])
172
+ , Make.For(Make.Name('indexSherpa', Make.Store()), iter=Make.Call(Make.Name('range'), listParameters=[Make.Attribute(Make.Name('stateParallel'), 'taskDivisions')])
173
+ , body=[Make.Assign([Make.Subscript(Make.Name('listStatesParallel'), slice=Make.Name('indexSherpa'), context=Make.Store())], value=Make.Call(Make.Attribute(Make.Subscript(Make.Name('dictionaryConcurrency'), slice=Make.Name('indexSherpa')), 'result')))
174
+ , Make.AugAssign(Make.Name('groupsOfFoldsTotal', Make.Store()), op=ast.Add(), value=Make.Attribute(Make.Subscript(Make.Name('listStatesParallel'), slice=Make.Name('indexSherpa')), 'groupsOfFolds'))])])
175
+
176
+ , Make.AnnAssign(Make.Name('foldsTotal', Make.Store()), annotation=Make.Name('int'), value=Make.Mult.join([Make.Name('groupsOfFoldsTotal'), Make.Attribute(Make.Name('stateParallel'), 'leavesTotal')]))
177
+ , Make.Return(Make.Tuple([Make.Name('foldsTotal'), Make.Name('listStatesParallel')]))]
178
+ , returns=Make.Subscript(Make.Name('tuple'), slice=Make.Tuple([Make.Name('int'), Make.Subscript(Make.Name('list'), slice=Make.Name(dataclassIdentifierParallel))])))
179
+ , imports = LedgerOfImports(Make.Module([Make.ImportFrom('concurrent.futures', list_alias=[Make.alias('Future', asName='ConcurrentFuture'), Make.alias('ProcessPoolExecutor')]),
180
+ Make.ImportFrom('copy', list_alias=[Make.alias('deepcopy')]),
181
+ Make.ImportFrom('multiprocessing', list_alias=[Make.alias('set_start_method', asName='multiprocessing_set_start_method')])])
182
+ )
183
+ )
184
+
185
+ ingredientsModule = IngredientsModule([ingredientsFunction, unRepackDataclass, ingredientsDoTheNeedful]
186
+ , prologue = Make.Module([Make.If(test=Make.Compare(left=Make.Name('__name__'), ops=[Make.Eq()], comparators=[Make.Constant('__main__')]), body=[Make.Expr(Make.Call(Make.Name('multiprocessing_set_start_method'), listParameters=[Make.Constant('spawn')]))])])
187
+ )
188
+ ingredientsModule.removeImportFromModule('numpy')
189
+
190
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
191
+
192
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
193
+
194
+ return pathFilename
195
+
196
+ def makeMapFoldingModules() -> None:
197
+ """Make multidimensional map folding modules."""
198
+ astModule = getModule(logicalPathInfix='algorithms')
199
+ pathFilename: PurePath = makeDaoOfMapFoldingNumba(astModule, 'daoOfMapFoldingNumba', None, logicalPathInfixDEFAULT, identifierCallableSourceDispatcherDEFAULT)
200
+
201
+ astModule = getModule(logicalPathInfix='algorithms')
202
+ pathFilename = makeDaoOfMapFoldingParallelNumba(astModule, 'countParallelNumba', None, logicalPathInfixDEFAULT, identifierCallableSourceDispatcherDEFAULT)
203
+
204
+ astModule: ast.Module = getModule(logicalPathInfix='algorithms')
205
+ makeInitializeState(astModule, 'initializeState', 'transitionOnGroupsOfFolds', logicalPathInfixDEFAULT)
206
+
207
+ astModule = getModule(logicalPathInfix='algorithms')
208
+ pathFilename = makeTheorem2(astModule, 'theorem2', None, logicalPathInfixDEFAULT, None)
209
+
210
+ astModule = parsePathFilename2astModule(pathFilename)
211
+ pathFilename = trimTheorem2(astModule, 'theorem2Trimmed', None, logicalPathInfixDEFAULT, None)
212
+
213
+ astModule = parsePathFilename2astModule(pathFilename)
214
+ pathFilename = numbaOnTheorem2(astModule, 'theorem2Numba', None, logicalPathInfixDEFAULT, None)
215
+
216
+ astImportFrom: ast.ImportFrom = Make.ImportFrom(getLogicalPath(packageSettings.identifierPackage, logicalPathInfixDEFAULT, 'theorem2Numba'), list_alias=[Make.alias(identifierCallableSourceDEFAULT)])
217
+ makeUnRePackDataclass(astImportFrom)
218
+
219
+ if __name__ == '__main__':
220
+ makeMapFoldingModules()
File without changes