mapFolding 0.17.1__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 +7 -11
- easyRun/countFolds.py +11 -10
- easyRun/meanders.py +6 -8
- mapFolding/__init__.py +24 -36
- 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 -67
- mapFolding/algorithms/matrixMeandersNumPyndas.py +18 -18
- mapFolding/algorithms/oeisIDbyFormula.py +4 -4
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +3 -3
- mapFolding/basecamp.py +11 -80
- mapFolding/beDRY.py +107 -111
- mapFolding/dataBaskets.py +0 -56
- 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 +1 -1
- 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 +134 -80
- 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.1.dist-info → mapfolding-0.18.0.dist-info}/METADATA +11 -8
- mapfolding-0.18.0.dist-info/RECORD +305 -0
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/WHEEL +1 -1
- easyRun/eliminateFolds.py +0 -60
- mapFolding/algorithms/constraintPropagation.py +0 -184
- mapFolding/algorithms/elimination.py +0 -131
- mapFolding/algorithms/eliminationCount.py +0 -26
- mapFolding/algorithms/eliminationPinned.py +0 -35
- mapFolding/algorithms/iff.py +0 -206
- mapFolding/algorithms/patternFinder.py +0 -280
- mapFolding/algorithms/pinning2Dn.py +0 -345
- mapFolding/algorithms/pinning2DnAnnex.py +0 -43
- mapFolding/tests/verify.py +0 -323
- mapfolding-0.17.1.dist-info/RECORD +0 -112
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# ruff: noqa: T201
|
|
2
|
+
"""Analyze entropy of leaves in folding sequences to understand their distributional properties."""
|
|
3
|
+
from hunterMakesPy import raiseIfNone
|
|
4
|
+
from mapFolding._e import dimensionNearestTail, getLeafDomain, pileOrigin, 零
|
|
5
|
+
from mapFolding._e._dataDynamic import getDataFrameFoldings
|
|
6
|
+
from mapFolding._e.dataBaskets import EliminationState
|
|
7
|
+
from typing import Any, TYPE_CHECKING
|
|
8
|
+
import numpy
|
|
9
|
+
import pandas
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from pandas import DataFrame, Series
|
|
13
|
+
|
|
14
|
+
def measureEntropy(state: EliminationState, listLeavesAnalyzed: list[int] | None = None) -> pandas.DataFrame:
|
|
15
|
+
"""Measure the relative entropy and distributional properties of leaves across folding sequences.
|
|
16
|
+
|
|
17
|
+
This function analyzes how leaves are distributed across their mathematical domains by comparing
|
|
18
|
+
empirical distributions from actual folding sequences against uniform distributions. The analysis
|
|
19
|
+
uses Shannon entropy normalized by maximum possible entropy to produce comparable measures across
|
|
20
|
+
leaves with different domain sizes.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
state : EliminationState
|
|
25
|
+
The elimination state containing the map shape and dimension information.
|
|
26
|
+
listLeavesAnalyzed : list[int] | None = None
|
|
27
|
+
Specific leaves to analyze. If None, analyzes all leaves except the trivial ones
|
|
28
|
+
(0, 1, and leavesTotal-1) which always occupy the same pile.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
dataframeEntropy : pandas.DataFrame
|
|
33
|
+
DataFrame with columns:
|
|
34
|
+
- 'leaf': The leaf value being analyzed
|
|
35
|
+
- 'domainSize': Number of possible piles where this leaf can appear
|
|
36
|
+
- 'entropyActual': Shannon entropy of the empirical distribution
|
|
37
|
+
- 'entropyMaximum': Maximum possible entropy (uniform distribution)
|
|
38
|
+
- 'entropyRelative': entropyActual / entropyMaximum (0 to 1)
|
|
39
|
+
- 'concentrationMaximum': Maximum frequency / mean frequency
|
|
40
|
+
- 'bitPattern': Binary representation for easy identification of patterns
|
|
41
|
+
- 'bitCount': Number of 1s in binary representation
|
|
42
|
+
- 'trailingZeros': Number of trailing zeros (power of 2 factor)
|
|
43
|
+
Sorted by entropyRelative descending to show most uniform distributions first.
|
|
44
|
+
|
|
45
|
+
Notes
|
|
46
|
+
-----
|
|
47
|
+
The relative entropy metric allows fair comparison between leaves with vastly different domain
|
|
48
|
+
sizes. A value near 1.0 indicates nearly uniform distribution (high entropy, unpredictable),
|
|
49
|
+
while values near 0.0 indicate highly concentrated distribution (low entropy, predictable).
|
|
50
|
+
|
|
51
|
+
The concentration metric shows how peaked the distribution is by comparing the most frequent
|
|
52
|
+
position to the mean frequency. Higher values indicate more predictable placement.
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
dataframeFoldings: pandas.DataFrame = raiseIfNone(getDataFrameFoldings(state))
|
|
56
|
+
|
|
57
|
+
if listLeavesAnalyzed is None:
|
|
58
|
+
leavesExcluded: set[int] = {pileOrigin, 零, state.leavesTotal - 零}
|
|
59
|
+
listLeavesAnalyzed = [leaf for leaf in range(state.leavesTotal) if leaf not in leavesExcluded]
|
|
60
|
+
|
|
61
|
+
listEntropyRecords: list[dict[str, Any]] = []
|
|
62
|
+
|
|
63
|
+
for leaf in listLeavesAnalyzed:
|
|
64
|
+
domainLeaf: range = getLeafDomain(state, leaf)
|
|
65
|
+
domainSize: int = len(domainLeaf)
|
|
66
|
+
|
|
67
|
+
if domainSize == 0:
|
|
68
|
+
continue
|
|
69
|
+
|
|
70
|
+
dataframeMelted: pandas.DataFrame = dataframeFoldings[dataframeFoldings == leaf].melt(ignore_index=False)
|
|
71
|
+
dataframeMelted = dataframeMelted.dropna()
|
|
72
|
+
if dataframeMelted.empty:
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
arrayPileCounts: numpy.ndarray = numpy.bincount(dataframeMelted['variable'].astype(int), minlength=state.leavesTotal)
|
|
76
|
+
arrayPileCountsInDomain: numpy.ndarray = arrayPileCounts[list(domainLeaf)]
|
|
77
|
+
arrayFrequencies: numpy.ndarray = arrayPileCountsInDomain / arrayPileCountsInDomain.sum()
|
|
78
|
+
|
|
79
|
+
maskNonzero: numpy.ndarray = arrayFrequencies > 0
|
|
80
|
+
entropyActual: float = float(-numpy.sum(arrayFrequencies[maskNonzero] * numpy.log2(arrayFrequencies[maskNonzero])))
|
|
81
|
+
entropyMaximum: float = float(numpy.log2(domainSize))
|
|
82
|
+
entropyRelative: float = entropyActual / entropyMaximum if entropyMaximum > 0 else 0.0
|
|
83
|
+
|
|
84
|
+
frequencyMaximum: float = float(arrayFrequencies.max())
|
|
85
|
+
frequencyMean: float = 1.0 / domainSize
|
|
86
|
+
concentrationMaximum: float = frequencyMaximum / frequencyMean if frequencyMean > 0 else 0.0
|
|
87
|
+
|
|
88
|
+
listEntropyRecords.append({
|
|
89
|
+
'leaf': leaf,
|
|
90
|
+
'domainSize': domainSize,
|
|
91
|
+
'entropyActual': entropyActual,
|
|
92
|
+
'entropyMaximum': entropyMaximum,
|
|
93
|
+
'entropyRelative': entropyRelative,
|
|
94
|
+
'concentrationMaximum': concentrationMaximum,
|
|
95
|
+
'bitPattern': leaf.__format__('06b'),
|
|
96
|
+
'bitCount': leaf.bit_count(),
|
|
97
|
+
'trailingZeros': dimensionNearestTail(leaf),
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
return pandas.DataFrame(listEntropyRecords).sort_values('entropyRelative', ascending=False).reset_index(drop=True)
|
|
101
|
+
|
|
102
|
+
def analyzeEntropyForDimension(dimensionsTotal: int = 6) -> None:
|
|
103
|
+
"""Analyze entropy for all non-trivial leaves in a given dimension configuration."""
|
|
104
|
+
mapShape: tuple[int, ...] = (2,) * dimensionsTotal
|
|
105
|
+
state: EliminationState = EliminationState(mapShape)
|
|
106
|
+
|
|
107
|
+
print(f"\n{'=' * 80}")
|
|
108
|
+
print(f"Entropy Analysis for 2^{dimensionsTotal} (mapShape={mapShape})")
|
|
109
|
+
print(f"{'=' * 80}\n")
|
|
110
|
+
|
|
111
|
+
dataframeEntropy = measureEntropy(state)
|
|
112
|
+
|
|
113
|
+
print("\nTop 20 leaves by relative entropy (most uniform distributions):")
|
|
114
|
+
print(dataframeEntropy.head(20).to_string(index=False))
|
|
115
|
+
|
|
116
|
+
print("\n\nBottom 20 leaves by relative entropy (most concentrated distributions):")
|
|
117
|
+
print(dataframeEntropy.tail(20).to_string(index=False))
|
|
118
|
+
|
|
119
|
+
leaf63: int = 63
|
|
120
|
+
if leaf63 in dataframeEntropy['leaf'].to_numpy():
|
|
121
|
+
row63: Series = dataframeEntropy[dataframeEntropy['leaf'] == leaf63].iloc[0]
|
|
122
|
+
rankOf63: int = int(dataframeEntropy[dataframeEntropy['leaf'] == leaf63].index[0])
|
|
123
|
+
totalLeaves: int = len(dataframeEntropy)
|
|
124
|
+
|
|
125
|
+
print(f"\n\n{'=' * 80}")
|
|
126
|
+
print(f"Analysis of Leaf 63 ({bin(leaf63)} = 2^6 - 1, all dimensions have value 1)")
|
|
127
|
+
print(f"{'=' * 80}")
|
|
128
|
+
print(f"Rank: {rankOf63 + 1} / {totalLeaves}")
|
|
129
|
+
print(f"Domain Size: {row63['domainSize']}")
|
|
130
|
+
print(f"Entropy (actual): {row63['entropyActual']:.4f}")
|
|
131
|
+
print(f"Entropy (maximum): {row63['entropyMaximum']:.4f}")
|
|
132
|
+
print(f"Relative Entropy: {row63['entropyRelative']:.4f} (1.0 = uniform, 0.0 = concentrated)")
|
|
133
|
+
print(f"Concentration: {row63['concentrationMaximum']:.4f}x mean frequency")
|
|
134
|
+
print(f"Bit Count: {row63['bitCount']}")
|
|
135
|
+
print(f"Trailing Zeros: {row63['trailingZeros']}")
|
|
136
|
+
|
|
137
|
+
print("\n\nComparing leaf 63 to leaves with similar properties:")
|
|
138
|
+
|
|
139
|
+
bitCount: int = int(row63['bitCount'])
|
|
140
|
+
leavesWithSameBitCount: DataFrame = dataframeEntropy[dataframeEntropy['bitCount'] == bitCount]
|
|
141
|
+
print(f"\nLeaves with same bit_count ({bitCount}):")
|
|
142
|
+
subsetBitCount: DataFrame = leavesWithSameBitCount[['leaf', 'bitPattern', 'entropyRelative', 'concentrationMaximum']]
|
|
143
|
+
print(subsetBitCount.head(10).to_string(index=False))
|
|
144
|
+
|
|
145
|
+
trailingZeros: int = int(row63['trailingZeros'])
|
|
146
|
+
leavesWithSameTrailingZeros: DataFrame = dataframeEntropy[dataframeEntropy['trailingZeros'] == trailingZeros]
|
|
147
|
+
print(f"\nLeaves with same trailing zeros ({trailingZeros}):")
|
|
148
|
+
subsetTrailing: DataFrame = leavesWithSameTrailingZeros[['leaf', 'bitPattern', 'entropyRelative', 'concentrationMaximum']]
|
|
149
|
+
print(subsetTrailing.head(10).to_string(index=False))
|
|
150
|
+
|
|
151
|
+
powersOf2: DataFrame = dataframeEntropy[dataframeEntropy['bitCount'] == 1]
|
|
152
|
+
print("\nPowers of 2 (bitCount == 1):")
|
|
153
|
+
subsetPowers: DataFrame = powersOf2[['leaf', 'bitPattern', 'entropyRelative', 'concentrationMaximum']]
|
|
154
|
+
print(subsetPowers.to_string(index=False))
|
|
155
|
+
|
|
156
|
+
print(f"\n{'=' * 80}")
|
|
157
|
+
print("Summary Statistics")
|
|
158
|
+
print(f"{'=' * 80}")
|
|
159
|
+
print(dataframeEntropy[['entropyRelative', 'concentrationMaximum']].describe())
|
|
160
|
+
|
|
161
|
+
if __name__ == '__main__':
|
|
162
|
+
analyzeEntropyForDimension(6)
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# ruff: noqa: ERA001 T201 T203 # noqa: RUF100
|
|
2
|
+
# NOTE to AI assistants: this module is not representative of my coding style. Most of it is AI generated, but because it's temporary code, I didn't strictly enforce my usual standards. Do not emulate it.
|
|
3
|
+
from gmpy2 import bit_mask
|
|
4
|
+
from hunterMakesPy import raiseIfNone
|
|
5
|
+
from mapFolding import ansiColorReset, ansiColors
|
|
6
|
+
from mapFolding._e import (
|
|
7
|
+
dimensionNearestTail, dimensionNearest首, getDictionaryConditionalLeafPredecessors,
|
|
8
|
+
getDictionaryConditionalLeafSuccessors, getLeafDomain, howManyDimensionsHaveOddParity, Leaf, Pile, pileOrigin, 零)
|
|
9
|
+
from mapFolding._e._dataDynamic import getDataFrameFoldings
|
|
10
|
+
from mapFolding._e.dataBaskets import EliminationState
|
|
11
|
+
from pprint import pprint
|
|
12
|
+
from typing import Any
|
|
13
|
+
import numpy
|
|
14
|
+
import pandas
|
|
15
|
+
|
|
16
|
+
def getLeafUnconditionalPrecedence(state: EliminationState) -> pandas.DataFrame:
|
|
17
|
+
"""Identify leaves that always precede other leaves across all folding sequences.
|
|
18
|
+
|
|
19
|
+
(AI generated docstring)
|
|
20
|
+
|
|
21
|
+
Analyzes all valid folding sequences for a given elimination state to find pairs
|
|
22
|
+
of leaves (Earlier, Later) where the Earlier leaf appears at a smaller column
|
|
23
|
+
index than the Later leaf in every single folding sequence without exception.
|
|
24
|
+
|
|
25
|
+
The analysis proceeds as follows.
|
|
26
|
+
1. Load sequence data where each row is a folding and columns represent positions.
|
|
27
|
+
2. Build a positions matrix mapping each leaf value to its column index per row.
|
|
28
|
+
3. Construct a comparison cube testing whether each leaf precedes every other leaf.
|
|
29
|
+
4. Reduce across all rows to find pairs where precedence holds universally.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
state : EliminationState
|
|
34
|
+
The elimination state containing the map shape and dimension information.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
dataframePrecedence : pandas.DataFrame
|
|
39
|
+
A two-column DataFrame with 'Earlier' and 'Later' indicating leaf values
|
|
40
|
+
where the Earlier leaf unconditionally precedes the Later leaf.
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
dataframeSequences: pandas.DataFrame = raiseIfNone(getDataFrameFoldings(state))
|
|
44
|
+
arraySequences: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = dataframeSequences.to_numpy(dtype=numpy.int16)
|
|
45
|
+
|
|
46
|
+
rowsCount: int
|
|
47
|
+
positionsCount: int
|
|
48
|
+
rowsCount, positionsCount = arraySequences.shape
|
|
49
|
+
valueMaximum: int = int(arraySequences.max())
|
|
50
|
+
positionsMatrix: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.full((rowsCount, valueMaximum + 1), -1, dtype=numpy.int16)
|
|
51
|
+
|
|
52
|
+
rowIndices: numpy.ndarray[Any, numpy.dtype[numpy.int32]] = numpy.arange(rowsCount, dtype=numpy.int32)[:, None]
|
|
53
|
+
columnIndices: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.broadcast_to(numpy.arange(positionsCount, dtype=numpy.int16), (rowsCount, positionsCount))
|
|
54
|
+
positionsMatrix[rowIndices, arraySequences] = columnIndices
|
|
55
|
+
|
|
56
|
+
valuesPresentEveryRow: numpy.ndarray[Any, numpy.dtype[numpy.intp]] = numpy.where((positionsMatrix >= 0).all(axis=0))[0]
|
|
57
|
+
positionsAnalyzed: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsMatrix[:, valuesPresentEveryRow]
|
|
58
|
+
|
|
59
|
+
comparisonCube: numpy.ndarray[Any, numpy.dtype[numpy.bool_]] = positionsAnalyzed[:, :, None] < positionsAnalyzed[:, None, :]
|
|
60
|
+
alwaysEarlierMatrix: numpy.ndarray[Any, numpy.dtype[numpy.bool_]] = comparisonCube.all(axis=0) # pyright: ignore[reportAssignmentType]
|
|
61
|
+
numpy.fill_diagonal(alwaysEarlierMatrix, val=False)
|
|
62
|
+
|
|
63
|
+
indicesEarlier: numpy.ndarray[Any, numpy.dtype[numpy.intp]]
|
|
64
|
+
indicesLater: numpy.ndarray[Any, numpy.dtype[numpy.intp]]
|
|
65
|
+
indicesEarlier, indicesLater = numpy.where(alwaysEarlierMatrix)
|
|
66
|
+
dataframePrecedence: pandas.DataFrame = pandas.DataFrame(
|
|
67
|
+
{
|
|
68
|
+
'Earlier': valuesPresentEveryRow[indicesEarlier],
|
|
69
|
+
'Later': valuesPresentEveryRow[indicesLater],
|
|
70
|
+
}
|
|
71
|
+
).sort_values(['Earlier', 'Later']).reset_index(drop=True)
|
|
72
|
+
|
|
73
|
+
return dataframePrecedence
|
|
74
|
+
|
|
75
|
+
def getLeafConditionalPrecedence(state: EliminationState) -> pandas.DataFrame:
|
|
76
|
+
"""Identify precedence relationships that emerge only when a leaf is at its earliest column.
|
|
77
|
+
|
|
78
|
+
(AI generated docstring)
|
|
79
|
+
|
|
80
|
+
For each leaf, determines the earliest possible column it can occupy based on
|
|
81
|
+
bit structure properties (`bit_count` and `howMany0coordinatesAtTail`). Then
|
|
82
|
+
finds leaves that always precede it in the subset of foldings where that leaf
|
|
83
|
+
is at its earliest column. Excludes relationships already captured by the
|
|
84
|
+
unconditional precedence analysis.
|
|
85
|
+
|
|
86
|
+
The formula for the earliest column of a leaf is.
|
|
87
|
+
columnEarliest = leaf.bit_count() + (2^(howMany0coordinatesAtTail(leaf) + 1) - 2)
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
state : EliminationState
|
|
92
|
+
The elimination state containing the map shape and dimension information.
|
|
93
|
+
columnsToExclude : list[int] | None = None
|
|
94
|
+
Column indices (as integers) to exclude from analysis. Pass [0, 1, leavesTotal-1]
|
|
95
|
+
to exclude the trivially-pinned positions.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
dataframeConditionalPrecedence : pandas.DataFrame
|
|
100
|
+
A three-column DataFrame with 'Earlier', 'Later', and 'AtColumn' indicating
|
|
101
|
+
that when 'Later' is at column 'AtColumn', 'Earlier' always precedes it.
|
|
102
|
+
Only includes relationships not already present in unconditional precedence.
|
|
103
|
+
|
|
104
|
+
"""
|
|
105
|
+
dataframeSequences: pandas.DataFrame = raiseIfNone(getDataFrameFoldings(state))
|
|
106
|
+
columnsToExclude: list[int] | None = [pileOrigin, 零, state.pileLast]
|
|
107
|
+
if columnsToExclude is not None: # pyright: ignore[reportUnnecessaryComparison]
|
|
108
|
+
dataframeSequences = dataframeSequences.drop(columns=columnsToExclude)
|
|
109
|
+
arraySequences: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = dataframeSequences.to_numpy(dtype=numpy.int16)
|
|
110
|
+
|
|
111
|
+
rowsCount: int
|
|
112
|
+
positionsCount: int
|
|
113
|
+
rowsCount, positionsCount = arraySequences.shape
|
|
114
|
+
valueMaximum: int = int(arraySequences.max())
|
|
115
|
+
positionsMatrix: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.full((rowsCount, valueMaximum + 1), -1, dtype=numpy.int16)
|
|
116
|
+
|
|
117
|
+
rowIndices: numpy.ndarray[Any, numpy.dtype[numpy.int32]] = numpy.arange(rowsCount, dtype=numpy.int32)[:, None]
|
|
118
|
+
columnIndices: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.broadcast_to(numpy.arange(positionsCount, dtype=numpy.int16), (rowsCount, positionsCount))
|
|
119
|
+
positionsMatrix[rowIndices, arraySequences] = columnIndices
|
|
120
|
+
|
|
121
|
+
columnOffset: int = 2 if columnsToExclude is not None and 0 in columnsToExclude and 1 in columnsToExclude else 0 # pyright: ignore[reportUnnecessaryComparison]
|
|
122
|
+
|
|
123
|
+
dataframeUnconditional: pandas.DataFrame = getLeafUnconditionalPrecedence(state)
|
|
124
|
+
setUnconditional: set[tuple[Any, Any]] = set(zip(dataframeUnconditional['Earlier'], dataframeUnconditional['Later'], strict=True))
|
|
125
|
+
|
|
126
|
+
listConditionalRelationships: list[dict[str, int]] = []
|
|
127
|
+
|
|
128
|
+
for leafLater in range(state.leavesTotal):
|
|
129
|
+
columnEarliestOriginal: int = leafLater.bit_count() + (2 ** (dimensionNearestTail(leafLater) + 1) - 2)
|
|
130
|
+
columnEarliestIndex: int = columnEarliestOriginal - columnOffset
|
|
131
|
+
|
|
132
|
+
if columnEarliestIndex < 0:
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
maskRowsAtEarliestColumn: numpy.ndarray[Any, numpy.dtype[numpy.bool_]] = (positionsMatrix[:, leafLater] == columnEarliestIndex)
|
|
136
|
+
|
|
137
|
+
if not numpy.any(maskRowsAtEarliestColumn):
|
|
138
|
+
continue
|
|
139
|
+
|
|
140
|
+
positionsSubset: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsMatrix[maskRowsAtEarliestColumn]
|
|
141
|
+
|
|
142
|
+
for leafEarlier in range(state.leavesTotal):
|
|
143
|
+
if leafEarlier == leafLater:
|
|
144
|
+
continue
|
|
145
|
+
|
|
146
|
+
positionsOfEarlier: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsSubset[:, leafEarlier]
|
|
147
|
+
|
|
148
|
+
isEarlierAlwaysPresentAndPrecedes: bool = bool(numpy.all((positionsOfEarlier >= 0) & (positionsOfEarlier < columnEarliestIndex)))
|
|
149
|
+
if isEarlierAlwaysPresentAndPrecedes and (leafEarlier, leafLater) not in setUnconditional:
|
|
150
|
+
listConditionalRelationships.append({
|
|
151
|
+
'Earlier': leafEarlier,
|
|
152
|
+
'Later': leafLater,
|
|
153
|
+
'AtColumn': columnEarliestOriginal
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
dataframeConditionalPrecedence: pandas.DataFrame = pandas.DataFrame(listConditionalRelationships).sort_values(['Later', 'Earlier']).reset_index(drop=True)
|
|
157
|
+
|
|
158
|
+
return dataframeConditionalPrecedence
|
|
159
|
+
|
|
160
|
+
def getLeafConditionalPrecedenceAtLastPileOfLeafDomain(state: EliminationState) -> pandas.DataFrame:
|
|
161
|
+
"""Identify precedence relationships that emerge only when a leaf is at the last pile in its domain.
|
|
162
|
+
|
|
163
|
+
(AI generated docstring)
|
|
164
|
+
|
|
165
|
+
For each leaf, determines the last pile it can occupy within its mathematical
|
|
166
|
+
domain, then finds leaves that always precede it in the subset of foldings
|
|
167
|
+
where that leaf is observed at that last-in-domain pile. Excludes relationships
|
|
168
|
+
already captured by the unconditional precedence analysis.
|
|
169
|
+
|
|
170
|
+
The formula for the last pile *in* the domain of a leaf is.
|
|
171
|
+
pileLastOfLeaf = int(bit_mask(dimensionsTotal) ^ bit_mask(dimensionsTotal - dimensionNearest首(leaf))) - howManyDimensionsHaveOddParity(leaf) + 1
|
|
172
|
+
|
|
173
|
+
Parameters
|
|
174
|
+
----------
|
|
175
|
+
state : EliminationState
|
|
176
|
+
The elimination state containing the map shape and dimension information.
|
|
177
|
+
columnsToExclude : list[int] | None = None
|
|
178
|
+
Column indices (as integers) to exclude from analysis. Pass [0, 1, leavesTotal-1]
|
|
179
|
+
to exclude the trivially-pinned positions.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
dataframeConditionalPrecedenceAtLastPile : pandas.DataFrame
|
|
184
|
+
A three-column DataFrame with 'Earlier', 'Later', and 'AtColumn' indicating
|
|
185
|
+
that when 'Later' is at column 'AtColumn' (its last-in-domain pile),
|
|
186
|
+
'Earlier' always precedes it. Only includes relationships not already
|
|
187
|
+
present in unconditional precedence.
|
|
188
|
+
|
|
189
|
+
"""
|
|
190
|
+
dataframeSequences: pandas.DataFrame = raiseIfNone(getDataFrameFoldings(state))
|
|
191
|
+
columnsToExclude: list[int] | None = [pileOrigin, 零, state.pileLast]
|
|
192
|
+
if columnsToExclude is not None: # pyright: ignore[reportUnnecessaryComparison]
|
|
193
|
+
dataframeSequences = dataframeSequences.drop(columns=columnsToExclude)
|
|
194
|
+
arraySequences: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = dataframeSequences.to_numpy(dtype=numpy.int16)
|
|
195
|
+
|
|
196
|
+
rowsCount: int
|
|
197
|
+
positionsCount: int
|
|
198
|
+
rowsCount, positionsCount = arraySequences.shape
|
|
199
|
+
valueMaximum: int = int(arraySequences.max())
|
|
200
|
+
positionsMatrix: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.full((rowsCount, valueMaximum + 1), -1, dtype=numpy.int16)
|
|
201
|
+
|
|
202
|
+
rowIndices: numpy.ndarray[Any, numpy.dtype[numpy.int32]] = numpy.arange(rowsCount, dtype=numpy.int32)[:, None]
|
|
203
|
+
columnIndices: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.broadcast_to(numpy.arange(positionsCount, dtype=numpy.int16), (rowsCount, positionsCount))
|
|
204
|
+
positionsMatrix[rowIndices, arraySequences] = columnIndices
|
|
205
|
+
|
|
206
|
+
columnOffset: int = 2 if columnsToExclude is not None and 0 in columnsToExclude and 1 in columnsToExclude else 0 # pyright: ignore[reportUnnecessaryComparison]
|
|
207
|
+
|
|
208
|
+
dataframeUnconditional: pandas.DataFrame = getLeafUnconditionalPrecedence(state)
|
|
209
|
+
setUnconditional: set[tuple[Any, Any]] = set(zip(dataframeUnconditional['Earlier'], dataframeUnconditional['Later'], strict=True))
|
|
210
|
+
|
|
211
|
+
listConditionalRelationships: list[dict[str, int]] = []
|
|
212
|
+
|
|
213
|
+
for leafLater in range(state.leavesTotal):
|
|
214
|
+
pileLastOfLeafOriginal: int = int(bit_mask(state.dimensionsTotal) ^ bit_mask(state.dimensionsTotal - dimensionNearest首(leafLater))) - howManyDimensionsHaveOddParity(leafLater) + 1
|
|
215
|
+
pileLastOfLeafIndex: int = pileLastOfLeafOriginal - columnOffset
|
|
216
|
+
|
|
217
|
+
if pileLastOfLeafIndex < 0:
|
|
218
|
+
continue
|
|
219
|
+
|
|
220
|
+
maskRowsAtLastPileOfLeaf: numpy.ndarray[Any, numpy.dtype[numpy.bool_]] = (positionsMatrix[:, leafLater] == pileLastOfLeafIndex)
|
|
221
|
+
|
|
222
|
+
if not numpy.any(maskRowsAtLastPileOfLeaf):
|
|
223
|
+
continue
|
|
224
|
+
|
|
225
|
+
positionsSubset: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsMatrix[maskRowsAtLastPileOfLeaf]
|
|
226
|
+
|
|
227
|
+
for leafEarlier in range(state.leavesTotal):
|
|
228
|
+
if leafEarlier == leafLater:
|
|
229
|
+
continue
|
|
230
|
+
|
|
231
|
+
positionsOfEarlier: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsSubset[:, leafEarlier]
|
|
232
|
+
|
|
233
|
+
isEarlierAlwaysPresentAndPrecedes: bool = bool(numpy.all((positionsOfEarlier >= 0) & (positionsOfEarlier < pileLastOfLeafIndex)))
|
|
234
|
+
if isEarlierAlwaysPresentAndPrecedes and (leafEarlier, leafLater) not in setUnconditional:
|
|
235
|
+
listConditionalRelationships.append({
|
|
236
|
+
'Earlier': leafEarlier,
|
|
237
|
+
'Later': leafLater,
|
|
238
|
+
'AtColumn': pileLastOfLeafOriginal
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
dataframeConditionalPrecedenceAtLastPile: pandas.DataFrame = pandas.DataFrame(listConditionalRelationships).sort_values(['Later', 'Earlier']).reset_index(drop=True)
|
|
242
|
+
|
|
243
|
+
return dataframeConditionalPrecedenceAtLastPile
|
|
244
|
+
|
|
245
|
+
def getLeafConditionalSuccession(state: EliminationState) -> pandas.DataFrame:
|
|
246
|
+
"""When a leaf is at the last pile in its domain, identify leaves that must come after it."""
|
|
247
|
+
dataframeSequences: pandas.DataFrame = raiseIfNone(getDataFrameFoldings(state))
|
|
248
|
+
columnsToExclude: list[int] | None = [pileOrigin, 零, state.pileLast]
|
|
249
|
+
if columnsToExclude is not None: # pyright: ignore[reportUnnecessaryComparison]
|
|
250
|
+
dataframeSequences = dataframeSequences.drop(columns=columnsToExclude)
|
|
251
|
+
arraySequences: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = dataframeSequences.to_numpy(dtype=numpy.int16)
|
|
252
|
+
|
|
253
|
+
rowsCount: int
|
|
254
|
+
positionsCount: int
|
|
255
|
+
rowsCount, positionsCount = arraySequences.shape
|
|
256
|
+
valueMaximum: int = int(arraySequences.max())
|
|
257
|
+
positionsMatrix: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.full((rowsCount, valueMaximum + 1), -1, dtype=numpy.int16)
|
|
258
|
+
|
|
259
|
+
rowIndices: numpy.ndarray[Any, numpy.dtype[numpy.int32]] = numpy.arange(rowsCount, dtype=numpy.int32)[:, None]
|
|
260
|
+
columnIndices: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.broadcast_to(numpy.arange(positionsCount, dtype=numpy.int16), (rowsCount, positionsCount))
|
|
261
|
+
positionsMatrix[rowIndices, arraySequences] = columnIndices
|
|
262
|
+
|
|
263
|
+
columnOffset: int = 2 if columnsToExclude is not None and 0 in columnsToExclude and 1 in columnsToExclude else 0 # pyright: ignore[reportUnnecessaryComparison]
|
|
264
|
+
|
|
265
|
+
dataframeUnconditional: pandas.DataFrame = getLeafUnconditionalPrecedence(state)
|
|
266
|
+
setUnconditional: set[tuple[Any, Any]] = set(zip(dataframeUnconditional['Earlier'], dataframeUnconditional['Later'], strict=True))
|
|
267
|
+
|
|
268
|
+
listConditionalRelationships: list[dict[str, int]] = []
|
|
269
|
+
|
|
270
|
+
for leafEarlier in range(state.leavesTotal):
|
|
271
|
+
pileLastOfLeafOriginal: int = int(bit_mask(state.dimensionsTotal) ^ bit_mask(state.dimensionsTotal - dimensionNearest首(leafEarlier))) - howManyDimensionsHaveOddParity(leafEarlier) + 1
|
|
272
|
+
pileLastOfLeafIndex: int = pileLastOfLeafOriginal - columnOffset
|
|
273
|
+
|
|
274
|
+
if pileLastOfLeafIndex < 0:
|
|
275
|
+
continue
|
|
276
|
+
|
|
277
|
+
maskRowsAtLastPileOfLeaf: numpy.ndarray[Any, numpy.dtype[numpy.bool_]] = (positionsMatrix[:, leafEarlier] == pileLastOfLeafIndex)
|
|
278
|
+
|
|
279
|
+
if not numpy.any(maskRowsAtLastPileOfLeaf):
|
|
280
|
+
continue
|
|
281
|
+
|
|
282
|
+
positionsSubset: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsMatrix[maskRowsAtLastPileOfLeaf]
|
|
283
|
+
|
|
284
|
+
for leafLater in range(state.leavesTotal):
|
|
285
|
+
if leafLater == leafEarlier:
|
|
286
|
+
continue
|
|
287
|
+
|
|
288
|
+
positionsOfLater: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsSubset[:, leafLater]
|
|
289
|
+
isLaterAlwaysPresentAndFollows: bool = bool(numpy.all((positionsOfLater >= 0) & (pileLastOfLeafIndex < positionsOfLater)))
|
|
290
|
+
if isLaterAlwaysPresentAndFollows and (leafEarlier, leafLater) not in setUnconditional:
|
|
291
|
+
listConditionalRelationships.append({
|
|
292
|
+
'Earlier': leafEarlier,
|
|
293
|
+
'Later': leafLater,
|
|
294
|
+
'AtColumn': pileLastOfLeafOriginal,
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
dataframeConditionalSuccession: pandas.DataFrame = pandas.DataFrame(listConditionalRelationships, columns=['Earlier', 'Later', 'AtColumn']).sort_values(['Earlier', 'Later']).reset_index(drop=True)
|
|
298
|
+
|
|
299
|
+
return dataframeConditionalSuccession
|
|
300
|
+
|
|
301
|
+
def getLeafConditionalPrecedenceAcrossLeafDomain(state: EliminationState, leafLater: Leaf) -> pandas.DataFrame:
|
|
302
|
+
dataframeSequences: pandas.DataFrame = raiseIfNone(getDataFrameFoldings(state))
|
|
303
|
+
columnsToExclude: list[Pile] | None = [pileOrigin, 零, state.pileLast]
|
|
304
|
+
if columnsToExclude is not None: # pyright: ignore[reportUnnecessaryComparison]
|
|
305
|
+
dataframeSequences = dataframeSequences.drop(columns=columnsToExclude)
|
|
306
|
+
arraySequences: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = dataframeSequences.to_numpy(dtype=numpy.int16)
|
|
307
|
+
|
|
308
|
+
rowsCount: int
|
|
309
|
+
positionsCount: int
|
|
310
|
+
rowsCount, positionsCount = arraySequences.shape
|
|
311
|
+
valueMaximum: int = int(arraySequences.max())
|
|
312
|
+
positionsMatrix: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.full((rowsCount, valueMaximum + 1), -1, dtype=numpy.int16)
|
|
313
|
+
|
|
314
|
+
rowIndices: numpy.ndarray[Any, numpy.dtype[numpy.int32]] = numpy.arange(rowsCount, dtype=numpy.int32)[:, None]
|
|
315
|
+
columnIndices: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = numpy.broadcast_to(numpy.arange(positionsCount, dtype=numpy.int16), (rowsCount, positionsCount))
|
|
316
|
+
positionsMatrix[rowIndices, arraySequences] = columnIndices
|
|
317
|
+
|
|
318
|
+
columnOffset: int = 2 if columnsToExclude is not None and 0 in columnsToExclude and 1 in columnsToExclude else 0 # pyright: ignore[reportUnnecessaryComparison]
|
|
319
|
+
|
|
320
|
+
dataframeUnconditional: pandas.DataFrame = getLeafUnconditionalPrecedence(state)
|
|
321
|
+
setUnconditional: set[tuple[Any, Any]] = set(zip(dataframeUnconditional['Earlier'], dataframeUnconditional['Later'], strict=True))
|
|
322
|
+
|
|
323
|
+
leafDomain: range = getLeafDomain(state, leafLater)
|
|
324
|
+
|
|
325
|
+
listConditionalRelationships: list[dict[str, int]] = []
|
|
326
|
+
for pileOfLeafOriginal in leafDomain:
|
|
327
|
+
if pileOfLeafOriginal <= 1:
|
|
328
|
+
continue
|
|
329
|
+
if pileOfLeafOriginal >= state.pileLast:
|
|
330
|
+
continue
|
|
331
|
+
|
|
332
|
+
pileOfLeafIndex: int = pileOfLeafOriginal - columnOffset
|
|
333
|
+
if pileOfLeafIndex < 0:
|
|
334
|
+
continue
|
|
335
|
+
|
|
336
|
+
maskRowsAtPileOfLeaf: numpy.ndarray[Any, numpy.dtype[numpy.bool_]] = (positionsMatrix[:, leafLater] == pileOfLeafIndex)
|
|
337
|
+
if not numpy.any(maskRowsAtPileOfLeaf):
|
|
338
|
+
continue
|
|
339
|
+
|
|
340
|
+
positionsSubset: numpy.ndarray[Any, numpy.dtype[numpy.int16]] = positionsMatrix[maskRowsAtPileOfLeaf]
|
|
341
|
+
maskAlwaysEarlier: numpy.ndarray[Any, numpy.dtype[numpy.bool_]] = numpy.all((positionsSubset >= 0) & (positionsSubset < pileOfLeafIndex), axis=0)
|
|
342
|
+
maskAlwaysEarlier[leafLater] = False
|
|
343
|
+
indicesEarlier: numpy.ndarray[Any, numpy.dtype[numpy.intp]] = numpy.flatnonzero(maskAlwaysEarlier)
|
|
344
|
+
|
|
345
|
+
for leafEarlierCandidate in indicesEarlier.tolist():
|
|
346
|
+
leafEarlier: Leaf = int(leafEarlierCandidate)
|
|
347
|
+
if (leafEarlier, leafLater) in setUnconditional:
|
|
348
|
+
continue
|
|
349
|
+
listConditionalRelationships.append({
|
|
350
|
+
'Earlier': leafEarlier,
|
|
351
|
+
'Later': leafLater,
|
|
352
|
+
'AtColumn': pileOfLeafOriginal,
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
dataframeConditionalPrecedenceAcrossDomain: pandas.DataFrame = pandas.DataFrame(listConditionalRelationships, columns=['Earlier', 'Later', 'AtColumn']).sort_values(['AtColumn', 'Earlier']).reset_index(drop=True)
|
|
356
|
+
return dataframeConditionalPrecedenceAcrossDomain
|
|
357
|
+
|
|
358
|
+
def getLeafConditionalPrecedenceAcrossLeafDomainPileGroups(state: EliminationState, leafLater: Leaf) -> list[list[Pile]]:
|
|
359
|
+
dataframeConditional: pandas.DataFrame = getLeafConditionalPrecedenceAcrossLeafDomain(state, leafLater)
|
|
360
|
+
pilesSortedUnique: list[Pile]
|
|
361
|
+
if dataframeConditional.empty:
|
|
362
|
+
pilesSortedUnique = []
|
|
363
|
+
else:
|
|
364
|
+
pilesSortedUnique = sorted({int(pile) for pile in dataframeConditional['AtColumn'].tolist()})
|
|
365
|
+
|
|
366
|
+
listPileGroups: list[list[Pile]] = []
|
|
367
|
+
for pile in pilesSortedUnique:
|
|
368
|
+
if not listPileGroups:
|
|
369
|
+
listPileGroups.append([pile])
|
|
370
|
+
elif pile == listPileGroups[-1][-1] + 2:
|
|
371
|
+
listPileGroups[-1].append(pile)
|
|
372
|
+
else:
|
|
373
|
+
listPileGroups.append([pile])
|
|
374
|
+
return listPileGroups
|
|
375
|
+
|
|
376
|
+
def getLeafPilesAtDomainEndFromConditionalPrecedenceAcrossLeafDomain(state: EliminationState, leaf: Leaf) -> list[Pile]:
|
|
377
|
+
listPileGroups: list[list[Pile]] = getLeafConditionalPrecedenceAcrossLeafDomainPileGroups(state, leaf)
|
|
378
|
+
listPilesAtEnd: list[Pile] = []
|
|
379
|
+
if listPileGroups:
|
|
380
|
+
listPilesAtEnd = listPileGroups[-1]
|
|
381
|
+
return listPilesAtEnd
|
|
382
|
+
|
|
383
|
+
def getDictionaryPilesAtDomainEndsFromConditionalPrecedenceAcrossLeafDomain(state: EliminationState, listLeavesAnalyzed: list[Leaf] | None = None) -> dict[Leaf, list[Pile]]:
|
|
384
|
+
if listLeavesAnalyzed is None:
|
|
385
|
+
leavesExcluded: set[Leaf] = {pileOrigin, 零, state.leavesTotal - 零}
|
|
386
|
+
listLeavesAnalyzed = [leaf for leaf in range(state.leavesTotal) if leaf not in leavesExcluded]
|
|
387
|
+
|
|
388
|
+
dictionaryPilesAtDomainEnds: dict[Leaf, list[Pile]] = {}
|
|
389
|
+
for leaf in listLeavesAnalyzed:
|
|
390
|
+
listPilesAtEnd: list[Pile] = getLeafPilesAtDomainEndFromConditionalPrecedenceAcrossLeafDomain(state, leaf)
|
|
391
|
+
if listPilesAtEnd:
|
|
392
|
+
dictionaryPilesAtDomainEnds[leaf] = listPilesAtEnd
|
|
393
|
+
return dictionaryPilesAtDomainEnds
|
|
394
|
+
|
|
395
|
+
if __name__ == '__main__':
|
|
396
|
+
state = EliminationState((2,) * 6)
|
|
397
|
+
# leaf33 is wrong because of step = 4.
|
|
398
|
+
# leaf33 and leaf49 are already known from prior analysis.
|
|
399
|
+
dictionaryPilesAtDomainEnds = getDictionaryPilesAtDomainEndsFromConditionalPrecedenceAcrossLeafDomain(state)
|
|
400
|
+
print(ansiColors.BlackOnCyan + 'dictionaryPilesAtDomainEnds' + ansiColorReset)
|
|
401
|
+
pprint(dictionaryPilesAtDomainEnds, width=140)
|
|
402
|
+
pprint(getDictionaryConditionalLeafPredecessors(state), width=380, compact=True)
|
|
403
|
+
pprint(getDictionaryConditionalLeafSuccessors(state), width=380, compact=True)
|