mapFolding 0.15.4__py3-none-any.whl → 0.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. mapFolding/__init__.py +7 -9
  2. mapFolding/_theSSOT.py +1 -0
  3. mapFolding/algorithms/daoOfMapFolding.py +1 -2
  4. mapFolding/algorithms/getBucketsTotal.py +137 -0
  5. mapFolding/algorithms/matrixMeanders.py +457 -286
  6. mapFolding/algorithms/oeisIDbyFormula.py +310 -76
  7. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +84 -0
  8. mapFolding/basecamp.py +99 -14
  9. mapFolding/dataBaskets.py +74 -0
  10. mapFolding/oeis.py +3 -2
  11. mapFolding/reference/A000682facts.py +662 -0
  12. mapFolding/reference/A005316facts.py +62 -0
  13. mapFolding/reference/matrixMeandersAnalysis/__init__.py +1 -0
  14. mapFolding/reference/matrixMeandersAnalysis/evenEven.py +144 -0
  15. mapFolding/reference/matrixMeandersAnalysis/oddEven.py +54 -0
  16. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +55 -0
  17. mapFolding/someAssemblyRequired/A007822/__init__.py +0 -0
  18. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +185 -0
  19. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +71 -0
  20. mapFolding/someAssemblyRequired/RecipeJob.py +2 -2
  21. mapFolding/someAssemblyRequired/__init__.py +9 -2
  22. mapFolding/someAssemblyRequired/_toolIfThis.py +4 -3
  23. mapFolding/someAssemblyRequired/_toolkitContainers.py +8 -8
  24. mapFolding/someAssemblyRequired/infoBooth.py +27 -30
  25. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +1 -1
  26. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +5 -2
  27. mapFolding/someAssemblyRequired/makingModules_count.py +301 -0
  28. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +120 -0
  29. mapFolding/someAssemblyRequired/mapFolding/__init__.py +0 -0
  30. mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +220 -0
  31. mapFolding/someAssemblyRequired/toolkitMakeModules.py +152 -0
  32. mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
  33. mapFolding/someAssemblyRequired/transformationTools.py +1 -0
  34. mapFolding/syntheticModules/A007822/__init__.py +1 -0
  35. mapFolding/syntheticModules/{algorithmA007822Numba.py → A007822/algorithmNumba.py} +2 -4
  36. mapFolding/syntheticModules/A007822/asynchronous.py +148 -0
  37. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +68 -0
  38. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +53 -0
  39. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +47 -0
  40. mapFolding/syntheticModules/dataPackingA007822.py +1 -1
  41. mapFolding/tests/test_computations.py +2 -2
  42. mapFolding/trim_memory.py +62 -0
  43. mapFolding/zCuzDocStoopid/__init__.py +1 -0
  44. mapFolding/zCuzDocStoopid/makeDocstrings.py +63 -0
  45. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/METADATA +9 -2
  46. mapfolding-0.16.0.dist-info/RECORD +100 -0
  47. mapFolding/someAssemblyRequired/A007822rawMaterials.py +0 -46
  48. mapFolding/someAssemblyRequired/makeAllModules.py +0 -764
  49. mapfolding-0.15.4.dist-info/RECORD +0 -78
  50. /mapFolding/syntheticModules/{algorithmA007822.py → A007822/algorithm.py} +0 -0
  51. /mapFolding/syntheticModules/{initializeStateA007822.py → A007822/initializeState.py} +0 -0
  52. /mapFolding/syntheticModules/{theorem2A007822.py → A007822/theorem2.py} +0 -0
  53. /mapFolding/syntheticModules/{theorem2A007822Numba.py → A007822/theorem2Numba.py} +0 -0
  54. /mapFolding/syntheticModules/{theorem2A007822Trimmed.py → A007822/theorem2Trimmed.py} +0 -0
  55. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/WHEEL +0 -0
  56. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/entry_points.txt +0 -0
  57. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/licenses/LICENSE +0 -0
  58. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/top_level.txt +0 -0
@@ -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
- """
@@ -326,7 +326,7 @@ if __name__ == '__main__':
326
326
  """
327
327
 
328
328
  if __name__ == '__main__':
329
- state = transitionOnGroupsOfFolds(MapFoldingState((2,4)))
329
+ state = transitionOnGroupsOfFolds(MapFoldingState((1,27)))
330
330
  pathModule = PurePosixPath(packageSettings.pathPackage, 'jobs')
331
331
  pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(state.mapShape, pathModule))
332
332
  aJob = RecipeJobTheorem2(state, pathModule=pathModule, pathFilenameFoldsTotal=pathFilenameFoldsTotal)
@@ -100,7 +100,9 @@ def _variableCompatibility(ingredientsFunction: IngredientsFunction, job: Recipe
100
100
  # `identifier` in Augmented Assignment, or in Assignments and value is Constant.
101
101
  NodeChanger(findThis=IfThis.isAnyOf(
102
102
  Be.AugAssign.targetIs(IfThis.isNestedNameIdentifier(identifier))
103
- , IfThis.isAllOf(IfThis.isAssignAndTargets0Is(IfThis.isNameIdentifier(identifier))
103
+ , IfThis.isAllOf(
104
+ Be.Assign.targetsIs(Be.at(0, IfThis.isNestedNameIdentifier(identifier)))
105
+ # IfThis.isAssignAndTargets0Is(IfThis.isNameIdentifier(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)
@@ -113,6 +115,7 @@ def _variableCompatibility(ingredientsFunction: IngredientsFunction, job: Recipe
113
115
 
114
116
  # `identifier` in Comparison.
115
117
  NodeChanger(Be.Compare.leftIs(IfThis.isNestedNameIdentifier(identifier))
118
+ # , doThat=Grab.comparatorsAttribute(Grab.index(0, lambda comparator, annotation=annotation: Then.replaceWith(Make.Call(annotation, listParameters=[comparator]))))
116
119
  , doThat=lambda node, annotation=annotation: Grab.comparatorsAttribute(lambda at, annotation=annotation: Then.replaceWith([Make.Call(annotation, listParameters=[node.comparators[0]])])(at[0]))(node)
117
120
  ).visit(ingredientsFunction.astFunctionDef)
118
121
 
@@ -220,6 +223,6 @@ def fromMapShape(mapShape: tuple[DatatypeLeavesTotal, ...]) -> None:
220
223
  makeJob(aJob)
221
224
 
222
225
  if __name__ == '__main__':
223
- mapShape = (1, 15)
226
+ mapShape = (1, 3)
224
227
  fromMapShape(mapShape)
225
228
 
@@ -0,0 +1,301 @@
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 | str | 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 | str | 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 | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
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
+
231
+ if sourceCallableDispatcher is not None:
232
+ NodeChanger(
233
+ findThis=IfThis.isCallIdentifier(sourceCallableDispatcher)
234
+ , doThat=Then.replaceWith(astExprCall_filterAsymmetricFoldsLeafBelow)
235
+ ).visit(ingredientsFunction.astFunctionDef)
236
+
237
+ ingredientsFunction = removeUnusedParameters(ingredientsFunction)
238
+ ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
239
+
240
+ ingredientsModule = IngredientsModule(ingredientsFunction)
241
+ ingredientsModule.removeImportFromModule('numpy')
242
+
243
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
244
+
245
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
246
+
247
+ return pathFilename
248
+
249
+ def trimTheorem2(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: PathLike[str] | PurePath | str | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
250
+ """Generate constrained Theorem 2 implementation by removing unnecessary logic.
251
+
252
+ (AI generated docstring)
253
+
254
+ Creates a trimmed version of the Theorem 2 implementation by eliminating conditional logic that is not needed under specific
255
+ constraint assumptions. This transformation removes checks for unconstrained dimensions, simplifying the algorithm for cases
256
+ where dimensional constraints are guaranteed to be satisfied by external conditions.
257
+
258
+ The trimming operation is particularly valuable for generating lean implementations where the calling context ensures that
259
+ certain conditions will always be met, allowing the removal of defensive programming constructs that add computational
260
+ overhead without providing benefits in the constrained environment.
261
+
262
+ Parameters
263
+ ----------
264
+ astModule : ast.Module
265
+ Source module containing the Theorem 2 implementation.
266
+ moduleIdentifier : str
267
+ Name for the generated trimmed module.
268
+ callableIdentifier : str | None = None
269
+ Name for the trimmed computational function.
270
+ logicalPathInfix : PathLike[str] | PurePath | str | None = None
271
+ Directory path for organizing the generated module.
272
+ sourceCallableDispatcher : str | None = None
273
+ Optional dispatcher function identifier (unused).
274
+
275
+ Returns
276
+ -------
277
+ pathFilename : PurePath
278
+ Filesystem path where the trimmed module was written.
279
+
280
+ """
281
+ sourceCallableIdentifier = identifierCallableSourceDEFAULT
282
+ ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
283
+ ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
284
+
285
+ dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
286
+
287
+ findThis = IfThis.isIfUnaryNotAttributeNamespaceIdentifier(dataclassInstanceIdentifier, 'dimensionsUnconstrained')
288
+ doThat = Then.removeIt
289
+ NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
290
+
291
+ ingredientsModule = IngredientsModule(ingredientsFunction)
292
+ ingredientsModule.removeImportFromModule('numpy')
293
+
294
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
295
+
296
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
297
+
298
+ return pathFilename
299
+
300
+
301
+
@@ -0,0 +1,120 @@
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 | str | 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
+
69
+ def makeUnRePackDataclass(astImportFrom: ast.ImportFrom, moduleIdentifier: str = identifierModuleDataPackingDEFAULT) -> None:
70
+ """Generate interface module for dataclass unpacking and repacking operations.
71
+
72
+ Parameters
73
+ ----------
74
+ astImportFrom : ast.ImportFrom
75
+ Import statement specifying the target optimized function to call.
76
+
77
+ Returns
78
+ -------
79
+ None
80
+ The generated module is written directly to the filesystem.
81
+
82
+ """
83
+ callableIdentifierHARDCODED: str = 'sequential'
84
+
85
+ algorithmSourceModule: identifierDotAttribute = identifierModuleSourceAlgorithmDEFAULT
86
+ callableIdentifier: identifierDotAttribute = callableIdentifierHARDCODED
87
+ logicalPathInfix: identifierDotAttribute = logicalPathInfixDEFAULT
88
+ logicalPathInfixAlgorithm: identifierDotAttribute = logicalPathInfixAlgorithmDEFAULT
89
+ sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDispatcherDEFAULT
90
+
91
+ logicalPathSourceModule: identifierDotAttribute = '.'.join([packageSettings.identifierPackage, logicalPathInfixAlgorithm, algorithmSourceModule]) # noqa: FLY002
92
+
93
+ ingredientsFunction: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
94
+ ingredientsFunction.astFunctionDef.name = callableIdentifier
95
+
96
+ shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
97
+
98
+ ingredientsFunction.imports.update(shatteredDataclass.imports)
99
+ ingredientsFunction.imports.addAst(astImportFrom)
100
+ targetCallableIdentifier: str = astImportFrom.names[0].name
101
+ ingredientsFunction = raiseIfNone(unpackDataclassCallFunctionRepackDataclass(ingredientsFunction, targetCallableIdentifier, shatteredDataclass))
102
+ targetFunctionDef: ast.FunctionDef = raiseIfNone(extractFunctionDef(parseLogicalPath2astModule(raiseIfNone(astImportFrom.module)), targetCallableIdentifier))
103
+ astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
104
+ , doThat=Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)))
105
+ astTuple.ctx = Make.Store()
106
+
107
+ changeAssignCallToTarget = NodeChanger(
108
+ findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
109
+ , doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts))))
110
+ changeAssignCallToTarget.visit(ingredientsFunction.astFunctionDef)
111
+
112
+ ingredientsModule = IngredientsModule(ingredientsFunction)
113
+ ingredientsModule.removeImportFromModule('numpy')
114
+
115
+ pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
116
+
117
+ write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
118
+
119
+
120
+
File without changes