mapFolding 0.9.3__py3-none-any.whl → 0.9.5__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.
- mapFolding/__init__.py +41 -7
- mapFolding/basecamp.py +100 -9
- mapFolding/beDRY.py +7 -15
- mapFolding/dataBaskets.py +12 -0
- mapFolding/datatypes.py +4 -4
- mapFolding/oeis.py +2 -7
- mapFolding/someAssemblyRequired/RecipeJob.py +97 -3
- mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +326 -0
- mapFolding/someAssemblyRequired/__init__.py +37 -29
- mapFolding/someAssemblyRequired/_theTypes.py +19 -19
- mapFolding/someAssemblyRequired/_tool_Make.py +12 -6
- mapFolding/someAssemblyRequired/_tool_Then.py +59 -21
- mapFolding/someAssemblyRequired/_toolboxAST.py +57 -0
- mapFolding/someAssemblyRequired/_toolboxAntecedents.py +123 -40
- mapFolding/someAssemblyRequired/_toolboxContainers.py +128 -37
- mapFolding/someAssemblyRequired/_toolboxPython.py +52 -50
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +274 -0
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +6 -4
- mapFolding/someAssemblyRequired/toolboxNumba.py +3 -27
- mapFolding/someAssemblyRequired/transformationTools.py +47 -177
- mapFolding/syntheticModules/daoOfMapFolding.py +74 -0
- mapFolding/syntheticModules/dataPacking.py +25 -0
- mapFolding/syntheticModules/initializeCount.py +49 -0
- mapFolding/syntheticModules/theorem2.py +49 -0
- mapFolding/syntheticModules/theorem2Numba.py +45 -0
- mapFolding/syntheticModules/theorem2Trimmed.py +43 -0
- {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/METADATA +2 -1
- mapfolding-0.9.5.dist-info/RECORD +59 -0
- {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/WHEEL +1 -1
- tests/test_computations.py +4 -2
- mapFolding/Z0Z_flowControl.py +0 -99
- mapfolding-0.9.3.dist-info/RECORD +0 -51
- /mapFolding/{theDaoOfMapFolding.py → daoOfMapFolding.py} +0 -0
- {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.9.3.dist-info → mapfolding-0.9.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
from mapFolding import raiseIfNoneGitHubIssueNumber3, The
|
|
2
|
+
from mapFolding.someAssemblyRequired import (
|
|
3
|
+
ast_Identifier,
|
|
4
|
+
astModuleToIngredientsFunction,
|
|
5
|
+
be,
|
|
6
|
+
DOT,
|
|
7
|
+
extractFunctionDef,
|
|
8
|
+
grab,
|
|
9
|
+
ifThis,
|
|
10
|
+
IngredientsFunction,
|
|
11
|
+
IngredientsModule,
|
|
12
|
+
LedgerOfImports,
|
|
13
|
+
Make,
|
|
14
|
+
NodeChanger,
|
|
15
|
+
NodeTourist,
|
|
16
|
+
parseLogicalPath2astModule,
|
|
17
|
+
parsePathFilename2astModule,
|
|
18
|
+
Then,
|
|
19
|
+
str_nameDOTname,
|
|
20
|
+
)
|
|
21
|
+
from mapFolding.someAssemblyRequired.toolboxNumba import decorateCallableWithNumba, parametersNumbaLight
|
|
22
|
+
from mapFolding.someAssemblyRequired.transformationTools import (
|
|
23
|
+
inlineFunctionDef,
|
|
24
|
+
removeDataclassFromFunction,
|
|
25
|
+
removeUnusedParameters,
|
|
26
|
+
shatter_dataclassesDOTdataclass,
|
|
27
|
+
unpackDataclassCallFunctionRepackDataclass,
|
|
28
|
+
write_astModule,
|
|
29
|
+
)
|
|
30
|
+
from pathlib import PurePath
|
|
31
|
+
import ast
|
|
32
|
+
|
|
33
|
+
algorithmSourceModuleHARDCODED = 'daoOfMapFolding'
|
|
34
|
+
sourceCallableIdentifierHARDCODED = 'count'
|
|
35
|
+
logicalPathInfixHARDCODED: ast_Identifier = 'syntheticModules'
|
|
36
|
+
theCountingIdentifierHARDCODED: ast_Identifier = 'groupsOfFolds'
|
|
37
|
+
|
|
38
|
+
def makeInitializeGroupsOfFolds():
|
|
39
|
+
callableIdentifierHARDCODED = 'initializeGroupsOfFolds'
|
|
40
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'initializeCount'
|
|
41
|
+
|
|
42
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
43
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
44
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
45
|
+
|
|
46
|
+
callableIdentifier = callableIdentifierHARDCODED
|
|
47
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
48
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
49
|
+
|
|
50
|
+
astModule = parseLogicalPath2astModule(logicalPathSourceModule)
|
|
51
|
+
countInitializeIngredients = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule)
|
|
52
|
+
, LedgerOfImports(astModule))
|
|
53
|
+
|
|
54
|
+
countInitializeIngredients.astFunctionDef.name = callableIdentifier
|
|
55
|
+
|
|
56
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(countInitializeIngredients.astFunctionDef)
|
|
57
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
58
|
+
theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
59
|
+
|
|
60
|
+
findThis = ifThis.isWhileAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
61
|
+
doThat = grab.testAttribute(grab.andDoAllOf([
|
|
62
|
+
grab.opsAttribute(Then.replaceWith([ast.Eq()])), # type: ignore
|
|
63
|
+
grab.leftAttribute(grab.attrAttribute(Then.replaceWith(theCountingIdentifier))) # type: ignore
|
|
64
|
+
]))
|
|
65
|
+
NodeChanger(findThis, doThat).visit(countInitializeIngredients.astFunctionDef.body[0])
|
|
66
|
+
|
|
67
|
+
ingredientsModule = IngredientsModule(countInitializeIngredients)
|
|
68
|
+
|
|
69
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
70
|
+
|
|
71
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
72
|
+
|
|
73
|
+
def makeDaoOfMapFolding():
|
|
74
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'daoOfMapFolding'
|
|
75
|
+
|
|
76
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
77
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
78
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
79
|
+
|
|
80
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
81
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
82
|
+
|
|
83
|
+
astModule = parseLogicalPath2astModule(logicalPathSourceModule)
|
|
84
|
+
daoOfMapFolding = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule)
|
|
85
|
+
, LedgerOfImports(astModule))
|
|
86
|
+
|
|
87
|
+
dataclassName: ast.expr | None = NodeTourist(be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(daoOfMapFolding.astFunctionDef)
|
|
88
|
+
if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
|
|
89
|
+
dataclass_Identifier: ast_Identifier | None = NodeTourist(be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
|
|
90
|
+
if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
91
|
+
|
|
92
|
+
dataclassLogicalPathModule = None
|
|
93
|
+
for moduleWithLogicalPath, listNameTuples in daoOfMapFolding.imports.dictionaryImportFrom.items():
|
|
94
|
+
for nameTuple in listNameTuples:
|
|
95
|
+
if nameTuple[0] == dataclass_Identifier:
|
|
96
|
+
dataclassLogicalPathModule = moduleWithLogicalPath
|
|
97
|
+
break
|
|
98
|
+
if dataclassLogicalPathModule:
|
|
99
|
+
break
|
|
100
|
+
if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
|
|
101
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(daoOfMapFolding.astFunctionDef)
|
|
102
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
103
|
+
shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
|
|
104
|
+
|
|
105
|
+
# theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
106
|
+
# doubleTheCount = Make.AugAssign(Make.Attribute(ast.Name(dataclassInstanceIdentifier), theCountingIdentifier), ast.Mult(), Make.Constant(2))
|
|
107
|
+
# findThis = be.Return
|
|
108
|
+
# doThat = Then.insertThisAbove([doubleTheCount])
|
|
109
|
+
# NodeChanger(findThis, doThat).visit(daoOfMapFolding.astFunctionDef)
|
|
110
|
+
|
|
111
|
+
daoOfMapFolding.imports.update(shatteredDataclass.imports)
|
|
112
|
+
daoOfMapFolding = removeDataclassFromFunction(daoOfMapFolding, shatteredDataclass)
|
|
113
|
+
|
|
114
|
+
daoOfMapFolding = removeUnusedParameters(daoOfMapFolding)
|
|
115
|
+
|
|
116
|
+
daoOfMapFolding = decorateCallableWithNumba(daoOfMapFolding, parametersNumbaLight)
|
|
117
|
+
|
|
118
|
+
sourceCallableIdentifier = The.sourceCallableDispatcher
|
|
119
|
+
|
|
120
|
+
doTheNeedful: IngredientsFunction = astModuleToIngredientsFunction(astModule, sourceCallableIdentifier)
|
|
121
|
+
doTheNeedful.imports.update(shatteredDataclass.imports)
|
|
122
|
+
targetCallableIdentifier = daoOfMapFolding.astFunctionDef.name
|
|
123
|
+
doTheNeedful = unpackDataclassCallFunctionRepackDataclass(doTheNeedful, targetCallableIdentifier, shatteredDataclass)
|
|
124
|
+
astTuple: ast.Tuple | None = NodeTourist(be.Return, Then.extractIt(DOT.value)).captureLastMatch(daoOfMapFolding.astFunctionDef)
|
|
125
|
+
if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
|
|
126
|
+
astTuple.ctx = ast.Store()
|
|
127
|
+
|
|
128
|
+
findThis = ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(targetCallableIdentifier))
|
|
129
|
+
doThat = Then.replaceWith(Make.Assign(listTargets=[astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
|
|
130
|
+
NodeChanger(findThis, doThat).visit(doTheNeedful.astFunctionDef)
|
|
131
|
+
|
|
132
|
+
ingredientsModule = IngredientsModule([daoOfMapFolding, doTheNeedful])
|
|
133
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
134
|
+
|
|
135
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
136
|
+
|
|
137
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
138
|
+
|
|
139
|
+
return pathFilename
|
|
140
|
+
|
|
141
|
+
def makeTheorem2():
|
|
142
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'theorem2'
|
|
143
|
+
|
|
144
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
145
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
146
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
147
|
+
|
|
148
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
149
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
150
|
+
|
|
151
|
+
astModule = parseLogicalPath2astModule(logicalPathSourceModule)
|
|
152
|
+
countTheorem2 = IngredientsFunction(inlineFunctionDef(sourceCallableIdentifier, astModule)
|
|
153
|
+
, LedgerOfImports(astModule))
|
|
154
|
+
|
|
155
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(countTheorem2.astFunctionDef)
|
|
156
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
157
|
+
|
|
158
|
+
findThis = ifThis.isWhileAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
159
|
+
doThat = grab.testAttribute(grab.comparatorsAttribute(Then.replaceWith([Make.Constant(4)]))) # type: ignore
|
|
160
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
161
|
+
|
|
162
|
+
findThis = ifThis.isIfAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
163
|
+
doThat = Then.extractIt(DOT.body)
|
|
164
|
+
insertLeaf = NodeTourist(findThis, doThat).captureLastMatch(countTheorem2.astFunctionDef)
|
|
165
|
+
findThis = ifThis.isIfAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
166
|
+
doThat = Then.replaceWith(insertLeaf)
|
|
167
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
168
|
+
|
|
169
|
+
findThis = ifThis.isAttributeNamespace_IdentifierGreaterThan0(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
170
|
+
doThat = Then.removeIt
|
|
171
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
172
|
+
|
|
173
|
+
findThis = ifThis.isAttributeNamespace_IdentifierLessThanOrEqual(dataclassInstanceIdentifier, 'leaf1ndex')
|
|
174
|
+
doThat = Then.removeIt
|
|
175
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
176
|
+
|
|
177
|
+
theCountingIdentifier = theCountingIdentifierHARDCODED
|
|
178
|
+
doubleTheCount = Make.AugAssign(Make.Attribute(ast.Name(dataclassInstanceIdentifier), theCountingIdentifier), ast.Mult(), Make.Constant(2))
|
|
179
|
+
findThis = be.Return
|
|
180
|
+
doThat = Then.insertThisAbove([doubleTheCount])
|
|
181
|
+
NodeChanger(findThis, doThat).visit(countTheorem2.astFunctionDef)
|
|
182
|
+
|
|
183
|
+
ingredientsModule = IngredientsModule(countTheorem2)
|
|
184
|
+
|
|
185
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
186
|
+
|
|
187
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
188
|
+
|
|
189
|
+
return pathFilename
|
|
190
|
+
|
|
191
|
+
def trimTheorem2(pathFilenameSource: PurePath):
|
|
192
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
193
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
194
|
+
ingredientsFunction = astModuleToIngredientsFunction(parsePathFilename2astModule(pathFilenameSource), sourceCallableIdentifier)
|
|
195
|
+
|
|
196
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(ingredientsFunction.astFunctionDef)
|
|
197
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
198
|
+
|
|
199
|
+
findThis = ifThis.isIfUnaryNotAttributeNamespace_Identifier(dataclassInstanceIdentifier, 'dimensionsUnconstrained')
|
|
200
|
+
doThat = Then.removeIt
|
|
201
|
+
NodeChanger(findThis, doThat).visit(ingredientsFunction.astFunctionDef)
|
|
202
|
+
|
|
203
|
+
ingredientsModule = IngredientsModule(ingredientsFunction)
|
|
204
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
205
|
+
|
|
206
|
+
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem + 'Trimmed')
|
|
207
|
+
|
|
208
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
209
|
+
|
|
210
|
+
logicalPath: list[str] = []
|
|
211
|
+
if The.packageName:
|
|
212
|
+
logicalPath.append(The.packageName)
|
|
213
|
+
if logicalPathInfix:
|
|
214
|
+
logicalPath.append(logicalPathInfix)
|
|
215
|
+
logicalPath.append(pathFilename.stem)
|
|
216
|
+
moduleWithLogicalPath: str_nameDOTname = '.'.join(logicalPath)
|
|
217
|
+
|
|
218
|
+
astImportFrom: ast.ImportFrom = Make.ImportFrom(moduleWithLogicalPath, list_astAlias=[Make.alias(ingredientsFunction.astFunctionDef.name)])
|
|
219
|
+
|
|
220
|
+
return pathFilename
|
|
221
|
+
|
|
222
|
+
def numbaOnTheorem2(pathFilenameSource: PurePath):
|
|
223
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
224
|
+
sourceCallableIdentifier = sourceCallableIdentifierHARDCODED
|
|
225
|
+
countNumbaTheorem2 = astModuleToIngredientsFunction(parsePathFilename2astModule(pathFilenameSource), sourceCallableIdentifier)
|
|
226
|
+
dataclassName: ast.expr | None = NodeTourist(be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(countNumbaTheorem2.astFunctionDef)
|
|
227
|
+
if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
|
|
228
|
+
dataclass_Identifier: ast_Identifier | None = NodeTourist(be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
|
|
229
|
+
if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
230
|
+
|
|
231
|
+
dataclassLogicalPathModule = None
|
|
232
|
+
for moduleWithLogicalPath, listNameTuples in countNumbaTheorem2.imports.dictionaryImportFrom.items():
|
|
233
|
+
for nameTuple in listNameTuples:
|
|
234
|
+
if nameTuple[0] == dataclass_Identifier:
|
|
235
|
+
dataclassLogicalPathModule = moduleWithLogicalPath
|
|
236
|
+
break
|
|
237
|
+
if dataclassLogicalPathModule:
|
|
238
|
+
break
|
|
239
|
+
if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
|
|
240
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(countNumbaTheorem2.astFunctionDef)
|
|
241
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
242
|
+
shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
|
|
243
|
+
|
|
244
|
+
countNumbaTheorem2.imports.update(shatteredDataclass.imports)
|
|
245
|
+
countNumbaTheorem2 = removeDataclassFromFunction(countNumbaTheorem2, shatteredDataclass)
|
|
246
|
+
|
|
247
|
+
countNumbaTheorem2 = removeUnusedParameters(countNumbaTheorem2)
|
|
248
|
+
|
|
249
|
+
countNumbaTheorem2 = decorateCallableWithNumba(countNumbaTheorem2, parametersNumbaLight)
|
|
250
|
+
|
|
251
|
+
ingredientsModule = IngredientsModule(countNumbaTheorem2)
|
|
252
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
253
|
+
|
|
254
|
+
pathFilename = pathFilenameSource.with_stem(pathFilenameSource.stem.replace('Trimmed', '') + 'Numba')
|
|
255
|
+
|
|
256
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
257
|
+
|
|
258
|
+
logicalPath: list[str] = []
|
|
259
|
+
if The.packageName:
|
|
260
|
+
logicalPath.append(The.packageName)
|
|
261
|
+
if logicalPathInfix:
|
|
262
|
+
logicalPath.append(logicalPathInfix)
|
|
263
|
+
logicalPath.append(pathFilename.stem)
|
|
264
|
+
moduleWithLogicalPath: str_nameDOTname = '.'.join(logicalPath)
|
|
265
|
+
|
|
266
|
+
astImportFrom: ast.ImportFrom = Make.ImportFrom(moduleWithLogicalPath, list_astAlias=[Make.alias(countNumbaTheorem2.astFunctionDef.name)])
|
|
267
|
+
|
|
268
|
+
return astImportFrom
|
|
269
|
+
|
|
270
|
+
def makeUnRePackDataclass(astImportFrom: ast.ImportFrom):
|
|
271
|
+
moduleIdentifierHARDCODED: ast_Identifier = 'dataPacking'
|
|
272
|
+
|
|
273
|
+
algorithmSourceModule = algorithmSourceModuleHARDCODED
|
|
274
|
+
sourceCallableIdentifier = The.sourceCallableDispatcher
|
|
275
|
+
logicalPathSourceModule = '.'.join([The.packageName, algorithmSourceModule])
|
|
276
|
+
|
|
277
|
+
logicalPathInfix = logicalPathInfixHARDCODED
|
|
278
|
+
moduleIdentifier = moduleIdentifierHARDCODED
|
|
279
|
+
|
|
280
|
+
doTheNeedful: IngredientsFunction = astModuleToIngredientsFunction(parseLogicalPath2astModule(logicalPathSourceModule), sourceCallableIdentifier)
|
|
281
|
+
dataclassName: ast.expr | None = NodeTourist(be.arg, Then.extractIt(DOT.annotation)).captureLastMatch(doTheNeedful.astFunctionDef)
|
|
282
|
+
if dataclassName is None: raise raiseIfNoneGitHubIssueNumber3
|
|
283
|
+
dataclass_Identifier: ast_Identifier | None = NodeTourist(be.Name, Then.extractIt(DOT.id)).captureLastMatch(dataclassName)
|
|
284
|
+
if dataclass_Identifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
285
|
+
|
|
286
|
+
dataclassLogicalPathModule = None
|
|
287
|
+
for moduleWithLogicalPath, listNameTuples in doTheNeedful.imports.dictionaryImportFrom.items():
|
|
288
|
+
for nameTuple in listNameTuples:
|
|
289
|
+
if nameTuple[0] == dataclass_Identifier:
|
|
290
|
+
dataclassLogicalPathModule = moduleWithLogicalPath
|
|
291
|
+
break
|
|
292
|
+
if dataclassLogicalPathModule:
|
|
293
|
+
break
|
|
294
|
+
if dataclassLogicalPathModule is None: raise raiseIfNoneGitHubIssueNumber3
|
|
295
|
+
dataclassInstanceIdentifier = NodeTourist(be.arg, Then.extractIt(DOT.arg)).captureLastMatch(doTheNeedful.astFunctionDef)
|
|
296
|
+
if dataclassInstanceIdentifier is None: raise raiseIfNoneGitHubIssueNumber3
|
|
297
|
+
shatteredDataclass = shatter_dataclassesDOTdataclass(dataclassLogicalPathModule, dataclass_Identifier, dataclassInstanceIdentifier)
|
|
298
|
+
|
|
299
|
+
doTheNeedful.imports.update(shatteredDataclass.imports)
|
|
300
|
+
doTheNeedful.imports.addAst(astImportFrom)
|
|
301
|
+
targetCallableIdentifier = astImportFrom.names[0].name
|
|
302
|
+
doTheNeedful = unpackDataclassCallFunctionRepackDataclass(doTheNeedful, targetCallableIdentifier, shatteredDataclass)
|
|
303
|
+
targetFunctionDef = extractFunctionDef(parseLogicalPath2astModule(astImportFrom.module), targetCallableIdentifier) # type: ignore
|
|
304
|
+
if targetFunctionDef is None: raise raiseIfNoneGitHubIssueNumber3
|
|
305
|
+
astTuple: ast.Tuple | None = NodeTourist(be.Return, Then.extractIt(DOT.value)).captureLastMatch(targetFunctionDef)
|
|
306
|
+
if astTuple is None: raise raiseIfNoneGitHubIssueNumber3
|
|
307
|
+
astTuple.ctx = ast.Store()
|
|
308
|
+
|
|
309
|
+
findThis = ifThis.isAssignAndValueIs(ifThis.isCall_Identifier(targetCallableIdentifier))
|
|
310
|
+
doThat = Then.replaceWith(Make.Assign(listTargets=[astTuple], value=Make.Call(Make.Name(targetCallableIdentifier), astTuple.elts)))
|
|
311
|
+
NodeChanger(findThis, doThat).visit(doTheNeedful.astFunctionDef)
|
|
312
|
+
|
|
313
|
+
ingredientsModule = IngredientsModule(doTheNeedful)
|
|
314
|
+
ingredientsModule.removeImportFromModule('numpy')
|
|
315
|
+
|
|
316
|
+
pathFilename = PurePath(The.pathPackage, logicalPathInfix, moduleIdentifier + The.fileExtension)
|
|
317
|
+
|
|
318
|
+
write_astModule(ingredientsModule, pathFilename, The.packageName)
|
|
319
|
+
|
|
320
|
+
if __name__ == '__main__':
|
|
321
|
+
makeInitializeGroupsOfFolds()
|
|
322
|
+
pathFilename = makeTheorem2()
|
|
323
|
+
pathFilename = trimTheorem2(pathFilename)
|
|
324
|
+
astImportFrom = numbaOnTheorem2(pathFilename)
|
|
325
|
+
makeUnRePackDataclass(astImportFrom)
|
|
326
|
+
makeDaoOfMapFolding()
|
|
@@ -1,63 +1,64 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Code Transformation Framework for Algorithm Optimization and Testing
|
|
3
3
|
|
|
4
|
-
This package implements a comprehensive framework for programmatically analyzing,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
functional implementations into highly-optimized variants with verified correctness.
|
|
4
|
+
This package implements a comprehensive framework for programmatically analyzing, transforming, and generating optimized
|
|
5
|
+
Python code. It serves as the algorithmic optimization engine for the mapFolding package, enabling the conversion of
|
|
6
|
+
readable, functional implementations into highly-optimized variants with verified correctness.
|
|
8
7
|
|
|
9
8
|
## Core Architecture Components
|
|
10
9
|
|
|
11
10
|
1. **AST Manipulation Tools**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
- Pattern recognition with composable predicates (ifThis)
|
|
12
|
+
- Node access with consistent interfaces (DOT)
|
|
13
|
+
- AST traversal and transformation (NodeChanger, NodeTourist)
|
|
14
|
+
- AST construction with sane defaults (Make)
|
|
15
|
+
- Node transformation operations (grab, Then)
|
|
17
16
|
|
|
18
17
|
2. **Container and Organization**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
- Import tracking and management (LedgerOfImports)
|
|
19
|
+
- Function packaging with dependencies (IngredientsFunction)
|
|
20
|
+
- Module assembly with structured components (IngredientsModule)
|
|
21
|
+
- Recipe configuration for generating optimized code (RecipeSynthesizeFlow)
|
|
22
|
+
- Dataclass decomposition for compatibility (ShatteredDataclass)
|
|
24
23
|
|
|
25
24
|
3. **Optimization assembly lines**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
- General-purpose Numba acceleration (makeNumbaFlow)
|
|
26
|
+
- Job-specific optimization for concrete parameters (makeJobNumba)
|
|
27
|
+
- Specialized component transformation (decorateCallableWithNumba)
|
|
29
28
|
|
|
30
29
|
## Integration with Testing Framework
|
|
31
30
|
|
|
32
|
-
The transformation components are extensively tested through the package's test suite,
|
|
33
|
-
|
|
34
|
-
process and the resulting optimized code:
|
|
31
|
+
The transformation components are extensively tested through the package's test suite, which provides specialized
|
|
32
|
+
fixtures and utilities for validating both the transformation process and the resulting optimized code:
|
|
35
33
|
|
|
36
|
-
- **syntheticDispatcherFixture**: Creates and tests a complete Numba-optimized module
|
|
37
|
-
|
|
34
|
+
- **syntheticDispatcherFixture**: Creates and tests a complete Numba-optimized module using RecipeSynthesizeFlow
|
|
35
|
+
configuration
|
|
38
36
|
|
|
39
37
|
- **test_writeJobNumba**: Tests the job-specific optimization process with RecipeJob
|
|
40
38
|
|
|
41
|
-
These fixtures enable users to test their own custom recipes and job configurations
|
|
42
|
-
|
|
43
|
-
extending the test suite for custom implementations.
|
|
39
|
+
These fixtures enable users to test their own custom recipes and job configurations with minimal effort. See the
|
|
40
|
+
documentation in tests/__init__.py for details on extending the test suite for custom implementations.
|
|
44
41
|
|
|
45
|
-
The framework balances multiple optimization levels - from general algorithmic
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
The framework balances multiple optimization levels - from general algorithmic improvements to parameter-specific
|
|
43
|
+
optimizations - while maintaining the ability to verify correctness at each transformation stage through the integrated
|
|
44
|
+
test suite.
|
|
48
45
|
"""
|
|
49
46
|
|
|
50
47
|
from mapFolding.someAssemblyRequired._theTypes import (
|
|
51
48
|
ast_expr_Slice as ast_expr_Slice,
|
|
52
49
|
ast_Identifier as ast_Identifier,
|
|
50
|
+
astClassHasDOTbody as astClassHasDOTbody,
|
|
51
|
+
astClassHasDOTbody_expr as astClassHasDOTbody_expr,
|
|
52
|
+
astClassHasDOTbodyList_stmt as astClassHasDOTbodyList_stmt,
|
|
53
53
|
astClassHasDOTnameNotName as astClassHasDOTnameNotName,
|
|
54
|
+
astClassHasDOTnameNotNameAlways as astClassHasDOTnameNotNameAlways,
|
|
55
|
+
astClassHasDOTnameNotNameOptionally as astClassHasDOTnameNotNameOptionally,
|
|
54
56
|
astClassHasDOTtarget as astClassHasDOTtarget,
|
|
55
57
|
astClassHasDOTtarget_expr as astClassHasDOTtarget_expr,
|
|
56
58
|
astClassHasDOTtargetAttributeNameSubscript as astClassHasDOTtargetAttributeNameSubscript,
|
|
57
59
|
astClassHasDOTvalue as astClassHasDOTvalue,
|
|
58
60
|
astClassHasDOTvalue_expr as astClassHasDOTvalue_expr,
|
|
59
61
|
astClassHasDOTvalue_exprNone as astClassHasDOTvalue_exprNone,
|
|
60
|
-
astClassOptionallyHasDOTnameNotName as astClassOptionallyHasDOTnameNotName,
|
|
61
62
|
ImaCallToName as ImaCallToName,
|
|
62
63
|
intORlist_ast_type_paramORstr_orNone as intORlist_ast_type_paramORstr_orNone,
|
|
63
64
|
intORstr_orNone as intORstr_orNone,
|
|
@@ -81,9 +82,16 @@ from mapFolding.someAssemblyRequired._tool_Make import Make as Make
|
|
|
81
82
|
from mapFolding.someAssemblyRequired._tool_Then import grab as grab, Then as Then
|
|
82
83
|
|
|
83
84
|
from mapFolding.someAssemblyRequired._toolboxContainers import (
|
|
85
|
+
DeReConstructField2ast as DeReConstructField2ast,
|
|
84
86
|
IngredientsFunction as IngredientsFunction,
|
|
85
87
|
IngredientsModule as IngredientsModule,
|
|
86
88
|
LedgerOfImports as LedgerOfImports,
|
|
87
89
|
RecipeSynthesizeFlow as RecipeSynthesizeFlow,
|
|
88
90
|
ShatteredDataclass as ShatteredDataclass,
|
|
89
91
|
)
|
|
92
|
+
|
|
93
|
+
from mapFolding.someAssemblyRequired._toolboxAST import (
|
|
94
|
+
astModuleToIngredientsFunction as astModuleToIngredientsFunction,
|
|
95
|
+
extractClassDef as extractClassDef,
|
|
96
|
+
extractFunctionDef as extractFunctionDef,
|
|
97
|
+
)
|
|
@@ -1,32 +1,35 @@
|
|
|
1
|
-
from
|
|
1
|
+
from mapFolding import astDOTParamSpec, astDOTTryStar, astDOTtype_param, astDOTTypeAlias, astDOTTypeVar, astDOTTypeVarTuple
|
|
2
|
+
from typing import Any, TypeAlias as typing_TypeAlias, TypeVar as typing_TypeVar
|
|
2
3
|
import ast
|
|
4
|
+
|
|
3
5
|
# TODO understand typing.
|
|
4
6
|
|
|
5
7
|
stuPyd: typing_TypeAlias = str
|
|
6
|
-
if TYPE_CHECKING:
|
|
7
|
-
""" 3.12 new: ast.ParamSpec, ast.type_param, ast.TypeAlias, ast.TypeVar, ast.TypeVarTuple
|
|
8
|
-
3.11 new: ast.TryStar"""
|
|
9
|
-
astClassHasDOTnameNotName: typing_TypeAlias = ast.alias | ast.AsyncFunctionDef | ast.ClassDef | ast.FunctionDef | ast.ParamSpec | ast.TypeVar | ast.TypeVarTuple
|
|
10
|
-
astClassHasDOTvalue_expr: typing_TypeAlias = ast.Assign | ast.Attribute | ast.AugAssign | ast.Await | ast.DictComp | ast.Expr | ast.FormattedValue | ast.keyword | ast.MatchValue | ast.NamedExpr | ast.Starred | ast.Subscript | ast.TypeAlias | ast.YieldFrom
|
|
11
|
-
|
|
12
|
-
else:
|
|
13
|
-
astClassHasDOTnameNotName = stuPyd
|
|
14
|
-
astClassHasDOTvalue_expr = stuPyd
|
|
15
8
|
|
|
9
|
+
# NOTE An idea to subclass antecedents to effectively TypeGuard more than just the top level of the antecedent.
|
|
16
10
|
class ImaCallToName(ast.Call):
|
|
17
11
|
func: ast.Name # pyright: ignore[reportIncompatibleVariableOverride]
|
|
18
12
|
# assert isinstance(ast.Call.func, ast.Name), "brinkmanship"
|
|
19
13
|
# func: ast.Name
|
|
20
14
|
|
|
15
|
+
# Some common attributes of ast classes.
|
|
16
|
+
astClassHasDOTbody_expr: typing_TypeAlias = ast.Expression | ast.IfExp | ast.Lambda
|
|
17
|
+
astClassHasDOTbodyList_stmt: typing_TypeAlias = ast.AsyncFor | ast.AsyncWith | ast.ClassDef | ast.ExceptHandler | ast.For | ast.FunctionDef | ast.If | ast.Interactive | ast.match_case | ast.Module | ast.Try | astDOTTryStar | ast.While | ast.With
|
|
18
|
+
astClassHasDOTbody: typing_TypeAlias = astClassHasDOTbody_expr | astClassHasDOTbodyList_stmt
|
|
19
|
+
|
|
20
|
+
astClassHasDOTnameNotNameAlways: typing_TypeAlias = ast.alias | ast.AsyncFunctionDef | ast.ClassDef | ast.FunctionDef | astDOTParamSpec | astDOTTypeVar | astDOTTypeVarTuple
|
|
21
|
+
astClassHasDOTnameNotNameOptionally: typing_TypeAlias = ast.ExceptHandler | ast.MatchAs | ast.MatchStar
|
|
22
|
+
astClassHasDOTnameNotName: typing_TypeAlias = astClassHasDOTnameNotNameAlways | astClassHasDOTnameNotNameOptionally
|
|
23
|
+
|
|
21
24
|
astClassHasDOTtargetAttributeNameSubscript: typing_TypeAlias = ast.AnnAssign | ast.AugAssign
|
|
22
25
|
astClassHasDOTtarget_expr: typing_TypeAlias = ast.AsyncFor | ast.comprehension | ast.For
|
|
23
26
|
astClassHasDOTtarget: typing_TypeAlias = ast.NamedExpr | astClassHasDOTtarget_expr | astClassHasDOTtargetAttributeNameSubscript
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
astClassHasDOTvalue_expr: typing_TypeAlias = ast.Assign | ast.Attribute | ast.AugAssign | ast.Await | ast.DictComp | ast.Expr | ast.FormattedValue | ast.keyword | ast.MatchValue | ast.NamedExpr | ast.Starred | ast.Subscript | astDOTTypeAlias | ast.YieldFrom
|
|
27
29
|
astClassHasDOTvalue_exprNone: typing_TypeAlias = ast.AnnAssign | ast.Return | ast.Yield
|
|
28
30
|
astClassHasDOTvalue: typing_TypeAlias = ast.Constant | ast.MatchSingleton | astClassHasDOTvalue_expr | astClassHasDOTvalue_exprNone
|
|
29
31
|
|
|
32
|
+
# Type hints through TypeAlias or type "hints" through the identifier name.
|
|
30
33
|
ast_expr_Slice: typing_TypeAlias = ast.expr
|
|
31
34
|
ast_Identifier: typing_TypeAlias = str
|
|
32
35
|
intORlist_ast_type_paramORstr_orNone: typing_TypeAlias = Any
|
|
@@ -34,10 +37,11 @@ intORstr_orNone: typing_TypeAlias = Any
|
|
|
34
37
|
list_ast_type_paramORstr_orNone: typing_TypeAlias = Any
|
|
35
38
|
str_nameDOTname: typing_TypeAlias = stuPyd
|
|
36
39
|
|
|
40
|
+
# Limited success with TypeVar.
|
|
37
41
|
个 = typing_TypeVar('个', bound = ast.AST, covariant = True)
|
|
38
42
|
NodeORattribute = typing_TypeVar('NodeORattribute', bound = ast.AST | ast_expr_Slice | ast_Identifier | str_nameDOTname | bool | Any | None, covariant = True)
|
|
39
43
|
|
|
40
|
-
#
|
|
44
|
+
# For my reference, all ast classes by subgroup:
|
|
41
45
|
Ima_ast_boolop: typing_TypeAlias = ast.boolop | ast.And | ast.Or
|
|
42
46
|
Ima_ast_cmpop: typing_TypeAlias = ast.cmpop | ast.Eq | ast.NotEq | ast.Lt | ast.LtE | ast.Gt | ast.GtE | ast.Is | ast.IsNot | ast.In | ast.NotIn
|
|
43
47
|
Ima_ast_excepthandler: typing_TypeAlias = ast.excepthandler | ast.ExceptHandler
|
|
@@ -47,11 +51,7 @@ Ima_ast_mod: typing_TypeAlias = ast.mod | ast.Expression | ast.FunctionType | as
|
|
|
47
51
|
Ima_ast_operator: typing_TypeAlias = ast.operator | ast.Add | ast.Sub | ast.Mult | ast.MatMult | ast.Div | ast.Mod | ast.Pow | ast.LShift | ast.RShift | ast.BitOr | ast.BitXor | ast.BitAnd | ast.FloorDiv
|
|
48
52
|
Ima_ast_orphan = ast.alias | ast.arg | ast.arguments | ast.comprehension | ast.keyword | ast.match_case | ast.withitem
|
|
49
53
|
iMa_ast_pattern: typing_TypeAlias = ast.pattern | ast.MatchAs | ast.MatchClass | ast.MatchMapping | ast.MatchOr | ast.MatchSequence | ast.MatchSingleton | ast.MatchStar | ast.MatchValue
|
|
54
|
+
Ima_ast_stmt: typing_TypeAlias = ast.stmt | ast.AnnAssign | ast.Assert | ast.Assign | ast.AsyncFor | ast.AsyncFunctionDef | ast.AsyncWith | ast.AugAssign | ast.Break | ast.ClassDef | ast.Continue | ast.Delete | ast.Expr | ast.For | ast.FunctionDef | ast.Global | ast.If | ast.Import | ast.ImportFrom | ast.Match | ast.Nonlocal | ast.Pass | ast.Raise | ast.Return | ast.Try | astDOTTryStar | astDOTTypeAlias | ast.While | ast.With
|
|
50
55
|
Ima_ast_type_ignore: typing_TypeAlias = ast.type_ignore | ast.TypeIgnore
|
|
56
|
+
Ima_ast_type_param: typing_TypeAlias = astDOTtype_param | astDOTParamSpec | astDOTTypeVar | astDOTTypeVarTuple
|
|
51
57
|
Ima_ast_unaryop: typing_TypeAlias = ast.unaryop | ast.Invert | ast.Not | ast.UAdd | ast.USub
|
|
52
|
-
if TYPE_CHECKING:
|
|
53
|
-
Ima_ast_stmt: typing_TypeAlias = ast.stmt | ast.AnnAssign | ast.Assert | ast.Assign | ast.AsyncFor | ast.AsyncFunctionDef | ast.AsyncWith | ast.AugAssign | ast.Break | ast.ClassDef | ast.Continue | ast.Delete | ast.Expr | ast.For | ast.FunctionDef | ast.Global | ast.If | ast.Import | ast.ImportFrom | ast.Match | ast.Nonlocal | ast.Pass | ast.Raise | ast.Return | ast.Try | ast.TryStar | ast.TypeAlias | ast.While | ast.With
|
|
54
|
-
Ima_ast_type_param: typing_TypeAlias = ast.type_param | ast.ParamSpec | ast.TypeVar | ast.TypeVarTuple
|
|
55
|
-
else:
|
|
56
|
-
Ima_ast_stmt = stuPyd
|
|
57
|
-
Ima_ast_type_param = stuPyd
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"""
|
|
2
2
|
AST Node Construction Utilities for Python Code Generation
|
|
3
3
|
|
|
4
|
-
This module provides the Make class with static methods for creating AST nodes
|
|
5
|
-
|
|
6
|
-
directly, making programmatic code generation more intuitive and less error-prone.
|
|
4
|
+
This module provides the Make class with static methods for creating AST nodes with sane defaults. It abstracts away the
|
|
5
|
+
complexity of constructing AST nodes directly, making programmatic code generation more intuitive and less error-prone.
|
|
7
6
|
|
|
8
|
-
The Make class serves as a factory for creating various types of AST nodes needed
|
|
9
|
-
|
|
10
|
-
a consistent pattern that maps cleanly to Python's syntax while handling the
|
|
7
|
+
The Make class serves as a factory for creating various types of AST nodes needed in code generation, transformation,
|
|
8
|
+
and analysis workflows. Each method follows a consistent pattern that maps cleanly to Python's syntax while handling the
|
|
11
9
|
details of AST node construction.
|
|
12
10
|
"""
|
|
13
11
|
|
|
@@ -73,6 +71,10 @@ class Make:
|
|
|
73
71
|
buffaloBuffalo = addDOTattribute(buffaloBuffalo, identifier, context, **keywordArguments)
|
|
74
72
|
return buffaloBuffalo
|
|
75
73
|
|
|
74
|
+
@staticmethod
|
|
75
|
+
def AugAssign(target: ast.Attribute | ast.Name | ast.Subscript, operator: ast.operator, value: ast.expr, **keywordArguments: int) -> ast.AugAssign:
|
|
76
|
+
return ast.AugAssign(target, operator, value, **keywordArguments)
|
|
77
|
+
|
|
76
78
|
@staticmethod
|
|
77
79
|
def Call(callee: ast.expr, listArguments: Sequence[ast.expr] | None = None, list_astKeywords: Sequence[ast.keyword] | None = None) -> ast.Call:
|
|
78
80
|
return ast.Call(func=callee, args=list(listArguments) if listArguments else [], keywords=list(list_astKeywords) if list_astKeywords else [])
|
|
@@ -124,3 +126,7 @@ class Make:
|
|
|
124
126
|
@staticmethod
|
|
125
127
|
def Tuple(elements: Sequence[ast.expr] = [], context: ast.expr_context = ast.Load(), **keywordArguments: int) -> ast.Tuple:
|
|
126
128
|
return ast.Tuple(list(elements), context, **keywordArguments)
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
def While(test: ast.expr, doThis: list[ast.stmt], orElse: list[ast.stmt] = [], **keywordArguments: int) -> ast.While:
|
|
132
|
+
return ast.While(test, doThis, orElse, **keywordArguments)
|