mapFolding 0.16.2__py3-none-any.whl → 0.17.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 (80) hide show
  1. easyRun/A000682.py +2 -2
  2. easyRun/NOTcountingFolds.py +16 -8
  3. easyRun/countFolds.py +9 -2
  4. easyRun/generateAllModules.py +14 -0
  5. easyRun/meanders.py +4 -4
  6. mapFolding/__init__.py +1 -0
  7. mapFolding/_theSSOT.py +3 -2
  8. mapFolding/_theTypes.py +3 -0
  9. mapFolding/algorithms/A000136constraintPropagation.py +95 -0
  10. mapFolding/algorithms/A000136elimination.py +163 -0
  11. mapFolding/algorithms/A000136eliminationParallel.py +77 -0
  12. mapFolding/algorithms/A086345.py +75 -0
  13. mapFolding/algorithms/matrixMeanders.py +59 -18
  14. mapFolding/algorithms/matrixMeandersNumPyndas.py +841 -0
  15. mapFolding/algorithms/oeisIDbyFormula.py +2 -2
  16. mapFolding/algorithms/symmetricFolds.py +35 -0
  17. mapFolding/basecamp.py +100 -153
  18. mapFolding/dataBaskets.py +142 -65
  19. mapFolding/filesystemToolkit.py +4 -32
  20. mapFolding/oeis.py +5 -12
  21. mapFolding/reference/A086345Wu.py +25 -0
  22. mapFolding/reference/irvineJavaPort.py +3 -3
  23. mapFolding/reference/matrixMeandersAnalysis/signatures.py +3 -0
  24. mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +1 -1
  25. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +10 -45
  26. mapFolding/someAssemblyRequired/A007822/_asynchronousAnnex.py +51 -0
  27. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +39 -196
  28. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +57 -43
  29. mapFolding/someAssemblyRequired/RecipeJob.py +84 -34
  30. mapFolding/someAssemblyRequired/__init__.py +4 -8
  31. mapFolding/someAssemblyRequired/_toolkitContainers.py +38 -7
  32. mapFolding/someAssemblyRequired/infoBooth.py +41 -23
  33. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +140 -164
  34. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +63 -96
  35. mapFolding/someAssemblyRequired/makingModules_count.py +26 -30
  36. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +10 -72
  37. mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/makeMapFoldingModules.py +30 -35
  38. mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +13 -11
  39. mapFolding/someAssemblyRequired/toolkitMakeModules.py +5 -31
  40. mapFolding/someAssemblyRequired/toolkitNumba.py +3 -2
  41. mapFolding/someAssemblyRequired/transformationTools.py +12 -15
  42. mapFolding/syntheticModules/A007822/algorithm.py +45 -50
  43. mapFolding/syntheticModules/A007822/asynchronous.py +92 -36
  44. mapFolding/syntheticModules/A007822/initializeState.py +19 -23
  45. mapFolding/syntheticModules/A007822/theorem2.py +20 -24
  46. mapFolding/syntheticModules/A007822/theorem2Numba.py +23 -25
  47. mapFolding/syntheticModules/A007822/theorem2Trimmed.py +19 -23
  48. mapFolding/syntheticModules/countParallelNumba.py +1 -2
  49. mapFolding/syntheticModules/daoOfMapFoldingNumba.py +5 -4
  50. mapFolding/syntheticModules/initializeState.py +1 -1
  51. mapFolding/syntheticModules/meanders/bigInt.py +59 -22
  52. mapFolding/syntheticModules/theorem2.py +1 -1
  53. mapFolding/syntheticModules/theorem2Numba.py +30 -9
  54. mapFolding/syntheticModules/theorem2Trimmed.py +2 -2
  55. mapFolding/tests/test_computations.py +29 -3
  56. {mapfolding-0.16.2.dist-info → mapfolding-0.17.0.dist-info}/METADATA +11 -8
  57. mapfolding-0.17.0.dist-info/RECORD +107 -0
  58. mapFolding/_dataPacking.py +0 -68
  59. mapFolding/algorithms/matrixMeandersBeDry.py +0 -182
  60. mapFolding/algorithms/matrixMeandersNumPy.py +0 -333
  61. mapFolding/algorithms/matrixMeandersPandas.py +0 -334
  62. mapFolding/reference/meandersDumpingGround/A005316intOptimized.py +0 -122
  63. mapFolding/reference/meandersDumpingGround/A005316optimized128bit.py +0 -79
  64. mapFolding/reference/meandersDumpingGround/matrixMeandersBaseline.py +0 -65
  65. mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineAnnex.py +0 -84
  66. mapFolding/reference/meandersDumpingGround/matrixMeandersSimpleQueue.py +0 -90
  67. mapFolding/syntheticModules/A007822/algorithmNumba.py +0 -94
  68. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +0 -66
  69. mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +0 -70
  70. mapFolding/syntheticModules/A007822/asynchronousNumba.py +0 -79
  71. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +0 -65
  72. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +0 -56
  73. mapFolding/syntheticModules/dataPacking.py +0 -26
  74. mapFolding/syntheticModules/dataPackingA007822.py +0 -92
  75. mapfolding-0.16.2.dist-info/RECORD +0 -115
  76. /mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/__init__.py +0 -0
  77. {mapfolding-0.16.2.dist-info → mapfolding-0.17.0.dist-info}/WHEEL +0 -0
  78. {mapfolding-0.16.2.dist-info → mapfolding-0.17.0.dist-info}/entry_points.txt +0 -0
  79. {mapfolding-0.16.2.dist-info → mapfolding-0.17.0.dist-info}/licenses/LICENSE +0 -0
  80. {mapfolding-0.16.2.dist-info → mapfolding-0.17.0.dist-info}/top_level.txt +0 -0
@@ -2,61 +2,32 @@
2
2
 
3
3
  https://docs.exaloop.io/start/install/
4
4
  """
5
-
6
5
  from astToolkit import (
7
- Be, DOT, extractFunctionDef, Grab, identifierDotAttribute, IngredientsFunction, IngredientsModule, Make, NodeChanger,
8
- NodeTourist, parseLogicalPath2astModule, Then)
6
+ Be, extractFunctionDef, Grab, identifierDotAttribute, Make, NodeChanger, parseLogicalPath2astModule, Then)
7
+ from astToolkit.containers import IngredientsFunction, IngredientsModule
9
8
  from astToolkit.transformationTools import removeUnusedParameters, write_astModule
10
- from hunterMakesPy import autoDecodingRLE, raiseIfNone
11
- from mapFolding import DatatypeLeavesTotal, getPathFilenameFoldsTotal
9
+ from hunterMakesPy import raiseIfNone
10
+ from mapFolding import DatatypeLeavesTotal, getPathFilenameFoldsTotal, packageSettings
12
11
  from mapFolding.dataBaskets import MapFoldingState
13
- from mapFolding.someAssemblyRequired import IfThis
14
- from mapFolding.someAssemblyRequired.RecipeJob import RecipeJobTheorem2
15
- from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds
12
+ from mapFolding.someAssemblyRequired import DatatypeConfiguration, default, IfThis
13
+ from mapFolding.someAssemblyRequired.RecipeJob import (
14
+ customizeDatatypeViaImport, moveShatteredDataclass_arg2body, RecipeJobTheorem2)
15
+ from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
16
16
  from pathlib import Path, PurePosixPath
17
- from typing import cast, NamedTuple, TYPE_CHECKING
18
- import ast
17
+ from typing import cast, TYPE_CHECKING
19
18
  import subprocess
20
19
  import sys
21
20
 
22
21
  if TYPE_CHECKING:
23
22
  from io import TextIOBase
23
+ import ast
24
24
 
25
- class DatatypeConfiguration(NamedTuple):
26
- """Configuration for mapping framework datatypes to compiled datatypes.
27
-
28
- This configuration class defines how abstract datatypes used in the map folding framework should be replaced with compiled
29
- datatypes during code generation. Each configuration specifies the source module, target type name, and optional import alias
30
- for the transformation.
31
-
32
- Attributes
33
- ----------
34
- datatypeIdentifier : str
35
- Framework datatype identifier to be replaced.
36
- typeModule : identifierDotAttribute
37
- Module containing the target datatype (e.g., 'codon', 'numpy').
38
- typeIdentifier : str
39
- Concrete type name in the target module.
40
- type_asname : str | None = None
41
- Optional import alias for the type.
42
- """
25
+ # TODO Converge with `makeJobTheorem2Numba`.
43
26
 
44
- datatypeIdentifier: str
45
- typeModule: identifierDotAttribute
46
- typeIdentifier: str
47
- type_asname: str | None = None
48
-
49
- # TODO replace with dynamic system. Probably use `Final` in the dataclass.
50
- listIdentifiersStaticValuesHARDCODED: list[str] = ['dimensionsTotal', 'leavesTotal']
51
-
52
- # TODO Dynamically calculate the bitwidth of each datatype.
53
27
  listDatatypeConfigurations: list[DatatypeConfiguration] = [
54
28
  DatatypeConfiguration(datatypeIdentifier='DatatypeLeavesTotal', typeModule='numpy', typeIdentifier='uint8', type_asname='DatatypeLeavesTotal'),
55
29
  DatatypeConfiguration(datatypeIdentifier='DatatypeElephino', typeModule='numpy', typeIdentifier='uint8', type_asname='DatatypeElephino'),
56
30
  DatatypeConfiguration(datatypeIdentifier='DatatypeFoldsTotal', typeModule='numpy', typeIdentifier='int64', type_asname='DatatypeFoldsTotal'),
57
- ]
58
-
59
- listNumPy_dtype: list[DatatypeConfiguration] = [
60
31
  DatatypeConfiguration(datatypeIdentifier='Array1DLeavesTotal', typeModule='numpy', typeIdentifier='uint8', type_asname='Array1DLeavesTotal'),
61
32
  DatatypeConfiguration(datatypeIdentifier='Array1DElephino', typeModule='numpy', typeIdentifier='uint8', type_asname='Array1DElephino'),
62
33
  DatatypeConfiguration(datatypeIdentifier='Array3DLeavesTotal', typeModule='numpy', typeIdentifier='uint8', type_asname='Array3DLeavesTotal'),
@@ -78,76 +49,68 @@ def _addWriteFoldsTotal(ingredientsFunction: IngredientsFunction, job: RecipeJob
78
49
 
79
50
  return ingredientsFunction
80
51
 
81
- def _datatypeDefinitions(ingredientsFunction: IngredientsFunction, ingredientsModule: IngredientsModule) -> tuple[IngredientsFunction, IngredientsModule]:
82
- for datatypeConfig in [*listDatatypeConfigurations, *listNumPy_dtype]:
83
- ingredientsFunction.imports.removeImportFrom(datatypeConfig.typeModule, None, datatypeConfig.datatypeIdentifier)
84
- ingredientsFunction.imports.addImportFrom_asStr(datatypeConfig.typeModule, datatypeConfig.typeIdentifier, datatypeConfig.type_asname)
85
-
86
- ingredientsFunction.imports.removeImportFromModule('mapFolding.dataBaskets')
52
+ def _variableCompatibility(ingredientsFunction: IngredientsFunction, job: RecipeJobTheorem2) -> IngredientsFunction:
53
+ """Ensure the variable is compiled to the correct type.
87
54
 
88
- return ingredientsFunction, ingredientsModule
55
+ Add a type constructor to `identifier` to ensure compatibility if
56
+ - an incompatible type might be assigned to it,
57
+ - it might be compared with an incompatible type,
58
+ - it is used as an indexer but its type is not a valid indexer type.
89
59
 
90
- def _pythonCode2expr(string: str) -> ast.expr:
91
- """Convert *one* expression as a string of Python code to an `ast.expr`."""
92
- return raiseIfNone(NodeTourist(Be.Expr, Then.extractIt(DOT.value)).captureLastMatch(ast.parse(string)))
60
+ Parameters
61
+ ----------
62
+ ingredientsFunction : IngredientsFunction
63
+ Function to modify.
64
+ job : RecipeJobTheorem2
65
+ Configuration settings with identifiers and their type annotations.
93
66
 
94
- def _variableCompatibility(ingredientsFunction: IngredientsFunction, job: RecipeJobTheorem2) -> IngredientsFunction:
95
- # On some assignment or comparison values, add a type constructor to ensure compatibility.
96
- # On some values-as-indexer, add a type constructor to ensure indexing-method compatibility.
67
+ Returns
68
+ -------
69
+ ingredientsFunction : IngredientsFunction
70
+ Modified function.
71
+ """
97
72
  for ast_arg in job.shatteredDataclass.list_argAnnotated4ArgumentsSpecification:
98
- identifier = ast_arg.arg
99
- annotation = raiseIfNone(ast_arg.annotation)
100
-
101
- # `identifier` in Augmented Assignment, or in Assignments and value is Constant.
102
- NodeChanger(findThis=IfThis.isAnyOf(
103
- Be.AugAssign.targetIs(IfThis.isNestedNameIdentifier(identifier))
104
- , IfThis.isAllOf(
105
- Be.Assign.targetsIs(Be.at(0, IfThis.isNestedNameIdentifier(identifier)))
106
- , Be.Assign.valueIs(Be.Constant))
73
+ identifier: str = ast_arg.arg
74
+ annotation: ast.expr = raiseIfNone(ast_arg.annotation)
75
+
76
+ # ------- `identifier` is target of Augmented Assignment, or --------------
77
+ # ------- `identifier` is target of Assignment and value is Constant. -----
78
+ NodeChanger(
79
+ IfThis.isAnyOf(
80
+ Be.AugAssign.targetIs(IfThis.isNestedNameIdentifier(identifier))
81
+ , IfThis.isAllOf(Be.Assign.targetsIs(Be.at(0, IfThis.isNestedNameIdentifier(identifier)))
82
+ , Be.Assign.valueIs(Be.Constant))
107
83
  )
108
84
  , doThat=lambda node, annotation=annotation: Grab.valueAttribute(Then.replaceWith(Make.Call(annotation, listParameters=[node.value])))(node)
109
85
  ).visit(ingredientsFunction.astFunctionDef)
110
86
 
111
- # `identifier` - 1.
87
+ # ------- `identifier` - 1. ----------------------------------------------
112
88
  NodeChanger(Be.BinOp.leftIs(IfThis.isNestedNameIdentifier(identifier))
113
89
  , doThat=lambda node, annotation=annotation: Grab.rightAttribute(Then.replaceWith(Make.Call(annotation, listParameters=[node.right])))(node)
114
90
  ).visit(ingredientsFunction.astFunctionDef)
115
91
 
116
- # `identifier` in Comparison.
92
+ # ------- `identifier` in Comparison. -------------------------------------
117
93
  NodeChanger(Be.Compare.leftIs(IfThis.isNestedNameIdentifier(identifier))
118
94
  , doThat=lambda node, annotation=annotation: Grab.comparatorsAttribute(lambda at, annotation=annotation: Then.replaceWith([Make.Call(annotation, listParameters=[node.comparators[0]])])(at[0]))(node)
119
95
  ).visit(ingredientsFunction.astFunctionDef)
120
96
 
121
- # `identifier` has exactly one index value.
97
+ # ------- `identifier` has exactly one index value. -----------------------
122
98
  NodeChanger(IfThis.isAllOf(Be.Subscript.valueIs(IfThis.isNestedNameIdentifier(identifier))
123
99
  , lambda node: not Be.Subscript.sliceIs(Be.Tuple)(node))
124
100
  , doThat=lambda node: Grab.sliceAttribute(Then.replaceWith(Make.Call(Make.Name('int'), listParameters=[node.slice])))(node)
125
101
  ).visit(ingredientsFunction.astFunctionDef)
126
102
 
127
- # `identifier` has multiple index values.
103
+ # ------- `identifier` has multiple index values. -------------------------
128
104
  NodeChanger(IfThis.isAllOf(Be.Subscript.valueIs(IfThis.isNestedNameIdentifier(identifier))
129
- , Be.Subscript.sliceIs(Be.Tuple))
105
+ , Be.Subscript.sliceIs(Be.Tuple))
130
106
  , doThat=lambda node: Grab.sliceAttribute(Grab.eltsAttribute(
131
107
  Then.replaceWith([
132
- Make.Call(Make.Name('int'), listParameters=[cast('ast.Tuple', node.slice).elts[index]])
133
- for index in range(len(cast('ast.Tuple', node.slice).elts))])))(node)
108
+ Make.Call(Make.Name('int'), listParameters=[cast(ast.Tuple, node.slice).elts[index]])
109
+ for index in range(len(cast(ast.Tuple, node.slice).elts))])))(node)
134
110
  ).visit(ingredientsFunction.astFunctionDef)
135
111
 
136
112
  return ingredientsFunction
137
113
 
138
- def _move_arg2body(identifier: str, job: RecipeJobTheorem2) -> ast.AnnAssign | ast.Assign:
139
- Ima___Assign, elementConstructor = job.shatteredDataclass.Z0Z_field2AnnAssign[identifier]
140
- match elementConstructor:
141
- case 'scalar':
142
- cast('ast.Constant', cast('ast.Call', Ima___Assign.value).args[0]).value = int(job.state.__dict__[identifier])
143
- case 'array':
144
- dataAsStrRLE: str = autoDecodingRLE(job.state.__dict__[identifier], assumeAddSpaces=True)
145
- dataAs_ast_expr: ast.expr = _pythonCode2expr(dataAsStrRLE)
146
- cast('ast.Call', Ima___Assign.value).args = [dataAs_ast_expr]
147
- case _:
148
- pass
149
- return Ima___Assign
150
-
151
114
  def makeJob(job: RecipeJobTheorem2) -> None:
152
115
  """Generate an optimized module for map folding calculations.
153
116
 
@@ -157,35 +120,37 @@ def makeJob(job: RecipeJobTheorem2) -> None:
157
120
  Parameters
158
121
  ----------
159
122
  job : RecipeJobTheorem2
160
- Configuration recipe containing source locations, target paths, and state.
123
+ Configuration recipe containing source locations, target paths, raw materials, and state.
161
124
 
162
125
  """
163
- ingredientsCount: IngredientsFunction = IngredientsFunction(raiseIfNone(extractFunctionDef(job.source_astModule, job.countCallable)))
126
+ ingredientsCount: IngredientsFunction = IngredientsFunction(raiseIfNone(extractFunctionDef(job.source_astModule, job.identifierCallable)))
164
127
  ingredientsCount.astFunctionDef.decorator_list = []
165
128
 
166
129
  # Replace identifiers-with-static-values with their values.
167
- listIdentifiersStaticValues: list[str] = listIdentifiersStaticValuesHARDCODED
168
- for identifier in listIdentifiersStaticValues:
130
+ for identifier in job.shatteredDataclass.listIdentifiersStaticScalars:
169
131
  NodeChanger(IfThis.isNameIdentifier(identifier)
170
- , Then.replaceWith(Make.Constant(int(job.state.__dict__[identifier])))
132
+ , Then.replaceWith(Make.Constant(int(eval(f"job.state.{identifier}")))) # noqa: S307
171
133
  ).visit(ingredientsCount.astFunctionDef)
172
134
 
173
135
  ingredientsCount.imports.update(job.shatteredDataclass.imports)
174
- ingredientsCount = removeUnusedParameters(ingredientsCount)
175
- NodeChanger(Be.arg, lambda removeIt: ingredientsCount.astFunctionDef.body.insert(0, _move_arg2body(removeIt.arg, job))).visit(ingredientsCount.astFunctionDef)
136
+ ingredientsCount.removeUnusedParameters()
137
+ NodeChanger(Be.arg, lambda removeIt: ingredientsCount.astFunctionDef.body.insert(0, moveShatteredDataclass_arg2body(removeIt.arg, job))).visit(ingredientsCount.astFunctionDef)
176
138
 
177
139
  ingredientsCount = _addWriteFoldsTotal(ingredientsCount, job)
178
140
  ingredientsCount = _variableCompatibility(ingredientsCount, job)
179
141
 
180
142
  ingredientsModule = IngredientsModule(launcher=Make.Module([
181
143
  Make.If(Make.Compare(Make.Name('__name__'), [Make.Eq()], [Make.Constant('__main__')])
182
- , body=[Make.Expr(Make.Call(Make.Name(job.countCallable)))])]))
144
+ , body=[Make.Expr(Make.Call(Make.Name(job.identifierCallable)))])]))
145
+
146
+ ingredientsCount, ingredientsModule = customizeDatatypeViaImport(ingredientsCount, ingredientsModule, listDatatypeConfigurations)
183
147
 
184
- ingredientsCount, ingredientsModule = _datatypeDefinitions(ingredientsCount, ingredientsModule)
148
+ ingredientsCount.imports.removeImportFromModule('mapFolding.dataBaskets')
185
149
 
186
150
  ingredientsModule.appendIngredientsFunction(ingredientsCount)
187
151
 
188
152
  if sys.platform == 'linux':
153
+ Path(job.pathFilenameModule).parent.mkdir(parents=True, exist_ok=True)
189
154
  buildCommand: list[str] = ['codon', 'build', '--exe', '--release',
190
155
  '--fast-math', '--enable-unsafe-fp-math', '--disable-exceptions',
191
156
  '--mcpu=native',
@@ -193,13 +158,14 @@ def makeJob(job: RecipeJobTheorem2) -> None:
193
158
  '-']
194
159
  streamText = subprocess.Popen(buildCommand, stdin=subprocess.PIPE, text=True)
195
160
  if streamText.stdin is not None:
196
- write_astModule(ingredientsModule, pathFilename=cast('TextIOBase', streamText.stdin), packageName=job.packageIdentifier)
161
+ write_astModule(ingredientsModule, pathFilename=cast(TextIOBase, streamText.stdin), packageName=job.packageIdentifier)
197
162
  streamText.stdin.close()
198
163
  streamText.wait()
199
164
  subprocess.run(['/usr/bin/strip', str(job.pathFilenameModule.with_suffix(''))], check=False)
200
165
  sys.stdout.write(f"sudo systemd-run --unit={job.moduleIdentifier} --nice=-10 --property=CPUAffinity=0 {job.pathFilenameModule.with_suffix('')}\n")
201
166
  else:
202
- write_astModule(ingredientsModule, pathFilename=job.pathFilenameModule, packageName=job.packageIdentifier)
167
+ ingredientsModule.write_astModule(job.pathFilenameModule, identifierPackage=job.packageIdentifier or '')
168
+ sys.stdout.write(f"python {Path(job.pathFilenameModule)}\n")
203
169
 
204
170
  def fromMapShape(mapShape: tuple[DatatypeLeavesTotal, ...]) -> None:
205
171
  """Create a binary executable for a map-folding job from map dimensions.
@@ -214,14 +180,15 @@ def fromMapShape(mapShape: tuple[DatatypeLeavesTotal, ...]) -> None:
214
180
  along one axis.
215
181
 
216
182
  """
217
- state = transitionOnGroupsOfFolds(MapFoldingState(mapShape))
183
+ state: MapFoldingState = transitionOnGroupsOfFolds(MapFoldingState(mapShape))
218
184
  pathModule = PurePosixPath(Path.home(), 'mapFolding', 'jobs')
219
- source_astModule = parseLogicalPath2astModule('mapFolding.syntheticModules.theorem2A007822Numba')
185
+ logicalPath2astModule: identifierDotAttribute = f'{packageSettings.identifierPackage}.{default['logicalPath']['synthetic']}.theorem2Numba'
186
+ source_astModule: ast.Module = parseLogicalPath2astModule(logicalPath2astModule)
220
187
  pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(state.mapShape, pathModule))
221
188
  aJob = RecipeJobTheorem2(state, source_astModule=source_astModule, pathModule=pathModule, pathFilenameFoldsTotal=pathFilenameFoldsTotal)
222
189
  makeJob(aJob)
223
190
 
224
191
  if __name__ == '__main__':
225
- mapShape = (1, 3)
192
+ mapShape: tuple[DatatypeLeavesTotal, ...] = (1, 14)
226
193
  fromMapShape(mapShape)
227
194
 
@@ -3,19 +3,17 @@
3
3
  These transformation functions will work on at least two different algorithms. If a transformation function only works on a
4
4
  specific type of algorithm, it will be in a subdirectory.
5
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
6
+ from astToolkit import Be, DOT, Grab, identifierDotAttribute, Make, NodeChanger, NodeTourist, Then
7
+ from astToolkit.containers import (
8
+ astModuleToIngredientsFunction, IngredientsFunction, IngredientsModule, LedgerOfImports)
9
+ from astToolkit.transformationTools import inlineFunctionDef
10
10
  from hunterMakesPy import raiseIfNone
11
11
  from mapFolding import packageSettings
12
- from mapFolding.someAssemblyRequired import (
13
- identifierCallableSourceDEFAULT, identifierCountingDEFAULT, IfThis, ShatteredDataclass)
12
+ from mapFolding.someAssemblyRequired import default, Default, IfThis, ShatteredDataclass
14
13
  from mapFolding.someAssemblyRequired.toolkitMakeModules import findDataclass, getLogicalPath, getPathFilename
15
14
  from mapFolding.someAssemblyRequired.toolkitNumba import decorateCallableWithNumba, parametersNumbaLight
16
15
  from mapFolding.someAssemblyRequired.transformationTools import (
17
16
  removeDataclassFromFunction, shatter_dataclassesDOTdataclass, unpackDataclassCallFunctionRepackDataclass)
18
- from os import PathLike
19
17
  from pathlib import PurePath
20
18
  from typing import cast
21
19
  import ast
@@ -42,7 +40,7 @@ def makeMapFoldingNumba(astModule: ast.Module, identifierModule: str, identifier
42
40
  Filesystem path where the optimized module was written.
43
41
 
44
42
  """
45
- sourceCallableIdentifier: str = identifierCallableSourceDEFAULT
43
+ sourceCallableIdentifier: str = default['function']['counting']
46
44
  ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
47
45
  ingredientsFunction.astFunctionDef.name = identifierCallable or sourceCallableIdentifier
48
46
 
@@ -50,7 +48,7 @@ def makeMapFoldingNumba(astModule: ast.Module, identifierModule: str, identifier
50
48
 
51
49
  ingredientsFunction.imports.update(shatteredDataclass.imports)
52
50
  ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclass)
53
- ingredientsFunction = removeUnusedParameters(ingredientsFunction)
51
+ ingredientsFunction.removeUnusedParameters()
54
52
  ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
55
53
 
56
54
  ingredientsModule = IngredientsModule(ingredientsFunction)
@@ -61,7 +59,7 @@ def makeMapFoldingNumba(astModule: ast.Module, identifierModule: str, identifier
61
59
  ingredientsFunctionDispatcher.imports.update(shatteredDataclass.imports)
62
60
  targetCallableIdentifier = ingredientsFunction.astFunctionDef.name
63
61
  ingredientsFunctionDispatcher = unpackDataclassCallFunctionRepackDataclass(ingredientsFunctionDispatcher, targetCallableIdentifier, shatteredDataclass)
64
- astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
62
+ astTuple: ast.Tuple = cast(ast.Tuple, raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
65
63
  , doThat=Then.extractIt(DOT.value)).captureLastMatch(ingredientsFunction.astFunctionDef)))
66
64
  astTuple.ctx = Make.Store()
67
65
 
@@ -76,11 +74,11 @@ def makeMapFoldingNumba(astModule: ast.Module, identifierModule: str, identifier
76
74
 
77
75
  pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, identifierModule)
78
76
 
79
- write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
77
+ ingredientsModule.write_astModule(pathFilename, identifierPackage=packageSettings.identifierPackage)
80
78
 
81
79
  return pathFilename
82
80
 
83
- def makeTheorem2(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
81
+ def makeTheorem2(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None, identifiers: Default | None = None) -> PurePath:
84
82
  """Generate module by applying optimization predicted by Theorem 2.
85
83
 
86
84
  Parameters
@@ -101,19 +99,17 @@ def makeTheorem2(astModule: ast.Module, identifierModule: str, identifierCallabl
101
99
  pathFilename : PurePath
102
100
  Filesystem path where the theorem-optimized module was written.
103
101
  """
104
- identifierCallableInitializeDataclassHARDCODED = 'transitionOnGroupsOfFolds'
105
- identifierModuleInitializeDataclassHARDCODED = 'initializeState'
102
+ dictionaryIdentifiers = identifiers or default
103
+ identifierCallableInitializeDataclass = dictionaryIdentifiers['function']['initializeState']
104
+ identifierModuleInitializeDataclass = dictionaryIdentifiers['module']['initializeState']
106
105
 
107
- identifierCallableInitializeDataclass = identifierCallableInitializeDataclassHARDCODED
108
- identifierModuleInitializeDataclass = identifierModuleInitializeDataclassHARDCODED
109
-
110
- sourceCallableIdentifier = identifierCallableSourceDEFAULT
106
+ sourceCallableIdentifier = dictionaryIdentifiers['function']['counting']
111
107
  ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
112
108
  ingredientsFunction.astFunctionDef.name = identifierCallable or sourceCallableIdentifier
113
109
 
114
110
  dataclassInstanceIdentifier: str = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
115
111
 
116
- theCountingIdentifier: str = identifierCountingDEFAULT
112
+ theCountingIdentifier: str = dictionaryIdentifiers['variable']['counting']
117
113
  doubleTheCount: ast.AugAssign = Make.AugAssign(Make.Attribute(Make.Name(dataclassInstanceIdentifier), theCountingIdentifier), Make.Mult(), Make.Constant(2))
118
114
 
119
115
  NodeChanger(
@@ -162,7 +158,7 @@ def makeTheorem2(astModule: ast.Module, identifierModule: str, identifierCallabl
162
158
 
163
159
  # Update any calls to the original function name with the new target function name
164
160
  NodeChanger(
165
- findThis = Be.Call.funcIs(Be.Name.idIs(IfThis.isIdentifier(identifierCallableSourceDEFAULT)))
161
+ findThis = Be.Call.funcIs(Be.Name.idIs(IfThis.isIdentifier(dictionaryIdentifiers['function']['counting'])))
166
162
  , doThat = Grab.funcAttribute(Grab.idAttribute(Then.replaceWith(targetCallableIdentifier)))
167
163
  ).visit(ingredientsFunctionDispatcher.astFunctionDef)
168
164
 
@@ -178,11 +174,11 @@ def makeTheorem2(astModule: ast.Module, identifierModule: str, identifierCallabl
178
174
 
179
175
  pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, identifierModule)
180
176
 
181
- write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
177
+ ingredientsModule.write_astModule(pathFilename, identifierPackage=packageSettings.identifierPackage)
182
178
 
183
179
  return pathFilename
184
180
 
185
- def numbaOnTheorem2(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
181
+ def numbaOnTheorem2(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
186
182
  """Generate Numba-accelerated Theorem 2 implementation with dataclass decomposition.
187
183
 
188
184
  Parameters
@@ -204,7 +200,7 @@ def numbaOnTheorem2(astModule: ast.Module, identifierModule: str, identifierCall
204
200
  Filesystem path where the accelerated module was written.
205
201
 
206
202
  """
207
- sourceCallableIdentifier = identifierCallableSourceDEFAULT
203
+ sourceCallableIdentifier = default['function']['counting']
208
204
  ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
209
205
  ingredientsFunction.astFunctionDef.name = identifierCallable or sourceCallableIdentifier
210
206
 
@@ -214,7 +210,7 @@ def numbaOnTheorem2(astModule: ast.Module, identifierModule: str, identifierCall
214
210
 
215
211
  ingredientsFunction.imports.update(shatteredDataclass.imports)
216
212
  ingredientsFunction: IngredientsFunction = removeDataclassFromFunction(ingredientsFunction, shatteredDataclass)
217
- ingredientsFunction = removeUnusedParameters(ingredientsFunction)
213
+ ingredientsFunction.removeUnusedParameters()
218
214
  ingredientsFunction = decorateCallableWithNumba(ingredientsFunction, parametersNumbaLight)
219
215
 
220
216
  ingredientsModule = IngredientsModule(ingredientsFunction)
@@ -225,7 +221,7 @@ def numbaOnTheorem2(astModule: ast.Module, identifierModule: str, identifierCall
225
221
  ingredientsFunctionDispatcher.imports.update(shatteredDataclass.imports)
226
222
  targetCallableIdentifier = ingredientsFunction.astFunctionDef.name
227
223
  ingredientsFunctionDispatcher = unpackDataclassCallFunctionRepackDataclass(ingredientsFunctionDispatcher, targetCallableIdentifier, shatteredDataclass)
228
- astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
224
+ astTuple: ast.Tuple = cast(ast.Tuple, raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
229
225
  , doThat=Then.extractIt(DOT.value)).captureLastMatch(ingredientsFunction.astFunctionDef)))
230
226
  astTuple.ctx = Make.Store()
231
227
 
@@ -240,11 +236,11 @@ def numbaOnTheorem2(astModule: ast.Module, identifierModule: str, identifierCall
240
236
 
241
237
  pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, identifierModule)
242
238
 
243
- write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
239
+ ingredientsModule.write_astModule(pathFilename, identifierPackage=packageSettings.identifierPackage)
244
240
 
245
241
  return pathFilename
246
242
 
247
- def trimTheorem2(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
243
+ def trimTheorem2(astModule: ast.Module, identifierModule: str, identifierCallable: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath:
248
244
  """Generate constrained Theorem 2 implementation by removing unnecessary logic.
249
245
 
250
246
  Parameters
@@ -266,7 +262,7 @@ def trimTheorem2(astModule: ast.Module, identifierModule: str, identifierCallabl
266
262
  Filesystem path where the trimmed module was written.
267
263
 
268
264
  """
269
- sourceCallableIdentifier: str = identifierCallableSourceDEFAULT
265
+ sourceCallableIdentifier: str = default['function']['counting']
270
266
  ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
271
267
  ingredientsFunction.astFunctionDef.name = identifierCallable or sourceCallableIdentifier
272
268
 
@@ -286,7 +282,7 @@ def trimTheorem2(astModule: ast.Module, identifierModule: str, identifierCallabl
286
282
 
287
283
  # Update any calls to the original function name with the new target function name
288
284
  NodeChanger(
289
- findThis = Be.Call.funcIs(Be.Name.idIs(IfThis.isIdentifier(identifierCallableSourceDEFAULT)))
285
+ findThis = Be.Call.funcIs(Be.Name.idIs(IfThis.isIdentifier(default['function']['counting'])))
290
286
  , doThat = Grab.funcAttribute(Grab.idAttribute(Then.replaceWith(targetCallableIdentifier)))
291
287
  ).visit(ingredientsFunctionDispatcher.astFunctionDef)
292
288
 
@@ -294,7 +290,7 @@ def trimTheorem2(astModule: ast.Module, identifierModule: str, identifierCallabl
294
290
 
295
291
  pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, identifierModule)
296
292
 
297
- write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
293
+ ingredientsModule.write_astModule(pathFilename, identifierPackage=packageSettings.identifierPackage)
298
294
 
299
295
  return pathFilename
300
296
 
@@ -1,23 +1,15 @@
1
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
2
+ from astToolkit import Be, DOT, Grab, identifierDotAttribute, NodeChanger, NodeTourist, Then
3
+ from astToolkit.containers import IngredientsFunction, IngredientsModule, LedgerOfImports
4
+ from astToolkit.transformationTools import inlineFunctionDef
6
5
  from hunterMakesPy import raiseIfNone
7
6
  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
7
+ from mapFolding.someAssemblyRequired import default, Default, IfThis
8
+ from mapFolding.someAssemblyRequired.toolkitMakeModules import getPathFilename
16
9
  from pathlib import PurePath
17
- from typing import cast
18
10
  import ast
19
11
 
20
- def makeInitializeState(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None) -> PurePath: # noqa: ARG001
12
+ def makeInitializeState(astModule: ast.Module, moduleIdentifier: str, callableIdentifier: str | None = None, logicalPathInfix: identifierDotAttribute | None = None, sourceCallableDispatcher: str | None = None, identifiers: Default | None = None) -> PurePath: # noqa: ARG001
21
13
  """Generate initialization module for counting variable setup.
22
14
 
23
15
  (AI generated docstring)
@@ -49,73 +41,19 @@ def makeInitializeState(astModule: ast.Module, moduleIdentifier: str, callableId
49
41
  Filesystem path where the initialization module was written.
50
42
 
51
43
  """
52
- sourceCallableIdentifier: identifierDotAttribute = identifierCallableSourceDEFAULT
44
+ dictionaryIdentifiers: Default = identifiers or default
45
+ sourceCallableIdentifier: identifierDotAttribute = dictionaryIdentifiers['function']['counting']
53
46
  ingredientsFunction = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule), LedgerOfImports(astModule))
54
47
  ingredientsFunction.astFunctionDef.name = callableIdentifier or sourceCallableIdentifier
55
48
 
56
49
  dataclassInstanceIdentifier: identifierDotAttribute = raiseIfNone(NodeTourist(Be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef))
57
- theCountingIdentifier: identifierDotAttribute = identifierCountingDEFAULT
50
+ theCountingIdentifier: identifierDotAttribute = dictionaryIdentifiers['variable']['counting']
58
51
 
59
52
  findThis = IfThis.isWhileAttributeNamespaceIdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
60
53
  doThat = Grab.testAttribute(Grab.andDoAllOf([Grab.opsAttribute(Then.replaceWith([ast.Eq()])), Grab.leftAttribute(Grab.attrAttribute(Then.replaceWith(theCountingIdentifier)))]))
61
54
  NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef.body[0])
62
55
 
63
56
  pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
64
- write_astModule(IngredientsModule(ingredientsFunction), pathFilename, packageSettings.identifierPackage)
57
+ IngredientsModule(ingredientsFunction).write_astModule(pathFilename, identifierPackage=packageSettings.identifierPackage)
65
58
 
66
59
  return pathFilename
67
-
68
- def makeUnRePackDataclass(astImportFrom: ast.ImportFrom, moduleIdentifier: str = identifierModuleDataPackingDEFAULT) -> PurePath:
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
- moduleIdentifier : str = identifierModuleDataPackingDEFAULT
77
- Name for the generated interface module.
78
-
79
- Returns
80
- -------
81
- pathFilename : PurePath
82
- Filesystem path where the interface module was written.
83
- """
84
- callableIdentifierHARDCODED: str = 'sequential'
85
-
86
- algorithmSourceModule: identifierDotAttribute = identifierModuleSourceAlgorithmDEFAULT
87
- callableIdentifier: str = callableIdentifierHARDCODED
88
- logicalPathInfix: identifierDotAttribute = logicalPathInfixDEFAULT
89
- logicalPathInfixAlgorithm: identifierDotAttribute = logicalPathInfixAlgorithmDEFAULT
90
- sourceCallableIdentifier: str = identifierCallableSourceDispatcherDEFAULT
91
-
92
- logicalPathSourceModule: identifierDotAttribute = '.'.join([packageSettings.identifierPackage, logicalPathInfixAlgorithm, algorithmSourceModule]) # noqa: FLY002
93
-
94
- ingredientsFunction: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
95
- ingredientsFunction.astFunctionDef.name = callableIdentifier
96
-
97
- shatteredDataclass: ShatteredDataclass = shatter_dataclassesDOTdataclass(*findDataclass(ingredientsFunction))
98
-
99
- ingredientsFunction.imports.update(shatteredDataclass.imports)
100
- ingredientsFunction.imports.addAst(astImportFrom)
101
- targetCallableIdentifier: str = astImportFrom.names[0].name
102
- ingredientsFunction = raiseIfNone(unpackDataclassCallFunctionRepackDataclass(ingredientsFunction, targetCallableIdentifier, shatteredDataclass))
103
- targetFunctionDef: ast.FunctionDef = raiseIfNone(extractFunctionDef(parseLogicalPath2astModule(raiseIfNone(astImportFrom.module)), targetCallableIdentifier))
104
- astTuple: ast.Tuple = cast('ast.Tuple', raiseIfNone(NodeTourist(Be.Return.valueIs(Be.Tuple)
105
- , doThat=Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)))
106
- astTuple.ctx = Make.Store()
107
-
108
- changeAssignCallToTarget = NodeChanger(
109
- findThis = Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier))
110
- , doThat = Then.replaceWith(Make.Assign([astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts))))
111
- changeAssignCallToTarget.visit(ingredientsFunction.astFunctionDef)
112
-
113
- ingredientsModule = IngredientsModule(ingredientsFunction)
114
- ingredientsModule.removeImportFromModule('numpy')
115
-
116
- pathFilename: PurePath = getPathFilename(packageSettings.pathPackage, logicalPathInfix, moduleIdentifier)
117
-
118
- write_astModule(ingredientsModule, pathFilename, packageSettings.identifierPackage)
119
-
120
- return pathFilename
121
-