mapFolding 0.17.0__py3-none-any.whl → 0.18.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.
- easyRun/NOTcountingFolds.py +16 -10
- easyRun/__init__.py +1 -0
- easyRun/countFolds.py +17 -9
- easyRun/meanders.py +6 -8
- mapFolding/__init__.py +24 -35
- mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_hypothesis.py +189 -0
- mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_p2d6.py +143 -0
- mapFolding/_e/Z0Z_analysisPython/__init__.py +4 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/__init__.py +0 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200.py +369 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2001.py +694 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/211.py +514 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/2111.py +480 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214.py +511 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/2141.py +515 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/211.py +485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/2111.py +442 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/211.py +313 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2111.py +343 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214.py +400 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/2141.py +497 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/211.py +463 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/2111.py +441 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266.py +35 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/2661.py +35 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200.py +382 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2001.py +630 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/211.py +488 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/2111.py +475 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214.py +473 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/2141.py +500 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +465 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +439 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/211.py +599 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2111.py +536 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214.py +506 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/2141.py +533 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/211.py +489 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/2111.py +474 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001Negative.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211.py +1397 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111Negative.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211Negative.py +1397 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141Negative.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214Negative.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211.py +1366 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +1366 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214.py +1102 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141Negative.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214Negative.py +1102 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111Negative.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211Negative.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266.py +32 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661.py +1162 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661Negative.py +1162 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266Negative.py +32 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001Negative.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111.py +1176 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +1176 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +1038 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +1038 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111Negative.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211Negative.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141.py +1364 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141Negative.py +1364 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214Negative.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200.py +3133 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001.py +6039 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001Negative.py +6039 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200Negative.py +3133 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211.py +3527 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111.py +2300 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111Negative.py +2300 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211Negative.py +3527 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214.py +3597 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141.py +3317 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141Negative.py +3317 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214Negative.py +3597 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211.py +3161 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111.py +2877 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +2877 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +3161 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211.py +2981 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111.py +3055 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111Negative.py +3055 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211Negative.py +2981 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214.py +3221 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141.py +3988 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141Negative.py +3988 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214Negative.py +3221 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211.py +3652 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111.py +2863 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111Negative.py +2863 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211Negative.py +3652 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001.py +4566 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001Negative.py +4566 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200Negative.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211.py +3006 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +3006 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214.py +3304 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141.py +3015 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +3015 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +3304 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +2939 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +2589 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +2589 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +2939 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211.py +3899 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111.py +2996 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111Negative.py +2996 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211Negative.py +3899 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214.py +3223 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141.py +3020 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141Negative.py +3020 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214Negative.py +3223 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211.py +3250 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111.py +2667 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +2667 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +3250 -0
- mapFolding/_e/Z0Z_analysisPython/measure.py +162 -0
- mapFolding/_e/Z0Z_analysisPython/positionAnalysis.py +403 -0
- mapFolding/_e/Z0Z_analysisPython/positionAnalysisPileRanges2d6.py +110 -0
- mapFolding/_e/Z0Z_analysisPython/theExcluderBeast.py +640 -0
- mapFolding/_e/Z0Z_analysisPython/toolkit.py +166 -0
- mapFolding/_e/Z0Z_analysisPython/toolkitCSVsequences.py +188 -0
- mapFolding/_e/Z0Z_analysisPython/workBenchPatternFinder.py +284 -0
- mapFolding/_e/Z0Z_notes/__init__.py +0 -0
- mapFolding/_e/Z0Z_notes/knowledgeDump.py +214 -0
- mapFolding/_e/__init__.py +45 -0
- mapFolding/_e/_beDRY.py +547 -0
- mapFolding/_e/_dataDynamic.py +1164 -0
- mapFolding/_e/_measure.py +579 -0
- mapFolding/_e/_semiotics.py +363 -0
- mapFolding/_e/_theTypes.py +31 -0
- mapFolding/_e/algorithms/__init__.py +1 -0
- mapFolding/_e/algorithms/constraintPropagation.py +158 -0
- mapFolding/_e/algorithms/elimination.py +118 -0
- mapFolding/_e/algorithms/eliminationCrease.py +66 -0
- mapFolding/_e/algorithms/iff.py +584 -0
- mapFolding/_e/basecamp.py +89 -0
- mapFolding/_e/dataBaskets.py +123 -0
- mapFolding/_e/dataRaw/__init__.py +0 -0
- mapFolding/_e/easyRun/__init__.py +0 -0
- mapFolding/_e/easyRun/eliminateFolds.py +72 -0
- mapFolding/_e/easyRun/pinning.py +62 -0
- mapFolding/_e/filters.py +384 -0
- mapFolding/_e/pin2/344/270/212nDimensions.py +882 -0
- mapFolding/_e/pin2/344/270/212nDimensionsAnnex.py +551 -0
- mapFolding/_e/pin2/344/270/212nDimensionsByCrease.py +190 -0
- mapFolding/_e/pin2/344/270/212nDimensionsByDomain.py +459 -0
- mapFolding/_e/pinIt.py +436 -0
- mapFolding/_semiotics.py +42 -0
- mapFolding/_theSSOT.py +11 -56
- mapFolding/_theTypes.py +52 -68
- mapFolding/algorithms/A086345.py +8 -3
- mapFolding/algorithms/__init__.py +1 -1
- mapFolding/algorithms/matrixMeandersNumPyndas.py +18 -18
- mapFolding/algorithms/oeisIDbyFormula.py +4 -4
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +3 -3
- mapFolding/basecamp.py +13 -28
- mapFolding/beDRY.py +108 -99
- mapFolding/filesystemToolkit.py +15 -11
- mapFolding/oeis.py +17 -16
- mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +2 -2
- mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineV2.py +0 -1
- mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +8 -10
- mapFolding/someAssemblyRequired/RecipeJob.py +5 -5
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +5 -2
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +9 -11
- mapFolding/someAssemblyRequired/mapFoldingModules/makeMapFoldingModules.py +2 -1
- mapFolding/someAssemblyRequired/transformationTools.py +2 -2
- mapFolding/tests/Z0Z_test_e_excluder.py +155 -0
- mapFolding/tests/conftest.py +193 -314
- mapFolding/tests/dataSamples/A001417.py +455 -0
- mapFolding/tests/dataSamples/__init__.py +1 -0
- mapFolding/tests/dataSamples/measurementData.py +1818 -0
- mapFolding/tests/dataSamples/p2DnDomain3_2_/351/246/226/344/270/200_/351/246/226/351/233/266/344/270/200.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain3_/351/246/226/344/270/200.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain5_4.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain6_5.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain6_7_5_4.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain7_6.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +15 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/272/214_/351/246/226/344/272/214.py +15 -0
- mapFolding/tests/dataSamples/semioticsData.py +135 -0
- mapFolding/tests/test_computations.py +133 -88
- mapFolding/tests/test_e_computations.py +42 -0
- mapFolding/tests/test_e_dataDynamic.py +189 -0
- mapFolding/tests/test_e_measurements.py +257 -0
- mapFolding/tests/test_e_pinning.py +61 -0
- mapFolding/tests/test_e_semiotics.py +128 -0
- mapFolding/tests/test_filesystem.py +39 -17
- mapFolding/tests/{test_other.py → test_parameterValidation.py} +3 -3
- mapFolding/tests/{test_tasks.py → test_taskDivisions.py} +42 -23
- mapFolding/zCuzDocStoopid/makeDocstrings.py +3 -2
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/METADATA +15 -9
- mapfolding-0.18.0.dist-info/RECORD +305 -0
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/WHEEL +1 -1
- easyRun/A000682.py +0 -25
- easyRun/A005316.py +0 -20
- mapFolding/algorithms/A000136constraintPropagation.py +0 -95
- mapFolding/algorithms/A000136elimination.py +0 -163
- mapFolding/algorithms/A000136eliminationParallel.py +0 -77
- mapfolding-0.17.0.dist-info/RECORD +0 -107
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from concurrent.futures import as_completed, Future, ProcessPoolExecutor
|
|
2
|
+
from cytoolz.dicttoolz import valfilter as leafFilter
|
|
3
|
+
from itertools import filterfalse
|
|
4
|
+
from mapFolding._e import DOTitems, DOTvalues, Folding, getIteratorOfLeaves, mapShapeIs2上nDimensions
|
|
5
|
+
from mapFolding._e.algorithms.iff import removeIFFViolationsFromEliminationState
|
|
6
|
+
from mapFolding._e.dataBaskets import EliminationState
|
|
7
|
+
from mapFolding._e.filters import thisIsAPileRangeOfLeaves
|
|
8
|
+
from mapFolding._e.pin2上nDimensions import pinPilesAtEnds, reduceAllPermutationSpaceInEliminationState
|
|
9
|
+
from mapFolding._e.pinIt import (
|
|
10
|
+
deconstructPermutationSpaceAtPile, disqualifyAppendingLeafAtPile, moveFoldingToListFolding)
|
|
11
|
+
from math import factorial
|
|
12
|
+
from more_itertools import first
|
|
13
|
+
from tqdm import tqdm
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from mapFolding._e import PermutationSpace
|
|
18
|
+
|
|
19
|
+
def pinByCrease(state: EliminationState) -> EliminationState:
|
|
20
|
+
listFolding: list[Folding] = []
|
|
21
|
+
|
|
22
|
+
while state.listPermutationSpace:
|
|
23
|
+
|
|
24
|
+
permutationSpace: PermutationSpace = state.listPermutationSpace.pop()
|
|
25
|
+
|
|
26
|
+
pile, pileRangeOfLeaves = first(DOTitems(leafFilter(thisIsAPileRangeOfLeaves, permutationSpace)))
|
|
27
|
+
|
|
28
|
+
sherpa: EliminationState = EliminationState(state.mapShape, pile=pile, permutationSpace=permutationSpace)
|
|
29
|
+
sherpa.listPermutationSpace.extend(DOTvalues(deconstructPermutationSpaceAtPile(sherpa.permutationSpace, sherpa.pile, filterfalse(disqualifyAppendingLeafAtPile(sherpa), getIteratorOfLeaves(pileRangeOfLeaves)))))
|
|
30
|
+
sherpa = moveFoldingToListFolding(removeIFFViolationsFromEliminationState(reduceAllPermutationSpaceInEliminationState(sherpa)))
|
|
31
|
+
|
|
32
|
+
listFolding.extend(sherpa.listFolding)
|
|
33
|
+
|
|
34
|
+
state.listPermutationSpace.extend(sherpa.listPermutationSpace)
|
|
35
|
+
|
|
36
|
+
state.listFolding.extend(listFolding)
|
|
37
|
+
return state
|
|
38
|
+
|
|
39
|
+
def doTheNeedful(state: EliminationState, workersMaximum: int) -> EliminationState:
|
|
40
|
+
"""Do the things necessary so that `pinByCrease` operates efficiently."""
|
|
41
|
+
if not mapShapeIs2上nDimensions(state.mapShape):
|
|
42
|
+
return state
|
|
43
|
+
|
|
44
|
+
if not state.listPermutationSpace:
|
|
45
|
+
state = pinPilesAtEnds(state, 1)
|
|
46
|
+
else:
|
|
47
|
+
state = moveFoldingToListFolding(state)
|
|
48
|
+
|
|
49
|
+
with ProcessPoolExecutor(workersMaximum) as concurrencyManager:
|
|
50
|
+
|
|
51
|
+
listPermutationSpace: list[PermutationSpace] = state.listPermutationSpace.copy()
|
|
52
|
+
state.listPermutationSpace = []
|
|
53
|
+
|
|
54
|
+
listClaimTickets: list[Future[EliminationState]] = [
|
|
55
|
+
concurrencyManager.submit(pinByCrease, EliminationState(state.mapShape, listPermutationSpace=[permutationSpace]))
|
|
56
|
+
for permutationSpace in listPermutationSpace
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
for claimTicket in tqdm(as_completed(listClaimTickets), total=len(listClaimTickets), disable=False):
|
|
60
|
+
state.listFolding.extend(claimTicket.result().listFolding)
|
|
61
|
+
|
|
62
|
+
state.Theorem4Multiplier = factorial(state.dimensionsTotal)
|
|
63
|
+
state.groupsOfFolds = len(state.listFolding)
|
|
64
|
+
|
|
65
|
+
return state
|
|
66
|
+
|
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
"""Verify that a folding sequence is possible.
|
|
2
|
+
|
|
3
|
+
Notes
|
|
4
|
+
-----
|
|
5
|
+
Eight forbidden inequalities of matching parity k and r *à la* Koehler (1968), indices of:
|
|
6
|
+
[k < r < k+1 < r+1] [r < k+1 < r+1 < k] [k+1 < r+1 < k < r] [r+1 < k < r < k+1]
|
|
7
|
+
[r < k < r+1 < k+1] [k < r+1 < k+1 < r] [r+1 < k+1 < r < k] [k+1 < r < k < r+1]
|
|
8
|
+
|
|
9
|
+
Four forbidden inequalities of matching parity k and r *à la* Legendre (2014), indices of:
|
|
10
|
+
[k < r < k+1 < r+1] [k+1 < r+1 < k < r] [r+1 < k < r < k+1] [k < r+1 < k+1 < r]
|
|
11
|
+
|
|
12
|
+
Citations
|
|
13
|
+
---------
|
|
14
|
+
- John E. Koehler, Folding a strip of stamps, Journal of Combinatorial Theory, Volume 5, Issue 2, 1968, Pages 135-152, ISSN
|
|
15
|
+
0021-9800, https://doi.org/10.1016/S0021-9800(68)80048-1.
|
|
16
|
+
- Stéphane Legendre, Foldings and meanders, The Australasian Journal of Combinatorics, Volume 58, Part 2, 2014, Pages 275-291,
|
|
17
|
+
ISSN 2202-3518, https://ajc.maths.uq.edu.au/pdf/58/ajc_v58_p275.pdf.
|
|
18
|
+
|
|
19
|
+
See Also
|
|
20
|
+
--------
|
|
21
|
+
- "[Annotated, corrected, scanned copy]" of Koehler (1968) at https://oeis.org/A001011.
|
|
22
|
+
- Citations in BibTeX format "mapFolding/citations".
|
|
23
|
+
"""
|
|
24
|
+
from collections.abc import Callable
|
|
25
|
+
from cytoolz.dicttoolz import valfilter as leafFilter
|
|
26
|
+
from cytoolz.functoolz import curry as syntacticCurry
|
|
27
|
+
from functools import cache
|
|
28
|
+
from itertools import combinations, filterfalse, product as CartesianProduct
|
|
29
|
+
from mapFolding import getLeavesTotal, inclusive
|
|
30
|
+
from mapFolding._e import Folding, Leaf, PermutationSpace, Pile
|
|
31
|
+
from mapFolding._e.dataBaskets import EliminationState
|
|
32
|
+
from mapFolding._e.filters import between, extractPinnedLeaves
|
|
33
|
+
from math import prod
|
|
34
|
+
from operator import floordiv, indexOf
|
|
35
|
+
|
|
36
|
+
#======== Forbidden inequalities ============================
|
|
37
|
+
|
|
38
|
+
def thisIsAViolationComplicated(pile: Pile, pileComparand: Pile, getLeafCrease: Callable[[], Leaf | None], getComparandCrease: Callable[[], Leaf | None], pileOf: Callable[[Leaf], Pile | None]) -> bool: # noqa: PLR0911
|
|
39
|
+
"""Validate.
|
|
40
|
+
|
|
41
|
+
Mathematical reasons for the design of this function
|
|
42
|
+
----------------------------------------------------
|
|
43
|
+
|
|
44
|
+
1. To confirm that a multidimensional folding is valid, confirm that each of the constituent one-dimensional¹ foldings is valid.
|
|
45
|
+
2. To confirm that a one-dimensional folding is valid, check that all creases that might cross do not cross.
|
|
46
|
+
|
|
47
|
+
A "crease" is a convenient lie: it is a shorthand description of two leaves that are physically connected to each other.
|
|
48
|
+
Leaves in a one-dimensional folding are physically connected to at most two other leaves: the leaf before and the leaf after.
|
|
49
|
+
When talking about a one-dimensional section of a multidimensional folding, we ignore the other dimensions and still reference
|
|
50
|
+
the leaves before and after. To check whether two creases cross, we must compare the four leaves of the two creases.
|
|
51
|
+
|
|
52
|
+
¹ A so-called one-dimensional folding, map, or strip of stamps has two dimensions, but one of the dimensions has a width of 1.
|
|
53
|
+
|
|
54
|
+
Idiosyncratic reasons for the design of this function
|
|
55
|
+
-----------------------------------------------------
|
|
56
|
+
|
|
57
|
+
I name the first `Leaf` of the first crease "`leaf`". I name the `Leaf` to which I am comparing `leaf` "`comparand`". A
|
|
58
|
+
crease² is a connection between a `Leaf` and the `Leaf` after it, therefore, the crease of "`leaf`" connects it to
|
|
59
|
+
"`leafCrease`". The crease of "`comparand`" connects it to "`comparandCrease`".
|
|
60
|
+
|
|
61
|
+
I name the `Pile` of `leaf` as "`pile`". I name the `Pile` of `comparand` as "`pileComparand`".
|
|
62
|
+
|
|
63
|
+
Nearly everyone else names the leaves with letters, such as k, k+1, r, and r+1. (Which stand for Kahlo and Rivera, of course.)
|
|
64
|
+
|
|
65
|
+
² "increase" from Latin *in-* "in" + *crescere* "to grow" (from PIE root ⋆ker- "to grow").
|
|
66
|
+
https://www.etymonline.com/word/increase
|
|
67
|
+
|
|
68
|
+
Computational reasons for the design of this function
|
|
69
|
+
-----------------------------------------------------
|
|
70
|
+
|
|
71
|
+
If `leaf` and `comparand` do not have matching parity in the dimension, then their creases cannot cross. When you are
|
|
72
|
+
selecting the values of `leaf` and `comparand`, you ought to check that `leaf` and `comparand` have matching in the dimension.
|
|
73
|
+
This function cannot check the parity of `leaf` and `comparand`.
|
|
74
|
+
|
|
75
|
+
Computing a `Leaf` crease is not expensive, but 100,000,000 unnecessary-but-cheap-computations is expensive. Therefore,
|
|
76
|
+
instead of passing `leafCrease` and `comparandCrease`, pass the functions by which those values may be computed on demand.
|
|
77
|
+
|
|
78
|
+
Finally, because we need to compare the relative positions of the leaves, pass a function that returns the position of the
|
|
79
|
+
`Leaf` crease.
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
if pile < pileComparand:
|
|
83
|
+
|
|
84
|
+
comparandCrease: int | None = getComparandCrease()
|
|
85
|
+
if comparandCrease is None:
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
leafCrease: int | None = getLeafCrease()
|
|
89
|
+
if leafCrease is None:
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
pileComparandCrease: int | None = pileOf(comparandCrease)
|
|
93
|
+
if pileComparandCrease is None:
|
|
94
|
+
return False
|
|
95
|
+
pileLeafCrease: int | None = pileOf(leafCrease)
|
|
96
|
+
if pileLeafCrease is None:
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
if pileComparandCrease < pile:
|
|
100
|
+
if pileLeafCrease < pileComparandCrease: # [k+1 < r+1 < k < r]
|
|
101
|
+
return True
|
|
102
|
+
return pileComparand < pileLeafCrease # [r+1 < k < r < k+1]
|
|
103
|
+
|
|
104
|
+
if pileComparand < pileLeafCrease:
|
|
105
|
+
if pileLeafCrease < pileComparandCrease: # [k < r < k+1 < r+1]
|
|
106
|
+
return True
|
|
107
|
+
elif pile < pileComparandCrease < pileLeafCrease < pileComparand: # [k < r+1 < k+1 < r]
|
|
108
|
+
return True
|
|
109
|
+
return False
|
|
110
|
+
|
|
111
|
+
def thisIsAViolation(pile: Pile, pileComparand: Pile, pileCrease: Pile, pileComparandCrease: Pile) -> bool:
|
|
112
|
+
if pile < pileComparand:
|
|
113
|
+
if pileComparandCrease < pile:
|
|
114
|
+
if pileCrease < pileComparandCrease: # [k+1 < r+1 < k < r]
|
|
115
|
+
return True
|
|
116
|
+
return pileComparand < pileCrease # [r+1 < k < r < k+1]
|
|
117
|
+
if pileComparand < pileCrease:
|
|
118
|
+
if pileCrease < pileComparandCrease: # [k < r < k+1 < r+1]
|
|
119
|
+
return True
|
|
120
|
+
elif pile < pileComparandCrease < pileCrease < pileComparand: # [k < r+1 < k+1 < r]
|
|
121
|
+
return True
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
#======== Functions for a `Folding` =============================
|
|
125
|
+
|
|
126
|
+
def thisLeafFoldingIsValid(folding: Folding, mapShape: tuple[int, ...]) -> bool:
|
|
127
|
+
"""You can validate a concrete `Folding` by checking for crease crossings in every dimension.
|
|
128
|
+
|
|
129
|
+
This function is the leaf-level validator used after a candidate `Folding` is constructed.
|
|
130
|
+
For example, `mapFolding._e.algorithms.eliminationCrease` uses `thisLeafFoldingIsValid` [1]
|
|
131
|
+
to post-filter candidate foldings that already satisfy arithmetic invariants such as
|
|
132
|
+
`state.foldingCheckSum`.
|
|
133
|
+
|
|
134
|
+
Algorithm Details
|
|
135
|
+
-----------------
|
|
136
|
+
`thisLeafFoldingIsValid` treats each dimension of `mapShape` as a one-dimensional strip
|
|
137
|
+
projection and checks that no pair of potentially-crossing creases violates the forbidden
|
|
138
|
+
inequalities encoded by `thisIsAViolationComplicated` [3].
|
|
139
|
+
|
|
140
|
+
The leaf-boundary filter in `thisLeafFoldingIsValid` uses a cached leaf count derived from
|
|
141
|
+
`mapFolding.getLeavesTotal` [2].
|
|
142
|
+
|
|
143
|
+
`thisLeafFoldingIsValid` enumerates each pair of `(pile, leaf)` positions from `folding`
|
|
144
|
+
and combines each pair with each `dimension` index. The parity filter from
|
|
145
|
+
`matchingParityLeaf` reduces work by skipping pairs that cannot cross in the selected
|
|
146
|
+
`dimension`.
|
|
147
|
+
|
|
148
|
+
Performance Considerations
|
|
149
|
+
--------------------------
|
|
150
|
+
`thisLeafFoldingIsValid` defers crease computation by passing thunk functions returned by
|
|
151
|
+
`callGetCreasePost` into `thisIsAViolationComplicated`. This design avoids computing
|
|
152
|
+
`Leaf` creases for pairs that are rejected by earlier comparisons.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
folding : Folding
|
|
157
|
+
A `Folding` represented as an order of `Leaf` values by `Pile` index.
|
|
158
|
+
mapShape : tuple[int, ...]
|
|
159
|
+
A shape tuple that defines the mixed-radix leaf indexing scheme.
|
|
160
|
+
|
|
161
|
+
Returns
|
|
162
|
+
-------
|
|
163
|
+
isValid : bool
|
|
164
|
+
`True` when `folding` contains no crease crossing in any `dimension`.
|
|
165
|
+
|
|
166
|
+
References
|
|
167
|
+
----------
|
|
168
|
+
[1] mapFolding._e.algorithms.eliminationCrease
|
|
169
|
+
Internal package reference
|
|
170
|
+
[2] mapFolding.getLeavesTotal
|
|
171
|
+
Internal package reference
|
|
172
|
+
[3] mapFolding._e.algorithms.iff.thisIsAViolationComplicated
|
|
173
|
+
Internal package reference
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
foldingFiltered: filterfalse[tuple[int, int]] = filterfalse(lambda pileLeaf: pileLeaf[1] == _leavesTotal(mapShape) - 1, enumerate(folding)) # leafNPlus1 does not exist.
|
|
177
|
+
leafAndComparand: combinations[tuple[tuple[int, int], tuple[int, int]]] = combinations(foldingFiltered, 2)
|
|
178
|
+
|
|
179
|
+
leafAndComparandAcrossDimensions: CartesianProduct[tuple[tuple[tuple[int, int], tuple[int, int]], int]] = CartesianProduct(leafAndComparand, range(_dimensionsTotal(mapShape)))
|
|
180
|
+
parityInThisDimension: Callable[[tuple[tuple[tuple[int, int], tuple[int, int]], int]], bool] = matchingParityLeaf(mapShape)
|
|
181
|
+
leafAndComparandAcrossDimensionsFiltered: filter[tuple[tuple[tuple[int, int], tuple[int, int]], int]] = filter(parityInThisDimension, leafAndComparandAcrossDimensions)
|
|
182
|
+
|
|
183
|
+
return all(not thisIsAViolationComplicated(pile, pileComparand, callGetCreasePost(mapShape, leaf, aDimension), callGetCreasePost(mapShape, comparand, aDimension), inThis_pileOf(folding))
|
|
184
|
+
for ((pile, leaf), (pileComparand, comparand)), aDimension in leafAndComparandAcrossDimensionsFiltered)
|
|
185
|
+
|
|
186
|
+
@cache
|
|
187
|
+
def _leavesTotal(mapShape: tuple[int, ...]) -> int:
|
|
188
|
+
"""You can compute and memoize the total number of leaves for `mapShape`.
|
|
189
|
+
|
|
190
|
+
(AI generated docstring)
|
|
191
|
+
|
|
192
|
+
`_leavesTotal` exists to centralize leaf-count computation for hot validation paths such as
|
|
193
|
+
`thisLeafFoldingIsValid`. The `functools.cache` decorator memoizes the result per
|
|
194
|
+
`mapShape` value [1]. The leaf-count computation uses `mapFolding.getLeavesTotal` [2].
|
|
195
|
+
|
|
196
|
+
Parameters
|
|
197
|
+
----------
|
|
198
|
+
mapShape : tuple[int, ...]
|
|
199
|
+
A shape tuple used to derive the total number of leaves.
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
leavesTotal : int
|
|
204
|
+
The total number of leaves for `mapShape`.
|
|
205
|
+
|
|
206
|
+
References
|
|
207
|
+
----------
|
|
208
|
+
[1] functools.cache
|
|
209
|
+
https://docs.python.org/3/library/functools.html#functools.cache
|
|
210
|
+
[2] mapFolding.getLeavesTotal
|
|
211
|
+
Internal package reference
|
|
212
|
+
|
|
213
|
+
"""
|
|
214
|
+
return getLeavesTotal(mapShape)
|
|
215
|
+
|
|
216
|
+
def _dimensionsTotal(mapShape: tuple[int, ...]) -> int:
|
|
217
|
+
"""You can compute the number of dimensions encoded by `mapShape`.
|
|
218
|
+
|
|
219
|
+
(AI generated docstring)
|
|
220
|
+
|
|
221
|
+
`_dimensionsTotal` exists as a small, named adapter for code that iterates over each
|
|
222
|
+
dimension of `mapShape` [1].
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
mapShape : tuple[int, ...]
|
|
227
|
+
A shape tuple.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
dimensionsTotal : int
|
|
232
|
+
The number of dimensions in `mapShape`.
|
|
233
|
+
|
|
234
|
+
References
|
|
235
|
+
----------
|
|
236
|
+
[1] mapFolding._e.algorithms.iff.thisLeafFoldingIsValid
|
|
237
|
+
Internal package reference
|
|
238
|
+
|
|
239
|
+
"""
|
|
240
|
+
return len(mapShape)
|
|
241
|
+
|
|
242
|
+
def matchingParityLeaf(mapShape: tuple[int, ...]) -> Callable[[tuple[tuple[tuple[int, int], tuple[int, int]], int]], bool]:
|
|
243
|
+
"""You can build a parity predicate for `Leaf` pairs in a selected `dimension`.
|
|
244
|
+
|
|
245
|
+
(AI generated docstring)
|
|
246
|
+
|
|
247
|
+
`matchingParityLeaf` returns a predicate that matches the tuple shape produced by
|
|
248
|
+
`itertools.product` [1] over `(leafAndComparand, dimension)` in `thisLeafFoldingIsValid` [3].
|
|
249
|
+
The returned predicate delegates to `_matchingParityLeaf` [2].
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
mapShape : tuple[int, ...]
|
|
254
|
+
A shape tuple that defines leaf parity in each dimension.
|
|
255
|
+
|
|
256
|
+
Returns
|
|
257
|
+
-------
|
|
258
|
+
parityPredicate : collections.abc.Callable[[tuple[tuple[tuple[int, int], tuple[int, int]], int]], bool]
|
|
259
|
+
A predicate that returns `True` when the two `Leaf` values in the input tuple have
|
|
260
|
+
matching parity in the input `dimension`.
|
|
261
|
+
|
|
262
|
+
References
|
|
263
|
+
----------
|
|
264
|
+
[1] itertools.product
|
|
265
|
+
https://docs.python.org/3/library/itertools.html#itertools.product
|
|
266
|
+
[2] mapFolding._e.algorithms.iff._matchingParityLeaf
|
|
267
|
+
Internal package reference
|
|
268
|
+
[3] mapFolding._e.algorithms.iff.thisLeafFoldingIsValid
|
|
269
|
+
Internal package reference
|
|
270
|
+
|
|
271
|
+
"""
|
|
272
|
+
def repack(aCartesianProduct: tuple[tuple[tuple[int, int], tuple[int, int]], int]) -> bool:
|
|
273
|
+
((_pile, leaf), (_pileComparand, comparand)), dimension = aCartesianProduct
|
|
274
|
+
return _matchingParityLeaf(mapShape, leaf, comparand, dimension)
|
|
275
|
+
return repack
|
|
276
|
+
|
|
277
|
+
def _matchingParityLeaf(mapShape: tuple[int, ...], leaf: Leaf, comparand: Leaf, dimension: int) -> bool:
|
|
278
|
+
"""You can check whether `leaf` and `comparand` have matching parity in `dimension`.
|
|
279
|
+
|
|
280
|
+
(AI generated docstring)
|
|
281
|
+
|
|
282
|
+
`_matchingParityLeaf` is a small utility used to skip crease comparisons that cannot cross
|
|
283
|
+
in `thisLeafFoldingIsValid` [2].
|
|
284
|
+
|
|
285
|
+
Parameters
|
|
286
|
+
----------
|
|
287
|
+
mapShape : tuple[int, ...]
|
|
288
|
+
A shape tuple that defines the mixed-radix coordinate system.
|
|
289
|
+
leaf : Leaf
|
|
290
|
+
A leaf index.
|
|
291
|
+
comparand : Leaf
|
|
292
|
+
A second leaf index.
|
|
293
|
+
dimension : int
|
|
294
|
+
A dimension index into `mapShape`.
|
|
295
|
+
|
|
296
|
+
Returns
|
|
297
|
+
-------
|
|
298
|
+
hasMatchingParity : bool
|
|
299
|
+
`True` when `leaf` and `comparand` have matching parity in `dimension`.
|
|
300
|
+
|
|
301
|
+
References
|
|
302
|
+
----------
|
|
303
|
+
[1] mapFolding._e.algorithms.iff.ImaOddLeaf
|
|
304
|
+
Internal package reference
|
|
305
|
+
[2] mapFolding._e.algorithms.iff.thisLeafFoldingIsValid
|
|
306
|
+
Internal package reference
|
|
307
|
+
|
|
308
|
+
"""
|
|
309
|
+
return ImaOddLeaf(mapShape, leaf, dimension) == ImaOddLeaf(mapShape, comparand, dimension)
|
|
310
|
+
|
|
311
|
+
@cache
|
|
312
|
+
def ImaOddLeaf(mapShape: tuple[int, ...], leaf: Leaf, dimension: int) -> int:
|
|
313
|
+
r"""You can compute and memoize the parity bit of `leaf` in `dimension`.
|
|
314
|
+
|
|
315
|
+
(AI generated docstring)
|
|
316
|
+
|
|
317
|
+
`ImaOddLeaf` returns a parity bit ($0$ or $1$) derived from the mixed-radix coordinate of
|
|
318
|
+
`leaf` along `dimension`.
|
|
319
|
+
|
|
320
|
+
`ImaOddLeaf` uses the `functools.cache` decorator for memoization [1].
|
|
321
|
+
|
|
322
|
+
The coordinate extraction is:
|
|
323
|
+
$$
|
|
324
|
+
\left\lfloor \frac{leaf}{\prod mapShape[0:dimension]} \right\rfloor \bmod mapShape[dimension].
|
|
325
|
+
$$
|
|
326
|
+
|
|
327
|
+
The parity bit is the least-significant bit of the coordinate.
|
|
328
|
+
The coordinate extraction uses `productOfDimensions` to compute the stride [2].
|
|
329
|
+
|
|
330
|
+
Parameters
|
|
331
|
+
----------
|
|
332
|
+
mapShape : tuple[int, ...]
|
|
333
|
+
A shape tuple that defines the coordinate system.
|
|
334
|
+
leaf : Leaf
|
|
335
|
+
A leaf index.
|
|
336
|
+
dimension : int
|
|
337
|
+
A dimension index into `mapShape`.
|
|
338
|
+
|
|
339
|
+
Returns
|
|
340
|
+
-------
|
|
341
|
+
parityBit : int
|
|
342
|
+
A parity bit where `0` means even coordinate and `1` means odd coordinate.
|
|
343
|
+
|
|
344
|
+
References
|
|
345
|
+
----------
|
|
346
|
+
[1] functools.cache
|
|
347
|
+
https://docs.python.org/3/library/functools.html#functools.cache
|
|
348
|
+
[2] mapFolding._e.algorithms.iff.productOfDimensions
|
|
349
|
+
Internal package reference
|
|
350
|
+
|
|
351
|
+
"""
|
|
352
|
+
return (floordiv(leaf, productOfDimensions(mapShape, dimension)) % mapShape[dimension]) & 1
|
|
353
|
+
|
|
354
|
+
def productOfDimensions(mapShape: tuple[int, ...], dimension: int) -> int:
|
|
355
|
+
r"""You can compute the mixed-radix stride for the prefix of `mapShape`.
|
|
356
|
+
|
|
357
|
+
(AI generated docstring)
|
|
358
|
+
|
|
359
|
+
`productOfDimensions` computes $\prod mapShape[0:dimension]$ with a multiplicative
|
|
360
|
+
identity of $1$ using `math.prod` [1]. The return value acts as the stride that converts a
|
|
361
|
+
coordinate step in `dimension` into a `Leaf` index increment.
|
|
362
|
+
|
|
363
|
+
The return value is consumed by `getCreasePost` when converting a coordinate step into a
|
|
364
|
+
`Leaf` increment [2].
|
|
365
|
+
|
|
366
|
+
Parameters
|
|
367
|
+
----------
|
|
368
|
+
mapShape : tuple[int, ...]
|
|
369
|
+
A shape tuple.
|
|
370
|
+
dimension : int
|
|
371
|
+
A dimension index that selects the exclusive prefix length.
|
|
372
|
+
|
|
373
|
+
Returns
|
|
374
|
+
-------
|
|
375
|
+
stride : int
|
|
376
|
+
The product of the first `dimension` entries of `mapShape`.
|
|
377
|
+
|
|
378
|
+
References
|
|
379
|
+
----------
|
|
380
|
+
[1] math.prod
|
|
381
|
+
https://docs.python.org/3/library/math.html#math.prod
|
|
382
|
+
[2] mapFolding._e.algorithms.iff.getCreasePost
|
|
383
|
+
Internal package reference
|
|
384
|
+
|
|
385
|
+
"""
|
|
386
|
+
return prod(mapShape[0:dimension], start=1)
|
|
387
|
+
|
|
388
|
+
def callGetCreasePost(mapShape: tuple[int, ...], leaf: Leaf, dimension: int) -> Callable[[], Leaf | None]:
|
|
389
|
+
"""You can create a deferred crease computation for `leaf` in `dimension`.
|
|
390
|
+
|
|
391
|
+
(AI generated docstring)
|
|
392
|
+
|
|
393
|
+
`callGetCreasePost` returns a zero-argument callable that computes the same result as
|
|
394
|
+
`getCreasePost(mapShape, leaf, dimension)` [1] when the callable is invoked. This thunk shape
|
|
395
|
+
matches the interface required by `thisIsAViolationComplicated` [2]. `thisLeafFoldingIsValid`
|
|
396
|
+
constructs this thunk as part of crease validation [3].
|
|
397
|
+
|
|
398
|
+
Parameters
|
|
399
|
+
----------
|
|
400
|
+
mapShape : tuple[int, ...]
|
|
401
|
+
A shape tuple.
|
|
402
|
+
leaf : Leaf
|
|
403
|
+
A leaf index.
|
|
404
|
+
dimension : int
|
|
405
|
+
A dimension index.
|
|
406
|
+
|
|
407
|
+
Returns
|
|
408
|
+
-------
|
|
409
|
+
getCrease : collections.abc.Callable[[], Leaf | None]
|
|
410
|
+
A callable that computes the crease-post `Leaf` value, or `None` when the crease-post
|
|
411
|
+
leaf does not exist.
|
|
412
|
+
|
|
413
|
+
References
|
|
414
|
+
----------
|
|
415
|
+
[1] mapFolding._e.algorithms.iff.getCreasePost
|
|
416
|
+
Internal package reference
|
|
417
|
+
[2] mapFolding._e.algorithms.iff.thisIsAViolationComplicated
|
|
418
|
+
Internal package reference
|
|
419
|
+
[3] mapFolding._e.algorithms.iff.thisLeafFoldingIsValid
|
|
420
|
+
Internal package reference
|
|
421
|
+
|
|
422
|
+
"""
|
|
423
|
+
return lambda: getCreasePost(mapShape, leaf, dimension)
|
|
424
|
+
|
|
425
|
+
@cache
|
|
426
|
+
def getCreasePost(mapShape: tuple[int, ...], leaf: Leaf, dimension: int) -> Leaf | None:
|
|
427
|
+
"""You can compute and memoize the crease-post `Leaf` for `leaf` in `dimension`.
|
|
428
|
+
|
|
429
|
+
(AI generated docstring)
|
|
430
|
+
|
|
431
|
+
A crease-post `Leaf` is the adjacent leaf one step forward in `dimension`, expressed in
|
|
432
|
+
`Leaf` index space. When `leaf` is already at the boundary coordinate of `dimension`, the
|
|
433
|
+
crease-post `Leaf` does not exist and `getCreasePost` returns `None`.
|
|
434
|
+
|
|
435
|
+
`getCreasePost` uses the `functools.cache` decorator for memoization [1] and uses
|
|
436
|
+
`productOfDimensions` for stride computation [2].
|
|
437
|
+
|
|
438
|
+
Parameters
|
|
439
|
+
----------
|
|
440
|
+
mapShape : tuple[int, ...]
|
|
441
|
+
A shape tuple.
|
|
442
|
+
leaf : Leaf
|
|
443
|
+
A leaf index.
|
|
444
|
+
dimension : int
|
|
445
|
+
A dimension index.
|
|
446
|
+
|
|
447
|
+
Returns
|
|
448
|
+
-------
|
|
449
|
+
leafCreasePost : Leaf | None
|
|
450
|
+
The crease-post `Leaf` index, or `None` when the crease-post `Leaf` does not exist.
|
|
451
|
+
|
|
452
|
+
References
|
|
453
|
+
----------
|
|
454
|
+
[1] functools.cache
|
|
455
|
+
https://docs.python.org/3/library/functools.html#functools.cache
|
|
456
|
+
[2] mapFolding._e.algorithms.iff.productOfDimensions
|
|
457
|
+
Internal package reference
|
|
458
|
+
|
|
459
|
+
"""
|
|
460
|
+
leafCrease: Leaf | None = None
|
|
461
|
+
if ((leaf // productOfDimensions(mapShape, dimension)) % mapShape[dimension]) + 1 < mapShape[dimension]:
|
|
462
|
+
leafCrease = leaf + productOfDimensions(mapShape, dimension)
|
|
463
|
+
return leafCrease
|
|
464
|
+
|
|
465
|
+
inThis_pileOf = syntacticCurry(indexOf)
|
|
466
|
+
|
|
467
|
+
#======== Functions for a `PermutationSpace` ============================
|
|
468
|
+
|
|
469
|
+
def permutationSpaceHasIFFViolation(state: EliminationState) -> bool:
|
|
470
|
+
"""You can detect forbidden crease crossings inside `state.permutationSpace`.
|
|
471
|
+
|
|
472
|
+
`permutationSpaceHasIFFViolation` is a pruning predicate used before counting or expanding a
|
|
473
|
+
candidate `PermutationSpace`. `removeIFFViolationsFromEliminationState` uses
|
|
474
|
+
`permutationSpaceHasIFFViolation` to filter `state.listPermutationSpace` [5], and
|
|
475
|
+
a caller such as `mapFolding._e.pin2上nDimensions` uses `removeIFFViolationsFromEliminationState`
|
|
476
|
+
[6] as part of building a reduced search space.
|
|
477
|
+
|
|
478
|
+
Algorithm Details
|
|
479
|
+
-----------------
|
|
480
|
+
`permutationSpaceHasIFFViolation` interprets `state.permutationSpace` as a partial mapping
|
|
481
|
+
from `Pile` to `Leaf`. The pinned leaves extracted by `extractPinnedLeaves` [1] are inverted
|
|
482
|
+
to a `Leaf`-to-`Pile` mapping so crease-post leaves can be looked up by `Leaf` index.
|
|
483
|
+
|
|
484
|
+
`permutationSpaceHasIFFViolation` filters candidate assignments with `between` [2] to skip
|
|
485
|
+
leaves that cannot have a crease-post leaf in a selected dimension.
|
|
486
|
+
|
|
487
|
+
For each `dimension`, `permutationSpaceHasIFFViolation`:
|
|
488
|
+
|
|
489
|
+
- enumerates each `(pile, leaf)` assignment that can have a crease-post leaf,
|
|
490
|
+
- derives the crease-post leaf using `getCreasePost` [4],
|
|
491
|
+
- looks up the crease-post leaf pile using pinned assignments,
|
|
492
|
+
- groups crease pairs by parity using `ImaOddLeaf`,
|
|
493
|
+
- checks each pair of crease pairs with `thisIsAViolation` [3].
|
|
494
|
+
|
|
495
|
+
Parameters
|
|
496
|
+
----------
|
|
497
|
+
state : EliminationState
|
|
498
|
+
An elimination state that provides `state.mapShape`, `state.permutationSpace`, and
|
|
499
|
+
bounds such as `state.leafLast`.
|
|
500
|
+
|
|
501
|
+
Returns
|
|
502
|
+
-------
|
|
503
|
+
hasViolation : bool
|
|
504
|
+
`True` when at least one forbidden crease crossing is detected.
|
|
505
|
+
|
|
506
|
+
References
|
|
507
|
+
----------
|
|
508
|
+
[1] mapFolding._e.filters.extractPinnedLeaves
|
|
509
|
+
Internal package reference
|
|
510
|
+
[2] mapFolding._e.filters.between
|
|
511
|
+
Internal package reference
|
|
512
|
+
[3] mapFolding._e.algorithms.iff.thisIsAViolation
|
|
513
|
+
Internal package reference
|
|
514
|
+
[4] mapFolding._e.algorithms.iff.getCreasePost
|
|
515
|
+
Internal package reference
|
|
516
|
+
[5] mapFolding._e.algorithms.iff.removeIFFViolationsFromEliminationState
|
|
517
|
+
Internal package reference
|
|
518
|
+
[6] mapFolding._e.pin2上nDimensions
|
|
519
|
+
Internal package reference
|
|
520
|
+
|
|
521
|
+
"""
|
|
522
|
+
leafToPile: dict[Leaf, Pile] = {leafValue: pileKey for pileKey, leafValue in extractPinnedLeaves(state.permutationSpace).items()}
|
|
523
|
+
|
|
524
|
+
for dimension in range(state.dimensionsTotal):
|
|
525
|
+
listPileCreaseByParity: list[list[tuple[int, int]]] = [[], []]
|
|
526
|
+
for pile, leaf in sorted(leafFilter(between(0, state.leafLast - inclusive), state.permutationSpace).items()):
|
|
527
|
+
leafCrease: int | None = getCreasePost(state.mapShape, leaf, dimension)
|
|
528
|
+
if leafCrease is None:
|
|
529
|
+
continue
|
|
530
|
+
pileCrease: int | None = leafToPile.get(leafCrease)
|
|
531
|
+
if pileCrease is None:
|
|
532
|
+
continue
|
|
533
|
+
listPileCreaseByParity[ImaOddLeaf(state.mapShape, leaf, dimension)].append((pile, pileCrease))
|
|
534
|
+
for groupedParity in listPileCreaseByParity:
|
|
535
|
+
if len(groupedParity) < 2:
|
|
536
|
+
continue
|
|
537
|
+
for (pilePrimary, pilePrimaryCrease), (pileComparand, pileComparandCrease) in combinations(groupedParity, 2):
|
|
538
|
+
if thisIsAViolation(pilePrimary, pileComparand, pilePrimaryCrease, pileComparandCrease):
|
|
539
|
+
return True
|
|
540
|
+
return False
|
|
541
|
+
|
|
542
|
+
def removeIFFViolationsFromEliminationState(state: EliminationState) -> EliminationState:
|
|
543
|
+
"""You can filter `state.listPermutationSpace` by removing crease-crossing candidates.
|
|
544
|
+
|
|
545
|
+
(AI generated docstring)
|
|
546
|
+
|
|
547
|
+
`removeIFFViolationsFromEliminationState` is a mutating filter step that keeps only those
|
|
548
|
+
`PermutationSpace` values that satisfy `permutationSpaceHasIFFViolation(state) == False` [1].
|
|
549
|
+
This function is used by pinning flows that enumerate multiple candidate permutation
|
|
550
|
+
spaces and then prune candidate permutation spaces before deeper elimination work.
|
|
551
|
+
A caller such as `mapFolding._e.pin2上nDimensions` uses this function [2].
|
|
552
|
+
|
|
553
|
+
Thread Safety
|
|
554
|
+
------------
|
|
555
|
+
`removeIFFViolationsFromEliminationState` mutates `state.listPermutationSpace` and updates
|
|
556
|
+
`state.permutationSpace` while iterating. Do not share `state` across threads while
|
|
557
|
+
`removeIFFViolationsFromEliminationState` is running.
|
|
558
|
+
|
|
559
|
+
Parameters
|
|
560
|
+
----------
|
|
561
|
+
state : EliminationState
|
|
562
|
+
An elimination state that provides `state.listPermutationSpace` and a writable
|
|
563
|
+
`state.permutationSpace`.
|
|
564
|
+
|
|
565
|
+
Returns
|
|
566
|
+
-------
|
|
567
|
+
state : EliminationState
|
|
568
|
+
The same `state` instance with `state.listPermutationSpace` filtered.
|
|
569
|
+
|
|
570
|
+
References
|
|
571
|
+
----------
|
|
572
|
+
[1] mapFolding._e.algorithms.iff.permutationSpaceHasIFFViolation
|
|
573
|
+
Internal package reference
|
|
574
|
+
[2] mapFolding._e.pin2上nDimensions
|
|
575
|
+
Internal package reference
|
|
576
|
+
|
|
577
|
+
"""
|
|
578
|
+
listPermutationSpace: list[PermutationSpace] = state.listPermutationSpace.copy()
|
|
579
|
+
state.listPermutationSpace = []
|
|
580
|
+
for permutationSpace in listPermutationSpace:
|
|
581
|
+
state.permutationSpace = permutationSpace
|
|
582
|
+
if not permutationSpaceHasIFFViolation(state):
|
|
583
|
+
state.listPermutationSpace.append(permutationSpace)
|
|
584
|
+
return state
|