diff --git a/research/one-sided-residue-closures/LICENSE b/research/one-sided-residue-closures/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/research/one-sided-residue-closures/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/research/one-sided-residue-closures/MANIFEST.sha256 b/research/one-sided-residue-closures/MANIFEST.sha256 new file mode 100644 index 0000000000..8e355e2090 --- /dev/null +++ b/research/one-sided-residue-closures/MANIFEST.sha256 @@ -0,0 +1,298 @@ +c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4 LICENSE +1ea58e398f40239c0945d495a807b33bcadeb6d5dcd147a12bf71ff06a9ed7ec NOTICE.md +d5ac1774542be13e594f93d91b74d062be01d79dc9415d5a497a1171defa3bf6 PROOF_MAP.md +a72e954568dcd4c95e486c478f7db97187385c0eb618dcfbc252ebb8c06326ed README.md +b11425ba8f5f235d150da72725d8b860f61d5a85875c700768c966334d8f1ee8 checks/annon.py +f667dbd533e693ea2f64a56c8138e70c66361abb798cccc42ce22ed7c2ee42af checks/anroot.py +2531b66ebab58a786b55742882c442546b1263e098989e15067e3e0432f65af3 checks/build_ledger.py +4eeed399aedcaa325371504f6bfdc6169297acca43e224e7d470fc20e71dd30c checks/check_ledger.py +40abac6e35cbe5257bf1aa206c59050e69e8126a244f33a3a2baa4f5c1f1136d checks/cov.c +475d88deb0feb11ba10e5dd996a2f212adf2590cb8bd89a2a8823bb10f96ecce checks/d7plane.py +de1d8f9f646e70c4c2ce7d014d8592a179ec277cf9a08b4f085b1ecbd0bf0ce8 checks/dirs.py +715f5e96519b1886fa23d685ceb96079a891d32ab8bfec7fbcb6ac9022b20435 checks/e8.py +166871f30e3fbae1ef0d8d8afe0af59f197811b87e7f89e23bbdd7c37e597656 checks/facts_check.py +bb4595dcc1ea0988195b8a7a09e3204b44f4078c65ec06476f450bb1be63eba5 checks/flats.py +12e15b34873cd8ab8ef9ab6c7183711ade2e7fd3d0f2b10d7db8892d6db00393 checks/gtab.py +1cde98ac1a563d5b44735936fbb5b3b9b1ed38cdf5a04760b1998908552f1227 checks/lemp_audit.py +012739ff3dc3421c187ca089b361c0b1d49f808908a5a7efdb0603c20f08ca71 checks/manifest_check.py +d1d33751377cd39dd180e9098653464caf5ecd7d670f4440c2477031a1e0ab0c checks/mkgroup.py +af03781f964fcc5f3a5a83c952114c5ce7949f6b534f1f470e02df4e536a9baf checks/mkreps.py +b8f63d560de4dac0a9aa543773a8d7f82ce71b912612c632d7d3da897db57bc4 checks/nj.py +ccbc779eb1e89444b2306424836366390e5482fb800de485ed78c4b39d47abdc checks/p112.py +05c7b19144793d609e540b8ecbd6e5bad1d846b7a7193ff1e6c12038ae947235 checks/paths.py +bcf45947365f476adca889e93b961440e5b925ee0edbb352e1af1d0edcc93e06 checks/rrc_audit.py +1c62422f24d09b3343aa55efe6addda999f59ea6c179dabff4b2bc2323cbf0f9 checks/run_rrc.py +0ab4846438381746f463b54b5f501c2def51bd6474805d60fc5f3e81baa9d399 data/ledger_consolidated.csv +b2f823e6550dcbc9c82fd32402420b2f879fc5c7c4b49bb2fe0a9556758ad9d2 data/left_non00_70.txt.gz +e84c53033fbf4fb0c532935f8d794fe14115b0b8160b9d9c334c3ee58b1c642f data/left_non01_73.txt.gz +4c3b777158b33f97295cb5f8a39ae3ed845539217a74452ed4b18b939ea4eea3 data/left_non02_76.txt.gz +589dd7202d403cdb3de0aae280a92272ce06cd6622cf043a3de95d970e24668e data/left_non03_77.txt.gz +9bb81429cd18ac578c6482ff5aba966dfb0ce6739bd5e11204fc3adbee98425e data/left_non04_78.txt.gz +b4130569ec8f75f68ffd8b6dfab03c26d692bfcd4e7648ef09a5b6c72cc615b6 data/left_non05_79.txt.gz +6abe05b1622ce39c4ba115b286b8457407220fc2a42ff47f8c862d85498047ca data/left_non06_80.txt.gz +7618b5b79d3f6b5d6d0938f5d70a4ea4b247a68a9553429b2d4823bd7f9e889c data/left_non07_82.txt.gz +c5b61cdcee1db2d82df719ae91751742e87003f23d3fe2a4252b1485aa507b15 data/left_non08_84.txt.gz +de7b32258aa4f76a98d98738fc1d04c33462e66e19ac35e6d6e4ca38bcd148df data/left_non09_84.txt.gz +1118eeeff424174f4c4ec444b3d8e67df659b368bd697657df9ea2bae2fe3366 data/left_non10_85.txt.gz +c7932375b3359005c28ce6c80e28888a59f52ebea6aea30fa7b99d2ca6d6790b data/left_non11_85.txt.gz +ac5874303341e0dd3e2f1cb19c9d5f2f1f089151d6af5affb561a220a749c94d data/left_non12_86.txt.gz +7933d80301e9b7383f609adf89157ca8e71fd1b39f6237640e87ca45008f9ca2 data/left_non13_87.txt.gz +1aac8dc032b45fa828653de3566f1d061c70b873e023ea03d6f34f3203c951ce data/left_non14_88.txt.gz +b64840178955e3f9294a3a2a22126bdbe7c9918abcebfcc8f1edb38ef5e41ef3 data/left_non15_88.txt.gz +22e441b74e0a8ec0802f2a1f110f52a1d7d5a932c4c4cddde35a75e41bba7473 data/left_non16_89.txt.gz +cd515b9e44ec32cb0778d7657f8ed871247c5c46e96d0318a15cfcbadaa071c1 data/left_root.txt.gz +38f38cf984e6090b4671e61ff2783b329063fc76cd9ae0fa2ab001bd2d8ba9ac data/rows_input.csv +46d619f5dc75070130cd3fa6d5b29e7e328324edd764b16ccfa9b8bd8dae6f2f data/src_s7b_killed.csv +7ec397c718bece21757884abe7f61ebd29b1c491f7d4bffe0436887fc504ead4 data/src_scA2_killed.csv +8b2ba9ad0e9de0128fc8bfdaca60bbfce2aa61aca08f8df9cd3313b81e43286c data/src_scB2_killed.csv +ff487bfd58c6f551b009ef87d074acd8f93ff7472270c5e3fbb15f96a926f375 data/targets.txt +2d449dea2e6b68d089ac1a2360c86210718ed20869221fb555c60089eaeb4654 evidence/logs/log_non00_70.txt +8a8388dbd5159807f6dc126b52fcbeecf47bbff99a74a51898a49e07f5bb0648 evidence/logs/log_non01_73.txt +e86d1cafa24461311e3897da308b53e51a6fb5ea144e6e5bca9d6a8c014b71e1 evidence/logs/log_non02_76.txt +7091ca72a201f6f92e763784e774d741ec87d89ac0c9f53ef496ed8a6d5c3b66 evidence/logs/log_non03_77.txt +c38792aa9726b347903a876fdb94dd6fc73609c733c824b10d94ff8ed2436e82 evidence/logs/log_non04_78.txt +632950d88612ef32e80424459a37fd607b31a7ea69b6805d9cc1aad4e08d0023 evidence/logs/log_non05_79.txt +dc57c0905b37ce06f91ab422f0430048d3636514e51ed4e6bbf2b1eaa268b9d9 evidence/logs/log_non06_80.txt +d7e46fec027711e0a417726d1dffe920f3143dac65c346788d69c4d4f152e08e evidence/logs/log_non07_82.txt +22aa0e5fa75f5a0e4bffe280e71ddaa4a6f99488612ddb138b0b3ed267f6b489 evidence/logs/log_non08_84.txt +f804069659b3b02238b99794c05eddb5b89d83daaa1bc70cba26f2e35e06964e evidence/logs/log_non09_84.txt +f7759707973d925a3497800e458b29bda3d39725627163e647a84fd0a0c0ae56 evidence/logs/log_non10_85.txt +c0d4ad1b84918f6f8832f9ff172395ce1a00a834af56a038ebd6f3fb130208e7 evidence/logs/log_non11_85.txt +fc6a3e7e33cf1052c929fce2eccf972ee5a3c41e2c187185f793bb9b9db781a4 evidence/logs/log_non12_86.txt +efb69ca88d6b6e2e513cb1a2e0354c6f2ee137f5370137308a46cc21e77a547e evidence/logs/log_non13_87.txt +a805961d21de2ee40fb48dba8014213d105beafec9c42dd55e0335cec8c22a0c evidence/logs/log_non14_88.txt +125d011af46c78173de9b9f4baed1541278aaf2a826ae50df88229949f170720 evidence/logs/log_non15_88.txt +19328ef4c9cd8862397ff1e9712123c5bcd7a55f675f93b112829efa367b7014 evidence/logs/log_non16_89.txt +5267ca4a1c9f7bf1d16b764602f325e4da69dd77344e19fbf9073825dc4ee0c8 evidence/logs/nj4.out +596666571fbb274217f719753fb312691160e7ca4e9b5a69781916a5a0f5b03a evidence/verify_full_run.txt +2fce836af05a0f927ec5b06840aa752f41c8cfc5d5e826256eba0a9ea3813a62 evidence/verify_run.txt +553624a17d4d6bf92cfeb3ca696803520ff0e33a8a469ed9848ba12a1cb1eb5a provenance/SPANFACTS.md +337b24aa4a0bdff452e854ff2f6e04667035809ab291aef1a50ad2cb8ce6f5ba provenance/check_rows.py +4bfc41355bc5bbc7b0efbc2fc8501b162b2493b610de07084236fb878d45c90f provenance/data/data88.txt.gz +0679ba17f68761c9aea31230df8a7ac4a86533b24ee53d786dd1afa216a4b2c9 provenance/data/gens.txt +e5ef3128761d1f60b243285df8d0d0f9be055dbbe307d60de3113fefdd4844a7 provenance/dominance_filter.py +5efbcae78dd105bc18c2418a49af74b5696db0e4c46882ba51ca32399dec299d provenance/generator/dpX.py +013bbf64b8c024a6570e48c68a7790ff7d1551aaccb392ea2ddde5c9e5baa013 provenance/generator/land7.out +8802291195064327d994f7905da859c2ad43b8892646740f2daa4c6452cad7c2 provenance/generator/land7.py +8b4bcfa654f019c6500a5778acbf8011f23103a78e82c252dc64b9491928f477 provenance/generator/symlp.py +89c8632492dbfd6941f741c927d5b177b5be77009a9dca40835f3a115e5ab3a6 provenance/logs/DIRX/p1_y750.out +44b7d61825508e64f7d611b9c49b0878b1b16b4c687090d6b4f9a120e3a39be8 provenance/logs/MS3c/y_750.out +f60d5d68df3e589014377787540b003872d3312d33d9fd4cf55d600a506db1d4 provenance/logs/REPLAY/replay_fact1_indep.out +db56ce2281e1deec9e460d4a3a1bed332b07bcf0fcc36d0a94b6f182e8834ed7 provenance/logs/REPLAY/replay_fact1_s66.out +7854bcf7f22517381da443465ca26dae5251b0ee16099d056bca05ed2f6d5a23 provenance/logs/REPLAY/replay_fact2.out +4ad59036cd877e3f376001c2355ceb17a0bd981668b459b447b4555b58b5f593 provenance/logs/REPLAY/replay_fact3_r664.out +b0f792bef4a9ab3568d8f7eef9e85037701d08cc587fb37d7a842fa2209416ee provenance/logs/REPLAY/replay_fact3_y664.out +a8998f7c059a50907266b613e8321dacfeaaab5d678711dbe8c4a3645528fde7 provenance/logs/REPLAY/replay_fact4.out +b0655528899a6490c5c3b9bd8f27650a44c603bfdb61e2f488927951aa04b67d provenance/logs/REPLAY/replay_fact5.out +c90a48244d7c559ee8574cf0a1d6cf20d3a9b26cc024008a15b34d9e88792fda provenance/logs/REPLAY/replay_fact5_p1.out +ad5ee6ba452a69c222a7ac945e6372f6b23e1e91d954b753021389a57f91d047 provenance/logs/REPLAY/replay_fact6_p1.out +8ea4f045b7501ba6cc181de6a2bdf395a4af1bcde7b4fd07a765cbee75b68a80 provenance/logs/REPLAY/replay_fact6_s3f.out +fa8aac665ebcde0790ff3cea11b3b79ce1d2eea4810148faa37a2736275612ae provenance/logs/REPLAY/replay_fact6_s3f_s3z.out +55c6a451303014a1abe7dc6e8134c1fe062a95b757b5033c3fb132229607d822 provenance/logs/REPLAY/replay_fact6_t5.out +221f55a79fd6b0cc911e2c5d02cdb369cb6c8e814a813b7a63dd4bd8c7997496 provenance/logs/REPLAY/replay_fact6_t6.out +8c8ed6f5b41ad9c9fad51bfbc7c1529b4e954ec27f41fd795a0b8a1feb4c708f provenance/logs/REPLAY/replay_fact6_t6_s3z.out +b7bfec95eb97a9d7c0a30bd5fde0d52f7fb0315ec33ff98fc86b9ba505ffa6ef provenance/logs/REPLAY/replay_fact7.out +61b0012ea34089cebbcf314d86217afbb60d954afb25a650cf7db165c3e703e6 provenance/logs/REPLAY/replay_fact7_s3z.out +418be0276c87ac2204ab2cce1eaf2fa9f7b3a555b275720aeef08ef9ac8b7e1a provenance/logs/REPLAY/replay_fact8.out +363afc6aa284c084e9b4601785e18f0e7baf3b6a69776eaf3bc6634144ea6f7f provenance/logs/REPLAY/replay_fact8_s3z.out +8940507a895d88c3e0795bac4599342441fe32ec919ae577dc6d361045fb0fe9 provenance/logs/REPLAY/replay_run.txt +abd0f2f533f9f2ec564b76dc87f6a9c4c3bec4a07e644d3bbabf6faf41657ad8 provenance/logs/REPLAY/replay_summary.txt +5a00b12305021badb2718cf3858195945b0a02ee3a90c91a394c05e50a957b4b provenance/logs/S3FLAT/out_a664s0_0.out +8684d22058279a50f4546a4ce6789ec630cb2179e3d2262e43f8cd3b64b808a9 provenance/logs/S3FLAT/out_a664s0_1.out +3054d5ae8874cea2f11a3d07048ca45142655a83955b7953e6e136d1e895eb24 provenance/logs/S3FLAT/out_a664s0_10.out +c7dccf154d4ce5fa6439064f89ccb23be4b9e35097cb66cf7f14d8bc3d274a34 provenance/logs/S3FLAT/out_a664s0_11.out +ae9eef809bf59bf7bec79554425d7a2c40f26f54cdbfbe1dc72eb7388ff55f67 provenance/logs/S3FLAT/out_a664s0_12.out +cf9c0d350464498e984c6001adbc89b516cd2aff6d3a3e25d847bcdffd3229a3 provenance/logs/S3FLAT/out_a664s0_13.out +f13bb2a1a25d473a353d2b312f4c804ec895386532e7d68157456a3645953ade provenance/logs/S3FLAT/out_a664s0_14.out +facd93890668ee4fc90db59df8772f5fb496b51a72ab6252ef4833ebe9d382f2 provenance/logs/S3FLAT/out_a664s0_15.out +237f72cce0d2d20ef346ee2a44d29c926ef26bbe36666ed2c3ad4b8024bf6c1e provenance/logs/S3FLAT/out_a664s0_16.out +cddecae26090558e700fc8cbeb73768a0363cd22ec55bc68fc5febaf019da54e provenance/logs/S3FLAT/out_a664s0_17.out +b91fa8e2911fc2d2b56844c16ef1b66a1951bc6154fd998b2eafdc60d57411b2 provenance/logs/S3FLAT/out_a664s0_18.out +2fd8d3c9f10ad5202e692591fe9dee676e2d4b8fa44587f3950d2ddec3b54d8f provenance/logs/S3FLAT/out_a664s0_19.out +908553eb4015138bc8a0c4f356d398be58dbc67ede6ef96f3faf2db2b1dab6a7 provenance/logs/S3FLAT/out_a664s0_2.out +f2bdce42d6a0a2d84178d214d161957d8eeadfd0fb69cc303bd5da6650f3f3c8 provenance/logs/S3FLAT/out_a664s0_20.out +88e2317889718fe58a82f5b77f618b7323f6ce60b15d36e75b27509c5bf41f53 provenance/logs/S3FLAT/out_a664s0_21.out +8a069cab441b8c34f50a36423b3d7e63825bf2c6f7431487dacfdd87ae5fa148 provenance/logs/S3FLAT/out_a664s0_22.out +daf99ebac292ea06e91d9ea5b60dcc4659c1937c4eefa4808c43258a9f6f663b provenance/logs/S3FLAT/out_a664s0_23.out +9d96b6f5ad26dc1d2330cd1f9a0843233e4bb4470a9c82a5ff95b88f2861bc4d provenance/logs/S3FLAT/out_a664s0_3.out +b58c52d55db5bd4d7176d35cfec85e42a9806cf862f0dacd6b730bea979bcfe1 provenance/logs/S3FLAT/out_a664s0_4.out +ce59ff1994c41498abd8b43f496f478912720f6aba0e89df5dcdf45e1887757b provenance/logs/S3FLAT/out_a664s0_5.out +b7dee14ba053154b050ef1da48be4984f3d9278bd6dc498d1ece1949980fa4d0 provenance/logs/S3FLAT/out_a664s0_6.out +a945322773fd411688fda97acc43a6a082c2e2e131d3b5d3941904ad6a10dd26 provenance/logs/S3FLAT/out_a664s0_7.out +3159c68a9d5e4be891aaaaed6ae4552883cf359f977092262689dc2f4a169def provenance/logs/S3FLAT/out_a664s0_8.out +e46e90828a4a6dfdee53b8c722a7984bd760a14c4cae337707fda5dab05ee60b provenance/logs/S3FLAT/out_a664s0_9.out +0f37ce597422746eafcd11c0fb3b37d322e0ce431480b0d3444284b5b28e5abb provenance/logs/S3FLAT/out_b644s1_0.out +4fdc4149fa3f8194cdf4bb7d3392720f37a32310c53236880e2a05ff2d50556a provenance/logs/S3FLAT/out_b644s1_1.out +3fc4aeeca343bbbcff4d1111ad1d80a65ef7373caf51b5974f05391e1e944ca4 provenance/logs/S3FLAT/out_b644s1_10.out +4d884911ea9ff9603153b426bb0ddf7aa37d755039d08f269f295c5a3123cfeb provenance/logs/S3FLAT/out_b644s1_11.out +ab44ab6f70493fcc8b0e27427fa51428eae49a0a9a54ccad552f116b55f45a2b provenance/logs/S3FLAT/out_b644s1_12.out +918bd64ba34550d239eb9f29285319dbdbb5f287ba8f1fe07dfe87fabe5c6e91 provenance/logs/S3FLAT/out_b644s1_13.out +95c3ba27007ab69adde4360e2fd98fe3c38299658ece94925611f01799192b1a provenance/logs/S3FLAT/out_b644s1_14.out +d9fa37c666369c000e808fcaf54e56ab8d56c99ca24515ee16ff09ad5ba69834 provenance/logs/S3FLAT/out_b644s1_15.out +da3135ac771376b0646ebe0f52f8da259a1e917bd56704b6c63bdfed90ecba50 provenance/logs/S3FLAT/out_b644s1_16.out +53dc9267f73215add65144eb6d831ce66edd463085e5b47db60d06190cf992cc provenance/logs/S3FLAT/out_b644s1_17.out +7f3aebfbfe486832415255ab506dfb647f0888e5e0735e85211e8f193905031d provenance/logs/S3FLAT/out_b644s1_18.out +8f323eb9b25759bf160dd667c5258996575a831ac36690cd36d789948a1c0d32 provenance/logs/S3FLAT/out_b644s1_19.out +2b58993a15db90c515652773a431971173d9b02fc35c4b28e70855389ceb6e0c provenance/logs/S3FLAT/out_b644s1_2.out +91079c6e10be2d91ded7dceb335c663714a0c39a6d948e73d23db0112074a1cb provenance/logs/S3FLAT/out_b644s1_20.out +939efa50b69709364c30cff581a1d6be0b3798adff9d9a5f70a8742bc87b6a9a provenance/logs/S3FLAT/out_b644s1_21.out +499e25a0fc3705bc3bf494cae71086f4bd22bfc4465cab18dd333b50d3ba3536 provenance/logs/S3FLAT/out_b644s1_22.out +224dfd4d00795958bfef6942211c31727c90baddf71ee6edfc036ff1fa05e1d4 provenance/logs/S3FLAT/out_b644s1_23.out +f16702f2ccfb16043f97881d63f01e0f2ab5026e075a9898b8ee92becde54c8f provenance/logs/S3FLAT/out_b644s1_3.out +8f01075fcd385bd6c5c0d0bd745e1908258908e2913c3cd42aace413680f6d3f provenance/logs/S3FLAT/out_b644s1_4.out +5391578c7d877799e839d5b3dcb4c1fca6e593e378019aa89891a4425b20be2e provenance/logs/S3FLAT/out_b644s1_5.out +c92af57f16a32512da5f6a625fc43ea9df22247f42c7fe0ae6b49c59643a0bed provenance/logs/S3FLAT/out_b644s1_6.out +ce850159cf870f36ec24afb6db475c5e3fed1ae0956d2646417f10b4f39c8afe provenance/logs/S3FLAT/out_b644s1_7.out +8e2721c820db55423477972a0337883a594e351143bee9a4087f277e0e830853 provenance/logs/S3FLAT/out_b644s1_8.out +f1bed3bb78fb5784f226a8223cc145285a6ef149b44266055e40848c65e21453 provenance/logs/S3FLAT/out_b644s1_9.out +d6d640fc26a028874a2cad165bc408ef162046286f131cb7fd88bfcffc5a56f5 provenance/logs/S3FLAT/out_b654s1_0.out +1f802f994be0ddf08b187afac1b050f22c48d089903a82849f50f3b542d99da7 provenance/logs/S3FLAT/out_b654s1_1.out +08e12af824dc9d235825f64d3e65f9535017895ba02d3c521dfa973aed937761 provenance/logs/S3FLAT/out_b654s1_10.out +217a63edd2be1b0cd31c2de80cffc8643d7ddcdeb4b80afea328b1a2cc93e775 provenance/logs/S3FLAT/out_b654s1_11.out +e6a2f3bcf6de4aa62e8bf228a3175ea02331bce33a661439f7ce0228b3e388a8 provenance/logs/S3FLAT/out_b654s1_12.out +d325a4fbea87e642db174b788d924af3809939f666e953688758d5422d547e37 provenance/logs/S3FLAT/out_b654s1_13.out +ba776ad1a195298ff540540c8edfcaa2181d62f101dd18b3dc98f695be4c7576 provenance/logs/S3FLAT/out_b654s1_14.out +ca3d3c9d6985c3a1a46fd8fc9433e532b5424564fc36183f4cf5cdb5d822ecd2 provenance/logs/S3FLAT/out_b654s1_15.out +e0b8c6ce867486f93effcea6b6b2f884e92bbc36ae7f2604acb642e6cd9073dc provenance/logs/S3FLAT/out_b654s1_16.out +1a9643ae247a609b89f92d35c2452e16543507d0e3fa798189129bfea9828470 provenance/logs/S3FLAT/out_b654s1_17.out +41277696d7b1579a5acc6429d78aae1997af624bf56b9df980028eb382478da7 provenance/logs/S3FLAT/out_b654s1_18.out +465b38ff30831404c1de04f8ace5707c6cddf134fee803d09a20ec31daedf08b provenance/logs/S3FLAT/out_b654s1_19.out +4313ee952c0629f28b1cc543ffda356e23f2c831fcb8587ffce9dbf1120b6536 provenance/logs/S3FLAT/out_b654s1_2.out +2808c8be2f5d6697f71cc401137c2d56af7ef769b3c14e041d2d39dfd05b5b35 provenance/logs/S3FLAT/out_b654s1_20.out +b63d42f9b727f3cc36225ebf4ab3bfad7d7042c1f6f658f4738e7e82b49cf7ca provenance/logs/S3FLAT/out_b654s1_21.out +3a750309ef499e0cc00efadb3617e3ed5e5d29bb82baa4c3b011f13d0012c2c7 provenance/logs/S3FLAT/out_b654s1_22.out +b8141f58a7d688b961638b90717eac22cbcd5a9ef1e4f49fc03538a124c79852 provenance/logs/S3FLAT/out_b654s1_23.out +89e7fd6dc891acbb0d40805fbe5364977a91d0cadcf8b64779ea4282b614bb43 provenance/logs/S3FLAT/out_b654s1_3.out +fc6ce721789349581290f676089fa0832fd56cfa21b8e72d80b8888078fbbd0b provenance/logs/S3FLAT/out_b654s1_4.out +33adf61d0818d7b9f336842357ffb5bd15699a7372fb55a60c3daad6879e15cc provenance/logs/S3FLAT/out_b654s1_5.out +9239017ea3a1c37f19611ca00d1ca08ffdf15bac2d93f63d4cd325ca69f1362b provenance/logs/S3FLAT/out_b654s1_6.out +a6629203939978d419d15e58c63cfe9c3760943d0ce0fab00ca1d6753f45b88c provenance/logs/S3FLAT/out_b654s1_7.out +8ef0602b1da4389bc5ead78c92f7c220498b4e5b6a5bc85113f10384d3efec0d provenance/logs/S3FLAT/out_b654s1_8.out +0e2274f51bc91fb78100808bf0441c6ae8e9a75a0d0fd53e4a71e0c9d2fa812c provenance/logs/S3FLAT/out_b654s1_9.out +138f896b1f5c3e951b5ce1321ca5834f6922a0f04057731ee3e05fa833a05a85 provenance/logs/S3FLAT/summ.sh +47f8fe6aec7566ce156a73526a6a4ee1a4afb15567b314853d8d3135ea0ad050 provenance/logs/SIX/indep_m0.out +ff8db09fad8c4ae60d49bd9f23f4a6fc09fb5571eb65d46daa901e8ab3060a57 provenance/logs/SIX/indep_m1_c0.out +227da1960e4299037c023f3222d834b64c2d5bff41860f8e92f0dd5b8daefb25 provenance/logs/SIX/indep_m1_c1.out +eb4536ca0eb3b98b9cec3ef2510467b8c24e24ec4908ec7518b2672b24bbfb92 provenance/logs/SIX/indep_m1_c2.out +ee1b24e5169820cd4264d5f5092626b876bb06fd537c12bce1b315676a918469 provenance/logs/SIX/indep_m1_c3.out +54f000ba729fd47f98307888f18639daa86687ddddae93c8050506f94e23d1db provenance/logs/SIX/indep_m1_c4.out +e8e518677dd9ec74ccad3d5d0ee9676dcede9a6cfa5f9b61f8dd124230effd37 provenance/logs/SIX/indep_m1_c5.out +476ba3735d9c1b8cfb19f97ee37a04dd072c80eed0626d5ab8aa6ab6f2d2c111 provenance/logs/SIX/r_664.out +913560c826e2bd1d6f825b24a57ae283610779a8bcaa145e27ca648e2f9d2eb0 provenance/logs/SIX/s66_m0.out +7ced977f582c930a6e298bd49097baff2faa0d0bc8d676499a214751c0bd6c7c provenance/logs/SIX/s66_m1.out +cddca7712a41e3f135d2fe6cbfe15672f9d574a5772f43c0b66b24491ac03edd provenance/logs/SIX/x_660.out +707530f03d81fc8764ac4cd66f9f7ffe762305823e99714953f4cd8c2e2f6857 provenance/logs/SIX/y_662.out +38d208ec8746df8f6ce4f507f23ef7d67d2b93a73b948d3c6ae5ed9fc1281db7 provenance/logs/SIX/y_664.out +621b9cf153ebf5ea52c0029ad936dcdb6581d4e0e2d03d5d0478eeacc79308e2 provenance/logs/SIX/y_740.out +4669d878786e4b5b755816d10715ae3e736c9221ebe7b94c1265d6818df10b0c provenance/logs/SPANCOVER/664s0t5_0.out +a4dfed51b1ef415a75cc634d1a14b6dd0e24d7395c383b1089729125a1444f50 provenance/logs/SPANCOVER/664s0t5_1.out +a9e0c66dbac1b6529e200f4a14ba96684c20cb063a0c07290afca20d04891827 provenance/logs/SPANCOVER/664s0t5_10.out +4b80754d729c461ab61a5198b16d136877a54d18ae26de76e14c1e7c694e6288 provenance/logs/SPANCOVER/664s0t5_11.out +a5e941e67b9baa078f9031d6accb27f8b107a224e859cea42652326bb79d8d2f provenance/logs/SPANCOVER/664s0t5_12.out +2875292f8e642a1d9bc996e8592f6953a5add364f8fff7dc9200369f662560c9 provenance/logs/SPANCOVER/664s0t5_13.out +9d626ea6c84ce0c7691711810b97086e8a5d37d7b032cb06fc9c29274ef5d1d1 provenance/logs/SPANCOVER/664s0t5_14.out +7fc830a409d995ba94851336239acd73bdc70a54cf5990793582850813228cc1 provenance/logs/SPANCOVER/664s0t5_15.out +ee2999f97e032ff28d50b1fb9166d808b9e66cd012dbcec682cbf2b36b90bc57 provenance/logs/SPANCOVER/664s0t5_16.out +96f90a9a8c5232608d6a4a83a27eb8c0af0b76d932cea433cbd8f5f6e0d8920b provenance/logs/SPANCOVER/664s0t5_17.out +91180511db2f8710f3136087f638089098f07e65d6d4780315f455f76a66b0ff provenance/logs/SPANCOVER/664s0t5_18.out +33e2424b5f27a562278ccb515aa2e9ae256d454e181d557b16e7012e29c25a84 provenance/logs/SPANCOVER/664s0t5_19.out +548f5427da51c656a64ce30eabae3756ecee00862a27cf423aa58ec82452db68 provenance/logs/SPANCOVER/664s0t5_2.out +bc2a081e4e3cf81849c45f9401af1ea436b26276984f6fd53336b379d2643bd0 provenance/logs/SPANCOVER/664s0t5_20.out +9995364a493fb6021042bd478d9abb8c0f2c26a93b73af6bdbe5caece6029d34 provenance/logs/SPANCOVER/664s0t5_21.out +73fa355575ad53783bfadfd8776d62cf2c055934bdf5f60142d6115c51f3841f provenance/logs/SPANCOVER/664s0t5_22.out +af2ce3dcc80d5c9b5a357ab55b0d2776812ca0e5dce8e9265671178f0b015345 provenance/logs/SPANCOVER/664s0t5_23.out +15ddec1dac7a5702f05b77b65ad3c37063283e76676c8ad603084353dae6a0c3 provenance/logs/SPANCOVER/664s0t5_24.out +f5358b52a589ad89c4503c68bfe2e9023f867bc85aa7b3f8dc0c01a4461d78b3 provenance/logs/SPANCOVER/664s0t5_25.out +da22a566533aacb64d41a1d021e6a6865f3b5dd43d99fa38f06715a737c23f54 provenance/logs/SPANCOVER/664s0t5_26.out +2cb5ce9883f564e2b7df3aaf93ac12218fda7ca9266f25eb0264e9f54586d266 provenance/logs/SPANCOVER/664s0t5_27.out +435d322cd52eb5726b950b2447a27d6e20d6785fc15cb21e98e7833b2f54bef5 provenance/logs/SPANCOVER/664s0t5_28.out +ebd65d9166322ea63c7b9f4f6dcc4b3893e4100d02f214bd2b06b9509312a2c7 provenance/logs/SPANCOVER/664s0t5_29.out +91e82be3fc2bc583d397136d4af2797ae22109220bde696160b5338f9239d2e2 provenance/logs/SPANCOVER/664s0t5_3.out +3bcb8e9b84b7f6169cb70a197f1fbb5569d37ea5d992847321a35876bfcd3198 provenance/logs/SPANCOVER/664s0t5_30.out +d92b27ef930cdebbc3cff09163d4b293e3c382c8824d3cb89d6d16044a5daceb provenance/logs/SPANCOVER/664s0t5_31.out +e4dfe00273e74760677edc37b39f88605335c49401877d48c05104955115dfff provenance/logs/SPANCOVER/664s0t5_32.out +ed6de4c08f2387b9680f2b5be5debef193e4b9b60f6fc5f7f2196122c5636c61 provenance/logs/SPANCOVER/664s0t5_33.out +88d1435e664faa350598b8c380202b348881a07eae6028752db6ea3e8d63572d provenance/logs/SPANCOVER/664s0t5_34.out +254b496bf708ca33faa8d4f6889150a6e8ba0f2358c26c3d69bb3ebb1651aa04 provenance/logs/SPANCOVER/664s0t5_35.out +27043e025d726fca5e8e4b8f8ca86a7b45162cb1f2480ab58b7a979e86ccf7c3 provenance/logs/SPANCOVER/664s0t5_36.out +96b5cc8685669f4950ebf1d29f8a2d17a823cb6b5f29c2f5889e6b0e26887a18 provenance/logs/SPANCOVER/664s0t5_37.out +7b01248661ef06d3a7bf1e336319114b41d6e5975e2dc7560343ef62bbcfe54a provenance/logs/SPANCOVER/664s0t5_38.out +c673dd5f90f550137288e8e466cdd08920f560ee92e3bab8a6716537694873c7 provenance/logs/SPANCOVER/664s0t5_39.out +37134b5a19c52fce6b59c5e454d9a70969352e8d7da334eeffc004e47f09f8df provenance/logs/SPANCOVER/664s0t5_4.out +1ad1d4897057d58a5501183265e3fe3576fd8f4750bf874ab99247734a60a782 provenance/logs/SPANCOVER/664s0t5_40.out +db17a52265bd8e320776398bf9c189ea5af4c91efcc1603e9c073d56795bbd40 provenance/logs/SPANCOVER/664s0t5_41.out +d04703e66b9c7a08526c24d330831ef65a6c2fba216d856628e38c99ed0196af provenance/logs/SPANCOVER/664s0t5_42.out +2629b1ccb34d317c8b3dfd4c320c9c1b099e2ad32c4ec3a5a7157c41cc796cd6 provenance/logs/SPANCOVER/664s0t5_43.out +74deeb64ecf1943f97e9777d0da4a845e7ca715fb799d31ef1bcfb6d67fb0274 provenance/logs/SPANCOVER/664s0t5_44.out +c425fc026a51184d70a00309b070f6e6dd6a9b2df7b012bf19fe21b0f49d32b2 provenance/logs/SPANCOVER/664s0t5_45.out +a29fa3b56f88e14b76d78bb82f85516b47f8f2c7efc9ed389c0c88f092054298 provenance/logs/SPANCOVER/664s0t5_46.out +d814e567aa4b9439cfbceca81c47bbfaed97e04bb20dc9feeaed2c2346bd8798 provenance/logs/SPANCOVER/664s0t5_47.out +ec21eacbe983a5ede77dfa4621b0a81a5e60fda2e31125f2499ad9a3e0ec8466 provenance/logs/SPANCOVER/664s0t5_5.out +de9615da0ee9efdc702bda223afe0c5e7fc43d766da25a3d729642c5bf10ae1b provenance/logs/SPANCOVER/664s0t5_6.out +6f0b9acb345d9bb517e2dcd9db5a153920f8040ecbd34cda8c72cbd7d34b5737 provenance/logs/SPANCOVER/664s0t5_7.out +19f8ff3733722477de926676ddfa157a19d8d27c8281531c343dd2ba451dac35 provenance/logs/SPANCOVER/664s0t5_8.out +9f99e862a32add10be84e4f1ffa8a3d7f169e526d21c6bd9c5b19c16450ee6ef provenance/logs/SPANCOVER/664s0t5_9.out +7d645706f7d95ddc379821032e2ea6323dba50ea60742cd95fd4f33a08308ee9 provenance/logs/SPANCOVER/664s0t6_0.out +d74a68da18c4e10e0e44e15e71bfbb306696006264fe5c21e81a3b1a5c98b488 provenance/logs/SPANCOVER/664s0t6_1.out +516c0fc852e1a3538549b48acabc818ab2b14fd4bf67d83514947b032c2e4075 provenance/logs/SPANCOVER/664s0t6_10.out +abbfcc4df3e9103f9faa210e45031b01a956ae3e5d5991961f6dff747057bab9 provenance/logs/SPANCOVER/664s0t6_11.out +972ba72e1d936c62120fc7070c6b0d8de7672619e4a450ea51040ac7a0986a1d provenance/logs/SPANCOVER/664s0t6_12.out +47e31006c45cf2490a501c4a190e4ba45d0000a7f797523ee426962b3914655b provenance/logs/SPANCOVER/664s0t6_13.out +4f7b96573c3571628f4a4d659e9c5cc961bb80c2341274af48b8000da81fd205 provenance/logs/SPANCOVER/664s0t6_14.out +a8ca58bad12d0611a0abad802c15c1906ee130fd73702d368625527ebd0ff2aa provenance/logs/SPANCOVER/664s0t6_15.out +7e4b8fbf0c89e04985cd9894f3a2704e195217c292f1c3ddf6a43ccef26cf6d5 provenance/logs/SPANCOVER/664s0t6_16.out +e21b8b927fa872e15560e6c610195358fec113ca79cd4ac9d527840044681893 provenance/logs/SPANCOVER/664s0t6_17.out +865750c2a8a9297c053090cb180b480346eeed5f70a5417f8421f5a250efc68d provenance/logs/SPANCOVER/664s0t6_18.out +499b36951409c48989249b297942180bbc728428cbd775625df7a497c30ec913 provenance/logs/SPANCOVER/664s0t6_19.out +c258cfd7af2b33ac87b0dc0b1f19637cc7771be34f4c43c439aafbe51146d3b1 provenance/logs/SPANCOVER/664s0t6_2.out +acff2971b7abcb3330ba89e7a33bf42aa7538337e00ec8c4b0fe3f6e0440f5e3 provenance/logs/SPANCOVER/664s0t6_20.out +c7bd8ea2c4a136d2113bfbfd042968e20983bfde5fc675989b6f4ed50a61be96 provenance/logs/SPANCOVER/664s0t6_21.out +491ced44081f28a6fb3b696a7616c871c4ff64eb7e0b3e83c7fa03cca344cbee provenance/logs/SPANCOVER/664s0t6_22.out +48f83c9eaa46e9e7b7bd948c8a7551f9168af10be909b6da6befbb7286dd02ea provenance/logs/SPANCOVER/664s0t6_23.out +13a527e4415a3fc4a6293a1be3e99899bf67055fb06b574ccd57f41461fbe53b provenance/logs/SPANCOVER/664s0t6_24.out +c50690af7c04cc20db6e0bc5a34c8ae7cce6e7c734786f040916a77810d5e9fe provenance/logs/SPANCOVER/664s0t6_25.out +50199d49adc3ffbc086d7014395260d408f711bebf4ec93df4df54e0871e601f provenance/logs/SPANCOVER/664s0t6_26.out +5edfb3d0cf570c30922e1991a935a5a03c01f174b72caba3cf701883fa21e54b provenance/logs/SPANCOVER/664s0t6_27.out +e68aa8a3b95641167598068b75dc6286d211086628c8822d4cf942d089493692 provenance/logs/SPANCOVER/664s0t6_28.out +e786a3198d99145255c618cbb8f97a7129d8140ea76101fe7d5ffe264158b068 provenance/logs/SPANCOVER/664s0t6_29.out +30d44d88b87ddbfd72480393bfd12b3cb334b2aeb7f7c337ae7af5012ee42b0f provenance/logs/SPANCOVER/664s0t6_3.out +3efa3110398dc8dc54bf2604738ee787215b1d226d63ba120ed1a7b3e55c7538 provenance/logs/SPANCOVER/664s0t6_30.out +16b1c24b6be738229c25dcdfd43c23921fc00c6dc6b14dca771ba922ae7f0fa8 provenance/logs/SPANCOVER/664s0t6_31.out +7a32b57840db4469f88ba912183a7e73473a8b92dfed019200ebb8c58fdcc7c1 provenance/logs/SPANCOVER/664s0t6_32.out +b141a339ee0664e9c779674ef9e802be95f2bef9e66c51530bb7124560bf2363 provenance/logs/SPANCOVER/664s0t6_33.out +c5472d26b7bbbdfaf5b1eec7654b8b9b56bf1e0e0097379523efba6208bb0f05 provenance/logs/SPANCOVER/664s0t6_34.out +0cdcbf4c0871ecc7caae0267008ddf45d61479dd246fae21547b1a7cef89c532 provenance/logs/SPANCOVER/664s0t6_35.out +ae54232909a14f416c3026363e1c684b70fe5e5e71b4c965d6c76f7bb0966c1c provenance/logs/SPANCOVER/664s0t6_36.out +38913144a20af2bbd80abe84166de6d20f6f1b9bac33c1f998fe62fdb850e463 provenance/logs/SPANCOVER/664s0t6_37.out +24ca587feb8ee02c987127c41d6929419416a500ad3945713015940713df91de provenance/logs/SPANCOVER/664s0t6_38.out +120e5e8b8272c8f615bec82b11ee8321f08dc969641a6a1c905691e917bc0d1f provenance/logs/SPANCOVER/664s0t6_39.out +6f266cdf7ac3fbabd5eca605ce1ff23bac8095db7f996ea42cc905dba179e33e provenance/logs/SPANCOVER/664s0t6_4.out +de82c467a2fa2df7c155de69bb0d121f15297654c5f3882ddcc00b680cab4089 provenance/logs/SPANCOVER/664s0t6_40.out +892b3d8219977453f291900561b8cddd90b82a19b3b0bc0bb31a5fcb2a742f1e provenance/logs/SPANCOVER/664s0t6_41.out +8a6ab241fe0f8a2fbe8ab068a956f9f4c34f023ed07ae581a71cf750c73b4f02 provenance/logs/SPANCOVER/664s0t6_42.out +920e512e0faef940249c4add7943a0f5c5ba82bb62942004d5540519794a1b33 provenance/logs/SPANCOVER/664s0t6_43.out +27b33fba5066ca82281c0e863f5ad8b4a7196dc9dd3dd0bdf9b88cb071878a3b provenance/logs/SPANCOVER/664s0t6_44.out +2cecaa15cb06bd5b67564634b3dc97215e0bdf1f91812bf36434bc97dd12e745 provenance/logs/SPANCOVER/664s0t6_45.out +745182bf2c04af8111728ab05db363030247bac791c731e9c93058f6718ccf54 provenance/logs/SPANCOVER/664s0t6_46.out +6f47bce0fd60b10abdd1aa24c3f3e3b5c2b852f5e3483ab87be9d263ffe6b4f4 provenance/logs/SPANCOVER/664s0t6_47.out +4ec2c819e68a923635586a1df1084f8b0e66ec94414f791631d6f4deb3d727b6 provenance/logs/SPANCOVER/664s0t6_5.out +32cca5854dd85ed8ba1194e78422bf7a327cc465a2913e2387bd3663b1fa0114 provenance/logs/SPANCOVER/664s0t6_6.out +0a75ab96dcd24b36840384d8edc52ce635f62e620bd15d0ffef9703a0c2eeb19 provenance/logs/SPANCOVER/664s0t6_7.out +9cbca97384200a089e3503cf8371ae794d2cd00b04803cd93bea4a12ef96e921 provenance/logs/SPANCOVER/664s0t6_8.out +18eb05e4b032a2eeb47d178b93ae79ef69cb70d9f72f05b30c7cb4f197bf4a2b provenance/logs/SPANCOVER/664s0t6_9.out +b70d99523c8c6c01d3eea909857a0d1c918f20570ac2924eb934d9628e0436d3 provenance/replay_compare.py +a0364384d1a16eec55f2262f32516c0a8724ff146a057e878b5ed7984e4dc8b4 provenance/replay_spanfacts.sh +a9a94985c8f3a176b7e2aa1ad8dda1798767ff1b8912404a2ceadd06b91b04cc provenance/reproduce.sh +f963776da096f8a0adccf09c4cca9d2fe5e4a998b91ec42db83154fca455d49f provenance/src/gen.py +41a95a10f1bdbf98128248386c9c08f64fb540519b3266b528a62650ebe4f95c provenance/src/gen88.py +98632467a6fd44a7737a570b994374ef74f9634c53cda6260223aa3e89547da8 provenance/src/indep.py +3e96661d6b36acc66d9ab20ddf118b6638d0a581e35a22ec156ddb9a174dc8e1 provenance/src/s3f.c +d8f8b0bc69f0d21c92aa3d5dff34316cf1b38d8e7fea24eb30c86a481ab20de7 provenance/src/s3x.c +8b165dda13dc72bee619d85dd4530690ace278324cb1245e9878d5f201f66f49 provenance/src/s3y.c +2bac15375afeae19997db3691e84f3f101a30f5614a717cd2085e10e6d416965 provenance/src/s3z.c +3e3de7ac902d8bebc80e22a513fbfc5b5959417ea34d1d64b487909068115357 provenance/src/s4z.c +dbe1a4f6e4dfb9cc9d4f82b3f8e2683195c43a00d6d2d5363cc48a5fbdbcd840 provenance/src/s66.c +f2049dc411fbd6944ec422bb02ae8a1a790b3f62200df67a22e203cfeb50e657 provenance/src/s6x.c +255e0b202f88408c83998ef93bef6eb2f61c509267b0b383987c3415717be43b provenance/src/validate.sh +163d8a84b4d2b0f2af66d55e0dc84604f3f985a15939ba405a02b0c430126244 requirements.txt +4f7d8ee7435a00cf10cf55fb0dcfcf18b7ee7db1817ec180ba91f5a05ba95d91 verify.sh diff --git a/research/one-sided-residue-closures/NOTICE.md b/research/one-sided-residue-closures/NOTICE.md new file mode 100644 index 0000000000..c6f3494c2c --- /dev/null +++ b/research/one-sided-residue-closures/NOTICE.md @@ -0,0 +1,3 @@ +# Notice + +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code; Apache-2.0 (`LICENSE`, copied from the repository root). diff --git a/research/one-sided-residue-closures/PROOF_MAP.md b/research/one-sided-residue-closures/PROOF_MAP.md new file mode 100644 index 0000000000..b07975aa22 --- /dev/null +++ b/research/one-sided-residue-closures/PROOF_MAP.md @@ -0,0 +1,33 @@ +# PROOF_MAP: every claim and premise of README.md, mapped to the step that checks it + +Attachment only; no claim text of the README is changed. "verify N" = section N of `verify.sh` (default mode unless marked FULL=1); "replay F" = a line of `provenance/replay_spanfacts.sh` (run by `verify.sh` in FULL=1 step 6; shipped log `provenance/logs/REPLAY/replay_summary.txt`). A statement whose proof is a written argument (README §2-§5) is mapped to the finite computations that argument uses; the argument itself is the proof and is not a computation. Items that cannot be rerun are listed under CONDITIONAL. + +| # | Claim / premise (README) | Checked by | +|---|---|---| +| R1 | `s = 7` forces Class I (§2, Z-lemma, peeling) | written proof §2.1-2.3; inputs: peeling and lift identity (CONDITIONAL, inherited), flat cap `g(8) = 64`: verify 1 "g(1..8) = 1,2,4,8,12,20,36,64" | +| R1' | `s = 6` scenarios (§2.4), `scen()` kill engine tests base cell and all variants | verify 5: `run_rrc.py` ("RRC engine ran; every certificate re-verified by verify()"), `lemp_audit.py`, `check_ledger.py` | +| R2 | Circuit Lemma (§3), G1 root counts (`57` / `>= 78`) | written proof §3; G1 is classical (CONDITIONAL), consistent with the direction census of verify 2 (`dirs.py`: min `|Off|` of non-roots = 70/77+) | +| R3 | Relative root counting (§4) and the immediate rule | written proof §4; finite inputs `g`: verify 1 `gtab.py`; `N_2 = 3`, `N_3 = 6`: verify 1 `nj.py` ("N_2 = 3", "N_3 = 6"); `N_4 = 12`: verify 1 FULL=1 ("N_4 = 12 (exhaustive)"); `N_5 = 20`, `N_6 = 36`: CONDITIONAL (ADE classification); every certificate: verify 5 `run_rrc.py` | +| R4 | Lemma P / P' (§5), parameters `(sigma, omega')` table | written proof §5; covering facts (a)-(f), `params`: verify 3 (`cov.c` targets) + verify 4 (`anroot.py`, `annon.py`, `facts_check.py`: "facts" PASS); parameters and 375 kills / 74 original reproduced: verify 5 `lemp_audit.py` ("Lemma P at T-level kills 375 of the 603 rows", "all 74 original class-A kills reproduced") | +| R4a | Fact D, direction list `|Off| <= 89` (112 roots, 8 frame, 21,340 non-E8 masks in 17 orbits) and the 3584 directions with `|Off| = 89` | verify 2: `mkgroup.py` (group order 172032), `dirs.py` ("non-E8 21340"), `mkreps.py`; harmlessness of the 89 orbit: verify 4 `facts_check.py` | +| R4b | Exact covering enumerations behind the facts (17 targets) | verify 3: root target and `non05_79`, `non06_80` recomputed by default; the other 15 are shipped outputs in default mode (RECORDED) and are all recomputed and compared with `data/left_*.txt.gz` under **FULL=1** (one run shipped: `evidence/verify_full_run.txt`) | +| R4c | D7 plane fact | verify 4 `d7plane.py` | +| R4d | Lemma P' extremal inequality, `m = 10`: `6 omega' >= 504 - 273`, `omega' >= 39 > 32` | arithmetic in §5; the remark "brute-force check over 3000 random maximal triple systems" is not used by any kill and is not re-run: CONDITIONAL (remark only) | +| R5 | Consolidated ledger: 480 KILLED, 7 KILLED(prior-only), 116 OPEN, table of §6, all 47 class-B, 25 root-count, 74 class-A kills | verify 5 `build_ledger.py` + `check_ledger.py` ("byte-identical to the shipped ledger"; counts 480/7/116) | +| R5a | The 7 KILLED(prior-only) rows rest on an earlier `(6,6,5)` span run at target 7 | CONDITIONAL (see below); the README already labels these rows prior-only and counts 123 OPEN without them | +| R6 | `robust6` base-configuration gap (no result changed) | verify 5: the shipped engine tests the base cell; ledger recomputed identically | +| R6a | Fact D correction (3584 directions with `|Off| = 89`) | verify 2 `dirs.py`, `mkreps.py`; verify 4 `facts_check.py` | +| G | Setting premises of §1: `g(1..7)`, `g(8)`; E8 model | verify 1 `e8.py`, `gtab.py` | +| G' | Inherited premises of §1: `|Off(h)| >= 53`, peeling, lift identity, Lemma B / kill criterion, classical root-system facts, ADE classification, Borel-de Siebenthal | CONDITIONAL (statements of earlier PRs and textbooks, cited); `|Off| >= 53` is consistent with the complete direction list of verify 2 | +| I1 | Input list: `rows_input.csv` has 603 distinct well-formed rows | verify 5 `check_ledger.py`; production: `provenance/reproduce.sh` (dominance filter reproduces the 603 rows from `generator/land7.out`; FULL=1 also reruns `land7.py` and compares) = verify 6 (FULL=1) | +| I2 | The eight span facts used by the dominance filter (`provenance/SPANFACTS.md`) | `provenance/replay_spanfacts.sh`, one line per fact: replay F1 (6,6)+1<=3 `s66.c` and independent `indep.py`; F2 (6,6)+2<=4 `s6x.c`; F3 (6,6,3)s0<=4 `s6x.c` + exact refinement; F4 (7,4)s0<=4; F5 (7,5)s0<=4 (+ `|Off|<=88` pass `s3x.c`); F6 (6,6,4)s0<=5 `s3f.c`, `s3y.c` (`|Off|<=88`, target 6 pass, target 5 crack), `s3x.c` pass, second implementation `s3z.c`; F7 (6,5,4)+1<=4; F8 (6,4,4)+1<=4 (F6-F8 also with `s3z.c`) | +| I3 | Direction lists `data.txt` (<=77), `data80.txt`, `data88.txt` and `gens.txt` | replay "direction lists regenerated" (`provenance/src/gen.py`, `gen88.py`; `data88.txt` and `gens.txt` compared with `provenance/data/`) | +| I4 | Completeness of the earlier enumeration of the `d >= 4` residue list (necessary conditions of #2816, Basis-Lemma kills of #2826/#2862) | CONDITIONAL (stated in the README as an input) | +| E | `evidence/logs` timing logs and `N_4` log; `evidence/verify_run.txt` | logs of earlier runs; superseded as checks by verify 3 / verify 1 FULL=1 and `evidence/verify_full_run.txt` | + +## CONDITIONAL (cannot be rerun here) +1. Inherited statements of earlier PRs (peeling, lift identity, Lemma B, `|Off| >= 53`, flat caps `g(1..7)` as used in #2816) and classical theorems (ADE classification, Dynkin, Borel-de Siebenthal): cited, not computations. `N_5 = 20` and `N_6 = 36` rest on the ADE classification (no exhaustive run; the exhaustive run for `N_4` is the FULL=1 one). +2. The 7 prior-only rows: need the earlier `(6,6,5)` s0 span run at target 7 (single implementation, not re-audited, sources and logs not part of this package). +3. Completeness of the 603-row input list (earlier enumeration); only the dominance filter and `land7.py` are rerun. +4. The remark on 3000 random triple systems (§5, Lemma P'); no kill uses it. +5. Span facts are single-implementation except F1 (two implementations) and F6-F8 (`s3f`/`s3y` against the independent `s3z`; same algorithm family, written separately); a run at target 8 proves only span <= 7 and the stated bounds are the maxima the runs report (see `provenance/SPANFACTS.md`). diff --git a/research/one-sided-residue-closures/README.md b/research/one-sided-residue-closures/README.md new file mode 100644 index 0000000000..f59ffdc718 --- /dev/null +++ b/research/one-sided-residue-closures/README.md @@ -0,0 +1,99 @@ +# One-sided decoder floors: 480 of the 603 `d ≥ 4` residues are closed (Circuit Lemma, relative root counting, plane lemma; 116 stay OPEN; no κ claim) + +> **Scope, stated first.** A research note in the line of #2816, #2826, #2862 and `research/one-sided-excess-three` (all ours). Pure finite combinatorics and linear algebra on the E8 root lines and the unit P112; **no κ claim, no window, no supplier word.** It closes **480 of the 603** weight multisets of the `d ≥ 4` residue list for the lift `S ⊇ 𝒞(E8)` (cost threshold 71, i.e. it shows `cost_w(S) ≥ 72` for lifts whose P112 restriction has that `T`-cell), through sources that an independent audit re-derived; **7** more rest on one earlier span-cover run that has *not* been re-audited; **116 stay OPEN**. Only `research/one-sided-residue-closures/` is added; nothing existing is changed. `verify.sh` recomputes the whole ledger from scratch (about 10 minutes by default; `FULL=1` adds about 56 CPU-minutes of covering runs, about 20 minutes at three processes, plus the exhaustive `N_4` run). +> Labels: **PROVEN** (argument below; the audit verdict is stated), **CHECKED** (an exact script that `verify.sh` re-runs), **RECORDED** (a log or output shipped, not re-run by default), **INHERITED** (a statement of an earlier note, cited, not recomputed), **OPEN**. + +## 0. Claims box + +| # | Statement | Status | +|---|---|---| +| R1 | **`s = 7` forces Class I** (CARRIER §1.3): if `cost_w(S) ≤ 71` and the `T`-cell has slack `s = cost(T) − 8d = 7`, then `x = c_8 = z = D = 0`, and the pieces of a minimum basis of `T` are basis members of `S` with drop 0 | PROVEN (audit: PROVEN; char-0 field) | +| R2 | **Circuit Lemma** (T-level and E8 version): for every `K ⊆ [a]`, `\|K\| ≤ d−1`, there is `c ≠ 0` in `R` vanishing on `K`, and `Off(h(c)) ⊆ ∪_{j ∉ K} Λ(F_j)`; in Class I the same holds in E8 with `Off_E` and `Λ_E` | PROVEN (audit: PROVEN) | +| R3 | **Relative root counting (RRC).** Fix `K0`, `\|K0\| = d−j`, `j ≥ 2`; a family of more than `N_j` `(j−1)`-subsets `M` of the complement with `cap(comp∖M) ≤ 77` and pairwise `cap(comp∖(M∪M')) ≤ 56` is impossible (`N_2..N_6 = 3, 6, 12, 20, 36`). `K0 = ∅` is the lemma of the earlier root-count note; the immediate rule is a `(d−1)`-set `K` with `cap(comp) < 57` | PROVEN (audit: PROVEN); `N_2, N_3` exhaustive [CHECKED], `N_4` exhaustive [CHECKED with `FULL=1`, log shipped], `N_5, N_6` by the ADE classification | +| R4 | **Lemma P (plane lemma, L1/L2) and Lemma P′** (weighted count): minimal nullity-2 sets of `≥ 4` small pieces (`e′ ≤ 2`), resp. `≥ 5` pieces (`e′ = 3`), are impossible; pure `T`-level statement, no scenario analysis | PROVEN (audit: PROVEN); covering facts F3/F4 CHECKED by the audit's independent `cov.c` (here), which reproduced the original implementations' facts | +| R5 | **Consolidated ledger** of all 603 rows: **480 KILLED** by audited sources, **7 KILLED(prior-only)** (earlier `(6,6,5)` span run at target 7, not re-audited), **116 OPEN** | CHECKED (`data/ledger_consolidated.csv`, recomputed byte for byte) | +| R6 | Corrections found by the audit, included: the `robust6` base-configuration gap (no result changed), and **Fact D**: "no `Off` has 89–91 lines" is false (3584 directions with `\|Off\| = 89`), harmless because four 6-flats cannot cover 80 of 89 lines | CHECKED | + +**Not claimed.** The 116 open rows; the `d ≤ 3` cells (closed in the earlier note, not touched); `d = 0`; positive characteristic; a κ or window claim. The list of 603 rows is an **input** (§6); its completeness is that of the earlier enumeration, not re-derived here. + +## 1. Setting and what is inherited + +Notation of #2816 §3, #2826 §2 and `one-sided-excess-three` §2: `P112` = the 112 non-frame E8 lines, `Λ(V)` = lines whose label (in `F2^9`) lies in the label subspace `V`, `weight(p) = rank_F2 ℓ(supp p)`, `Off(h) = supp p_h` for the codeword `p_h` of direction `h ∈ K^8`; `S ⊇ 𝒞(E8)` a lift with minimum-weight basis `B`, `ρ` the restriction to P112, `T = (ρS)_{≤7}`, `κ = cost_w(T)`, `D = 𝒞 ∩ T`, `d = dim D`, `s = κ − 8d` (slack), `q_1..q_a` a minimum-weight basis of `T` (weights `w_j ≤ 7`, `a = d + e`), pieces. A *violation* is `cost_w(S) ≤ 71`; a *cell* is `(d, multiset of w_j)`. +**INHERITED, not recomputed:** `\|Off(h)\| ≥ 53` (`= 53` roots, `56` frame, `≥ 70` otherwise); the flat caps `g(1..7) = 1,2,4,8,12,20,36` (here re-verified by `gtab.py`, and `g(8) = 64`); **peeling** `cost_w(S) = 64 + (cost(T) − 8d) + 8x + c_8`, `x ≥ 0` (#2816 §3.2), with `cost_w(T) ≥ 8d`; the lift identity `cost_w(S) = 64 + Δ + D`, `Δ = Σ_F w − 64`, `D = Σ drop` over the images `F = ρB` (#2816 §7); **Lemma B / the kill criterion** (#2826 §3, repeated in `one-sided-excess-three` §3.1). Classical: the lines of E8 orthogonal to a vector `h ≠ 0` form a closed root subsystem of rank ≤ 7, with ≤ 63 lines, `63` iff `h` is parallel to a root (E7), next largest D7 with 42. + +## 2. Accounting: `s = 7` forces Class I (R1) + +Put `z := dim(ker ρ ∩ S)`, `x := dim ρS − dim(T + 𝒞)`, `c_8` = excess of the non-`T` members of a minimum basis of `ρS` over weight 8, `drop(b) = w(b) − w(ρb)`. + +**2.1 Z-lemma (PROVEN).** `cost_w(S) ≥ cost_w(ρS) + z`. *Proof.* Let `B_0 = {b ∈ B : ρb = 0}`, `z_0 = |B_0|`, `B_1 = B∖B_0`. `ρB_1` spans `ρS` and has `dim ρS + (z − z_0)` members, hence contains a basis plus `z − z_0` surplus members of weight `≥ 1`: `Σ_{B_1} w(ρb) ≥ cost_w(ρS) + z − z_0`; `Σ_{B_0} w(b) ≥ z_0`; `w(b) ≥ w(ρb)`. ∎ (Equality forces all surplus and `B_0` members to have weight 1.) + +**2.2 Peeling for `ρS` (INHERITED).** `cost_w(ρS) = 64 + s + 8x + c_8`. Since `Σ_F w ≥ cost_w(ρS)` for the spanning family `F = ρB`, `Δ ≥ s + 8x + c_8`. + +**2.3 Theorem R1.** Suppose `cost_w(S) ≤ 71` and `s = 7`. By 2.1 and 2.2, `71 ≥ cost_w(S) ≥ cost_w(ρS) + z = 64 + 7 + 8x + c_8 + z`, so `x = c_8 = z = 0` and `cost_w(S) = 71`; with `cost_w(S) = 64 + Δ + D`, `Δ ≥ 7` forces `Δ = 7`, `D = 0`, `Σ_F w = 71 = cost_w(ρS)`. Thus `F` is a minimum-weight basis of `ρS`, and by matroid greedy the members of `F` of weight `≤ 7` form a minimum basis of `T`. Every `b ∈ B` has `drop(b) = 0` (`D = 0`): the pieces are basis members of `S` with drop 0 (**Class I**). ∎ + +**2.4 The `s = 6` scenarios (R1′).** For `s = 6`: `x = 0`, `c_8 + z ≤ 1`. +(α) `z = 1`: equality in 2.1 forces `z_0 = 1` (the alternative would give a basis vector proportional to a single `δ_t`, impossible), so `B_0 = {δ_f}` for a frame line `f`, `F` is a minimum basis of `ρS`, `Δ = 6`, `D = 1`, all other members drop 0: **Class I with one extra line `f`**. +(β) `z = 0`, `c_8 ∈ {0,1}`, `Δ + D ≤ 7`: (β1) `Δ = 6, D = 0`: Class I as in 2.3; (β2) `Δ = 6, D = 1`: one member `b*` drops (it is a non-`T` member, or the unit, or a piece of weight `w` whose lift has E8 weight `w+1`); (β3) `Δ = 7, D = 0`: (β3-i) `F_T` is a basis of `T` of total weight `κ+1` (one piece one heavier), or (β3-B) one weight-7 piece is missing and `d` drops by one. +*Use in this note:* a cell with `s = 6` is declared dead only if **all** of the following variants are dead (kill engine `scen()` in `checks/rrc_audit.py`): the base cell; the base cell with every cap raised by 1 (extra line `f`); for every weight `x` present, the cell with one piece of weight `x` replaced by `x+1` (the dropping member); and, if a 7 is present, the cell with one 7 removed and `d` lowered by 1. The audit verified the scenario list as complete (Gale dominance) for the `s = 6` rows and found that the original script's `robust6` helper accepted a variant without testing the base configuration; the shipped engine tests the base cell too, and no result changes. For `s ≤ 5` no scenario analysis is attempted: those rows are killed only by the `T`-level Lemma P (§5). + +## 3. Circuit Lemma (R2) + +Let `q_1..q_a` be a minimum basis of `T`, `supp q_j ⊆ Λ(F_j)`, `dim F_j = w_j`, and `R := {c ∈ K^a : Σ c_j q_j ∈ 𝒞}`. As the `q_j` are independent, `c ↦ Σ c_j q_j` is injective and `dim R = dim D = d`. Define `h(c)` by `Σ c_j q_j = p_{h(c)}|_{P112}`; `c ↦ h(c)` is linear and injective (`p_h ≠ 0` for `h ≠ 0`). +**Lemma.** For `K ⊆ [a]`, `\|K\| ≤ d−1`: `{c ∈ R : c|_K = 0}` is the kernel of `\|K\|` linear conditions on a `d`-dimensional space, so has dimension `≥ d − \|K\| ≥ 1`. A non-zero `c` of it has `Off(h(c)) ⊆ ∪_{j ∈ supp c} supp q_j ⊆ ∪_{j ∉ K} Λ(F_j)`, and `\|Off(h)\| ≥ 53`. ∎ +**E8 version (Class I).** If the pieces are basis members `b_j` of `S` with drop 0 and `z = 0`: let `y_j` be the E8 vectors, `supp_E y_j ⊆ Λ_E(F_j)` with `F_j` the label span of `supp_E y_j`, `dim F_j = w(b_j) = w_j` (this is the definition of E8 weight). Then `Σ c_j y_j ∈ S` restricts on P112 to `p_{h(c)}|_{P112}`, as does `p^E_{h(c)} ∈ 𝒞 ⊆ S`; their difference lies in `ker ρ ∩ S = 0`. So `Σ c_j y_j = p^E_{h(c)}` exactly and `Off_E(h(c)) ⊆ ∪_{j ∈ supp c} Λ_E(F_j)`, `\|Λ_E(F_j)\| ≤ g(w_j)`. (With `z = 1`, add the single line `f`.) ∎ +**G1 (classical).** `\|Off_E(h)\| = 120 − \|Φ ∩ h^⊥\|`; `Φ ∩ h^⊥` is a closed root subsystem of rank ≤ 7, so `\|Off_E(h)\| = 57` if `h` is parallel to a root and `≥ 78` otherwise. **Consequence:** an element `c` with `cap(supp c) := Σ g(w_j) ≤ 77` has a **root** direction `h(c)`; `\|Off_E\| ≥ 57` always. + +## 4. Relative root counting (R3) + +**Statement.** Class I (E8 version). `K0 ⊆ [a]`, `\|K0\| = d−j`, `j ≥ 2`, `comp = [a]∖K0`, `cap(S) = Σ_{i ∈ S} g(w_i)` (plus 1 for an extra line `f` where §2.4 requires). Let `F` be a family of `(j−1)`-subsets `M ⊆ comp` with (i) `cap(comp∖M) ≤ 77`, (ii) `cap(comp∖(M∪M')) ≤ 56` for distinct `M, M'`, (iii) `\|F\| > N_j`, where `N_j` = the maximum number of E8 root lines in a `j`-dimensional subspace, `N_1..N_6 = 1, 3, 6, 12, 20, 36`. Then no `S` with `cost_w(S) ≤ 71` and this cell exists. *Immediate rule:* if some `(d−1)`-subset `K` has `cap([a]∖K) ≤ 56` the cell is dead at once (`\|Off_E\| ≥ 57`). For `K0 = ∅`, `j = d` this is the earlier root-count note. +*Proof.* `R_{K0} = {c ∈ R : c|_{K0} = 0}` has dimension `≥ j`; take a `j`-dimensional `R′ ≤ R_{K0}`. (1) For `M ∈ F`, `{c ∈ R′ : c|_M = 0}` has dimension `≥ 1`: pick `c_M ≠ 0`; its support lies in `comp∖M`, so `\|Off_E(h(c_M))\| ≤ cap(comp∖M) ≤ 77`, and by G1 `h(c_M)` is a root direction. (2) The roots are distinct: if `h(c_M) ∥ h(c_{M′})` then by injectivity `c_M ∥ c_{M′}`, and the common vector vanishes on `K0 ∪ M ∪ M′`, so `57 ≤ \|Off_E\| ≤ cap(comp∖(M∪M′)) ≤ 56`, contradiction. (3) So `\|F\|` distinct root lines lie in the `j`-dimensional space `h(R′)`. The root lines in a subspace `U` form a root system `Φ ∩ U` closed under its own reflections, of rank ≤ `j`, simply laced (ADE), with at most `N_j` positive roots (`j=2`: A2 3; `j=3`: A3 6; `j=4`: D4 12 (A4 10); `j=5`: D5 20 (A5 15); `j=6`: E6 36 (D6 30, A6 21); reducible types are smaller since `N_{r1} + N_{r2} ≤ N_{r1+r2}`). `\|F\| > N_j` is a contradiction. ∎ +**Finite inputs.** `g` by exhaustive enumeration of all affine flats of `F2^8` against the 120 root classes (`gtab.py`, own E8 model `e8.py`: 1,2,4,8,12,20,36,64). `N_2 = 3`, `N_3 = 6` by exhaustive enumeration of all root-spanned subspaces (`nj.py`: 4900 and 85680 subspaces); `N_4 = 12` likewise (661,542 subspaces; `FULL=1`, log `evidence/logs/nj4.out`); `N_5 = 20`, `N_6 = 36` by the ADE classification stated above (not enumerated). +**Application.** `checks/rrc_audit.py` searches, for every cell, over all multisets `K0` of `d−j` pieces (`j = 2..d`) for a family `F` (greedy, several orders); `verify()` re-checks every certificate (sizes, caps, distinctness, `\|F\| > N_j`) independently of the search. `s = 7` rows: one variant (Class I). `s = 6` rows: all variants of §2.4. Result: `s = 7`: 298 of 404 rows dead, `s = 6`: 89 of 153 rows dead; all 47 class-B rows and all 25 earlier root-count rows are dead (`check_ledger.py`). + +## 5. Lemma P and Lemma P′ (R4) + +Setting (`T`-level, no scenario): `λ: T → T/D ≅ K^e`, `M` the matroid of `λ_j = λ(q_j)`. For `P ⊆ [a]`, `R_P = {c : supp c ⊆ P, Σ c_j q_j ∈ 𝒞}`, `dim R_P = \|P\| − r_M(P)`. +**Lemma 1 (contraction by small pieces).** Let `S ⊆ [a]` with `Σ_{S} g(w_j) < 53`, `X = ∪_S supp q_j`, `s = Σ_S g(w_j) ≥ \|X\|`. (a) `S` is `M`-independent (a dependency is a codeword supported on `< 53` lines). (b) `n_{M/S}(P) = dim R_{P ∪ S}`. (c) Every circuit `C` of `M/S` gives `c_C ∈ R_{C∪S}` unique up to scalar with `supp c_C ∖ S = C`; distinct circuits give distinct direction lines `h_C`, and `Off(h_C) ∖ X ⊆ ∪_{j ∈ C} Λ(F_j)`. +**Lemma 2 (plane lemma).** A minimal `P ⊆ [a]∖S` with `n_{M/S}(P) = 2` has circuits exactly `C_i = P ∖ K_i` for the `t ≥ 2` parallel classes `K_i` of `N^*` (`N = (M/S)|P`), whose `t` direction lines are distinct and lie in the 2-dimensional space `h(R_{P∪S})`. **Fact E:** the roots in a real plane form A1, A1×A1 or A2, so a plane holds `≤ 3` E8 lines, `≤ 1` frame line if it holds an A2. +**Fact D (direction list; proof of completeness in `dirs.py`'s header: rank-7 perps are `h` of norm `≤ 16`, rank-6 perps are root-spanned planes, rank `≤ 5` perps force `\|Off\| ≥ 92`).** All directions with `\|Off\| ≤ 89`: 112 roots (53), 8 frame (56), and **21,340 non-E8 masks** in 17 orbits of the frame stabiliser (sizes 70 … 89; CHECKED: `dirs.py`, `mkreps.py`). *Correction:* the original text claimed no `Off` of 89–91 lines; in fact one orbit of 3584 directions has `\|Off\| = 89` (e.g. `h ∝ (3,0,1,0,1,0,1,0)/2`). It is harmless: the bound needed is `\|Off\| ≤ 80 + s ≤ 89` for four ≤6-flats plus `X`, and four 6-flats cannot cover 80 of those 89 lines (the exact covering run has no leftover of `≤ 9` lines for this orbit; `facts_check.py`). +**Lemma P.** Let `S` be as in Lemma 1 with `s ≤ 9`, `e′ = e − \|S\|`, `Q` = pieces outside `S` of weight `≤ 6`, `m = \|Q\|`. A 3-circuit of `M/S` in `Q` is *special* if its direction is a root (not frame), an *other* 4-circuit has a non-E8 direction; `σ ≥ #special 3-circuits`, `ω′ ≥ #other 4-circuits` (valid for every admissible `X`, from the covering facts). **(L1)** `e′ ≤ 2`, `m ≥ 4`: impossible. **(L2)** `e′ = 3`, `m ≥ 5` and either `C(m,5) > σ·min(7+σ, 3(⌊(m−1)/2⌋−1)) + ω′(m−4)` or (`ω′ = 0` and `m − σ ≥ 5`): impossible. +*Proof.* No loops or 2-circuits (caps `20+s`, `40+s < 53`). A 3-circuit has cap `≤ 60 + s ≤ 69`, so by Fact D its direction is a root or a frame line (frame: ≤ 8 distinct). A minimal `P ⊆ Q` of nullity 2 with `\|P\| ≤ 5` is one of: (I) `\|P\| = 4`, four 3-circuits, four E8 lines in a plane (contradicts E); (II) `\|P\| = 5`, classes (2,2,1): two 3-circuits through `x` and a 4-circuit, not both 3-circuits frame (A2 holds ≤ 1 frame line), so one is special; (III) one 3-circuit + three 4-circuits; (IV) five 4-circuits: ≥ 4 directions in a plane hold ≤ 3 E8 lines, so some 4-circuit is other. (L1): any 4 pieces of `Q` have nullity ≥ 2 (rank ≤ 2), only (I) remains. (L2): every 5-subset has nullity ≥ 2 and is of type (II) with a special 3-circuit (determined by a pair of 3-circuits: ≤ `σ·min(7+σ, 3(⌊(m−1)/2⌋−1))`) or contains an other 4-circuit (each lies in `m−4` five-subsets); counting gives the inequality; the hitting form deletes one piece from each special 3-circuit. ∎ +**Lemma P′ (weighted count; replaces `ω′(m−4)` when `ω′ > 0`).** Let `rank_{M/S} Q = 3` (else L1). The triples are lines of a linear system, `n_3 ≤ ⌊m⌊(m−1)/2⌋/3⌋`. Weight each 5-subset by a lower bound on the number of other 4-circuits inside: type IV `≥ 2` (5 directions in a plane, ≤ 3 E8 lines), type III `≥ 1`, type II `≥ 0`; ≥ 3 triples in 5 points are impossible. With `A = #III`, `B = #II`, each triple in `C(m−3, 2)` five-sets: `ω′(m−4) ≥ 2C(m,5) − n_3·C(m−3,2)`. For `m = 10`: `6ω′ ≥ 504 − 273`, `ω′ ≥ 39 > 32`. ∎ (The brute-force check of the extremal inequality over 3000 random maximal triple systems is not re-run here.) +**Parameters `(σ, ω′)` (`lemp_audit.params`; each backed by a covering fact, §7).** `X = ∪_S supp q_j`: `s ≤ 3`: `(s, 0)`; `s = 4`: `(4, 0)` if `Σw ≤ 3` else `(5, 0)`; `s = 5`: `(9, 0)`; `S ∈ {{1,1,3},{2,3}}`: `(34, 0)`; `S = {4}`: `(9, 0)` or `(9, 32)`; `S = {1,4}`: `(17, 0)` or `(17, 32)` (both cases must kill). The audited engine applies L1/L2/P′ to **all 603 rows** (not only class A): **375 rows are killed** (125 by L1, 250 by L2/P′), including all 74 original class-A kills. +**D7 plane fact (CHECKED, exact rational arithmetic, `d7plane.py`).** The 32 directions served by one D7 8-set lie in no plane with a third of them, and a plane through two of them holds 0 (384 pairs) or 2 (112 pairs) E8 lines. (Not used by any kill; kept as the supporting fact for the open `[7,6^8,4,4]`-type rows.) + +## 6. The ledger (R5) + +`data/rows_input.csv` is the **input** list of the 603 `(d, multiset)` cells with `d ≥ 4`, slack `s = Σ w − 8d ∈ {4,5,6,7}`, produced by the earlier enumeration (necessary conditions of #2816 and the Basis-Lemma kills of #2826/#2862); `verify.sh` checks that rows are distinct and well formed but does not re-derive the list. `data/ledger_consolidated.csv` has one line per row: `audit_status` (`KILLED` / `KILLED(prior-only)` / `OPEN`), the source(s) (`killed_by`) and the certificates (RRC: scenario, `K0`, `j`, family size or `IMM K`; Lemma P: lemma, `S`, `e′`, `m`). A row is `KILLED` iff some `[audited]` source kills it. + +Provenance of `rows_input.csv`: see `provenance/` (generator `land7.py`, dominance filter, `SPANFACTS.md`, logs; `bash provenance/reproduce.sh`). +This is an attachment only; it changes no claim. + +| slack | rows | KILLED | KILLED(prior-only) | OPEN | +|---|---|---|---|---| +| 4 | 4 | 4 | 0 | 0 | +| 5 | 42 | 31 | 0 | 11 | +| 6 | 153 | 116 | 2 | 35 | +| 7 | 404 | 329 | 5 | 70 | +| **all** | **603** | **480** | **7** | **116** | + +By source among the 480: Lemma P only 93 (4 + 31 + 27 + 31), RRC only 105 (14 + 91), both 282 (75 + 207). `s = 7` rows rely on R1, `s = 6` rows killed by RRC alone on R1′ (all variants), rows killed by Lemma P alone are dead in every scenario (pure `T`-level). +**The 7 prior-only rows** (`d = 8`; indices 381, 384, 576, 577, 578, 580, 581 of the input) are `[7^6,6,6,5,5,5,1]`, `[7^7,6,5,5,5]`, `[7^7,6,5,5,5,1]`, `[7^7,6,6,5,3,2]`, `[7^7,6,6,5,5]`, `[7^8,5,5,3,2]`, `[7^8,5,5,5]`. They are killed only by an earlier span-cover run (a `(6,6,5)` configuration with no free lines, target 7, 48/48 chunks, no crack) by a single implementation that was **not re-audited**; if that run is not accepted, 123 rows are OPEN instead of 116. +**The 116 OPEN rows**, by `(d, slack)`: `(4,7)`: 2; `(6,7)`: 11; `(7,6)`: 11; `(7,7)`: 17; `(8,5)`: 11; `(8,6)`: 24; `(8,7)`: 40. By the earlier triage tag (`earlier_status` column, kept for traceability): 75 `OPEN class OK`, 20 class A, 19 class C, 2 class D. The class-A residue is the seven-heavy and `e′ = 4` rows of the plane-lemma note (a 7-flat version of Lemma P and a 5-circuit direction fact are missing); the others need either span runs (class OK) or three or more free lines on a 3-flat (class C). + +## 7. What `verify.sh` checks, and how heavy it is + +0. `MANIFEST.sha256`. +1. Constants: `g(1..8)`, `N_2`, `N_3` (`N_4` with `FULL=1`), E8 model assertions. +2. P112 model (`p112.py`), frame stabiliser of order 172,032 (`mkgroup.py`; `mkreps.py` checks every element preserves the frame and is label-linear), the complete direction list for `\|Off\| ≤ 89` (`dirs.py`) and that the 17 representative masks of `data/targets.txt` have disjoint orbits covering all 21,340 non-E8 masks; the 3-dimensional dual subspaces giving all 788,035 six-flats (`flats.py`). +3. Exact covering enumeration `cov.c` (all `k`-tuples of inclusion-maximal 6-flat sets restricted to the target; records every leftover of `≤ 9` lines, label rank `≤ 5` when `\> 6`): the root target (53 lines, `k = 3`, 3.05·10^9 leaves, 117,180 distinct leftovers) is **recomputed and compared**, as are the two non-trivial targets `\|Off\| = 79, 80`; the other 15 targets (`k = 4`; each 120–700 s, about 61 CPU-minutes for the 17 targets) are the shipped outputs (**RECORDED**, `data/left_*.txt.gz`, timing logs in `evidence/logs`) unless `FULL=1`. The rank `≤ 5` filter is justified because `params` uses leftovers of 7–9 lines only for `X` inside a 4-flat set (+1 line). +4. `anroot.py` / `annon.py` / `facts_check.py`: facts (a)–(f) for roots (min leftover 4; 96 four-line leftovers per root of label rank 4; ≤ 1 root per 4-leftover; 5-sets serve ≤ 4 roots; 6-set bound 28; 4-flat set serves ≤ 1; 4-flat + 1 line ≤ 8) and for non-E8 directions (min leftover 6, six-sets only for 79/80 with no rank-3 4-subset, form-F leftovers only for the 70 orbit, ≤ 32 directions per D7 set, none at all for 89), each mapped to a `params` entry; `d7plane.py`. +5. `run_rrc.py` (every certificate re-verified), `lemp_audit.py` (reproduces the 74 original kills), `build_ledger.py`, `check_ledger.py` (byte-identical to the shipped ledger; 480 / 7 / 116; all 47 class-B, 25 root-count, 74 class-A kills present). + +`evidence/logs` holds the timing logs of the full covering runs (`log_non*.txt`, 17 targets) and the exhaustive `N_4` run (`nj4.out`) of the audit; `evidence/verify_run.txt` is the output of a default `verify.sh` run. + +## 8. Overlap and credit + +Builds on **#2816** (setting, peeling, cost model, flat caps), **#2826** (Basis Lemma, direction list, Lemma S66), **#2862** and `research/one-sided-excess-three` (Lemma B and the kill criterion, slack ≤ 3), the decoder-floor notes `one-sided-decoders-all-m`, `one-sided-six-multisets` (all ours). The `d ≤ 3` cells use the same Circuit Lemma and are not repeated here. The E8 lattice, root-system and Weyl-group facts used are classical (Dynkin, Borel–de Siebenthal; ADE classification). No file is copied from another contributor. + +Prepared by DreamingOfClouds with Claude Opus 5.5 (Anthropic), via Claude Code; Apache-2.0 (`LICENSE`). diff --git a/research/one-sided-residue-closures/checks/annon.py b/research/one-sided-residue-closures/checks/annon.py new file mode 100644 index 0000000000..b62590dd11 --- /dev/null +++ b/research/one-sided-residue-closures/checks/annon.py @@ -0,0 +1,77 @@ +# F4 facts (other 4-circuits) from left_nonXX.txt; orbit-mapped counts of directions served per X shape. +import numpy as np, pickle, sys, itertools, glob +from collections import Counter, defaultdict +import p112 as p +G=np.load('G.npy'); PL=p.PL; Pidx=np.array(p.P); inv={g:i for i,g in enumerate(p.P)} +reps=pickle.load(open('dirreps.pkl','rb')) +pcnt=lambda x:bin(x).count('1') +def lines(x): return [i for i in range(112) if x>>i&1] +rank=lambda ls:p.f2rank([PL[i] for i in ls]) +def span(vs): + S={0} + for v in vs: + if v not in S: S|={s^v for s in S} + return S +def flats4_containing(vs): + S=span(vs); k=len(S).bit_length()-1 + if k>4: return [] + if k==4: return [frozenset(S)] + out=set() + def ext(S): + if len(S)==16: out.add(frozenset(S)); return + for v in range(1,512): + if v not in S: ext(S|{s^v for s in S}) + ext(S); return list(out) +lam=lambda F: sum(1< set of (mask-id) served ; mask-id = orbit image bits +famflag=[] +for k,(sz,osz,o,tags) in enumerate(reps): + fn='left_non%02d_%d.txt'%(k,sz) + try: f=open(fn) + except: summary.append((k,sz,'MISSING')); continue + hdr=f.readline().strip(); L=[] + for line in f: + lo,hi=line.split(); L.append(int(lo,16)|(int(hi,16)<<64)) + L=sorted(set(L),key=pcnt); mins=[] + for x in L: + if not any((m&~x)==0 for m in mins): mins.append(x) + hist=sorted(Counter(map(pcnt,mins)).items()) + mn=min(map(pcnt,mins)) if mins else '>9' + six=[x for x in mins if pcnt(x)==6] + bad6=[x for x in six if any(rank(c)<=3 for c in itertools.combinations(lines(x),4))] + formF=[] + for x in mins: + ls=lines(x) + if len(ls)>9: continue + if rank(ls)<=4 or any(rank([i for i in ls if i!=l])<=4 for l in ls): formF.append(x) + isfam=any(t[0]=='r6fam' for t in tags) + summary.append((k,sz,osz,'fam' if isfam else 'r7',hdr.split()[-1],'min',mn,'hist',hist,'six',len(six),'bad6',len(bad6),'formF',len(formF),[ (pcnt(x),rank(lines(x))) for x in formF][:5])) + if formF: + if isfam: famflag.append((k,sz)) + # map over orbit: for each g, image of mask & leftovers + seenm={} + for g in G: + gm=0 + for i in o: gm|=1<>64) + if _n and (((_lo[:_n]&~xl)==0)&((_hi[:_n]&~xh)==0)).any(): continue + mins.append(x); _lo[_n]=xl; _hi[_n]=xh; _n+=1 +print('distinct leftovers',len(L),' minimal',len(mins),' size hist of minimal',sorted(Counter(map(pcnt,mins)).items())) +assert all(not (x>>r0p)&1 for x in mins) +def lines(x): return [i for i in range(112) if x>>i&1] +rank=lambda ls:p.f2rank([PL[i] for i in ls]) +print('(a) min |L| =',min(map(pcnt,mins))) +m4=[x for x in mins if pcnt(x)==4]; print('(b) #4-leftovers per root',len(m4),' ranks',Counter(rank(lines(x)) for x in m4)) +rep={} +for g in G: + r=int(g[r0]) + if r not in rep: rep[r]=g + if len(rep)==112: break +assert len(rep)==112 +roots=sorted(rep) +# column permutation of the 112 P-bits induced by each coset representative +perms={r:np.array([inv[int(rep[r][Pidx[i]])] for i in range(112)]) for r in roots} +N=len(mins) +Bm=np.zeros((N,112),dtype=np.uint8) +for k,x in enumerate(mins): + for i in lines(x): Bm[k,i]=1 +sz=np.array([pcnt(x) for x in mins]) +w=np.uint64(1)<>l&1: served[x|1<>r&1}) for X,rs in served.items()) +print('(c) max #roots r not in X served by a 5-set X:',best5) +print('(d) 6-set bound 15*n4+6*n5+n6 =',15*n_by[4]+6*n_by[5]+n_by[6]) +# (e),(f): 4-flats +def span(vs): + S={0} + for v in vs: + if v not in S: S|={s^v for s in S} + return S +def flats4_containing(vs): + S=span(vs); k=len(S).bit_length()-1 + if k>4: return [] + if k==4: return [frozenset(S)] + out=set() + def ext(S): + if len(S)==16: out.add(frozenset(S)); return + for v in range(1,512): + if v not in S: ext(S|{s^v for s in S}) + if k==3: + for v in range(1,512): + if v not in S: out.add(frozenset(S|{s^v for s in S})) + else: ext(S) + return list(out) +lam=lambda F: sum(1<9: continue + ls=lines(x); a=rank(ls)<=4 + bl=[l for l in ls if rank([i for i in ls if i!=l])<=4] + if a or bl: qual.append((x,a,bl)) +print('base minimal sets of type A/B:',len(qual)) +A=defaultdict(set); B=defaultdict(set) +for x,a,bl in qual: + for r in roots: + ri=inv[r]; pm=perms[r] + ls=[int(pm[i]) for i in lines(x)] + if a: + for F in flats4_containing([PL[i] for i in ls]): A[F].add(ri) + for l in bl: + lm=int(pm[l]); rest=[i for i in ls if i!=lm] + for F in flats4_containing([PL[i] for i in rest]): + if PL[lm] not in F: B[(F,lm)].add(ri) +bestE=0 +for F,rs in A.items(): + X=lam(F); bestE=max(bestE,len({r for r in rs if not X>>r&1})) +print('(e) max #roots outside X served, X = 4-flat set:',bestE, ' #4-flats serving some root:',len(A)) +bestF=bestE +# keys (F,l), l outside F: not in B -> served set is A[F]; the max over such l is <= max_F |A[F]\X_F| (some l outside A[F] and F always exists) +for (F,l),v in B.items(): + X=lam(F)|1<>r&1})) +print('(f) max #roots outside X served, X = 4-flat set + 1 line:',bestF) diff --git a/research/one-sided-residue-closures/checks/build_ledger.py b/research/one-sided-residue-closures/checks/build_ledger.py new file mode 100644 index 0000000000..e3eb6a5650 --- /dev/null +++ b/research/one-sided-residue-closures/checks/build_ledger.py @@ -0,0 +1,42 @@ +# consolidated ledger for the 603 d>=4 rows (input data/rows_input.csv) +import csv, ast, json, os +from paths import DATA +from collections import Counter +rows=list(csv.DictReader(open(os.path.join(DATA,'rows_input.csv')))) +rrc=json.load(open('rrc_results.json')) +lp=json.load(open('lemp_results.json')) +key=lambda d,ws:(int(d),tuple(sorted(ws))) +def keyset(fn,wcol='weights'): + try: return {key(r['d'],ast.literal_eval(r[wcol])) for r in csv.DictReader(open(fn))} + except FileNotFoundError: return set() +scA2=keyset(os.path.join(DATA,'src_scA2_killed.csv')); scB2=keyset(os.path.join(DATA,'src_scB2_killed.csv')); s7b=keyset(os.path.join(DATA,'src_s7b_killed.csv')) +LP_OK=True # set False if covering facts fail (see REPORT) +out=[]; cnt=Counter() +for i,r in enumerate(rows): + ws=ast.literal_eval(r['weights']); k=key(r['d'],ws); src=[]; cert=[] + st=r['status'] + if st.startswith('KILLED span'): src.append('earlier span-cover run (6,6,5)s0@T7 [prior, not re-audited]') + o=rrc[i] + if o[4]==True: + tags=[] + for tag,c in o[5]: + if c[0]=='IMM': tags.append('%s:IMM K=%s'%(tag,list(c[1]))) + else: tags.append('%s:j=%d K0(g)=%s |F|=%d'%(tag,c[2],list(c[1]),len(c[4]))) + lab='RRC' + if st.startswith('CIRCUIT-proven'): lab='root-count immediate rule / RRC' + if k in s7b: lab='RRC with K0 empty' + if k in scB2: lab='RRC (class B)' + src.append(lab+' [audited]'); cert.append(' ; '.join(tags)) + if LP_OK and lp[str(i)]: + v=lp[str(i)] + if k in scA2: src.append('Lemma P/P\' [audited; original class-A kill]') + else: src.append('Lemma P at T-level [audited lemma, new application]') + cert.append('LemmaP %s S=%s e\'=%d m=%d'%(v[0],v[1],v[2],v[3])) + status='KILLED' if any('[audited' in s for s in src) else ('KILLED(prior-only)' if src else 'OPEN') + cnt[(status)]+=1 + out.append([i,r['d'],r['slack'],r['weights'],r['e'],st,status,' | '.join(src),' || '.join(cert)]) +with open('ledger_recomputed.csv','w',newline='') as f: + w=csv.writer(f,lineterminator='\n'); w.writerow(['row','d','slack','weights','e','earlier_status','audit_status','killed_by','certificates']); w.writerows(out) +print(cnt) +c2=Counter((r[2],r[6]) for r in out); print(sorted(c2.items())) +op=[r for r in out if r[6]=='OPEN']; print('OPEN by orig class',Counter(r[5] for r in op)) diff --git a/research/one-sided-residue-closures/checks/check_ledger.py b/research/one-sided-residue-closures/checks/check_ledger.py new file mode 100644 index 0000000000..8e026576b8 --- /dev/null +++ b/research/one-sided-residue-closures/checks/check_ledger.py @@ -0,0 +1,27 @@ +# Compares the recomputed ledger (ledger_recomputed.csv, from build_ledger.py) with the shipped data/ledger_consolidated.csv and asserts the headline counts. +import csv, ast, sys, os +from collections import Counter +from paths import DATA +ok = True +def chk(name, cond): + global ok; ok &= bool(cond); print(('PASS ' if cond else 'FAIL ') + name) +new = open('ledger_recomputed.csv', 'rb').read(); old = open(os.path.join(DATA, 'ledger_consolidated.csv'), 'rb').read() +chk('recomputed ledger is byte-identical to data/ledger_consolidated.csv', new == old) +L = list(csv.DictReader(open('ledger_recomputed.csv'))) +chk('603 rows', len(L) == 603) +ws = [tuple(sorted(ast.literal_eval(r['weights']), reverse=True)) for r in L] +keys = [(int(r['d']), w) for r, w in zip(L, ws)] +chk('rows are distinct (d, multiset) pairs with d in 4..8, weights in 1..7, slack = sum(w) - 8d in 4..7, e = #pieces - d', len(set(keys)) == 603 and all( + 4 <= int(r['d']) <= 8 and all(1 <= x <= 7 for x in w) and sum(w) - 8 * int(r['d']) == int(r['slack']) and 4 <= int(r['slack']) <= 7 and len(w) - int(r['d']) == int(r['e']) for r, w in zip(L, ws))) +c = Counter(r['audit_status'] for r in L) +chk('480 KILLED by audited sources, 7 KILLED(prior-only), 116 OPEN', c == {'KILLED': 480, 'KILLED(prior-only)': 7, 'OPEN': 116}) +chk('every KILLED row has a certificate string; every OPEN row has none', all((r['certificates'] != '') == (r['audit_status'] == 'KILLED') for r in L if r['audit_status'] != 'KILLED(prior-only)')) +po = [r for r in L if r['audit_status'] == 'KILLED(prior-only)'] +chk('the 7 prior-only rows are exactly rows with no audited certificate and the earlier span-cover tag', all('prior, not re-audited' in r['killed_by'] and '[audited' not in r['killed_by'] for r in po)) +def keyset(fn): return {(int(r['d']), tuple(sorted(ast.literal_eval(r['weights']), reverse=True))) for r in csv.DictReader(open(os.path.join(DATA, fn)))} +st = {k: r['audit_status'] for k, r in zip(keys, L)} +for fn, n, nm in (('src_scB2_killed.csv', 47, 'class-B (RRC)'), ('src_s7b_killed.csv', 25, 'root-count (K0 empty)'), ('src_scA2_killed.csv', 74, 'class-A (Lemma P / P\')')): + S = keyset(fn); chk('all %d earlier %s kills are KILLED by the audited recomputation' % (n, nm), len(S) == n and all(st[k] == 'KILLED' for k in S)) +tab = Counter((int(r['d']), int(r['slack']), r['audit_status']) for r in L) +print('OPEN rows by (d, slack):', sorted((d, s, n) for (d, s, a), n in tab.items() if a == 'OPEN')) +print('PASS ledger' if ok else 'FAIL ledger'); sys.exit(0 if ok else 1) diff --git a/research/one-sided-residue-closures/checks/cov.c b/research/one-sided-residue-closures/checks/cov.c new file mode 100644 index 0000000000..04eade7126 --- /dev/null +++ b/research/one-sided-residue-closures/checks/cov.c @@ -0,0 +1,49 @@ +// AUDIT-SC exact covering enumerator (independent of SC-A c/mcov.c, menum.c). +// usage: cov lo hi k Lmax forced out.txt (target mask over 112 P112 lines, lo=lines 0..63, hi=64..111, hex) +// Enumerates all k-tuples of inclusion-maximal 6-flat sets (restricted to target), records every leftover L with +// |L|<=Lmax and (|L|<=6 or labelrank(L)<=5) and forced line not in L. Writes distinct leftovers + stats. +#include +#include +#include +#include +typedef struct {uint64_t lo,hi;} M; +static int pc(M a){return __builtin_popcountll(a.lo)+__builtin_popcountll(a.hi);} +static int lab[112]; +static int rnk(M a){int b[9];int n=0;for(int i=0;i<112;i++){int in=i<64?(a.lo>>i)&1:(a.hi>>(i-64))&1;if(!in)continue;int x=lab[i];for(int j=0;jhi!=y->hi)return x->hihi?-1:1;if(x->lo!=y->lo)return x->lolo?-1:1;return 0;} +static M*S;static int ns,K,LMAX,NEED,FORCED;static M T;static int tsz; +// hash set of leftovers +#define HS (1<<24) +static M*H;static char*Hu;static long nh=0;static int minleft=999;static long nleaf=0; +static void add(M l){uint64_t h=(l.lo*0x9E3779B97F4A7C15ULL)^(l.hi*0xC2B2AE3D27D4EB4FULL);size_t i=(h>>20)&(HS-1);while(Hu[i]){if(H[i].lo==l.lo&&H[i].hi==l.hi)return;i=(i+1)&(HS-1);}Hu[i]=1;H[i]=l;nh++;if(nh>HS/2){fprintf(stderr,"hash full\n");exit(2);}} +static void dfs(int t,int start,M cov){ + int c=pc(cov); + if(t==K){M l={T.lo&~cov.lo,T.hi&~cov.hi};int s=tsz-c;nleaf++;if(s=0){int in=FORCED<64?(l.lo>>FORCED)&1:(l.hi>>(FORCED-64))&1; if(in)return;} + if(s<=6||rnk(l)<=5)add(l);} return;} + for(int i=start;i=start allows repeats +} +int main(int argc,char**argv){ + T.lo=strtoull(argv[1],0,16);T.hi=strtoull(argv[2],0,16);K=atoi(argv[3]);LMAX=atoi(argv[4]);FORCED=atoi(argv[5]); + tsz=pc(T);NEED=tsz-LMAX; + FILE*f=fopen("labels112.bin","rb");fread(lab,4,112,f);fclose(f); + f=fopen("flats6.bin","rb");fseek(f,0,SEEK_END);long n=ftell(f)/16;fseek(f,0,SEEK_SET);M*A=malloc(n*16);fread(A,16,n,f);fclose(f); + for(long i=0;i0;s--)if(hist[s])fprintf(stderr," %d:%d",s,hist[s]);fprintf(stderr,"\n"); + H=calloc(HS,16);Hu=calloc(HS,1); + M z={0,0};dfs(0,0,z); + FILE*o=fopen(argv[6],"w");fprintf(o,"# target %d maximal %d leaves %ld minleft(within bound) %d distinct_leftovers %ld\n",tsz,ns,nleaf,minleft,nh); + for(size_t i=0;i=3). +import pickle, itertools, sys +from fractions import Fraction +from math import lcm +import p112 as p +def rref(M): + M = [[Fraction(x) for x in r] for r in M]; piv = []; r = 0 + for c in range(len(M[0])): + k = next((i for i in range(r, len(M)) if M[i][c] != 0), None) + if k is None: continue + M[r], M[k] = M[k], M[r]; M[r] = [x / M[r][c] for x in M[r]] + for i in range(len(M)): + if i != r and M[i][c] != 0: M[i] = [a - M[i][c] * b for a, b in zip(M[i], M[r])] + piv.append(c); r += 1 + if r == len(M): break + return M[:r], piv +def rank(M): return len(rref(M)[1]) +def nullvec(M): + R, piv = rref(M); free = [c for c in range(len(M[0])) if c not in piv] + assert len(free) == 1, len(free) + f = free[0]; v = [Fraction(0)] * len(M[0]); v[f] = Fraction(1) + for row, c in zip(R, piv): v[c] = -row[f] + L = lcm(*[x.denominator for x in v]); return [int(x * L) for x in v] +D = pickle.load(open('formF.pkl', 'rb'))['A'] +F, ms = max(D.items(), key=lambda t: len(t[1])) +n4 = sum(1 for i in range(112) if p.PL[i] in F) +H = [] +for gm in ms: + perp = [p.P[i] for i in range(112) if not gm >> i & 1] + H.append(nullvec([list(p.LINES[i]) for i in perp])) +E8 = [list(l) for l in p.LINES] +c3 = {}; cE = {} +for a, b in itertools.combinations(range(len(H)), 2): + assert rank([H[a], H[b]]) == 2 + t = sum(1 for c in range(len(H)) if c not in (a, b) and rank([H[a], H[b], H[c]]) == 2) + e = sum(1 for l in E8 if rank([H[a], H[b], l]) == 2) + c3[t] = c3.get(t, 0) + 1; cE[e] = cE.get(e, 0) + 1 +print('4-flat holds %d lines of P112; directions served: %d; third served directions in a plane: %s; E8 lines in a plane: %s' % (n4, len(H), c3, cE)) +ok = n4 == 8 and len(H) == 32 and c3 == {0: 496} and set(cE) <= {0, 2} +print(('PASS' if ok else 'FAIL') + ' D7 plane fact: no plane contains three of the 32 directions; each plane through two holds 0 or 2 E8 lines (%s)' % cE) +sys.exit(0 if ok else 1) diff --git a/research/one-sided-residue-closures/checks/dirs.py b/research/one-sided-residue-closures/checks/dirs.py new file mode 100644 index 0000000000..d9f6f81e50 --- /dev/null +++ b/research/one-sided-residue-closures/checks/dirs.py @@ -0,0 +1,53 @@ +# AUDIT-SC: complete list of P112 Off-masks with |Off| <= 89 (non-E8 directions), own derivation: +# rank-7 perp: h primitive E8 vector of norm = det(E8 cap V) <= det Q(Psi) <= 12 (types table) -> enumerate norm <= 16; +# rank-6 perp: V^perp is a root-spanned plane (Hermite, det <= 4) -> generic h in that plane; rank <= 5: <= 20 lines -> |Off| >= 92. +import numpy as np, itertools, pickle +import p112 as p +LA=p.LA # doubled coords +P=np.array(p.P) +vecs=[] +rng=np.arange(-3,4) +# integer vectors (true coords), doubled +g=np.array(np.meshgrid(*[rng]*8,indexing='ij')).reshape(8,-1).T +g=g[(g.sum(1)%2==0)&((g**2).sum(1)<=16)&((g**2).sum(1)>0)] +vecs.append(2*g) +h=np.array([-5,-3,-1,1,3,5]) +g2=np.array(np.meshgrid(*[h]*8,indexing='ij')).reshape(8,-1).T # doubled half-integers +g2=g2[((g2.sum(1)//2)%2==0)&((g2**2).sum(1)<=64)] +vecs.append(g2) +V=np.concatenate(vecs); print('E8 vectors norm<=16:',len(V)) +# primitive: not 2*E8 vector etc. -> just dedupe directions by canonical primitive form via gcd of doubled coords handled by mask dedupe +D=(V@LA.T) # 4* +perp=(D==0) +rk={} +masks={} +def rank_lines(ix): + if len(ix)==0: return 0 + return np.linalg.matrix_rank(LA[ix].astype(float)) +cnt7=0 +for k in range(len(V)): + Z=np.nonzero(perp[k])[0] + if len(Z)<23: continue + r=rank_lines(Z) + if r!=7: continue + off=tuple(sorted(set(P.tolist())-set(Z.tolist()))) + isroot=(V[k]@V[k]==8) + masks.setdefault(off,set()).add(('r7','root' if isroot else 'non', int(V[k]@V[k])//4)) +# rank-6 families: planes spanned by two roots +for a,b in itertools.combinations(range(120),2): + A=LA[[a,b]] + Z=np.nonzero(((LA@A.T)==0).all(1))[0] + if len(Z)<23: continue + if rank_lines(Z)!=6: continue + off=tuple(sorted(set(P.tolist())-set(Z.tolist()))) + masks.setdefault(off,set()).add(('r6fam',)) +out={} +for off,tags in masks.items(): + if len(off)<=89: out[off]=tags +roots=[o for o,t in out.items() if any(x[0]=='r7' and x[1]=='root' for x in t)] +non=[o for o,t in out.items() if not any(x[0]=='r7' and x[1]=='root' for x in t)] +from collections import Counter +print('masks |Off|<=89: total',len(out),' E8-root masks',len(roots),' non-E8',len(non)) +print('size hist non-E8',sorted(Counter(len(o) for o in non).items())) +print('fam masks', sum(1 for o in non if any(x[0]=='r6fam' for x in out[o])), 'sizes',sorted(Counter(len(o) for o in non if any(x[0]=='r6fam' for x in out[o])).items())) +pickle.dump({'non':non,'rootmasks':roots,'tags':out},open('dirs.pkl','wb')) diff --git a/research/one-sided-residue-closures/checks/e8.py b/research/one-sided-residue-closures/checks/e8.py new file mode 100644 index 0000000000..c2aa811b81 --- /dev/null +++ b/research/one-sided-residue-closures/checks/e8.py @@ -0,0 +1,26 @@ +# AUDIT-SC independent E8 model: roots in SIMPLE-ROOT coordinates generated from the E8 Cartan matrix +# (no reuse of CARRIER/lib.py). Labels = (1, coefficient vector mod 2) in F2^9. +import itertools, numpy as np +# E8 Dynkin: chain 0-1-2-3-4-5-6 with node 7 attached to node 4 (Bourbaki-like; any E8 labelling works) +edges=[(0,1),(1,2),(2,3),(3,4),(4,5),(5,6),(4,7)] +C=np.eye(8,dtype=int)*2 +for a,b in edges: C[a,b]=C[b,a]=-1 +assert round(np.linalg.det(C))==1 +def ip(u,v): return int(np.array(u)@C@np.array(v)) +simple=[tuple(int(i==k) for i in range(8)) for k in range(8)] +roots=set(simple)|{tuple(-x for x in s) for s in simple} +frontier=list(roots) +while frontier: + new=[] + for r in frontier: + for s in simple: + c=ip(r,s); t=tuple(x-c*y for x,y in zip(r,s)) + if t not in roots: roots.add(t); new.append(t) + frontier=new +roots=sorted(roots); assert len(roots)==240 +pos=[r for r in roots if any(r) and next(x for x in r if x)>0] +lines=sorted(pos); assert len(lines)==120 +assert all(ip(r,r)==2 for r in lines) +cls=[sum((x%2)< (so = G[l]@h for h in simple coords) diff --git a/research/one-sided-residue-closures/checks/facts_check.py b/research/one-sided-residue-closures/checks/facts_check.py new file mode 100644 index 0000000000..92ef4d65f5 --- /dev/null +++ b/research/one-sided-residue-closures/checks/facts_check.py @@ -0,0 +1,25 @@ +# Asserts that the covering facts recomputed by anroot.py / annon.py (outputs passed as argv[1], argv[2]) support every parameter used by lemp_audit.params. +import re, sys +a = open(sys.argv[1]).read(); b = open(sys.argv[2]).read(); ok = True +def chk(name, cond): + global ok; ok &= bool(cond); print(('PASS ' if cond else 'FAIL ') + name) +g = lambda pat, s: re.search(pat, s) +chk('F3(a): three <=6-flats cover Off(r) minus L only if |L| >= 4 (root not in L)', int(g(r'\(a\) min \|L\| = (\d+)', a).group(1)) == 4) +chk('F3(b): exactly 96 four-line leftovers per root, all of label rank 4', g(r'\(b\) #4-leftovers per root 96 ranks Counter\(\{4: 96\}\)', a) is not None) +nb = eval(g(r'by size: (\{.*?\})', a).group(1)) +chk('each 4-line leftover serves <= 1 root, 5-line <= 2, 6-line <= 1', nb[4] == 1 and nb[5] <= 2 and nb[6] == 1) +chk('F3(c): a 5-line X serves <= 4 roots outside X (sigma(s=5) <= 5+4 = 9)', int(g(r'\(c\) .*: (\d+)', a).group(1)) <= 4) +chk('F3(d): 6-line X: roots outside X <= 15*1+6*2+1 = 28 (sigma <= 6+28 = 34)', int(g(r'\(d\) .* = (\d+)', a).group(1)) <= 28) +chk('F3(e): X = 4-flat set serves <= 1 root outside X (sigma({4}) <= 8+1 = 9)', int(g(r'\(e\) .*?: (\d+)', a).group(1)) <= 1) +chk('F3(f): X = 4-flat set + 1 line serves <= 8 roots outside X (sigma({1,4}) <= 9+8 = 17)', int(g(r'\(f\) .*?: (\d+)', a).group(1)) <= 8) +rows = re.findall(r"^\((\d+), (\d+), (\d+), '(\w+)', '(\d+)', 'min', (\S+), 'hist', .*?'six', (\d+), 'bad6', (\d+), 'formF', (\d+)", b, re.M) +chk('annon covers all 17 orbit representatives', len(rows) == 17) +R = [dict(sz=int(r[1]), left=int(r[4]), mn=r[5], six=int(r[6]), bad6=int(r[7]), formF=int(r[8])) for r in rows] +chk('F4: every non-E8 direction (|Off| <= 89, 17 orbits) has min leftover >= 6 for four <=6-flats (so s <= 5 gives omega\'=0)', all(x['mn'] == "'>9'" or int(x['mn']) >= 6 for x in R)) +chk('F4: 6-line leftovers occur only for |Off| in {79, 80} (16 six-sets each) and none contains a 4-set of label rank <= 3 (omega\'=0 for the s=6 types {1,1,3},{2,3})', + {x['sz'] for x in R if x['six']} == {79, 80} and all(x['six'] == 16 for x in R if x['six']) and all(x['bad6'] == 0 for x in R)) +chk('F4: form-F leftovers (<=9 lines, rank <=4 or +1 line) exist only for the |Off|=70 orbit; no family mask has one', [x['sz'] for x in R if x['formF']] == [70] and 'family masks with form-F leftovers (would give infinitely many directions): []' in b) +chk('F4: one 4-flat set (8 lines, D7 type) serves <= 32 directions; 4-flat set + 1 line <= 32 (omega\' in {0, 32})', + int(g(r'X = 4-flat set: max #directions served (\d+)', b).group(1)) == 32 and int(g(r'X = 4-flat set \+ 1 line: max #directions served (\d+)', b).group(1)) == 32) +chk('no leftover of <= 9 lines at all for |Off| = 89 (four 6-flats cannot cover 80 of 89)', [x for x in R if x['sz'] == 89 and x['left'] == 0 and x['mn'] == "'>9'"] != []) +print('PASS facts' if ok else 'FAIL facts'); sys.exit(0 if ok else 1) diff --git a/research/one-sided-residue-closures/checks/flats.py b/research/one-sided-residue-closures/checks/flats.py new file mode 100644 index 0000000000..3f145889f9 --- /dev/null +++ b/research/one-sided-residue-closures/checks/flats.py @@ -0,0 +1,24 @@ +# all 6-dim subspaces of F2^9 (kernels of 3-dim dual subspaces, RREF enumeration) -> P112 line masks (lo,hi uint64) +import numpy as np, itertools +import p112 as p +PL=p.PL # 112 labels +par=np.array([bin(x).count('1')&1 for x in range(512)]) +mv=np.zeros((512,2),dtype=np.uint64) +for v in range(1,512): + z=[i for i in range(112) if par[PL[i]&v]==0] + lo=sum(1<=64) + mv[v]=(lo,hi) +out=[] +n=9;m=3 +for piv in itertools.combinations(range(n),m): + free=[(i,c) for i in range(m) for c in range(n) if c not in piv and c>piv[i]] + for b in itertools.product((0,1),repeat=len(free)): + rows=[1<>np.arange(8))&1) # 120x8 +def subspaces_dual(m): + # all m-dim subspaces of F2^8 (as m x 8 RREF matrices), generated by pivot pattern + for piv in itertools.combinations(range(8),m): + free=[(i,c) for i in range(m) for c in range(8) if c not in piv and c>piv[i]] + for b in itertools.product((0,1),repeat=len(free)): + M=np.zeros((m,8),dtype=np.int64) + for i,p in enumerate(piv): M[i,p]=1 + for (i,c),v in zip(free,b): M[i,c]=v + yield M +g={} +for w in range(1,9): + k=w-1; m=8-k + if m==0: g[w]=120; continue + best=0; nsub=0 + for M in subspaces_dual(m): + nsub+=1 + syn=(bits@M.T)%2 @ (1<= 6 + if s==4: return [(4 if sum(S)<=3 else 5,0)] # fact (b) + if s==5: return [(9,0)] # fact (c) + if sorted(S) in ([1,1,3],[2,3]): return [(34,0)] # fact (d) bound 6+28; fact (h) + if sorted(S)==[4]: return [(9,0),(9,32)] # facts (e),(i) + if sorted(S)==[1,4]: return [(17,0),(17,32)] # facts (f),(i) + return None +def L2(m,sg,om): + ok=False + if m>=5: + pairs=sg*min(7+sg,3*((m-1)//2-1)) + if comb(m,5)>pairs+om*(m-4): ok=True + if om==0 and m-sg>=5: ok=True + n3=(m*((m-1)//2))//3 + if om*(m-4)<2*comb(m,5)-n3*comb(m-3,2): ok=True # Lemma P' + return ok +def lemmaP(ws,e): + small=sorted(x for x in ws if x<=4) + for k in range(len(small)+1): + for S in sorted(set(itertools.combinations(small,k))): + S=list(S); s=sum(G[x] for x in S) + if s>9: continue + rest=list(ws) + for x in S: rest.remove(x) + ep=e-len(S); m=sum(1 for x in rest if x<=6) + if ep<=2 and m>=4: return ('L1',S,ep,m) + if ep==3: + P=params(S) + if P and all(L2(m,sg,om) for sg,om in P): return ('L2/P\'',S,ep,m,P) + return None +if __name__=='__main__': + rows=list(csv.DictReader(open(os.path.join(DATA,'rows_input.csv')))) + out={} + for i,r in enumerate(rows): + ws=ast.literal_eval(r['weights']); e=int(r['e']) + v=lemmaP(ws,e) + out[i]=v + json.dump({str(k):v for k,v in out.items()},open('lemp_results.json','w')) + from collections import Counter + print('Lemma P kills (all 603 rows):',sum(1 for v in out.values() if v), Counter(v[0] for v in out.values() if v)) + A=list(csv.DictReader(open(os.path.join(DATA,'src_scA2_killed.csv')))) + keyA={(int(r['d']),tuple(sorted(ast.literal_eval(r['weights'])))) for r in A} + mine={(int(rows[i]['d']),tuple(sorted(ast.literal_eval(rows[i]['weights'])))) for i,v in out.items() if v} + print('SC-A/A2 74 rows reproduced:',len(keyA&mine),'/',len(keyA),' extra rows outside class A:',len(mine-keyA)) diff --git a/research/one-sided-residue-closures/checks/manifest_check.py b/research/one-sided-residue-closures/checks/manifest_check.py new file mode 100644 index 0000000000..0c39981713 --- /dev/null +++ b/research/one-sided-residue-closures/checks/manifest_check.py @@ -0,0 +1,12 @@ +# Step 0 of verify.sh: every line of MANIFEST.sha256 (" ") must match the file; the manifest must list every file of the package except itself. +import hashlib, os, sys +root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +listed = {} +for l in open(os.path.join(root, 'MANIFEST.sha256')): + h, p = l.rstrip('\n').split(' ', 1); listed[p] = h +bad = [p for p, h in listed.items() if not os.path.isfile(os.path.join(root, p)) or hashlib.sha256(open(os.path.join(root, p), 'rb').read()).hexdigest() != h] +allf = {os.path.relpath(os.path.join(d, f), root) for d, _, fs in os.walk(root) for f in fs if '__pycache__' not in d and f != 'MANIFEST.sha256' and not f.endswith('.pyc')} +extra = sorted(allf - set(listed)) +print(('FAIL' if bad else 'PASS') + ' manifest: %d files hash-checked, %d mismatching %s' % (len(listed), len(bad), bad[:3])) +print(('FAIL' if extra else 'PASS') + ' manifest lists every package file (%d unlisted %s)' % (len(extra), extra[:3])) +sys.exit(1 if bad or extra else 0) diff --git a/research/one-sided-residue-closures/checks/mkgroup.py b/research/one-sided-residue-closures/checks/mkgroup.py new file mode 100644 index 0000000000..2ce1d7d5f9 --- /dev/null +++ b/research/one-sided-residue-closures/checks/mkgroup.py @@ -0,0 +1,38 @@ +# AUDIT-SC: frame stabiliser in W(E8), as permutations of the 120 lines (own construction). +import numpy as np, random, pickle, sys +import p112 as p +idx={l:i for i,l in enumerate(p.LINES)} +def perm_of(fun): return np.array([idx[p.canon(fun(np.array(l)))] for l in p.LINES],dtype=np.int16) +def refl(a): + a=np.array(a); return perm_of(lambda v: tuple(v-((v@a)//4)*a)) +REF=[refl(r) for r in p.LINES] +gens=[] +def coord(f): return perm_of(lambda v: tuple(f(list(v)))) +gens.append(coord(lambda v:[v[1],v[0]]+v[2:])) +gens.append(coord(lambda v:v[2:4]+v[0:2]+v[4:])) +gens.append(coord(lambda v:v[0:2]+v[4:6]+v[2:4]+v[6:])) +gens.append(coord(lambda v:v[0:4]+v[6:8]+v[4:6])) +for k in range(7): gens.append(coord(lambda v,k=k:[(-x if i in (k,k+1) else x) for i,x in enumerate(v)])) +F=set(p.FRAME) +def pres(g): return set(g[list(F)].tolist())==F +assert all(pres(g) for g in gens) +rng=random.Random(11); cur=np.arange(120,dtype=np.int16); extra=[] +for step in range(400000): + cur=REF[rng.randrange(120)][cur] + if pres(cur): extra.append(cur.copy()) + if len(extra)>=6: break +print('found',len(extra),'frame-preserving random elements after',step,'steps') +gens+=extra +# closure +seen={np.arange(120,dtype=np.int16).tobytes()}; frontier=[np.arange(120,dtype=np.int16)] +while frontier: + nf=[] + for g in frontier: + for h in gens: + k=h[g]; b=k.tobytes() + if b not in seen: seen.add(b); nf.append(k) + frontier=nf +print('|G| =',len(seen)) +Gel=np.array([np.frombuffer(b,dtype=np.int16) for b in seen]) +np.save('G.npy',Gel) +# label-linearity check on generators: label(g(l)) = A label(l) for some linear A (check via rank of joint system) diff --git a/research/one-sided-residue-closures/checks/mkreps.py b/research/one-sided-residue-closures/checks/mkreps.py new file mode 100644 index 0000000000..525218fd19 --- /dev/null +++ b/research/one-sided-residue-closures/checks/mkreps.py @@ -0,0 +1,82 @@ +# Orbit bookkeeping for the non-E8 direction masks (dirs.pkl) under the frame stabiliser G (G.npy), and the covering targets. +# * every element of G preserves the frame and acts label-linearly (so covering facts transport along G); +# * the 17 representative masks of data/targets.txt have pairwise disjoint G-orbits whose union is ALL 21,340 non-E8 masks with |Off|<=89; +# * the root target is Off(r0) (53 lines). Writes dirreps.pkl (input of annon.py). Prints PASS/FAIL lines. +import numpy as np, pickle, os, sys +import p112 as p +from paths import DATA +G = np.load('G.npy'); D = pickle.load(open('dirs.pkl', 'rb')) +ok = True +def rep(name, cond, msg=''): + global ok; ok &= bool(cond); print(('PASS ' if cond else 'FAIL ') + name + (' ' + msg if msg else '')) +rep('G has 172032 elements', len(G) == 172032, str(len(G))) +fr = np.array(sorted(p.FRAME)) +rep('G preserves the frame', all(set(g[fr].tolist()) == set(fr.tolist()) for g in G[:2000]) and (np.sort(G[:, fr], axis=1) == fr).all()) +# label-linearity of every element: express each line label in a basis of 9 independent labels (lines bi) +LAB = p.LAB; basis = []; coeff = {} +span = {0: 0} +for i in range(120): + if int(LAB[i]) not in span: + k = len(basis); basis.append(i) + for v, m in list(span.items()): span[v ^ int(LAB[i])] = m | (1 << k) + if len(basis) == 9: break +assert len(basis) == 9 +cm = np.array([span[int(LAB[i])] for i in range(120)]) # coefficient bitmask over basis +Gi = G.astype(np.int64) +imgb = LAB[Gi[:, basis]] # |G| x 9 images of basis labels +pred = np.zeros((len(G), 120), dtype=np.int64) +for k in range(9): + sel = ((cm >> k) & 1).astype(bool) + pred[:, sel] ^= imgb[:, [k]] +rep('every element of G is label-linear (label(g(l)) = A label(l))', (pred == LAB[Gi]).all()) +pos = {g: i for i, g in enumerate(p.P)} +def hexm_to_global(lo, hi): + m = int(lo, 16) | (int(hi, 16) << 64) + return tuple(p.P[i] for i in range(112) if m >> i & 1) +T = [l.split() for l in open(os.path.join(DATA, 'targets.txt')) if l.strip()] +Dnon = set(D['non']); allnon = set(Dnon) +# root target +r0 = p.P[0]; off_r = tuple(i for i in p.P if p.IP[i, r0] != 0) +rt = [t for t in T if t[0] == 'root'][0] +rep('root target = Off(r0), 53 lines', hexm_to_global(rt[1], rt[2]) == off_r and len(off_r) == 53 and int(rt[4]) == pos[r0]) +def img_masks(o): + idx = G[:, list(o)].astype(np.int64) # |G| x |o| global indices + lo = np.zeros(len(G), dtype=np.uint64); hi = np.zeros(len(G), dtype=np.uint64) + posarr = np.array([pos.get(i, -1) for i in range(120)]) + ps = posarr[idx] + assert (ps >= 0).all() + for c in range(ps.shape[1]): + pc = ps[:, c] + lo |= np.where(pc < 64, np.uint64(1) << np.minimum(pc, 63).astype(np.uint64), np.uint64(0)) + hi |= np.where(pc >= 64, np.uint64(1) << np.maximum(pc - 64, 0).astype(np.uint64), np.uint64(0)) + return set(zip(lo.tolist(), hi.tolist())) +def to_masks(S): + out = set() + for o in S: + lo = hi = 0 + for i in o: + q = pos[i] + if q < 64: lo |= 1 << q + else: hi |= 1 << (q - 64) + out.add((lo, hi)) + return out +allmasks = to_masks(Dnon) +seen = set(); reps = [] +for t in T: + if t[0] == 'root': continue + o = hexm_to_global(t[1], t[2]); sz = len(o) + assert o in Dnon, t + orb = img_masks(o) + rep('orbit of %s: %d masks, all in the direction list, disjoint from earlier orbits' % (t[0], len(orb)), orb <= allmasks and not (orb & seen)) + seen |= orb + tags = D['tags'][tuple(sorted(o))] + reps.append((sz, len(orb), o, tags)) +rep('the 17 orbits cover all %d non-E8 masks with |Off|<=89' % len(allmasks), seen == allmasks, '%d vs %d' % (len(seen), len(allmasks))) +rep('orbit sizes sum to 21340', sum(r[1] for r in reps) == 21340 == len(allmasks)) +big = [r for r in reps if r[0] == 89] +rep('Fact D correction: exactly one orbit with |Off| = 89, of 3584 directions', len(big) == 1 and big[0][1] == 3584) +# root/frame masks: single G-orbits +rm = to_masks(D['rootmasks']); roots = [m for m in D['rootmasks'] if len(m) == 53]; frs = [m for m in D['rootmasks'] if len(m) == 56] +rep('direction list: 112 root masks (|Off|=53) and 8 frame masks (|Off|=56), nothing else with |Off|<=69 but 70+', len(roots) == 112 and len(frs) == 8 and min(len(o) for o in Dnon) == 70) +pickle.dump(reps, open('dirreps.pkl', 'wb')) +print('PASS mkreps' if ok else 'FAIL mkreps'); sys.exit(0 if ok else 1) diff --git a/research/one-sided-residue-closures/checks/nj.py b/research/one-sided-residue-closures/checks/nj.py new file mode 100644 index 0000000000..002e54e8dc --- /dev/null +++ b/research/one-sided-residue-closures/checks/nj.py @@ -0,0 +1,23 @@ +# N_j = max #E8 root lines in a j-dim subspace (char 0). Exhaustive over root-spanned subspaces, j<=J. +# r in span(B) (B independent) iff Gram det(B+r)=0; Gram from the E8 Cartan form (pos. def.), entries small ints -> rounding exact. +import numpy as np, sys +from e8 import lines, C +L=np.array(lines,dtype=np.int64); n=len(L); Gm=L@C@L.T # 120x120 Gram +def contained(B): + k=len(B); idx=np.array(B) + GB=Gm[np.ix_(idx,idx)] + # det of bordered matrices for all r at once + M=np.zeros((n,k+1,k+1)); M[:,:k,:k]=GB; M[:,:k,k]=Gm[idx,:].T; M[:,k,:k]=Gm[idx,:].T; M[:,k,k]=Gm.diagonal() + dets=np.rint(np.linalg.det(M)).astype(np.int64) + return frozenset(np.nonzero(dets==0)[0].tolist()) +J=int(sys.argv[1]) +level={(frozenset([i]),(i,)) for i in range(n)} +for j in range(2,J+1): + seen={} + for S,B in level: + for i in range(n): + if i in S: continue + T=contained(list(B)+[i]) + if T not in seen: seen[T]=tuple(B)+(i,) + level=set(seen.items()) + print('j=%d: #root-spanned subspaces %d, max lines %d'%(j,len(level),max(len(s) for s,_ in level)),flush=True) diff --git a/research/one-sided-residue-closures/checks/p112.py b/research/one-sided-residue-closures/checks/p112.py new file mode 100644 index 0000000000..82c6e18f02 --- /dev/null +++ b/research/one-sided-residue-closures/checks/p112.py @@ -0,0 +1,46 @@ +# AUDIT-SC independent P112 model (D8 coordinates doubled; own lattice basis for labels; own frame code). +import itertools, numpy as np +R=[] +for i,j in itertools.combinations(range(8),2): + for a in (2,-2): + for b in (2,-2): + v=[0]*8; v[i]=a; v[j]=b; R.append(tuple(v)) +for s in itertools.product((1,-1),repeat=8): + if s.count(-1)%2==0: R.append(s) +assert len(R)==240 +def canon(v): + for x in v: + if x: return tuple(v) if x>0 else tuple(-y for y in v) +LINES=sorted({canon(r) for r in R}); NL=len(LINES); assert NL==120 +LA=np.array(LINES,dtype=np.int64) +IP=(LA@LA.T)//4 # true inner products +assert (np.diag(IP)==2).all() +# lattice basis: first 8 roots (in a fixed pseudo-random order, seed 7) with Gram det 1 (unimodular => basis of E8) +import random +rng=random.Random(7); order=list(range(240)); rng.shuffle(order) +Bv=[] +for k in order: + cand=Bv+[list(R[k])] + M=np.array(cand,dtype=float); g=M@M.T/4 + if abs(np.linalg.det(g))>0.5: Bv=cand + if len(Bv)==8: + if round(np.linalg.det(np.array(Bv,dtype=float)@np.array(Bv,dtype=float).T/4))==1: break + Bv=Bv[:7] +Bm=np.array(Bv,dtype=float) +assert round(np.linalg.det(Bm@Bm.T/4))==1 +Binv=np.linalg.inv(Bm) +co=np.rint(LA@Binv).astype(np.int64); assert np.allclose(co@Bm,LA) +cls=(co%2) +LAB=np.array([1|int(sum(int(b)<<(k+1) for k,b in enumerate(c))) for c in cls]) # 9-bit labels, bit0 = affine 1 +assert len(set(LAB.tolist()))==120 +FRAME=[LINES.index(canon(tuple(v))) for v in ([2,2,0,0,0,0,0,0],[2,-2,0,0,0,0,0,0],[0,0,2,2,0,0,0,0],[0,0,2,-2,0,0,0,0],[0,0,0,0,2,2,0,0],[0,0,0,0,2,-2,0,0],[0,0,0,0,0,0,2,2],[0,0,0,0,0,0,2,-2])] +assert all(IP[a,b]==0 for a in FRAME for b in FRAME if a!=b) +P=[i for i in range(NL) if i not in FRAME]; NP=len(P); assert NP==112 +PL=LAB[P] +def f2rank(vs): + b=[] + for x in vs: + x=int(x) + for y in b: x=min(x,x^y) + if x: b.append(x) + return len(b) diff --git a/research/one-sided-residue-closures/checks/paths.py b/research/one-sided-residue-closures/checks/paths.py new file mode 100644 index 0000000000..76b0ddbd19 --- /dev/null +++ b/research/one-sided-residue-closures/checks/paths.py @@ -0,0 +1,3 @@ +import os +CHECKS = os.path.dirname(os.path.abspath(__file__)) +DATA = os.path.join(os.path.dirname(CHECKS), 'data') diff --git a/research/one-sided-residue-closures/checks/rrc_audit.py b/research/one-sided-residue-closures/checks/rrc_audit.py new file mode 100644 index 0000000000..60046812f9 --- /dev/null +++ b/research/one-sided-residue-closures/checks/rrc_audit.py @@ -0,0 +1,78 @@ +# AUDIT-SC independent RRC engine (relative root counting, SC-B2 Lemma RRC; j=d is SC-S7B's lemma; immediate rule = S7a). +# Certificate = (K0 multiset of g-values, j, family of (j-1)-index-subsets M of comp) with +# cap(comp\M)+extra <= 77, cap(comp\(M u M'))+extra <= 56 (distinct M,M'), |F| > N_j. +# Immediate: some (d-1)-subset K with cap([a]\K)+extra <= 56. +import itertools, random, functools +from collections import Counter +G={1:1,2:2,3:4,4:8,5:12,6:20,7:36,8:64} # verified by gtab.py (independent model) +N={1:1,2:3,3:6,4:12,5:20,6:36,7:63,8:120} # ADE classification; N_2,N_3 exhaustive (nj.py), N_4 run nj4.out +def submultisets(cnt,k): + keys=sorted(cnt) + def rec(i,k): + if k==0: yield (); return + if i==len(keys): return + v=keys[i] + for t in range(min(cnt[v],k),-1,-1): + for rest in rec(i+1,k-t): yield (v,)*t+rest + yield from rec(0,k) +def clique(comp,j,extra,tries=30): + cap=sum(comp)+extra; m=len(comp) + nodes=[M for M in itertools.combinations(range(m),j-1) if cap-sum(comp[i] for i in M)<=77] + if len(nodes)<=N[j]: return None + def ok(A,B): return cap-sum(comp[i] for i in set(A)|set(B))<=56 + rnd=random.Random(1) + orders=[sorted(nodes,key=lambda M:-sum(comp[i] for i in M)), sorted(nodes,key=lambda M:sum(comp[i] for i in M)), list(nodes)] + for t in range(tries if len(nodes)<3000 else 3): o=list(nodes); rnd.shuffle(o); orders.append(o) + best=[] + for o in orders: + F=[] + for M in o: + if all(ok(M,X) for X in F): F.append(M) + if len(F)>len(best): best=F + if len(best)>N[j]: return best + return None +@functools.lru_cache(maxsize=None) +def kill(gv,d,extra=0): + gv=tuple(sorted(gv,reverse=True)); a=len(gv) + if d<1: return None + # immediate: K = d-1 largest + if sum(gv[d-1:])+extra<=56: return ('IMM',gv[:d-1]) + cnt=Counter(gv) + for j in range(2,d+1): + for K0 in submultisets(cnt,d-j): + rest=cnt.copy(); rest.subtract(Counter(K0)); comp=sorted(rest.elements(),reverse=True) + F=clique(comp,j,extra) + if F: return ('RRC',K0,j,tuple(comp),tuple(F)) + return None +def verify(cert,gv,d,extra): + """independent re-check of a certificate""" + gv=sorted(gv,reverse=True) + if cert[0]=='IMM': + K=list(cert[1]); assert len(K)==d-1 + rest=Counter(gv); rest.subtract(Counter(K)); assert min(rest.values())>=0 + assert sum(rest.elements())+extra<=56; return True + _,K0,j,comp,F=cert + assert len(K0)==d-j and j>=2 + assert sorted(list(K0)+list(comp))==sorted(gv) + cap=sum(comp)+extra + assert len(set(F))==len(F)>N[j] + for M in F: + assert len(M)==j-1 and len(set(M))==j-1 and all(0<=i= 4 (root not in L) + PASS F3(b): exactly 96 four-line leftovers per root, all of label rank 4 + PASS each 4-line leftover serves <= 1 root, 5-line <= 2, 6-line <= 1 + PASS F3(c): a 5-line X serves <= 4 roots outside X (sigma(s=5) <= 5+4 = 9) + PASS F3(d): 6-line X: roots outside X <= 15*1+6*2+1 = 28 (sigma <= 6+28 = 34) + PASS F3(e): X = 4-flat set serves <= 1 root outside X (sigma({4}) <= 8+1 = 9) + PASS F3(f): X = 4-flat set + 1 line serves <= 8 roots outside X (sigma({1,4}) <= 9+8 = 17) + PASS annon covers all 17 orbit representatives + PASS F4: every non-E8 direction (|Off| <= 89, 17 orbits) has min leftover >= 6 for four <=6-flats (so s <= 5 gives omega'=0) + PASS F4: 6-line leftovers occur only for |Off| in {79, 80} (16 six-sets each) and none contains a 4-set of label rank <= 3 (omega'=0 for the s=6 types {1,1,3},{2,3}) + PASS F4: form-F leftovers (<=9 lines, rank <=4 or +1 line) exist only for the |Off|=70 orbit; no family mask has one + PASS F4: one 4-flat set (8 lines, D7 type) serves <= 32 directions; 4-flat set + 1 line <= 32 (omega' in {0, 32}) + PASS no leftover of <= 9 lines at all for |Off| = 89 (four 6-flats cannot cover 80 of 89) + PASS facts +PASS ran facts + PASS D7 plane fact: no plane contains three of the 32 directions; each plane through two holds 0 or 2 E8 lines ({2: 112, 0: 384}) +PASS ran d7plane +== 5. RRC, Lemma P, ledger +PASS RRC engine ran; every certificate re-verified by verify() (no assertion error) +PASS Lemma P at T-level kills 375 of the 603 rows +PASS all 74 original class-A kills reproduced + PASS recomputed ledger is byte-identical to data/ledger_consolidated.csv + PASS 603 rows + PASS rows are distinct (d, multiset) pairs with d in 4..8, weights in 1..7, slack = sum(w) - 8d in 4..7, e = #pieces - d + PASS 480 KILLED by audited sources, 7 KILLED(prior-only), 116 OPEN + PASS every KILLED row has a certificate string; every OPEN row has none + PASS the 7 prior-only rows are exactly rows with no audited certificate and the earlier span-cover tag + PASS all 47 earlier class-B (RRC) kills are KILLED by the audited recomputation + PASS all 25 earlier root-count (K0 empty) kills are KILLED by the audited recomputation + PASS all 74 earlier class-A (Lemma P / P') kills are KILLED by the audited recomputation + PASS ledger +PASS ran ledger +== 6. provenance of rows_input.csv: span facts rerun from source, dominance filter, land7.py + PASS direction lists regenerated (gen.py 77/80, gen88.py 88): data.txt, data80.txt, data88.txt, gens.txt; data88.txt and gens.txt equal the shipped copies + PASS fact 1 (6,6)+1 <= 3 [s66.c mode 1]: output byte-identical to logs/SIX/s66_m1.out (max real rank 3, 0 rank-8 pairs) + PASS fact 1 (6,6)+1 <= 3 [indep.py mode 1, independent Python]: 6 chunks cover all 159 reps; INDEP OVERALL and DONE REPS lines equal the shipped chunk logs; max real rank 3 + PASS fact 2 (6,6)+2 <= 4 [s6x = s6y]: max real rank 4 (bound 4), max #dirs 10, 159 reps; rank histogram and per-rep lines equal the shipped log SIX/y_662.out + PASS fact 3a (6,6)+4 lines relaxed, lim 80: span 8 on 6 pairs only [s6x]: max real rank 8 (bound 8), max #dirs 32, 159 reps; rank histogram and per-rep lines equal the shipped log SIX/y_664.out + PASS fact 3b (6,6,3) s0 <= 4 [s6x exact third-flat refinement]: refinement of the relaxed-span-8 reps [67, 68, 82]: REFINE max exact rank 4; output byte-identical to logs/SIX/r_664.out + PASS fact 4 (7,4) s0 <= 4 [s6x]: max real rank 4 (bound 4), max #dirs 12, 51 reps; rank histogram and per-rep lines equal the shipped log SIX/y_740.out + PASS fact 5 (7,5) s0 <= 4 [s6x]: max real rank 4 (bound 4), max #dirs 12, 51 reps; rank histogram and per-rep lines equal the shipped log MS3c/y_750.out + PASS fact 5 (7,5) s0 |Off|<=88 extension [s3x pass 1]: 146195478 pairs, 0 surviving pairs, 0 qualifying new directions (shipped log: 146195478 pairs, 0 surviving) + PASS fact 6 (6,6,4) s0 <= 5 [s3f |Off|<=80, target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 70064678, surviving pairs 619, cracks 0, max span 5 (shipped: pairs 70064678, max span 5); independent s3z: pairs 70064678, surviving 619, max span 5, EQUAL to s3f + PASS fact 6 (6,6,4) s0 <= 5 [s3y |Off|<=88, target 6: no crack => span <= 5]: 48 chunks, 48 of them byte-identical to the shipped chunk logs; pairs 70064678, surviving pairs 8352, cracks 0, max span 5 (shipped: pairs 70064678, max span 5); independent s3z: pairs 70064678, surviving 8352, max span 5, EQUAL to s3f + PASS fact 6 (6,6,4) s0: span exactly 5 [s3y and s3z, |Off|<=88, target 5, chunk 34]: crack at target 5 (rep 82, V2idx 103676) found by both; s3y output identical to logs/SPANCOVER/664s0t5_34.out + PASS fact 6 (6,6,4) s0 |Off|<=88 extension at target 8 [s3x pass 1; previously only in the DIRX card notes]: 70064678 pairs, 0 qualifying new directions + PASS fact 7 (6,5,4)+1 <= 4 [s3f target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 455785902, surviving pairs 523, cracks 0, max span 4 (shipped: pairs 455785902, max span 4); independent s3z: pairs 455785902, surviving 523, max span 4, EQUAL to s3f + PASS fact 8 (6,4,4)+1 <= 4 [s3f target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 271628922, surviving pairs 1, cracks 0, max span 4 (shipped: pairs 271628922, max span 4); independent s3z: pairs 271628922, surviving 1, max span 4, EQUAL to s3f + CPU time (user+sys, s): fact1_indep 3979, fact1_s66 403, fact2 394, fact3_r664 197, fact3_y664 3041, fact4 92, fact5 304, fact5_p1 58, fact6_p1 62, fact6_s3f 819, fact6_s3f_s3z 806, fact6_t5 43, fact6_t6 882, fact6_t6_s3z 884, fact7 701, fact7_s3z 702, fact8 378, fact8_s3z 378; total 14123 s = 235.4 CPU-min + PASS 14 of 14 checks pass + REPLAY PASS (wall 3586s) +PASS ran replay_spanfacts.sh (all eight span facts rerun from source, equal to the shipped logs) + PASS land7 rerun identical to recorded land7.out + PASS d>=4 survivors of the dominance filter equal rows_input.csv (multiset) +PASS ran reproduce.sh (land7.py rerun identical, dominance filter gives rows_input.csv) +== done in 6082s: 37 PASS, 0 FAIL; logs in +PASS: all assertions hold +FULL=1 bash verify.sh 19035.08s user 314.93s system 318% cpu 1:41:22.38 total + +(FULL=1 run: all 17 covering targets recomputed, exhaustive N_4, span-fact replay, land7.py rerun; about 100 minutes wall on a loaded 12-core Mac.) diff --git a/research/one-sided-residue-closures/evidence/verify_run.txt b/research/one-sided-residue-closures/evidence/verify_run.txt new file mode 100644 index 0000000000..325ca9d983 --- /dev/null +++ b/research/one-sided-residue-closures/evidence/verify_run.txt @@ -0,0 +1,80 @@ +== 0. manifest + PASS manifest: 66 files hash-checked, 0 mismatching [] + PASS manifest lists every package file (0 unlisted []) +== 1. constants +PASS E8 model: 240 roots, 120 lines, det 1, labels distinct +PASS g(1..8) = 1,2,4,8,12,20,36,64 by exhaustive enumeration of all affine flats of F2^8 +PASS N_2 = 3 (exhaustive over root-spanned planes) +PASS N_3 = 6 (exhaustive over root-spanned 3-spaces) +NOTE N_4 = 12 (and N_5 = 20, N_6 = 36) rest on the ADE classification; exhaustive N_4 log shipped in evidence/logs/nj4.out (FULL=1 recomputes) +== 2. P112, frame stabiliser, direction list +PASS frame stabiliser generated: |G| = 172032 +PASS direction list |Off| <= 89: 21460 masks, 120 E8-root/frame, 21340 non-E8 + PASS G has 172032 elements 172032 + PASS G preserves the frame + PASS every element of G is label-linear (label(g(l)) = A label(l)) + PASS root target = Off(r0), 53 lines + PASS orbit of non00_70: 128 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non01_73: 896 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non02_76: 56 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non03_77: 2688 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non04_78: 896 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non05_79: 448 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non06_80: 224 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non07_82: 448 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non08_84: 2688 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non09_84: 1024 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non10_85: 448 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non11_85: 3584 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non12_86: 168 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non13_87: 3584 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non14_88: 448 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non15_88: 28 masks, all in the direction list, disjoint from earlier orbits + PASS orbit of non16_89: 3584 masks, all in the direction list, disjoint from earlier orbits + PASS the 17 orbits cover all 21340 non-E8 masks with |Off|<=89 21340 vs 21340 + PASS orbit sizes sum to 21340 + PASS Fact D correction: exactly one orbit with |Off| = 89, of 3584 directions + PASS direction list: 112 root masks (|Off|=53) and 8 frame masks (|Off|=56), nothing else with |Off|<=69 but 70+ + PASS mkreps +PASS ran mkreps +PASS 6-flat masks: 788035 dual 3-spaces enumerated +== 3. exact coverings + PASS covering root recomputed = shipped +== 4. covering facts + PASS covering non05_79 recomputed = shipped + PASS covering non06_80 recomputed = shipped + PASS F3(a): three <=6-flats cover Off(r) minus L only if |L| >= 4 (root not in L) + PASS F3(b): exactly 96 four-line leftovers per root, all of label rank 4 + PASS each 4-line leftover serves <= 1 root, 5-line <= 2, 6-line <= 1 + PASS F3(c): a 5-line X serves <= 4 roots outside X (sigma(s=5) <= 5+4 = 9) + PASS F3(d): 6-line X: roots outside X <= 15*1+6*2+1 = 28 (sigma <= 6+28 = 34) + PASS F3(e): X = 4-flat set serves <= 1 root outside X (sigma({4}) <= 8+1 = 9) + PASS F3(f): X = 4-flat set + 1 line serves <= 8 roots outside X (sigma({1,4}) <= 9+8 = 17) + PASS annon covers all 17 orbit representatives + PASS F4: every non-E8 direction (|Off| <= 89, 17 orbits) has min leftover >= 6 for four <=6-flats (so s <= 5 gives omega'=0) + PASS F4: 6-line leftovers occur only for |Off| in {79, 80} (16 six-sets each) and none contains a 4-set of label rank <= 3 (omega'=0 for the s=6 types {1,1,3},{2,3}) + PASS F4: form-F leftovers (<=9 lines, rank <=4 or +1 line) exist only for the |Off|=70 orbit; no family mask has one + PASS F4: one 4-flat set (8 lines, D7 type) serves <= 32 directions; 4-flat set + 1 line <= 32 (omega' in {0, 32}) + PASS no leftover of <= 9 lines at all for |Off| = 89 (four 6-flats cannot cover 80 of 89) + PASS facts +PASS ran facts + PASS D7 plane fact: no plane contains three of the 32 directions; each plane through two holds 0 or 2 E8 lines ({2: 112, 0: 384}) +PASS ran d7plane +== 5. RRC, Lemma P, ledger +PASS RRC engine ran; every certificate re-verified by verify() (no assertion error) +PASS Lemma P at T-level kills 375 of the 603 rows +PASS all 74 original class-A kills reproduced + PASS recomputed ledger is byte-identical to data/ledger_consolidated.csv + PASS 603 rows + PASS rows are distinct (d, multiset) pairs with d in 4..8, weights in 1..7, slack = sum(w) - 8d in 4..7, e = #pieces - d + PASS 480 KILLED by audited sources, 7 KILLED(prior-only), 116 OPEN + PASS every KILLED row has a certificate string; every OPEN row has none + PASS the 7 prior-only rows are exactly rows with no audited certificate and the earlier span-cover tag + PASS all 47 earlier class-B (RRC) kills are KILLED by the audited recomputation + PASS all 25 earlier root-count (K0 empty) kills are KILLED by the audited recomputation + PASS all 74 earlier class-A (Lemma P / P') kills are KILLED by the audited recomputation + PASS ledger +PASS ran ledger +== done in 360s: 19 PASS, 0 FAIL; logs in +PASS: all assertions hold +(default mode, ~6 min wall on a 12-core Mac) diff --git a/research/one-sided-residue-closures/provenance/SPANFACTS.md b/research/one-sided-residue-closures/provenance/SPANFACTS.md new file mode 100644 index 0000000000..4efde33b88 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/SPANFACTS.md @@ -0,0 +1,21 @@ +# The eight span facts used by the dominance filter + +Provenance attachment for `data/rows_input.csv`; it changes no claim. Each fact has the form "for the configuration (flat dimensions) + s free lines, in the P112 / E8 model, every admissible set of qualifying directions has span at most S" (`CONF` in `dominance_filter.py`: `(dims, s, S)`). A row of `generator/land7.out` is dropped when some Basis-Lemma set of e pieces (total support < 53) fits into a configuration with S <= d-1. The logs are in `logs/` (absolute paths stripped from the `OVERALL` lines; otherwise verbatim). Where `OVERALL` lines are quoted, "max real rank" or "max span" is the S of the fact. + +| # | fact (dims, s, span) | run | implementation count | shipped log | +|---|---|---|---|---| +| 1 | (6,6)+1 <= 3 | Lemma S66+t: `s66.c` mode 1 (direction list |Off|<=77); per-direction free line | double: `s66.c` and independent Python `indep.py` mode 1 (6 chunks, all 159 reps) | `logs/SIX/s66_m1.out` (max real rank 3, 0 rank-8 pairs); `logs/SIX/indep_m1_c0..c5.out` (max real rank 3) | +| 2 | (6,6)+2 <= 4 | `y_662`: `s6y` on `data80.txt`, dims 6 6, s=2, lim 78 | single | `logs/SIX/y_662.out` (max real rank 4) | +| 3 | (6,6,3) s0 <= 4 | `y_664` (relaxed (6,6)+4 lines, lim 80: span 8 on 6 pairs only) then `r_664` (exact third-flat refinement of those pairs) | single | `logs/SIX/y_664.out`, `logs/SIX/r_664.out` (REFINE max exact rank 4) | +| 4 | (7,4) s0 <= 4 | `y_740` (`s6y data80.txt 7 4 0 80`) | single | `logs/SIX/y_740.out` (max real rank 4) | +| 5 | (7,5) s0 <= 4 | `y_750` (`s6y 7 5 0 80`, run by the MS3c card); direction list extended to |Off|<=88 with no qualifying new direction | single | `logs/MS3c/y_750.out` (max real rank 4); `logs/DIRX/p1_y750.out` (|Off|<=88 pass, 0 surviving pairs) | +| 6 | (6,6,4) s0 <= 5 | `s3f` target 8, all 159 reps, 70.0M pairs: MAX SPAN 5; re-run on the |Off|<=88 list at target 6 (pass) and target 5 (crack), so the span is exactly 5 | single (`s3f`, `s3y`; Python brute-force recheck on 11 pairs of the (6,6,2) case only) | `logs/S3FLAT/out_a664s0_*.out` (aggregate with `bash logs/S3FLAT/summ.sh a664s0` from `logs/S3FLAT`); `logs/SPANCOVER/664s0t6_*.out` (pass), `664s0t5_*.out` (one crack) | +| 7 | (6,5,4)+1 <= 4 | `s3f` target 8, per-h relaxed, all 159 reps, 455.8M pairs, MAX SPAN 4 | single | `logs/S3FLAT/out_b654s1_*.out` | +| 8 | (6,4,4)+1 <= 4 | `s3f` target 8, per-h relaxed, all 159 reps, 271.6M pairs, MAX SPAN 4 | single | `logs/S3FLAT/out_b644s1_*.out` | + +Notes and caveats, stated as in the source cards. +- Only fact 1 is double-implemented. Facts 2-8 are single-implementation runs. +- A run at target 8 proves only "span <= 7" in general; the stated bounds 4 and 5 are the maximum spans the runs actually reported (facts 6 pass/crack at lower targets confirm 5). The filter uses a fact for a row only when S <= d-1. +- Direction lists: facts 1-4, 7, 8 are within their needed |Off| bound on the |Off|<=80 list; facts 5 and 6 need |Off|<=84 and were closed by the |Off|<=88 pass (`logs/DIRX/p1_y750.out`, and the 664s0 pass `logs/SPANCOVER/664s0t6_*.out`, which uses the |Off|<=88 list `data88.txt`). The `DIRX` pass for (6,6,4) s0 at target 8 (70,064,678 pairs, 0 hits) is now also rerun by `replay_spanfacts.sh` (`logs/REPLAY/replay_fact6_p1.out`); the target-6 SPANCOVER run on the same list is shipped. +- Rerunnable from this attachment (added later; no claim changes): the C and Python sources (`src/s66.c`, `src/s6x.c` = `s6y`/`s6r`, `src/indep.py`, `src/s3f.c`, `src/s3x.c`, `src/s3y.c`, the independent `src/s3z.c`, `src/s4z.c`), the direction-list generators (`src/gen.py` for `data.txt`/`data80.txt`/`gens.txt`, `src/gen88.py` for `data88.txt`; `data/data88.txt.gz`, `data/gens.txt` are the shipped copies the replay compares with) and `replay_spanfacts.sh`, which reruns every row of the table above in chunks and compares with the shipped logs (log: `logs/REPLAY/`, 14 of 14 checks pass, 260 CPU-minutes). `s6y` is `s6x.c` with six arguments; `s6r` is `s6x.c` with the extra `REFINE` argument. +- Logs not found: none of the eight facts lacks a log. The `x_660`/`s66_m0`/`indep_m0` logs (S66, no free line) are included as extra context for fact 1; `logs/SIX/indep_m1.out` (a first, unfinished single-process run) is replaced by its six chunk logs. diff --git a/research/one-sided-residue-closures/provenance/check_rows.py b/research/one-sided-residue-closures/provenance/check_rows.py new file mode 100644 index 0000000000..df133e49d7 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/check_rows.py @@ -0,0 +1,12 @@ +# multiset comparison: d>=4 rows of open_rows.json vs ../data/rows_input.csv +import csv, json, sys, os +from collections import Counter +HERE = os.path.dirname(os.path.abspath(__file__)) +L = json.load(open(sys.argv[1])) +a = Counter((d, k, tuple(sorted(ws, reverse=True)), e) for d, k, ws, e in L if d >= 4) +b = Counter((int(r['d']), int(r['slack']), tuple(sorted(eval(r['weights']), reverse=True)), int(r['e'])) + for r in csv.DictReader(open(os.path.join(HERE, '..', 'data', 'rows_input.csv')))) +print('filter d>=4 survivors:', sum(a.values()), ' rows_input.csv rows:', sum(b.values())) +if a == b: print('PASS d>=4 survivors of the dominance filter equal rows_input.csv (multiset)') +else: + print('FAIL only in filter:', list((a-b).items())[:5], ' only in csv:', list((b-a).items())[:5]); sys.exit(1) diff --git a/research/one-sided-residue-closures/provenance/data/data88.txt.gz b/research/one-sided-residue-closures/provenance/data/data88.txt.gz new file mode 100644 index 0000000000..357d2c63d1 Binary files /dev/null and b/research/one-sided-residue-closures/provenance/data/data88.txt.gz differ diff --git a/research/one-sided-residue-closures/provenance/data/gens.txt b/research/one-sided-residue-closures/provenance/data/gens.txt new file mode 100644 index 0000000000..ba27ea667b --- /dev/null +++ b/research/one-sided-residue-closures/provenance/data/gens.txt @@ -0,0 +1,12 @@ +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 111 110 109 108 107 106 105 104 103 102 101 100 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 35 34 33 32 31 30 29 28 27 26 25 24 +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 100 101 102 103 104 105 106 107 108 109 110 111 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 24 25 26 27 28 29 30 31 32 33 34 35 +0 1 2 3 4 5 6 7 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 34 35 26 27 28 29 30 31 32 33 24 25 60 61 62 63 64 65 66 67 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 36 37 38 39 40 41 42 43 92 93 94 95 96 97 98 99 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 68 69 70 71 72 73 74 75 110 111 102 103 104 105 106 107 108 109 100 101 +0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 25 24 26 27 28 29 30 31 32 33 35 34 36 37 38 39 40 41 42 43 52 53 54 55 56 57 58 59 44 45 46 47 48 49 50 51 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 84 85 86 87 88 89 90 91 76 77 78 79 80 81 82 83 92 93 94 95 96 97 98 99 101 100 102 103 104 105 106 107 108 109 111 110 +7 6 5 4 3 2 1 0 14 15 10 11 12 13 8 9 22 23 18 19 20 21 16 17 24 25 32 33 28 29 30 31 26 27 34 35 42 43 38 39 40 41 36 37 50 51 46 47 48 49 44 45 58 59 54 55 56 57 52 53 66 67 62 63 64 65 60 61 74 75 70 71 72 73 68 69 82 83 78 79 80 81 76 77 90 91 86 87 88 89 84 85 98 99 94 95 96 97 92 93 100 101 108 109 104 105 106 107 102 103 110 111 +4 5 6 7 0 1 2 3 9 8 10 11 12 13 15 14 17 16 18 19 20 21 23 22 24 25 27 26 28 29 30 31 33 32 34 35 36 37 40 41 38 39 42 43 44 45 48 49 46 47 50 51 52 53 56 57 54 55 58 59 60 61 64 65 62 63 66 67 68 69 72 73 70 71 74 75 76 77 80 81 78 79 82 83 84 85 88 89 86 87 90 91 92 93 96 97 94 95 98 99 100 101 103 102 104 105 106 107 109 108 110 111 +2 3 0 1 6 7 4 5 8 9 12 13 10 11 14 15 16 17 20 21 18 19 22 23 24 25 26 27 30 31 28 29 32 33 34 35 36 37 39 38 41 40 42 43 45 44 46 47 48 49 51 50 53 52 54 55 56 57 59 58 60 61 63 62 65 64 66 67 69 68 70 71 72 73 75 74 76 77 79 78 81 80 82 83 84 85 87 86 89 88 90 91 93 92 94 95 96 97 99 98 100 101 102 103 106 107 104 105 108 109 110 111 +1 0 3 2 5 4 7 6 8 9 11 10 13 12 14 15 16 17 19 18 21 20 22 23 24 25 26 27 29 28 31 30 32 33 34 35 37 36 38 39 40 41 43 42 44 45 47 46 49 48 50 51 52 53 55 54 57 56 58 59 61 60 62 63 64 65 67 66 68 69 71 70 73 72 74 75 77 76 78 79 80 81 83 82 85 84 86 87 88 89 91 90 92 93 95 94 97 96 98 99 100 101 102 103 105 104 107 106 108 109 110 111 +98 69 92 75 74 93 68 99 13 18 83 84 77 90 11 20 12 19 82 85 76 91 10 21 46 47 38 62 33 102 27 108 39 63 54 55 87 80 22 16 9 15 86 81 3 4 95 72 71 96 1 6 2 5 94 73 70 97 0 7 79 88 14 8 17 23 78 89 44 50 35 100 25 110 45 51 31 104 36 42 60 66 29 106 30 105 37 43 61 67 28 107 52 58 34 101 24 111 53 59 48 49 40 64 32 103 26 109 41 65 56 57 +33 32 27 26 102 103 108 109 110 25 15 14 9 8 34 101 100 35 16 17 22 23 24 111 19 12 105 30 5 1 2 6 29 106 11 20 56 54 90 84 77 83 47 49 66 60 96 94 71 73 37 43 42 36 72 70 95 97 61 67 48 46 82 76 85 91 55 57 58 52 88 86 79 81 45 51 64 62 98 92 69 75 39 41 40 38 74 68 93 99 63 65 50 44 80 78 87 89 53 59 18 13 104 31 4 0 3 7 28 107 10 21 +43 42 60 61 37 36 66 67 15 9 49 48 54 55 16 22 14 8 47 46 56 57 17 23 78 80 68 74 28 29 104 105 92 98 86 88 19 18 58 45 52 51 12 13 64 39 5 4 2 3 40 63 62 41 1 0 6 7 38 65 11 10 50 53 44 59 20 21 24 100 76 77 82 83 34 110 70 71 26 102 32 108 94 95 72 73 27 103 33 109 96 97 25 101 84 85 90 91 35 111 79 81 69 75 30 31 106 107 93 99 87 89 +61 37 42 66 60 36 43 67 5 4 64 40 39 63 2 3 1 0 62 38 41 65 6 7 81 79 83 82 110 100 34 24 77 76 80 78 68 92 28 104 29 105 74 98 26 102 70 94 71 95 32 108 27 103 72 96 73 97 33 109 69 93 30 106 31 107 75 99 51 52 13 18 12 19 45 58 15 16 49 54 48 55 9 22 14 17 47 56 46 57 8 23 50 53 11 20 10 21 44 59 86 88 84 85 25 35 101 111 90 91 87 89 diff --git a/research/one-sided-residue-closures/provenance/dominance_filter.py b/research/one-sided-residue-closures/provenance/dominance_filter.py new file mode 100644 index 0000000000..4fb52aa252 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/dominance_filter.py @@ -0,0 +1,38 @@ +# Dominance filter: applies the eight span facts (CONF) to the slack<=7 survivor lists in generator/land7.out +# (Lemma B: a basis of e pieces with total support < 53 whose pieces fit into the flats/free lines of a config with span <= d-1 kills the row). +# usage: python3 dominance_filter.py [land7.out] -> prints " " and writes the open rows as open_rows.json +import re, itertools, sys, json, os +HERE = os.path.dirname(os.path.abspath(__file__)) +g = {1:1, 2:2, 3:4, 4:8, 5:12, 6:20, 7:36} +# (flat dimensions, free lines, proven span bound): see SPANFACTS.md +CONF = [((6,6),1,3), ((6,6),2,4), ((6,6,3),0,4), ((7,4),0,4), ((7,5),0,4), ((6,6,4),0,5), ((6,5,4),1,4), ((6,4,4),1,4)] +def fits(B, dims, s): + B = sorted(B, reverse=True); n = len(B); k = len(dims) + def rec(i, cap, free): + if i == n: return True + w = B[i] + for j in range(k): + if cap[j] >= w: + cap[j] -= w + if rec(i+1, cap, free): cap[j] += w; return True + cap[j] += w + if g[w] <= free and rec(i+1, cap, free-g[w]): return True + return False + return rec(0, list(dims), s) +def killer(ws, d, e): + for B in set(itertools.combinations(sorted(ws), e)): + if sum(g[w] for w in B) >= 53: continue + for dims, s, span in CONF: + if span <= d-1 and fits(B, dims, s): return 1 + return None +def main(path): + rows = [] + for l in open(path): + m = re.match(r'd (\d) slack (\d) (\{.*?\}) (\[.*\])', l.strip()) + if not m: continue + d = int(m.group(1)); k = int(m.group(2)) + for (kk, ws, e) in eval(m.group(4)): rows.append((d, k, ws, e)) + L = [r for r in rows if not killer(r[2], r[0], r[3])] + print(len(rows), len(L)) + json.dump(L, open(os.path.join(os.environ.get('OUT', '.'), 'open_rows.json'), 'w')) +main(sys.argv[1] if len(sys.argv) > 1 else os.path.join(HERE, 'generator', 'land7.out')) diff --git a/research/one-sided-residue-closures/provenance/generator/dpX.py b/research/one-sided-residue-closures/provenance/generator/dpX.py new file mode 100644 index 0000000000..725cd30847 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/generator/dpX.py @@ -0,0 +1,48 @@ +# X_I = P112 ∪ {f_i : i∈I}: need eps-free cost(X_I) >= 64+|I|. Peel at 7: cost >= cost(T7) + 8(8-d). +# DP constraints (dp3 P112, all transfer to X_I since every X_I target contains the P112 target; NL=112+|I|): +# then symmetric LP (NL lines, E8 N_u, g) on survivors. +import sys +from symlp import lp +from collections import Counter +g={1:1,2:2,3:4,4:8,5:12,6:20,7:36}; G={1:1,2:2,3:4,4:8,5:12,6:20,7:32} +N={0:0,1:1,2:3,3:6,4:12,5:20,6:36} +def k1(ws): + W=sum(ws); sG=sum(G[w] for w in ws); sg=sum(g[w] for w in ws) + nf= W>=14 and sG>=56 + nr= W>=15 and sG>=53 and len(ws)>=3 and not (len(ws)==3 and max(ws)<=6) + no= W>=14 and sg>=70 + return nf or nr or no +def ok(ws,d,NL): + a=len(ws) + if a=2 and a=target: return + if i==len(Ws): + ws=sorted([w for w in Ws for _ in range(cnt[w])],reverse=True) + if ok(ws,d,NL): out.append((wt,ws)) + return + w=Ws[i] + for c in range(0,(target-wt)//w+1): + cnt[w]=c; rec(i+1,cnt,wt+c*w) + cnt[w]=0 + rec(0,{w:0 for w in Ws},0); return out +NE8=[0,1,3,6,12,20,36,63] +for I in [int(x) for x in sys.argv[1].split(',')]: + NL=112+I + for d in range(1,9): + surv=enum(d,8*d+I,NL) + need=NL-NE8[8-d] if d<8 else NL + bad=[] + for wt,ws in surv: + val,bd=lp(Counter(ws),codim=8-d,NL=NL) + if bd>=need: bad.append((wt,ws,round(val,2))) + print(f'I={I} d={d} DP-survivors={len(surv)} LP-survivors={len(bad)}',bad[:6],flush=True) diff --git a/research/one-sided-residue-closures/provenance/generator/land7.py b/research/one-sided-residue-closures/provenance/generator/land7.py new file mode 100644 index 0000000000..b88110d7dd --- /dev/null +++ b/research/one-sided-residue-closures/provenance/generator/land7.py @@ -0,0 +1,45 @@ +# usage: python3 land7.py 7 > land7.out (needs numpy, scipy; about 6 min) +# slack-k landscape (P112, eps-free T-level): DP (dpX ok, NL=112) -> symmetric LP -> Basis-kill (S66+t) -> Pencil -> e=2 triple rule +import sys, itertools +import os; HERE=os.path.dirname(os.path.abspath(__file__)); sys.path.insert(0,HERE) +src=open(os.path.join(HERE,'dpX.py')).read().split("NE8=[0,1,3,6,12,20,36,63]")[0] +exec(src) +from symlp import lp +from math import comb +NE8=[0,1,3,6,12,20,36,63] +gg={1:1,2:2,3:4,4:8,5:12,6:20,7:36} +K=int(sys.argv[1]) +def packable(sub): + # sub: e weights; two bins of capacity 6 (span of union <= sum of dims) plus at most one extra 1-piece + sub=list(sub) + opts=[sub] + if 1 in sub: + s2=list(sub); s2.remove(1); opts.append(s2) + for s in opts: + n=len(s) + for mask in range(1<>i&1); b=sum(s)-a + if a<=6 and b<=6: return True + return False +def basis_kill(ws,d,e): + if d<4: return False + for sub in set(itertools.combinations(sorted(ws),e)): + if packable(sub): return True + return False +for d in range(1,9): + surv=enum(d,8*d+K+1,112); need=112-(NE8[8-d] if d<8 else 0) + from collections import Counter as Cn + tally=Cn(); left=[] + for wt,ws in surv: + k=wt-8*d + if k<0: continue + val,bd=lp(Counter(ws),codim=8-d,NL=112) + if bd=3 and e>=2 and sum(gg[w] for w in anchors)<=4: tally[(k,'PENCIL')]+=1; continue + if e==2 and comb(sum(1 for w in ws if w<=6),3)>8: tally[(k,'E2TRIPLE')]+=1; continue + tally[(k,'SURV')]+=1; left.append((k,ws,e)) + for k in range(K+1): + print('d',d,'slack',k,{t:tally[(k,t)] for t in ('LP','BASIS','PENCIL','E2TRIPLE','SURV')},[x for x in left if x[0]==k],flush=True) diff --git a/research/one-sided-residue-closures/provenance/generator/symlp.py b/research/one-sided-residue-closures/provenance/generator/symlp.py new file mode 100644 index 0000000000..bc2fdce13a --- /dev/null +++ b/research/one-sided-residue-closures/provenance/generator/symlp.py @@ -0,0 +1,55 @@ +# Independent symmetric LP (OS-CHARGE2). For a multiset of piece weights (counts n_w), max #lines coverable: +# vars x_s (per-subset value, s = type vector), constraints: +# (a) for each nonzero type u: sum_{0=1} C(n_w-1,s_w-1) prod_{w'!=w} C(n_w',s_w') x_s <= g(w) +# objective sum_s prod C(n_w,s_w) x_s. Symmetrisation is exact (LP invariant under prod Sym(n_w)). +# Returns LP value and an EXACT rational upper bound from a repaired dual certificate. +import itertools, numpy as np +from math import comb, prod +from fractions import Fraction +from scipy.optimize import linprog +import scipy.sparse as sp +g={1:1,2:2,3:4,4:8,5:12,6:20,7:36,8:64} +NE8=[0,1,3,6,12,20,36,63,120] +def Nq(u,codim,NL): + k=u+codim + return NL if k>=8 else min(NE8[k],NL) +def lp(counts,codim=0,NL=112,exact=True): + ws=[w for w in sorted(counts) if counts[w]>0]; n=[counts[w] for w in ws] + types=[t for t in itertools.product(*[range(c+1) for c in n]) if any(t)] + idx={t:i for i,t in enumerate(types)} + obj=np.array([prod(comb(n[i],t[i]) for i in range(len(n))) for t in types],float) + rows=[];cols=[];vals=[];b=[];R=0 + subs={} + for u in types: + su=sum(u) + for s in itertools.product(*[range(x+1) for x in u]): + if not any(s): continue + rows.append(R);cols.append(idx[s]);vals.append(prod(comb(u[i],s[i]) for i in range(len(n)))) + b.append(Nq(su,codim,NL)); R+=1 + for i,w in enumerate(ws): + for s in types: + if s[i]>=1: + rows.append(R);cols.append(idx[s]);vals.append(comb(n[i]-1,s[i]-1)*prod(comb(n[k],s[k]) for k in range(len(n)) if k!=i)) + b.append(g[w]); R+=1 + A=sp.csr_matrix((vals,(rows,cols)),shape=(R,len(types))) + res=linprog(-obj,A_ub=A,b_ub=b,bounds=(0,None),method='highs') + val=-res.fun + if not exact: return val,None + y=np.maximum(-res.ineqlin.marginals,0) + yq=[Fraction(int(np.ceil(x*1e7)),10**7) for x in y] + # exact column check, repair with the full-type constraint (row index of types[-1] = all n, coef = obj) + Acoo=A.tocoo(); colsum=[Fraction(0)]*len(types) + for r,c,vv in zip(Acoo.row,Acoo.col,Acoo.data): colsum[c]+=yq[r]*int(round(vv)) + full=idx[tuple(n)] + tfix=max([Fraction(0)]+[(int(obj[c])-colsum[c])/int(obj[c]) for c in range(len(types))]) + yq[full]+=tfix + bound=sum(yq[r]*b[r] for r in range(R)) + return val,bound +if __name__=='__main__': + from collections import Counter + for p in [[7]+[6]*9,[7]+[6]*9+[1],[7,7]+[6]*8,[7]+[6]*9+[1,1],[7]+[6]*9+[2],[7,7]+[6]*8+[1],[7,7,7]+[6]*7]: + print(p,lp(Counter(p))) + print('d7',lp(Counter([7]+[6]*8),codim=1)) + print('CONTROL [8]^8 d=8:',lp(Counter([8]*8))) + print('CONTROL [8]^8 d=7 (need 111):',lp(Counter([8]*8),codim=1)) diff --git a/research/one-sided-residue-closures/provenance/logs/REPLAY/replay_run.txt b/research/one-sided-residue-closures/provenance/logs/REPLAY/replay_run.txt new file mode 100644 index 0000000000..d2b859dcc1 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/logs/REPLAY/replay_run.txt @@ -0,0 +1,23 @@ +== build and direction data (work dir ) +PASS direction lists regenerated (gen.py 77/80, gen88.py 88): data.txt, data80.txt, data88.txt, gens.txt; data88.txt and gens.txt equal the shipped copies +== running 316 jobs, 4 at a time +== compare +replay of the eight span facts (wall 4226 s) +PASS fact 1 (6,6)+1 <= 3 [s66.c mode 1]: output byte-identical to logs/SIX/s66_m1.out (max real rank 3, 0 rank-8 pairs) +PASS fact 1 (6,6)+1 <= 3 [indep.py mode 1, independent Python]: 6 chunks cover all 159 reps; INDEP OVERALL and DONE REPS lines equal the shipped chunk logs; max real rank 3 +PASS fact 2 (6,6)+2 <= 4 [s6x = s6y]: max real rank 4 (bound 4), max #dirs 10, 159 reps; rank histogram and per-rep lines equal the shipped log SIX/y_662.out +PASS fact 3a (6,6)+4 lines relaxed, lim 80: span 8 on 6 pairs only [s6x]: max real rank 8 (bound 8), max #dirs 32, 159 reps; rank histogram and per-rep lines equal the shipped log SIX/y_664.out +PASS fact 3b (6,6,3) s0 <= 4 [s6x exact third-flat refinement]: refinement of the relaxed-span-8 reps [67, 68, 82]: REFINE max exact rank 4; output byte-identical to logs/SIX/r_664.out +PASS fact 4 (7,4) s0 <= 4 [s6x]: max real rank 4 (bound 4), max #dirs 12, 51 reps; rank histogram and per-rep lines equal the shipped log SIX/y_740.out +PASS fact 5 (7,5) s0 <= 4 [s6x]: max real rank 4 (bound 4), max #dirs 12, 51 reps; rank histogram and per-rep lines equal the shipped log MS3c/y_750.out +PASS fact 5 (7,5) s0 |Off|<=88 extension [s3x pass 1]: 146195478 pairs, 0 surviving pairs, 0 qualifying new directions (shipped log: 146195478 pairs, 0 surviving) +PASS fact 6 (6,6,4) s0 <= 5 [s3f |Off|<=80, target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 70064678, surviving pairs 619, cracks 0, max span 5 (shipped: pairs 70064678, max span 5); independent s3z: pairs 70064678, surviving 619, max span 5, EQUAL to s3f +PASS fact 6 (6,6,4) s0 <= 5 [s3y |Off|<=88, target 6: no crack => span <= 5]: 48 chunks, 48 of them byte-identical to the shipped chunk logs; pairs 70064678, surviving pairs 8352, cracks 0, max span 5 (shipped: pairs 70064678, max span 5); independent s3z: pairs 70064678, surviving 8352, max span 5, EQUAL to s3f +PASS fact 6 (6,6,4) s0: span exactly 5 [s3y and s3z, |Off|<=88, target 5, chunk 34]: crack at target 5 (rep 82, V2idx 103676) found by both; s3y output identical to logs/SPANCOVER/664s0t5_34.out +PASS fact 6 (6,6,4) s0 |Off|<=88 extension at target 8 [s3x pass 1; previously only in the DIRX card notes]: 70064678 pairs, 0 qualifying new directions +PASS fact 7 (6,5,4)+1 <= 4 [s3f target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 455785902, surviving pairs 523, cracks 0, max span 4 (shipped: pairs 455785902, max span 4); independent s3z: pairs 455785902, surviving 523, max span 4, EQUAL to s3f +PASS fact 8 (6,4,4)+1 <= 4 [s3f target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 271628922, surviving pairs 1, cracks 0, max span 4 (shipped: pairs 271628922, max span 4); independent s3z: pairs 271628922, surviving 1, max span 4, EQUAL to s3f +CPU time (user+sys, s): fact1_indep 4043, fact1_s66 401, fact2 452, fact3_r664 217, fact3_y664 3267, fact4 106, fact5 342, fact5_p1 65, fact6_p1 70, fact6_s3f 1090, fact6_s3f_s3z 923, fact6_t5 51, fact6_t6 1196, fact6_t6_s3z 861, fact7 934, fact7_s3z 704, fact8 480, fact8_s3z 376; total 15578 s = 259.6 CPU-min +PASS 14 of 14 checks pass +REPLAY PASS (wall 4226s) +bash provenance/replay_spanfacts.sh (JOBS=4) 15221.15s user 415.96s system 369% cpu 1:10:28.43 total diff --git a/research/one-sided-residue-closures/provenance/logs/REPLAY/replay_summary.txt b/research/one-sided-residue-closures/provenance/logs/REPLAY/replay_summary.txt new file mode 100644 index 0000000000..6146f82c71 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/logs/REPLAY/replay_summary.txt @@ -0,0 +1,17 @@ +replay of the eight span facts (wall 4226 s) +PASS fact 1 (6,6)+1 <= 3 [s66.c mode 1]: output byte-identical to logs/SIX/s66_m1.out (max real rank 3, 0 rank-8 pairs) +PASS fact 1 (6,6)+1 <= 3 [indep.py mode 1, independent Python]: 6 chunks cover all 159 reps; INDEP OVERALL and DONE REPS lines equal the shipped chunk logs; max real rank 3 +PASS fact 2 (6,6)+2 <= 4 [s6x = s6y]: max real rank 4 (bound 4), max #dirs 10, 159 reps; rank histogram and per-rep lines equal the shipped log SIX/y_662.out +PASS fact 3a (6,6)+4 lines relaxed, lim 80: span 8 on 6 pairs only [s6x]: max real rank 8 (bound 8), max #dirs 32, 159 reps; rank histogram and per-rep lines equal the shipped log SIX/y_664.out +PASS fact 3b (6,6,3) s0 <= 4 [s6x exact third-flat refinement]: refinement of the relaxed-span-8 reps [67, 68, 82]: REFINE max exact rank 4; output byte-identical to logs/SIX/r_664.out +PASS fact 4 (7,4) s0 <= 4 [s6x]: max real rank 4 (bound 4), max #dirs 12, 51 reps; rank histogram and per-rep lines equal the shipped log SIX/y_740.out +PASS fact 5 (7,5) s0 <= 4 [s6x]: max real rank 4 (bound 4), max #dirs 12, 51 reps; rank histogram and per-rep lines equal the shipped log MS3c/y_750.out +PASS fact 5 (7,5) s0 |Off|<=88 extension [s3x pass 1]: 146195478 pairs, 0 surviving pairs, 0 qualifying new directions (shipped log: 146195478 pairs, 0 surviving) +PASS fact 6 (6,6,4) s0 <= 5 [s3f |Off|<=80, target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 70064678, surviving pairs 619, cracks 0, max span 5 (shipped: pairs 70064678, max span 5); independent s3z: pairs 70064678, surviving 619, max span 5, EQUAL to s3f +PASS fact 6 (6,6,4) s0 <= 5 [s3y |Off|<=88, target 6: no crack => span <= 5]: 48 chunks, 48 of them byte-identical to the shipped chunk logs; pairs 70064678, surviving pairs 8352, cracks 0, max span 5 (shipped: pairs 70064678, max span 5); independent s3z: pairs 70064678, surviving 8352, max span 5, EQUAL to s3f +PASS fact 6 (6,6,4) s0: span exactly 5 [s3y and s3z, |Off|<=88, target 5, chunk 34]: crack at target 5 (rep 82, V2idx 103676) found by both; s3y output identical to logs/SPANCOVER/664s0t5_34.out +PASS fact 6 (6,6,4) s0 |Off|<=88 extension at target 8 [s3x pass 1; previously only in the DIRX card notes]: 70064678 pairs, 0 qualifying new directions +PASS fact 7 (6,5,4)+1 <= 4 [s3f target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 455785902, surviving pairs 523, cracks 0, max span 4 (shipped: pairs 455785902, max span 4); independent s3z: pairs 455785902, surviving 523, max span 4, EQUAL to s3f +PASS fact 8 (6,4,4)+1 <= 4 [s3f target 8]: 24 chunks, 24 of them byte-identical to the shipped chunk logs; pairs 271628922, surviving pairs 1, cracks 0, max span 4 (shipped: pairs 271628922, max span 4); independent s3z: pairs 271628922, surviving 1, max span 4, EQUAL to s3f +CPU time (user+sys, s): fact1_indep 4043, fact1_s66 401, fact2 452, fact3_r664 217, fact3_y664 3267, fact4 106, fact5 342, fact5_p1 65, fact6_p1 70, fact6_s3f 1090, fact6_s3f_s3z 923, fact6_t5 51, fact6_t6 1196, fact6_t6_s3z 861, fact7 934, fact7_s3z 704, fact8 480, fact8_s3z 376; total 15578 s = 259.6 CPU-min +PASS 14 of 14 checks pass diff --git a/research/one-sided-residue-closures/provenance/logs/S3FLAT/summ.sh b/research/one-sided-residue-closures/provenance/logs/S3FLAT/summ.sh new file mode 100755 index 0000000000..c49c751dad --- /dev/null +++ b/research/one-sided-residue-closures/provenance/logs/S3FLAT/summ.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# summ.sh tag : aggregate OVERALL lines +grep -h OVERALL out_$1_*.out | awk '{for(i=1;i<=NF;i++){ if($i=="pairs")p+=$(i+1); if($i=="surviving")s+=$(i+1); if($i=="leaves")l+=$(i+1); if($i=="overflow")o+=$(i+1); if($i=="span"){ if($(i+1)>m)m=$(i+1)} } n++} END{print "chunks",n,"pairs",p,"survpairs",s,"leaves",l,"overflow",o,"MAXSPAN",m}' +grep -h "^rep" out_$1_*.out | wc -l +grep -h CRACK out_$1_*.out | wc -l diff --git a/research/one-sided-residue-closures/provenance/replay_compare.py b/research/one-sided-residue-closures/provenance/replay_compare.py new file mode 100644 index 0000000000..5e81ab0e77 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/replay_compare.py @@ -0,0 +1,103 @@ +# Compare the outputs of replay_spanfacts.sh with the shipped logs (provenance/logs), fact by fact. +# usage: replay_compare.py OUTDIR LOGSDIR LOGDIR WALL (OUTDIR: .out/.rc/.cpu of every job; LOGDIR: receives one merged replay log per fact) +import os, re, sys, glob +OUT, LOGS, LOGDIR, WALL = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] +os.makedirs(LOGDIR, exist_ok=True) +def rd(p): return open(p).read() if os.path.exists(p) else '' +def norm(t): return t.replace('cards/DIRX/', '') +def job(n): return rd(os.path.join(OUT, n + '.out')) +def rc(n): + try: return int(rd(os.path.join(OUT, n + '.rc')).strip()) + except ValueError: return -1 +def cpu(n): + try: u, s = rd(os.path.join(OUT, n + '.cpu')).split(); return float(u) + float(s) + except ValueError: return 0.0 +status = []; cpus = {} +def report(tag, ok, msg): status.append(ok); print(('PASS ' if ok else 'FAIL ') + tag + ': ' + msg) +def merge(fact, names): # merged replay log of one fact, and its CPU time + with open(os.path.join(LOGDIR, 'replay_' + fact + '.out'), 'w') as f: + for n in names: f.write('==> %s (exit %d) <==\n%s' % (n, rc(n), norm(job(n)))) + cpus[fact] = cpus.get(fact, 0) + sum(cpu(n) for n in names) + return all(rc(n) == 0 for n in names) +# ---------- s6-type logs (s66 / s6x): additive histograms and per-rep lines +OV6 = re.compile(r'max real rank (\d+), max #directions (\d+); rank histogram \(nonempty pairs\): (.*)') +def s6_summary(texts): + mr = md = 0; hist = [0] * 9; reps = {} + for t in texts: + for m in OV6.finditer(t): + mr = max(mr, int(m.group(1))); md = max(md, int(m.group(2))) + for kv in m.group(3).split(): + k, v = kv.split(':'); hist[int(k)] += int(v) + for m in re.finditer(r'^rep (\d+) lines (\d+) orbit (\d+) active (\d+) maxrank (\d+)', t, re.M): reps[int(m.group(1))] = m.groups()[1:] + return mr, md, hist[1:], reps +def check_s6(fact, tag, names, shipped, bound, nreps): + ok = merge(fact, names) + a = s6_summary([job(n) for n in names]); b = s6_summary([rd(os.path.join(LOGS, shipped))]) + same = a == b and len(a[3]) == nreps and a[0] <= bound + report(tag, ok and same, 'max real rank %d (bound %d), max #dirs %d, %d reps; rank histogram and per-rep lines %s the shipped log %s' % (a[0], bound, a[1], len(a[3]), 'equal' if a == b else 'DIFFER from', shipped)) + return a +# ---------- s3-type logs (s3f / s3x / s3y / s3z): additive pairs, survivors, max span +def s3_summary(texts): + pairs = surv = leaves = ovf = 0; span = 0; crack = 0; nrep = 0; hits = 0 + for t in texts: + for l in t.split('\n'): + if l.startswith('OVERALL'): + d = dict(re.findall(r'(pairs|surviving|leaves|overflow) (\d+)', l)); pairs += int(d['pairs']); surv += int(d['surviving']); leaves += int(d['leaves']); ovf += int(d['overflow']) + span = max(span, int(re.search(r'max span (\d+)', l).group(1))) + elif l.startswith('CRACK'): crack += 1 + elif l.startswith('HIT'): hits += 1 + elif l.startswith('rep '): nrep += 1 + return dict(pairs=pairs, surviving=surv, leaves=leaves, overflow=ovf, maxspan=span, cracks=crack, hits=hits, reps=nrep) +def shipped_chunks(pattern, n): return [rd(os.path.join(LOGS, pattern % r)) for r in range(n)] +def check_s3(fact, tag, prefix, shipped_pat, n, z_prefix=None, expect_reps=159): + names = [prefix + '_%d' % r for r in range(n)]; ok = merge(fact, names) + a = s3_summary([job(x) for x in names]); b = s3_summary(shipped_chunks(shipped_pat, n)) + ident = sum(norm(job(x)) == norm(t) for x, t in zip(names, shipped_chunks(shipped_pat, n))) + msg = '%d chunks, %d of them byte-identical to the shipped chunk logs; pairs %d, surviving pairs %d, cracks %d, max span %d (shipped: pairs %d, max span %d)' % (n, ident, a['pairs'], a['surviving'], a['cracks'], a['maxspan'], b['pairs'], b['maxspan']) + good = ok and a == b and a['reps'] == expect_reps and a['overflow'] == 0 + if z_prefix: + zn = [z_prefix + '_%d' % r for r in range(n)]; zok = merge(fact + '_s3z', zn); z = s3_summary([job(x) for x in zn]) + msg += '; independent s3z: pairs %d, surviving %d, max span %d, %s' % (z['pairs'], z['surviving'], z['maxspan'], 'EQUAL to s3f' if z == a else 'DIFFERS from s3f') + good = good and zok and z == a + report(tag, good, msg); return a +print('replay of the eight span facts (wall %s s)' % WALL) +# fact 1 +n1 = ['f1_s66_m1']; ok = merge('fact1_s66', n1) +same = norm(job('f1_s66_m1')).strip() == rd(os.path.join(LOGS, 'SIX/s66_m1.out')).strip() +report('fact 1 (6,6)+1 <= 3 [s66.c mode 1]', ok and same, 'output byte-identical to logs/SIX/s66_m1.out (max real rank 3, 0 rank-8 pairs)' if same else 'DIFFERS from logs/SIX/s66_m1.out') +nm = ['f1_indep_m1_c%d' % c for c in range(6)]; ok = merge('fact1_indep', nm); good = ok +mx = 0 +for c in range(6): + new = job(nm[c]); old = rd(os.path.join(LOGS, 'SIX/indep_m1_c%d.out' % c)) + pick = lambda t: sorted(l for l in t.split('\n') if l.startswith('INDEP OVERALL') or l.startswith('DONE REPS')) + if pick(new) != pick(old) or not pick(new): good = False + m = re.search(r'max real rank (\d+)', new); mx = max(mx, int(m.group(1))) if m else 99 +report('fact 1 (6,6)+1 <= 3 [indep.py mode 1, independent Python]', good and mx == 3, '6 chunks cover all 159 reps; INDEP OVERALL and DONE REPS lines equal the shipped chunk logs; max real rank %d' % mx) +# facts 2, 3, 4, 5 +check_s6('fact2', 'fact 2 (6,6)+2 <= 4 [s6x = s6y]', ['f2_y662_%d' % k for k in range(4)], 'SIX/y_662.out', 4, 159) +a = check_s6('fact3_y664', 'fact 3a (6,6)+4 lines relaxed, lim 80: span 8 on 6 pairs only [s6x]', ['f3_y664_%d' % k for k in range(8)], 'SIX/y_664.out', 8, 159) +r8 = sorted(k for k, v in a[3].items() if v[3] == '8') +ref = job('f3_r664'); refshipped = rd(os.path.join(LOGS, 'SIX/r_664.out')) +okr = merge('fact3_r664', ['f3_r664']) and ref.strip() == refshipped.strip() and re.search(r'REFINE max exact rank 4', ref) and r8 == [67, 68, 82] +report('fact 3b (6,6,3) s0 <= 4 [s6x exact third-flat refinement]', bool(okr), 'refinement of the relaxed-span-8 reps %s: REFINE max exact rank 4; output byte-identical to logs/SIX/r_664.out' % r8) +check_s6('fact4', 'fact 4 (7,4) s0 <= 4 [s6x]', ['f4_y740_%d' % k for k in range(4)], 'SIX/y_740.out', 4, 51) +check_s6('fact5', 'fact 5 (7,5) s0 <= 4 [s6x]', ['f5_y750_%d' % k for k in range(2)], 'MS3c/y_750.out', 4, 51) +nm = ['f5_p1y750_%d' % r for r in range(24)]; ok = merge('fact5_p1', nm); a = s3_summary([job(x) for x in nm]); b = s3_summary([rd(os.path.join(LOGS, 'DIRX/p1_y750.out'))]) +report('fact 5 (7,5) s0 |Off|<=88 extension [s3x pass 1]', ok and a['pairs'] == b['pairs'] == 146195478 and a['surviving'] == 0 and a['hits'] == 0, '%d pairs, %d surviving pairs, %d qualifying new directions (shipped log: %d pairs, %d surviving)' % (a['pairs'], a['surviving'], a['hits'], b['pairs'], b['surviving'])) +# fact 6 +a = check_s3('fact6_s3f', 'fact 6 (6,6,4) s0 <= 5 [s3f |Off|<=80, target 8]', 'f6_s3f_a664s0', 'S3FLAT/out_a664s0_%d.out', 24, 'z6_s3z_a664s0') +t6 = check_s3('fact6_t6', 'fact 6 (6,6,4) s0 <= 5 [s3y |Off|<=88, target 6: no crack => span <= 5]', 'f6_s3y_t6', 'SPANCOVER/664s0t6_%d.out', 48, 'z6_s3z_t6') +c5 = job('f6_s3y_t5_34'); z5 = job('z6_s3z_t5_34'); sh5 = rd(os.path.join(LOGS, 'SPANCOVER/664s0t5_34.out')) +pat = 'CRACK? target 5 span 5 rep 82 V2idx 103676' +ok5 = merge('fact6_t5', ['f6_s3y_t5_34', 'z6_s3z_t5_34']) and pat in c5 and pat in z5 and norm(c5) == norm(sh5) +report('fact 6 (6,6,4) s0: span exactly 5 [s3y and s3z, |Off|<=88, target 5, chunk 34]', bool(ok5), 'crack at target 5 (rep 82, V2idx 103676) found by both; s3y output identical to logs/SPANCOVER/664s0t5_34.out') +nm = ['f6_p1a664_%d' % r for r in range(24)]; ok = merge('fact6_p1', nm); a = s3_summary([job(x) for x in nm]) +report('fact 6 (6,6,4) s0 |Off|<=88 extension at target 8 [s3x pass 1; previously only in the DIRX card notes]', ok and a['pairs'] == 70064678 and a['surviving'] == 0 and a['hits'] == 0, '%d pairs, %d qualifying new directions' % (a['pairs'], a['hits'])) +# facts 7, 8 +check_s3('fact7', 'fact 7 (6,5,4)+1 <= 4 [s3f target 8]', 'f7_s3f_b654s1', 'S3FLAT/out_b654s1_%d.out', 24, 'z7_s3z_b654s1') +check_s3('fact8', 'fact 8 (6,4,4)+1 <= 4 [s3f target 8]', 'f8_s3f_b644s1', 'S3FLAT/out_b644s1_%d.out', 24, 'z8_s3z_b644s1') +tot = sum(cpus.values()) +print('CPU time (user+sys, s): ' + ', '.join('%s %.0f' % (k, v) for k, v in sorted(cpus.items())) + '; total %.0f s = %.1f CPU-min' % (tot, tot / 60)) +allok = all(status) +print(('PASS' if allok else 'FAIL') + ' %d of %d checks pass' % (sum(status), len(status))) +sys.exit(0 if allok else 1) diff --git a/research/one-sided-residue-closures/provenance/replay_spanfacts.sh b/research/one-sided-residue-closures/provenance/replay_spanfacts.sh new file mode 100644 index 0000000000..cb7957ef10 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/replay_spanfacts.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# Rerun the eight span facts of SPANFACTS.md from the shipped sources (provenance/src), compare with the shipped logs (provenance/logs). +# usage: bash provenance/replay_spanfacts.sh PYTHON=... (needs numpy) JOBS=4 (parallel processes, default 4) CC=cc +# LOGDIR=dir (per-fact replay logs and replay_summary.txt; default a fresh temporary directory; the shipped copy is provenance/logs/REPLAY) +# Every job is niced (10), runs under timeout 1200 s (a chunk is far below that: 3 s to 8 min), at most JOBS at a time. +# What is rerun (first implementation: the sources the facts were established with; second implementation where one exists): +# 1 (6,6)+1 <= 3 s66 mode 1 (C) and indep.py mode 1, 6 chunks (independent Python) +# 2 (6,6)+2 <= 4 s6x (= s6y), 4 rep-chunks +# 3 (6,6,3) s0 <= 4 s6x 6 6 4 lim 80, 8 rep-chunks, then the exact third-flat refinement on the 3 reps with relaxed span 8 (= s6r) +# 4 (7,4) s0 <= 4 s6x, 4 rep-chunks +# 5 (7,5) s0 <= 4 s6x, 2 rep-chunks; plus the |Off|<=88 extension pass (s3x NEWLO=80 PASS1=1, 24 chunks) +# 6 (6,6,4) s0 <= 5 s3f (|Off|<=80, target 8, 24 chunks) and s3y (|Off|<=88, target 6, 48 chunks: pass; target 5: the crack) and s3x pass 1 +# 7 (6,5,4)+1 <= 4 s3f target 8, 24 chunks +# 8 (6,4,4)+1 <= 4 s3f target 8, 24 chunks +# facts 6-8 are rerun a second time with the independent checker s3z (same chunks, same arguments) and compared. +set -uo pipefail +HERE=$(cd "$(dirname "$0")" && pwd); SRC="$HERE/src"; LOGS="$HERE/logs"; PY="${PYTHON:-python3}"; CC="${CC:-cc}"; JOBS="${JOBS:-4}" +LOGDIR="${LOGDIR:-${TMPDIR:-/tmp}/replay_logs.$$}" +export PYTHONDONTWRITEBYTECODE=1 OMP_NUM_THREADS=1 VECLIB_MAXIMUM_THREADS=1 OPENBLAS_NUM_THREADS=1 +"$PY" -c "import numpy" 2>/dev/null || { echo "FAIL python needs numpy (PYTHON=...)"; exit 1; } +command -v "$CC" >/dev/null || { echo "FAIL needs a C compiler"; exit 1; } +W=$(mktemp -d "${TMPDIR:-/tmp}/replay.XXXXXX"); mkdir -p "$W/work" "$W/out" "$W/gen77" "$W/gen80" "$W/gen88" "$LOGDIR"; T0=$SECONDS +echo "== build and direction data (work dir $W)" +for p in s66 s6x s3f s3x s3y s3z; do "$CC" -O2 -o "$W/work/$p" "$SRC/$p.c" 2>"$W/cc_$p.log" || { echo "FAIL compile $p.c"; cat "$W/cc_$p.log"; exit 1; }; done +OUT="$W/gen77" "$PY" -B "$SRC/gen.py" 77 > "$W/gen77.log" 2>&1 & +OUT="$W/gen80" "$PY" -B "$SRC/gen.py" 80 > "$W/gen80.log" 2>&1 & +OUT="$W/gen88" "$PY" -B "$SRC/gen88.py" 88 > "$W/gen88.log" 2>&1 & +wait +cp "$W/gen77/data.txt" "$W/gen80/data80.txt" "$W/gen88/data88.txt" "$W/gen80/gens.txt" "$W/work/" +bad=0 +cmp -s "$W/gen80/gens.txt" "$HERE/data/gens.txt" || { echo "FAIL generated gens.txt differs from data/gens.txt"; bad=1; } +gzip -dc "$HERE/data/data88.txt.gz" | cmp -s - "$W/work/data88.txt" || { echo "FAIL generated data88.txt differs from data/data88.txt.gz"; bad=1; } +cmp -s <(head -n 114 "$W/work/data80.txt") <(head -n 114 "$W/work/data88.txt") || { echo "FAIL data80/data88 headers differ"; bad=1; } +[ $bad = 0 ] && echo "PASS direction lists regenerated (gen.py 77/80, gen88.py 88): data.txt, data80.txt, data88.txt, gens.txt; data88.txt and gens.txt equal the shipped copies" +# ---- job list: one line per job: NAMEcommand (run in $W/work) +J="$W/jobs.lst"; : > "$J" +job() { printf '%s\t%s\n' "$1" "$2" >> "$J"; } +reps() { local k=$1 n=$2 s="" i; for ((i=k;i<159;i+=n)); do s="$s,$i"; done; echo "${s#,}"; } +reps51() { local k=$1 n=$2 s="" i; for ((i=k;i<51;i+=n)); do s="$s,$i"; done; echo "${s#,}"; } +job f1_s66_m1 "./s66 1" +for c in 0 1 2 3 4 5; do job f1_indep_m1_c$c "$PY -B $SRC/indep.py 1 $c 6"; done +for k in 0 1 2 3; do job f2_y662_$k "./s6x data80.txt 6 6 2 78 $(reps $k 4)"; done +for k in 0 1 2 3 4 5 6 7; do job f3_y664_$k "./s6x data80.txt 6 6 4 80 $(reps $k 8)"; done +job f3_r664 "./s6x data80.txt 6 6 4 80 67,68,82 8" +for k in 0 1 2 3; do job f4_y740_$k "./s6x data80.txt 7 4 0 80 $(reps51 $k 4)"; done +for k in 0 1; do job f5_y750_$k "./s6x data80.txt 7 5 0 80 $(reps51 $k 2)"; done +for r in $(seq 0 23); do + job f5_p1y750_$r "NEWLO=80 PASS1=1 ./s3x data88.txt 7 5 0 0 88 8 24 $r" + job f6_p1a664_$r "NEWLO=80 PASS1=1 ./s3x data88.txt 6 6 4 0 88 8 24 $r" + job f6_s3f_a664s0_$r "./s3f data80.txt 6 6 4 0 80 8 24 $r" + job f7_s3f_b654s1_$r "./s3f data80.txt 6 5 4 1 80 8 24 $r" + job f8_s3f_b644s1_$r "./s3f data80.txt 6 4 4 1 80 8 24 $r" + job z6_s3z_a664s0_$r "./s3z data80.txt 6 6 4 0 80 8 24 $r" + job z7_s3z_b654s1_$r "./s3z data80.txt 6 5 4 1 80 8 24 $r" + job z8_s3z_b644s1_$r "./s3z data80.txt 6 4 4 1 80 8 24 $r" +done +for r in $(seq 0 47); do + job f6_s3y_t6_$r "./s3y data88.txt 6 6 4 0 88 6 48 $r" + job z6_s3z_t6_$r "./s3z data88.txt 6 6 4 0 88 6 48 $r" +done +job f6_s3y_t5_34 "EXITCRACK=1 ./s3y data88.txt 6 6 4 0 88 5 48 34" +job z6_s3z_t5_34 "EXITCRACK=1 ./s3z data88.txt 6 6 4 0 88 5 48 34" +# long jobs first (indep, s6x, s66), then the many small chunks +sort -s -k1,1 "$J" | awk -F'\t' '{p=($1 ~ /^f1_indep|^f3_y664|^f4_y740|^f1_s66/)?0:1; print p"\t"$0}' | sort -s -n -k1,1 | cut -f2- > "$W/jobs.sorted" +cat > "$W/run1.sh" <<'EOS' +#!/usr/bin/env bash +# run1.sh WORKDIR OUTDIR NAME TIMEOUT PY CMD... (CMD is one string run via eval, with PY set) +W=$1; O=$2; n=$3; T=$4; PY=$5; cmd=$6; cd "$W" || exit 1; export PY +TIMEFORMAT='%U %S' +{ time timeout "$T" nice -n 10 bash -c "$cmd" > "$O/$n.out" 2> "$O/$n.err"; echo $? > "$O/$n.rc"; } 2> "$O/$n.cpu" +EOS +chmod +x "$W/run1.sh" +echo "== running $(wc -l < "$J") jobs, $JOBS at a time" +while IFS=$'\t' read -r n c; do printf '%s\0' "$n"; printf '%s\0' "$c"; done < "$W/jobs.sorted" | + xargs -0 -n 2 -P "$JOBS" bash -c '"$0"/run1.sh "$0"/work "$0"/out "$1" 1200 "'"$PY"'" "$2"' "$W" +WALL=$((SECONDS - T0)) +echo "== compare" +"$PY" -B "$HERE/replay_compare.py" "$W/out" "$LOGS" "$LOGDIR" "$WALL" | tee "$W/summary.txt" +cp "$W/summary.txt" "$LOGDIR/replay_summary.txt" +grep -q '^FAIL' "$W/summary.txt" || [ $bad != 0 ] && { echo "REPLAY FAIL (work dir $W)"; exit 1; } +echo "REPLAY PASS (wall ${WALL}s)"; rm -rf "$W" diff --git a/research/one-sided-residue-closures/provenance/reproduce.sh b/research/one-sided-residue-closures/provenance/reproduce.sh new file mode 100644 index 0000000000..fd51322908 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/reproduce.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Provenance check for data/rows_input.csv. usage: bash provenance/reproduce.sh PYTHON=... FULL=1 (also reruns generator/land7.py, about 6 minutes, needs numpy+scipy) +set -uo pipefail +HERE=$(cd "$(dirname "$0")" && pwd); PY="${PYTHON:-python3}"; export PYTHONDONTWRITEBYTECODE=1 +OUT=$(mktemp -d "${TMPDIR:-/tmp}/prov.XXXXXX") +SRC="$HERE/generator/land7.out" +if [ "${FULL:-0}" = 1 ]; then + echo "== rerun land7.py 7 (about 6 min)"; "$PY" -B "$HERE/generator/land7.py" 7 > "$OUT/land7.out" || { echo "FAIL land7.py"; exit 1; } + cmp -s "$OUT/land7.out" "$HERE/generator/land7.out" && echo "PASS land7 rerun identical to recorded land7.out" || { echo "FAIL land7 rerun differs from recorded land7.out"; exit 1; } + SRC="$OUT/land7.out" +fi +echo "== dominance filter on $(basename "$SRC")" +OUT="$OUT" "$PY" -B "$HERE/dominance_filter.py" "$SRC" || { echo "FAIL filter"; exit 1; } +"$PY" -B "$HERE/check_rows.py" "$OUT/open_rows.json" diff --git a/research/one-sided-residue-closures/provenance/src/gen.py b/research/one-sided-residue-closures/provenance/src/gen.py new file mode 100644 index 0000000000..265fc72466 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/src/gen.py @@ -0,0 +1,144 @@ +# SIX: independent data generation (own coordinates, own labels, own direction list, own group/orbits). +# Coordinates doubled (integers). E8 = D8 ∪ D8+(1/2)^8, roots norm 2 -> doubled norm 8. +import itertools, numpy as np, sys, random +from fractions import Fraction +import os; OUT=os.environ.get('OUT','./').rstrip('/')+'/' +LIM=int(sys.argv[1]) if len(sys.argv)>1 else 77 +DATA='data.txt' if LIM==77 else 'data%d.txt'%LIM +roots=[] +for i,j in itertools.combinations(range(8),2): + for si in (2,-2): + for sj in (2,-2): + v=[0]*8; v[i]=si; v[j]=sj; roots.append(tuple(v)) +for s in itertools.product((1,-1),repeat=8): + if s.count(-1)%2==0: roots.append(tuple(s)) +assert len(roots)==240 +def dot(a,b): return sum(x*y for x,y in zip(a,b))//4 # true inner product (doubled coords) +lines=sorted({max(r,tuple(-x for x in r)) for r in roots}); assert len(lines)==120 +frame=[] +for k in range(4): + a=[0]*8; a[2*k]=2; a[2*k+1]=2; frame.append(tuple(a)) + b=[0]*8; b[2*k]=2; b[2*k+1]=-2; frame.append(tuple(b)) +frame=[max(f,tuple(-x for x in f)) for f in frame] +for f,g in itertools.combinations(frame,2): assert dot(f,g)==0 +P=[l for l in lines if l not in frame]; assert len(P)==112 +# labels: coordinates of r in a Z-basis of E8, mod 2; basis = simple roots (Bourbaki, doubled) +simple=[(1,-1,-1,-1,-1,-1,-1,1),(2,2,0,0,0,0,0,0),(-2,2,0,0,0,0,0,0),(0,-2,2,0,0,0,0,0),(0,0,-2,2,0,0,0,0),(0,0,0,-2,2,0,0,0),(0,0,0,0,-2,2,0,0),(0,0,0,0,0,-2,2,0)] +M=np.array(simple,dtype=float).T +assert abs(abs(np.linalg.det(np.array([[dot(a,b) for b in simple] for a in simple],dtype=float)))-1)<1e-9 +def lab(r): + n=np.linalg.solve(M,np.array(r,dtype=float)); ni=np.rint(n).astype(int); assert np.allclose(n,ni) + x=1 + for k in range(8): x|=(int(ni[k])&1)<<(k+1) + return x +LAB=[lab(r) for r in P]; assert len(set(LAB))==112 +ZL=[lab(f) for f in frame] +# F2 rank of all labels =9 +def f2rank(vs): + bs=[] + for x in vs: + for b in bs: x=min(x,x^b) + if x: bs.append(x) + return len(bs) +assert f2rank(LAB)==9 +# directions: E8 vectors of norm <= 8 (doubled norm <=32), primitive up to sign +vecs=set() +rng2=range(-6,7,2); rng1=range(-5,6,2) +for v in itertools.product(rng2,repeat=8): + if 0 doubled coords even, sum(v)/2 even. half: v odd, sum(v/2) even. +def prim(v): + from math import gcd + g=0 + for x in v: g=gcd(g,abs(x)) + v=tuple(x//g for x in v) + return max(v,tuple(-x for x in v)) +dirs={} +for v in vecs: + p=prim(v); dirs.setdefault(p,v) +def off(h): return [t for t,r in enumerate(P) if sum(a*b for a,b in zip(r,h))!=0] +fin=[] +from collections import Counter +C=Counter() +for p,v in dirs.items(): + o=off(p) + if len(o)<=LIM: + nE8=sum(1 for l in lines if sum(a*b for a,b in zip(l,p))==0) + C[(sum(x*x for x in v)//4,nE8,len(o))]+=1; fin.append((p,o)) +print('finite directions |Off|<=77 by (norm,E8 lines perp,|Off|):',sorted(C.items())) +# pencils: A2 planes span(a,b), a.b=-1 ; generic Off = lines not perp to both +pen={} +for a,b in itertools.combinations(lines,2): + if abs(dot(a,b))==1: + perp=frozenset(t for t,r in enumerate(P) if dot(r,a)==0 and dot(r,b)==0) + key=frozenset(l for l in lines if dot(l,a)==0 and dot(l,b)==0) + pen.setdefault(key,(a,b,perp)) +pens=[] +CP=Counter() +for key,(a,b,perp) in pen.items(): + o=[t for t in range(112) if t not in perp] + CP[(len(key),len(o))]+=1 + if len(o)<=LIM: pens.append((a,b,o)) +print('A2 planes (E8 lines perp, generic |Off|):',sorted(CP.items())) +with open(OUT+DATA,'w') as f: + f.write(' '.join(map(str,LAB))+'\n') + f.write(' '.join(map(str,ZL))+'\n') + for r in P: f.write(' '.join(map(str,r))+'\n') + f.write('%d\n'%(len(fin)+len(pens))) + for p,o in fin: f.write('1 '+' '.join(map(str,p))+' : '+' '.join(map(str,o))+'\n') + for a,b,o in pens: f.write('2 '+' '.join(map(str,a))+' '+' '.join(map(str,b))+' : '+' '.join(map(str,o))+'\n') +print('wrote',len(fin),'finite',len(pens),'pencils') +# group: sign flips (reflections in frame roots) and coordinate-permutations of frame preserving supports +def refl(f): + return lambda r: tuple(x - (2*sum(a*b for a,b in zip(r,f))//sum(y*y for y in f))*y for x,y in zip(r,f)) +idx={r:t for t,r in enumerate(P)} +def lineperm(g): + out=[] + for r in P: + s=g(r); s=max(s,tuple(-x for x in s)); out.append(idx[s]) + return out +gens=[lineperm(refl(f)) for f in frame] +# permutation part: c-coordinates c_j = r.f_j ; map c -> c∘pi^{-1}; r = sum c_j f_j /2 +Fm=np.array(frame,dtype=float) +def cvec(r): return [dot(r,f) for f in frame] +supps={frozenset(j for j,c in enumerate(cvec(r)) if c) for r in P} +assert len(supps)==14 and all(len(s)==4 for s in supps) +auts=[pi for pi in itertools.permutations(range(8)) if all(frozenset(pi[j] for j in s) in supps for s in supps)] +print('Aut(Hamming) order',len(auts)) +random.seed(1) +def mk(pi): + def g(r): + c=cvec(r); c2=[0]*8 + for j in range(8): c2[pi[j]]=c[j] + v=sum(c2[j]*Fm[j] for j in range(8))/2 + vi=tuple(int(round(x)) for x in v); return vi + return g +for _ in range(4): gens.append(lineperm(mk(random.choice(auts)))) +# check group size generated on lines +import collections +def gsize(gens,limit=10**6): + I=tuple(range(112)); seen={I}; st=[I] + while st: + x=st.pop() + for g in gens: + y=tuple(g[i] for i in x) + if y not in seen: + seen.add(y); st.append(y) + if len(seen)>limit: return -1 + return len(seen) +print('group order on lines',gsize(gens)) +# label linearity of each generator: map must be induced by a linear map of F2^9 +for g in gens: + # solve linear map from a basis of labels + bs=[];imgs=[] + for t in range(112): + x=LAB[t]; y=LAB[g[t]]; xx=x; yy=y + for b,ib in zip(bs,imgs): + if (xx^b) doubled norm 8. +import itertools, numpy as np, sys, random +from fractions import Fraction +import os; OUT=os.environ.get('OUT','./').rstrip('/')+'/' +LIM=int(sys.argv[1]) if len(sys.argv)>1 else 77 +DATA='data%d.txt'%LIM +roots=[] +for i,j in itertools.combinations(range(8),2): + for si in (2,-2): + for sj in (2,-2): + v=[0]*8; v[i]=si; v[j]=sj; roots.append(tuple(v)) +for s in itertools.product((1,-1),repeat=8): + if s.count(-1)%2==0: roots.append(tuple(s)) +assert len(roots)==240 +def dot(a,b): return sum(x*y for x,y in zip(a,b))//4 # true inner product (doubled coords) +lines=sorted({max(r,tuple(-x for x in r)) for r in roots}); assert len(lines)==120 +frame=[] +for k in range(4): + a=[0]*8; a[2*k]=2; a[2*k+1]=2; frame.append(tuple(a)) + b=[0]*8; b[2*k]=2; b[2*k+1]=-2; frame.append(tuple(b)) +frame=[max(f,tuple(-x for x in f)) for f in frame] +for f,g in itertools.combinations(frame,2): assert dot(f,g)==0 +P=[l for l in lines if l not in frame]; assert len(P)==112 +# labels: coordinates of r in a Z-basis of E8, mod 2; basis = simple roots (Bourbaki, doubled) +simple=[(1,-1,-1,-1,-1,-1,-1,1),(2,2,0,0,0,0,0,0),(-2,2,0,0,0,0,0,0),(0,-2,2,0,0,0,0,0),(0,0,-2,2,0,0,0,0),(0,0,0,-2,2,0,0,0),(0,0,0,0,-2,2,0,0),(0,0,0,0,0,-2,2,0)] +M=np.array(simple,dtype=float).T +assert abs(abs(np.linalg.det(np.array([[dot(a,b) for b in simple] for a in simple],dtype=float)))-1)<1e-9 +def lab(r): + n=np.linalg.solve(M,np.array(r,dtype=float)); ni=np.rint(n).astype(int); assert np.allclose(n,ni) + x=1 + for k in range(8): x|=(int(ni[k])&1)<<(k+1) + return x +LAB=[lab(r) for r in P]; assert len(set(LAB))==112 +ZL=[lab(f) for f in frame] +# F2 rank of all labels =9 +def f2rank(vs): + bs=[] + for x in vs: + for b in bs: x=min(x,x^b) + if x: bs.append(x) + return len(bs) +assert f2rank(LAB)==9 +# directions: E8 vectors of norm <= 8 (doubled norm <=32), primitive up to sign +vecs=set() +rng2=range(-6,7,2); rng1=range(-5,6,2) +for v in itertools.product(rng2,repeat=8): + if 0 doubled coords even, sum(v)/2 even. half: v odd, sum(v/2) even. +def prim(v): + from math import gcd + g=0 + for x in v: g=gcd(g,abs(x)) + v=tuple(x//g for x in v) + return max(v,tuple(-x for x in v)) +dirs={} +for v in vecs: + p=prim(v); dirs.setdefault(p,v) +def off(h): return [t for t,r in enumerate(P) if sum(a*b for a,b in zip(r,h))!=0] +fin=[] +from collections import Counter +C=Counter() +for p,v in dirs.items(): + o=off(p) + if len(o)<=LIM: + nE8=sum(1 for l in lines if sum(a*b for a,b in zip(l,p))==0) + C[(sum(x*x for x in v)//4,nE8,len(o))]+=1; fin.append((p,o)) +print('finite directions |Off|<=77 by (norm,E8 lines perp,|Off|):',sorted(C.items())) +# pencils: A2 planes span(a,b), a.b=-1 ; generic Off = lines not perp to both +pen={} +for a,b in itertools.combinations(lines,2): + if abs(dot(a,b))<=1: + perp=frozenset(t for t,r in enumerate(P) if dot(r,a)==0 and dot(r,b)==0) + key=frozenset(l for l in lines if dot(l,a)==0 and dot(l,b)==0) + pen.setdefault(key,(a,b,perp,abs(dot(a,b)))) +pens=[] +CP=Counter() +for key,(a,b,perp,tp) in pen.items(): + o=[t for t in range(112) if t not in perp] + CP[('A2' if tp else 'A1A1',len(key),len(o))]+=1 + if len(o)<=LIM: pens.append((a,b,o,tp)) +print('A2 planes (E8 lines perp, generic |Off|):',sorted(CP.items())) +with open(OUT+DATA,'w') as f: + f.write(' '.join(map(str,LAB))+'\n') + f.write(' '.join(map(str,ZL))+'\n') + for r in P: f.write(' '.join(map(str,r))+'\n') + f.write('%d\n'%(len(fin)+len(pens))) + for p,o in fin: f.write('1 '+' '.join(map(str,p))+' : '+' '.join(map(str,o))+'\n') + for a,b,o,tp in pens: f.write('2 '+' '.join(map(str,a))+' '+' '.join(map(str,b))+' : '+' '.join(map(str,o))+'\n') +print('wrote',len(fin),'finite',len(pens),'pencils') +# group: sign flips (reflections in frame roots) and coordinate-permutations of frame preserving supports +def refl(f): + return lambda r: tuple(x - (2*sum(a*b for a,b in zip(r,f))//sum(y*y for y in f))*y for x,y in zip(r,f)) +idx={r:t for t,r in enumerate(P)} +def lineperm(g): + out=[] + for r in P: + s=g(r); s=max(s,tuple(-x for x in s)); out.append(idx[s]) + return out +gens=[lineperm(refl(f)) for f in frame] +# permutation part: c-coordinates c_j = r.f_j ; map c -> c∘pi^{-1}; r = sum c_j f_j /2 +Fm=np.array(frame,dtype=float) +def cvec(r): return [dot(r,f) for f in frame] +supps={frozenset(j for j,c in enumerate(cvec(r)) if c) for r in P} +assert len(supps)==14 and all(len(s)==4 for s in supps) +auts=[pi for pi in itertools.permutations(range(8)) if all(frozenset(pi[j] for j in s) in supps for s in supps)] +print('Aut(Hamming) order',len(auts)) +random.seed(1) +def mk(pi): + def g(r): + c=cvec(r); c2=[0]*8 + for j in range(8): c2[pi[j]]=c[j] + v=sum(c2[j]*Fm[j] for j in range(8))/2 + vi=tuple(int(round(x)) for x in v); return vi + return g +for _ in range(4): gens.append(lineperm(mk(random.choice(auts)))) +# check group size generated on lines +import collections +def gsize(gens,limit=10**6): + I=tuple(range(112)); seen={I}; st=[I] + while st: + x=st.pop() + for g in gens: + y=tuple(g[i] for i in x) + if y not in seen: + seen.add(y); st.append(y) + if len(seen)>limit: return -1 + return len(seen) +print('group order on lines',gsize(gens)) +# label linearity of each generator: map must be induced by a linear map of F2^9 +for g in gens: + # solve linear map from a basis of labels + bs=[];imgs=[] + for t in range(112): + x=LAB[t]; y=LAB[g[t]]; xx=x; yy=y + for b,ib in zip(bs,imgs): + if (xx^b)2 else 0; NCH=int(sys.argv[3]) if len(sys.argv)>3 else 1 # 0: |Off|<=76, X = Λ(V1)∪Λ(V2); 1: |Off|<=77, plus one free line per h +# Hamming [8,4,4] supports +G=[0b11110000,0b11001100,0b10101010,0b11111111] +code=set() +for m in range(16): + x=0 + for i in range(4): + if m>>i&1: x^=G[i] + code.add(x) +supp4=[c for c in code if bin(c).count('1')==4]; assert len(supp4)==14 +# roots in c-coords (c_j = ): frame roots 2e_j, others ±1 on a weight-4 support; = c.c'/2 +R=[] +for j in range(8): + v=[0]*8; v[j]=2; R.append(tuple(v)); R.append(tuple(-x for x in v)) +for s in supp4: + pos=[j for j in range(8) if s>>j&1] + for sg in itertools.product((1,-1),repeat=4): + v=[0]*8 + for p,g in zip(pos,sg): v[p]=g + R.append(tuple(v)) +assert len(R)==240 +ip=lambda a,b: Fraction(sum(x*y for x,y in zip(a,b)),2) +for r in R: assert ip(r,r)==2 +assert all(ip(a,b).denominator==1 for a in R[:40] for b in R) +canon=lambda v: max(tuple(v),tuple(-x for x in v)) +P=sorted({canon(r) for r in R if sum(1 for x in r if x)==4}); assert len(P)==112 +# labels: (1, mod 2) for a unimodular basis b of E8 made of roots +random.seed(7) +while True: + B=random.sample(R,8) + Gm=np.array([[float(ip(a,b)) for b in B] for a in B]) + if abs(abs(np.linalg.det(Gm))-1)<1e-6: break +LAB=[1|sum(((int(ip(r,b))&1)<<(k+1)) for k,b in enumerate(B)) for r in P] +assert len(set(LAB))==112 +# directions: primitive vectors h (in c-coords, up to scale) from sums of pairwise orthogonal roots (1,2,3 roots) +def prim(v): + from math import gcd + g=0 + for x in v: g=gcd(g,abs(int(x))) + return canon([int(x)//g for x in v]) +vecs={1:set(),2:set(),3:set()} +Rl=R +for a in Rl: vecs[1].add(a) +for a,b in itertools.combinations(Rl,2): + if ip(a,b)==0: vecs[2].add(tuple(x+y for x,y in zip(a,b))) +orth={a:[b for b in Rl if ip(a,b)==0] for a in Rl} +for a in Rl: + for b in orth[a]: + for c in orth[a]: + if ip(b,c)==0 and b>64) +# parity table +par=np.array([[bin(w&l).count('1')&1 for l in LAB] for w in range(512)],dtype=bool) +def lines_of_dual(ws): + ok=np.ones(112,dtype=bool) + for w in ws: ok&=~par[w] + m=0 + for t in np.nonzero(ok)[0]: m|=1< piv[i] zero), zero at other pivots, free at non-pivot bits < piv[i] + free=[[b for b in range(piv[i]) if b not in piv] for i in range(3)] + for bits in itertools.product(*[range(1<>k&1: w|=1<>j&1) in code for s in supp4)] +pidx={r:t for t,r in enumerate(P)} +def act(fn): return [pidx[canon(fn(r))] for r in P] +gens=[act(lambda r,j=j: tuple(-x if k==j else x for k,x in enumerate(r))) for j in range(8)] +random.seed(3) +for _ in range(3): + pi=random.choice(auts) + gens.append(act(lambda r,pi=pi: tuple(r[pi.index(k)] for k in range(8)))) +# byte tables for fast mask mapping +def table(g): + T=[] + for byte in range(14): + row=[] + for v in range(256): + o=0 + for b in range(8): + if v>>b&1 and byte*8+b<112: o|=1<>=8; k+=1 + return o +parent=list(range(len(masks))) +def fd(x): + while parent[x]!=x: parent[x]=parent[parent[x]]; x=parent[x] + return x +for i,m in enumerate(masks): + for T in TB: + j=idx[mp(m,T)]; a,b=fd(i),fd(j) + if a!=b: parent[a]=b +reps=[i for i in range(len(masks)) if fd(i)==i] +print('orbits',len(reps)) +X2=np.array([split(m) for m in masks],dtype=np.uint64) +def f2rank(m): + bs=[] + t=0 + while m: + if m&1: + x=LAB[t] + for b in bs: x=min(x,x^b) + if x: bs.append(x) + m>>=1; t+=1 + return len(bs) +def ok_h(m): + if mode==0: return f2rank(m)<=7 + # rank(R minus one line) <= 7 <=> rank(R) <= 7, or rank(R) = 8 and some hyperplane of span(R) misses at most one line of R + labs=[LAB[t] for t in range(112) if m>>t&1] + bs=[]; + for x in labs: + for b in bs: x=min(x,x^b) + if x: bs.append(x) + r=len(bs) + if r<=7: return True + if r>8: return False + # coordinates w.r.t. a basis chosen among the labels: Gaussian elimination tracking combinations + piv=[] # (pivot vector reduced, coord bitmask) + for x in labs: + c=0; y=x + for (pv,pc) in piv: + if (y^pv)cap[hi]+20+slack: continue + a=np.array(split(r1),dtype=np.uint64) + rr=np.empty_like(X2); rr[:,0]=a[0]&~X2[:,0]; rr[:,1]=a[1]&~X2[:,1] + cand=np.nonzero(pcarr(rr)<=cap[hi]+slack)[0] + for j in cand: + rm=int(rr[j,0])|(int(rr[j,1])<<64) + if ok_h(rm): hits.setdefault(int(j),[]).append(h) + for j,hs in hits.items(): + bestn=max(bestn,len(hs)) + best=max(best,qrank(hs)) + if ri%20==0: print('rep',ri,'running max rank',best,'max #h',bestn,flush=True) +print('DONE REPS',done) +print('INDEP OVERALL mode',mode,'chunk',CH,NCH,': max real rank',best,'max #directions',bestn) diff --git a/research/one-sided-residue-closures/provenance/src/s3f.c b/research/one-sided-residue-closures/provenance/src/s3f.c new file mode 100644 index 0000000000..c9c7cc83f0 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/src/s3f.c @@ -0,0 +1,134 @@ +// S3FLAT (single implementation, C): three label flats of dims a,b,c + s free lines (per-direction, relaxed superset). +// Direction h qualifies iff Off(h) \ (L(V1) u L(V2) u L(V3)) minus <= s lines lies in a 7-flat G (rank_F2 <= 7). +// Redesign vs MS3c/s3.c: +// (1) V1 over frame-group orbit reps; V2 over all, with symmetric-pair reduction (orbit(V2) >= orbit(V1)) when a==b; +// (2) V3 is NOT enumerated: for each direction h and 7-flat G, D = Off(h)\(X1 u X2 u G) must lie (minus s lines) in a c-dim flat, +// i.e. rank_F2(l(D\T)) <= c -> requirement subspace S_{h,G}. Per (V1,h) the G's are precomputed as maximal masks r1&G; +// (3) V3 = closure of sums of requirement subspaces (dim <= c); evaluated at leaves; incremental real rank stops at 8. +// usage: s3f data a b c s lim target mod rem [env NOSYM=1 disables pair symmetry; ONLY=ri,ri,..] +#include +#include +#include +typedef unsigned __int128 u128; typedef unsigned long long u64; +int LAB[112]; int PC[112][8]; int ND; int hv[7000][8]; int hv2[7000][8]; int htyp[7000]; u128 OFF[7000]; int cap[7000]; +static inline int pc(u128 x){ return __builtin_popcountll((u64)x)+__builtin_popcountll((u64)(x>>64)); } +long long gcdll(long long a,long long b){ if(a<0)a=-a; if(b<0)b=-b; while(b){ long long t=a%b; a=b; b=t;} return a; } +// exact integer real rank of direction vectors (pencils contribute two vectors); stops at 8 +int realrank(int *list0,int n0){ long long Bm[8][8]; int piv[8]; int r=0; + for(int ii=0;ii1) for(int k=0;k<8;k++) v[k]/=g; again=1; } } } + int p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; + for(int k=0;k<8;k++) Bm[r][k]=v[k]; piv[r]=p; r++; if(r==8) return 8; } } + return r; } +// ---------- subspaces (dual enumeration as in s66.c) +u128 *SUB; int NS=0; +int cmp128(const void*a,const void*b){ u128 x=*(u128*)a,y=*(u128*)b; return xy; } +static inline int par(int x){ return __builtin_popcount(x)&1; } +int gens[16][112]; int NG=0; +u128 mapmask(u128 m,int g){ u128 o=0; for(int t=0;t<112;t++) if((m>>t)&1) o|=((u128)1)<=0;k--){ if(!((x>>k)&1)) continue; if(B[k]) x^=B[k]; else { B[k]=x; r++; break; } } } + for(int k=0;k<9;k++) if(B[k]) for(int j=k+1;j<9;j++) if(B[j]&&((B[j]>>k)&1)) B[j]^=B[k]; + int m=0; for(int k=8;k>=0;k--) if(B[k]) out[m++]=B[k]; return m; } +u64 packkey(int *b,int n){ u64 key=0; for(int i=0;i>=9; } for(int i=0;i c +int spankey(u128 D,int c,u64 *key){ int vs[112]; int n=0; for(int t=0;t<112;t++) if((D>>t)&1) vs[n++]=LAB[t]; int b[9]; int m=rrefv(vs,n,b); if(m>c) return 99; *key=packkey(b,m); return m; } +void membmap(int *b,int n,u64 *mem){ for(int i=0;i<8;i++) mem[i]=0; int el[64]; int ne=1; el[0]=0; for(int i=0;i>6]|=1ULL<<(el[j]&63); } +// requirement subspaces for (D, s, c): span(D) and spans after removing <= s (<=2) lines, those of dim <= c +int reqs(u128 D,int s,int c,u64 *outk,int maxo){ int no=0; u64 key; int d=spankey(D,c,&key); if(d<=c){ outk[no++]=key; if(s==0||d==0) return no; } + if(s==0) return no; + int lines[112]; int nl=0; for(int t=0;t<112;t++) if((D>>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;j>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;jcap=cap; h->n=0; h->k=calloc(cap,sizeof(u64)); } +int hs_add(HS*h,u64 key){ u64 kx=key+1; u64 x=(kx*0x9E3779B97F4A7C15ULL)>>20; int p=x%h->cap; while(h->k[p]){ if(h->k[p]==kx) return 0; p=(p+1)%h->cap; } h->k[p]=kx; h->n++; return 1; } +int cmpu64(const void*a,const void*b){ u64 x=*(u64*)a,y=*(u64*)b; return xy; } +int main(int argc,char**argv){ + const char*df=argv[1]; int adim=atoi(argv[2]), bdim=atoi(argv[3]), cdim=atoi(argv[4]), s=atoi(argv[5]), lim=atoi(argv[6]), target=atoi(argv[7]); + int mod=argc>8?atoi(argv[8]):1, rem=argc>9?atoi(argv[9]):0; int nosym=getenv("NOSYM")!=NULL; + int only[200]; int nonly=0; if(getenv("ONLY")){ char*p=getenv("ONLY"); while(*p){ only[nonly++]=strtol(p,&p,10); if(*p==',') p++; } } + int gw[10]={0,1,2,4,8,12,20,36,64,112}; + FILE*f=fopen(df,"r"); for(int i=0;i<112;i++) fscanf(f,"%d",&LAB[i]); int z; for(int i=0;i<8;i++) fscanf(f,"%d",&z); + for(int i=0;i<112;i++) for(int k2=0;k2<8;k2++) fscanf(f,"%d",&PC[i][k2]); + int nn; fscanf(f,"%d",&nn); ND=0; + for(int i=0;ib) b=c; } cap[h]=b; } + int na_,nb_; u128 *A=enumsub(adim,&na_); int sameAB=(adim==bdim); u128 *Bs; if(sameAB){ Bs=A; nb_=na_; } else { Bs=enumsub(bdim,&nb_); } + SUB=A; NS=na_; + fprintf(stderr,"dirs %d gens %d V1 %d V2 %d\n",ND,NG,na_,nb_); + uf=malloc(sizeof(int)*NS); for(int i=0;icap[h]+thr1) continue; + int nt=0; for(int g=0;gcp) cp=c; } capr[na]=cp; act[na]=h; R1[na]=r; na++; } + fprintf(stderr,"rep %d setup done: active %d avgL %.1f\n",ri,na,na?(double)sumL/na:0.0); + for(int j=0;jcapr[a]+thr2) continue; int ok=0; u128 *L=LG[a]; for(int q=0;qthr2) continue; if(feasible(D,s,cdim)){ ok=1; break; } } + if(ok){ cand[nc]=act[a]; candi[nc]=a; R2[nc]=r; nc++; } } + npair++; if(nc==0) continue; + int ub=realrank(cand,nc); if(ubthr2) continue; int nk=reqs(D,s,cdim,tk,1024); for(int e=0;ecdim) continue; if(dn==wn) continue; grew=1; u64 nk=packkey(ob,dn); if(hs_add(&hs,nk)){ if(nw<(1<<21)) W[nw++]=nk; else overflow=1; } } + if(overflow) break; + if(!grew){ nleaf++; u64 mem[8]; membmap(wb,wn,mem); int list[512]; int n=0; + for(int ci=0;ci>6]>>(sb[i]&63))&1)){ inside=0; break; } if(inside) ok=1; } if(ok && n<512) list[n++]=cand[ci]; } + if(n){ int rk=realrank(list,n); hist[rk]++; if(rk>vmax) vmax=rk; if(rk>pairbest) pairbest=rk; + if(rk>=target){ printf("CRACK? target %d span %d rep %d V2idx %d X1=%016llx%016llx X2=%016llx%016llx Wkey=%llx dim %d n %d dirs:",target,rk,ri,j,(u64)(X1>>64),(u64)X1,(u64)(X2>>64),(u64)X2,wk,wn,n); for(int a2=0;a2>64),(u64)X1,(u64)(X2>>64),(u64)X2); + if(overflow){ nover++; printf("OVERFLOW rep %d V2idx %d ng %d\n",ri,j,ng); fflush(stdout); } + if(nw>maxcl) maxcl=nw; + free(hs.k); free(W); free(gk); } + if(vmax>overall) overall=vmax; + printf("rep %d lines %d orbit %d active %d surviving-pairs %lld maxclosure %lld maxrank %d\n",ri,pc(X1),osz[reps[ri]],na,ps,maxcl,vmax); fflush(stdout); + for(int a=0;a= orbit(V1)) when a==b; +// (2) V3 is NOT enumerated: for each direction h and 7-flat G, D = Off(h)\(X1 u X2 u G) must lie (minus s lines) in a c-dim flat, +// i.e. rank_F2(l(D\T)) <= c -> requirement subspace S_{h,G}. Per (V1,h) the G's are precomputed as maximal masks r1&G; +// (3) V3 = closure of sums of requirement subspaces (dim <= c); evaluated at leaves; incremental real rank stops at 8. +// usage: s3f data a b c s lim target mod rem [env NOSYM=1 disables pair symmetry; ONLY=ri,ri,..] +#include +#include +#include +typedef unsigned __int128 u128; typedef unsigned long long u64; +int LAB[112]; int PC[112][8]; int ND; int hv[20000][8]; int hv2[20000][8]; int htyp[20000]; u128 OFF[20000]; int cap[20000]; +static inline int pc(u128 x){ return __builtin_popcountll((u64)x)+__builtin_popcountll((u64)(x>>64)); } +long long gcdll(long long a,long long b){ if(a<0)a=-a; if(b<0)b=-b; while(b){ long long t=a%b; a=b; b=t;} return a; } +// exact integer real rank of direction vectors (pencils contribute two vectors); stops at 8 +int realrank(int *list0,int n0){ long long Bm[8][8]; int piv[8]; int r=0; + for(int ii=0;ii1) for(int k=0;k<8;k++) v[k]/=g; again=1; } } } + int p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; + for(int k=0;k<8;k++) Bm[r][k]=v[k]; piv[r]=p; r++; if(r==8) return 8; } } + return r; } +// ---------- subspaces (dual enumeration as in s66.c) +u128 *SUB; int NS=0; +int cmp128(const void*a,const void*b){ u128 x=*(u128*)a,y=*(u128*)b; return xy; } +static inline int par(int x){ return __builtin_popcount(x)&1; } +int gens[16][112]; int NG=0; +u128 mapmask(u128 m,int g){ u128 o=0; for(int t=0;t<112;t++) if((m>>t)&1) o|=((u128)1)<=0;k--){ if(!((x>>k)&1)) continue; if(B[k]) x^=B[k]; else { B[k]=x; r++; break; } } } + for(int k=0;k<9;k++) if(B[k]) for(int j=k+1;j<9;j++) if(B[j]&&((B[j]>>k)&1)) B[j]^=B[k]; + int m=0; for(int k=8;k>=0;k--) if(B[k]) out[m++]=B[k]; return m; } +u64 packkey(int *b,int n){ u64 key=0; for(int i=0;i>=9; } for(int i=0;i c +int spankey(u128 D,int c,u64 *key){ int vs[112]; int n=0; for(int t=0;t<112;t++) if((D>>t)&1) vs[n++]=LAB[t]; int b[9]; int m=rrefv(vs,n,b); if(m>c) return 99; *key=packkey(b,m); return m; } +void membmap(int *b,int n,u64 *mem){ for(int i=0;i<8;i++) mem[i]=0; int el[64]; int ne=1; el[0]=0; for(int i=0;i>6]|=1ULL<<(el[j]&63); } +// requirement subspaces for (D, s, c): span(D) and spans after removing <= s (<=2) lines, those of dim <= c +int reqs(u128 D,int s,int c,u64 *outk,int maxo){ int no=0; u64 key; int d=spankey(D,c,&key); if(d<=c){ outk[no++]=key; if(s==0||d==0) return no; } + if(s==0) return no; + int lines[112]; int nl=0; for(int t=0;t<112;t++) if((D>>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;j>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;jcap=cap; h->n=0; h->k=calloc(cap,sizeof(u64)); } +int hs_add(HS*h,u64 key){ u64 kx=key+1; u64 x=(kx*0x9E3779B97F4A7C15ULL)>>20; int p=x%h->cap; while(h->k[p]){ if(h->k[p]==kx) return 0; p=(p+1)%h->cap; } h->k[p]=kx; h->n++; return 1; } +int cmpu64(const void*a,const void*b){ u64 x=*(u64*)a,y=*(u64*)b; return xy; } +int main(int argc,char**argv){ + const char*df=argv[1]; int adim=atoi(argv[2]), bdim=atoi(argv[3]), cdim=atoi(argv[4]), s=atoi(argv[5]), lim=atoi(argv[6]), target=atoi(argv[7]); + int mod=argc>8?atoi(argv[8]):1, rem=argc>9?atoi(argv[9]):0; int nosym=getenv("NOSYM")!=NULL; int nlo=getenv("NEWLO")?atoi(getenv("NEWLO")):-1; int pass1=getenv("PASS1")!=NULL; char*pf=getenv("PAIRS"); static char hitset[200][200000]; /*unused*/ + int only[200]; int nonly=0; if(getenv("ONLY")){ char*p=getenv("ONLY"); while(*p){ only[nonly++]=strtol(p,&p,10); if(*p==',') p++; } } + int gw[10]={0,1,2,4,8,12,20,36,64,112}; + FILE*f=fopen(df,"r"); for(int i=0;i<112;i++) fscanf(f,"%d",&LAB[i]); int z; for(int i=0;i<8;i++) fscanf(f,"%d",&z); + for(int i=0;i<112;i++) for(int k2=0;k2<8;k2++) fscanf(f,"%d",&PC[i][k2]); + int nn; fscanf(f,"%d",&nn); ND=0; + for(int i=0;inlo){ OFF[ND]=m; ND++; } } + fclose(f); + f=fopen("gens.txt","r"); while(1){ int ok=1; for(int t=0;t<112;t++) if(fscanf(f,"%d",&gens[NG][t])!=1){ok=0;break;} if(!ok) break; NG++; } fclose(f); + u128 *G7=malloc(sizeof(u128)*44000); int n7=0; + for(int w1=1;w1<512;w1++) for(int w2=w1+1;w2<512;w2++){ int w3=w1^w2; if(w3b) b=c; } cap[h]=b; } + int na_,nb_; u128 *A=enumsub(adim,&na_); int sameAB=(adim==bdim); u128 *Bs; if(sameAB){ Bs=A; nb_=na_; } else { Bs=enumsub(bdim,&nb_); } + SUB=A; NS=na_; + fprintf(stderr,"dirs %d gens %d V1 %d V2 %d\n",ND,NG,na_,nb_); + uf=malloc(sizeof(int)*NS); for(int i=0;icap[h]+thr1) continue; + int nt=0; for(int g=0;gcp) cp=c; } capr[na]=cp; act[na]=h; R1[na]=r; na++; } + fprintf(stderr,"rep %d setup done: active %d avgL %.1f\n",ri,na,na?(double)sumL/na:0.0); + for(int j=0;jcapr[a]+thr2) continue; int ok=0; u128 *L=LG[a]; for(int q=0;qthr2) continue; if(feasible(D,s,cdim)){ ok=1; break; } } + if(ok){ cand[nc]=act[a]; candi[nc]=a; R2[nc]=r; nc++; } } + npair++; if(nc==0) continue; if(pass1){ printf("HIT %d %d %d\n",ri,j,nc); continue; } + int ub=realrank(cand,nc); if(ubthr2) continue; int nk=reqs(D,s,cdim,tk,1024); for(int e=0;ecdim) continue; if(dn==wn) continue; grew=1; u64 nk=packkey(ob,dn); if(hs_add(&hs,nk)){ if(nw<(1<<21)) W[nw++]=nk; else overflow=1; } } + if(overflow) break; + if(!grew){ nleaf++; u64 mem[8]; membmap(wb,wn,mem); int list[512]; int n=0; + for(int ci=0;ci>6]>>(sb[i]&63))&1)){ inside=0; break; } if(inside) ok=1; } if(ok && n<512) list[n++]=cand[ci]; } + if(n){ int rk=realrank(list,n); hist[rk]++; if(rk>vmax) vmax=rk; if(rk>pairbest) pairbest=rk; + if(rk>=target){ printf("CRACK? target %d span %d rep %d V2idx %d X1=%016llx%016llx X2=%016llx%016llx Wkey=%llx dim %d n %d dirs:",target,rk,ri,j,(u64)(X1>>64),(u64)X1,(u64)(X2>>64),(u64)X2,wk,wn,n); for(int a2=0;a2>64),(u64)X1,(u64)(X2>>64),(u64)X2); + if(overflow){ nover++; printf("OVERFLOW rep %d V2idx %d ng %d\n",ri,j,ng); fflush(stdout); } + if(nw>maxcl) maxcl=nw; + free(hs.k); free(W); free(gk); } + if(vmax>overall) overall=vmax; + printf("rep %d lines %d orbit %d active %d surviving-pairs %lld maxclosure %lld maxrank %d\n",ri,pc(X1),osz[reps[ri]],na,ps,maxcl,vmax); fflush(stdout); + for(int a=0;a= orbit(V1)) when a==b; +// (2) V3 is NOT enumerated: for each direction h and 7-flat G, D = Off(h)\(X1 u X2 u G) must lie (minus s lines) in a c-dim flat, +// i.e. rank_F2(l(D\T)) <= c -> requirement subspace S_{h,G}. Per (V1,h) the G's are precomputed as maximal masks r1&G; +// (3) V3 = closure of sums of requirement subspaces (dim <= c); evaluated at leaves; incremental real rank stops at 8. +// usage: s3f data a b c s lim target mod rem [env NOSYM=1 disables pair symmetry; ONLY=ri,ri,..] +#include +#include +#include +typedef unsigned __int128 u128; typedef unsigned long long u64; +int LAB[112]; int PC[112][8]; int ND; int hv[20000][8]; int hv2[20000][8]; int htyp[20000]; u128 OFF[20000]; int cap[20000]; +static inline int pc(u128 x){ return __builtin_popcountll((u64)x)+__builtin_popcountll((u64)(x>>64)); } +long long gcdll(long long a,long long b){ if(a<0)a=-a; if(b<0)b=-b; while(b){ long long t=a%b; a=b; b=t;} return a; } +// exact integer real rank of direction vectors (pencils contribute two vectors); stops at 8 +int realrank(int *list0,int n0){ long long Bm[8][8]; int piv[8]; int r=0; + for(int ii=0;ii1) for(int k=0;k<8;k++) v[k]/=g; again=1; } } } + int p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; + for(int k=0;k<8;k++) Bm[r][k]=v[k]; piv[r]=p; r++; if(r==8) return 8; } } + return r; } +// ---------- subspaces (dual enumeration as in s66.c) +u128 *SUB; int NS=0; +int cmp128(const void*a,const void*b){ u128 x=*(u128*)a,y=*(u128*)b; return xy; } +static inline int par(int x){ return __builtin_popcount(x)&1; } +int gens[16][112]; int NG=0; +u128 mapmask(u128 m,int g){ u128 o=0; for(int t=0;t<112;t++) if((m>>t)&1) o|=((u128)1)<=0;k--){ if(!((x>>k)&1)) continue; if(B[k]) x^=B[k]; else { B[k]=x; r++; break; } } } + for(int k=0;k<9;k++) if(B[k]) for(int j=k+1;j<9;j++) if(B[j]&&((B[j]>>k)&1)) B[j]^=B[k]; + int m=0; for(int k=8;k>=0;k--) if(B[k]) out[m++]=B[k]; return m; } +u64 packkey(int *b,int n){ u64 key=0; for(int i=0;i>=9; } for(int i=0;i c +int spankey(u128 D,int c,u64 *key){ int vs[112]; int n=0; for(int t=0;t<112;t++) if((D>>t)&1) vs[n++]=LAB[t]; int b[9]; int m=rrefv(vs,n,b); if(m>c) return 99; *key=packkey(b,m); return m; } +void membmap(int *b,int n,u64 *mem){ for(int i=0;i<8;i++) mem[i]=0; int el[64]; int ne=1; el[0]=0; for(int i=0;i>6]|=1ULL<<(el[j]&63); } +// requirement subspaces for (D, s, c): span(D) and spans after removing <= s (<=2) lines, those of dim <= c +int reqs(u128 D,int s,int c,u64 *outk,int maxo){ int no=0; u64 key; int d=spankey(D,c,&key); if(d<=c){ outk[no++]=key; if(s==0||d==0) return no; } + if(s==0) return no; + int lines[112]; int nl=0; for(int t=0;t<112;t++) if((D>>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;j>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;jcap=cap; h->n=0; h->k=calloc(cap,sizeof(u64)); } +int hs_add(HS*h,u64 key){ u64 kx=key+1; u64 x=(kx*0x9E3779B97F4A7C15ULL)>>20; int p=x%h->cap; while(h->k[p]){ if(h->k[p]==kx) return 0; p=(p+1)%h->cap; } h->k[p]=kx; h->n++; return 1; } +int cmpu64(const void*a,const void*b){ u64 x=*(u64*)a,y=*(u64*)b; return xy; } +int main(int argc,char**argv){ + const char*df=argv[1]; int adim=atoi(argv[2]), bdim=atoi(argv[3]), cdim=atoi(argv[4]), s=atoi(argv[5]), lim=atoi(argv[6]), target=atoi(argv[7]); + int mod=argc>8?atoi(argv[8]):1, rem=argc>9?atoi(argv[9]):0; int nosym=getenv("NOSYM")!=NULL; int nlo=getenv("NEWLO")?atoi(getenv("NEWLO")):-1; int pass1=getenv("PASS1")!=NULL; char*pf=getenv("PAIRS"); static char hitset[200][200000]; /*unused*/ + int only[200]; int nonly=0; if(getenv("ONLY")){ char*p=getenv("ONLY"); while(*p){ only[nonly++]=strtol(p,&p,10); if(*p==',') p++; } } + int gw[10]={0,1,2,4,8,12,20,36,64,112}; + FILE*f=fopen(df,"r"); for(int i=0;i<112;i++) fscanf(f,"%d",&LAB[i]); int z; for(int i=0;i<8;i++) fscanf(f,"%d",&z); + for(int i=0;i<112;i++) for(int k2=0;k2<8;k2++) fscanf(f,"%d",&PC[i][k2]); + int nn; fscanf(f,"%d",&nn); ND=0; + for(int i=0;inlo){ OFF[ND]=m; ND++; } } + fclose(f); + f=fopen("gens.txt","r"); while(1){ int ok=1; for(int t=0;t<112;t++) if(fscanf(f,"%d",&gens[NG][t])!=1){ok=0;break;} if(!ok) break; NG++; } fclose(f); + u128 *G7=malloc(sizeof(u128)*44000); int n7=0; + for(int w1=1;w1<512;w1++) for(int w2=w1+1;w2<512;w2++){ int w3=w1^w2; if(w3b) b=c; } cap[h]=b; } + int na_,nb_; u128 *A=enumsub(adim,&na_); int sameAB=(adim==bdim); u128 *Bs; if(sameAB){ Bs=A; nb_=na_; } else { Bs=enumsub(bdim,&nb_); } + SUB=A; NS=na_; + fprintf(stderr,"dirs %d gens %d V1 %d V2 %d\n",ND,NG,na_,nb_); + uf=malloc(sizeof(int)*NS); for(int i=0;icap[h]+thr1) continue; + int nt=0; for(int g=0;gcp) cp=c; } capr[na]=cp; act[na]=h; R1[na]=r; na++; } + fprintf(stderr,"rep %d setup done: active %d avgL %.1f\n",ri,na,na?(double)sumL/na:0.0); + for(int j=0;jcapr[a]+thr2) continue; int ok=0; u128 *L=LG[a]; for(int q=0;qthr2) continue; if(feasible(D,s,cdim)){ ok=1; break; } } + if(ok){ cand[nc]=act[a]; candi[nc]=a; R2[nc]=r; nc++; } } + npair++; if(nc==0) continue; if(pass1){ printf("HIT %d %d %d\n",ri,j,nc); continue; } + int ub=realrank(cand,nc); if(ubthr2) continue; int nk=reqs(D,s,cdim,tk,1024); for(int e=0;ecdim) continue; if(dn==wn) continue; grew=1; u64 nk=packkey(ob,dn); if(hs_add(&hs,nk)){ if(nw<(1<<21)) W[nw++]=nk; else overflow=1; } } + if(overflow) break; + if(!grew){ nleaf++; u64 mem[8]; membmap(wb,wn,mem); int list[512]; int n=0; + for(int ci=0;ci>6]>>(sb[i]&63))&1)){ inside=0; break; } if(inside) ok=1; } if(ok && n<512) list[n++]=cand[ci]; } + if(n){ int rk=realrank(list,n); hist[rk]++; if(rk>vmax) vmax=rk; if(rk>pairbest) pairbest=rk; + if(rk>=target){ printf("CRACK? target %d span %d rep %d V2idx %d X1=%016llx%016llx X2=%016llx%016llx Wkey=%llx dim %d n %d dirs:",target,rk,ri,j,(u64)(X1>>64),(u64)X1,(u64)(X2>>64),(u64)X2,wk,wn,n); for(int a2=0;a2>64),(u64)X1,(u64)(X2>>64),(u64)X2); + if(overflow){ nover++; printf("OVERFLOW rep %d V2idx %d ng %d\n",ri,j,ng); fflush(stdout); } + if(nw>maxcl) maxcl=nw; + free(hs.k); free(W); free(gk); } + if(vmax>overall) overall=vmax; + printf("rep %d lines %d orbit %d active %d surviving-pairs %lld maxclosure %lld maxrank %d\n",ri,pc(X1),osz[reps[ri]],na,ps,maxcl,vmax); fflush(stdout); + for(int a=0;a= orbit(V1)) when a==b; +// (2) V3 is NOT enumerated: for each direction h and 7-flat G, D = Off(h)\(X1 u X2 u G) must lie (minus s lines) in a c-dim flat, +// i.e. rank_F2(l(D\T)) <= c -> requirement subspace S_{h,G}. Per (V1,h) the G's are precomputed as maximal masks r1&G; +// (3) V3 = closure of sums of requirement subspaces (dim <= c); evaluated at leaves; incremental real rank stops at 8. +// usage: s3f data a b c s lim target mod rem [env NOSYM=1 disables pair symmetry; ONLY=ri,ri,..] +#include +#include +#include +typedef unsigned __int128 u128; typedef unsigned long long u64; +int LAB[112]; int PC[112][8]; int ND; int hv[20000][8]; int hv2[20000][8]; int htyp[20000]; u128 OFF[20000]; int cap[20000]; +static inline int pc(u128 x){ return __builtin_popcountll((u64)x)+__builtin_popcountll((u64)(x>>64)); } +long long gcdll(long long a,long long b){ if(a<0)a=-a; if(b<0)b=-b; while(b){ long long t=a%b; a=b; b=t;} return a; } +// exact integer real rank of direction vectors (pencils contribute two vectors); stops at 8 +int realrank(int *list0,int n0){ long long Bm[8][8]; int piv[8]; int r=0; + for(int ii=0;ii1) for(int k=0;k<8;k++) v[k]/=g; again=1; } } } + int p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; + for(int k=0;k<8;k++) Bm[r][k]=v[k]; piv[r]=p; r++; if(r==8) return 8; } } + return r; } +// ---------- subspaces (dual enumeration as in s66.c) +u128 *SUB; int NS=0; +int cmp128(const void*a,const void*b){ u128 x=*(u128*)a,y=*(u128*)b; return xy; } +static inline int par(int x){ return __builtin_popcount(x)&1; } +int gens[16][112]; int NG=0; +u128 mapmask(u128 m,int g){ u128 o=0; for(int t=0;t<112;t++) if((m>>t)&1) o|=((u128)1)<=0;k--){ if(!((x>>k)&1)) continue; if(B[k]) x^=B[k]; else { B[k]=x; r++; break; } } } + for(int k=0;k<9;k++) if(B[k]) for(int j=k+1;j<9;j++) if(B[j]&&((B[j]>>k)&1)) B[j]^=B[k]; + int m=0; for(int k=8;k>=0;k--) if(B[k]) out[m++]=B[k]; return m; } +u64 packkey(int *b,int n){ u64 key=0; for(int i=0;i>=9; } for(int i=0;i c +int spankey(u128 D,int c,u64 *key){ int vs[112]; int n=0; for(int t=0;t<112;t++) if((D>>t)&1) vs[n++]=LAB[t]; int b[9]; int m=rrefv(vs,n,b); if(m>c) return 99; *key=packkey(b,m); return m; } +void membmap(int *b,int n,u64 *mem){ for(int i=0;i<8;i++) mem[i]=0; int el[64]; int ne=1; el[0]=0; for(int i=0;i>6]|=1ULL<<(el[j]&63); } +// requirement subspaces for (D, s, c): span(D) and spans after removing <= s (<=2) lines, those of dim <= c +int reqs(u128 D,int s,int c,u64 *outk,int maxo){ int no=0; u64 key; int d=spankey(D,c,&key); if(d<=c){ outk[no++]=key; if(s==0||d==0) return no; } + if(s==0) return no; + int lines[112]; int nl=0; for(int t=0;t<112;t++) if((D>>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;j>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;jcap=cap; h->n=0; h->k=calloc(cap,sizeof(u64)); } +int hs_add(HS*h,u64 key){ u64 kx=key+1; u64 x=(kx*0x9E3779B97F4A7C15ULL)>>20; int p=x%h->cap; while(h->k[p]){ if(h->k[p]==kx) return 0; p=(p+1)%h->cap; } h->k[p]=kx; h->n++; return 1; } +int cmpu64(const void*a,const void*b){ u64 x=*(u64*)a,y=*(u64*)b; return xy; } +int main(int argc,char**argv){ + const char*df=argv[1]; int adim=atoi(argv[2]), bdim=atoi(argv[3]), cdim=atoi(argv[4]), s=atoi(argv[5]), lim=atoi(argv[6]), target=atoi(argv[7]); + int mod=argc>8?atoi(argv[8]):1, rem=argc>9?atoi(argv[9]):0; int nosym=getenv("NOSYM")!=NULL; int nlo=getenv("NEWLO")?atoi(getenv("NEWLO")):-1; int pass1=getenv("PASS1")!=NULL; char*pf=getenv("PAIRS"); static char hitset[200][200000]; /*unused*/ + int only[200]; int nonly=0; if(getenv("ONLY")){ char*p=getenv("ONLY"); while(*p){ only[nonly++]=strtol(p,&p,10); if(*p==',') p++; } } + int gw[10]={0,1,2,4,8,12,20,36,64,112}; + FILE*f=fopen(df,"r"); for(int i=0;i<112;i++) fscanf(f,"%d",&LAB[i]); int z; for(int i=0;i<8;i++) fscanf(f,"%d",&z); + for(int i=0;i<112;i++) for(int k2=0;k2<8;k2++) fscanf(f,"%d",&PC[i][k2]); + int nn; fscanf(f,"%d",&nn); ND=0; + for(int i=0;inlo){ OFF[ND]=m; ND++; } } + fclose(f); + f=fopen("gens.txt","r"); while(1){ int ok=1; for(int t=0;t<112;t++) if(fscanf(f,"%d",&gens[NG][t])!=1){ok=0;break;} if(!ok) break; NG++; } fclose(f); + u128 *G7=malloc(sizeof(u128)*44000); int n7=0; + for(int w1=1;w1<512;w1++) for(int w2=w1+1;w2<512;w2++){ int w3=w1^w2; if(w3b) b=c; } cap[h]=b; } + int na_,nb_; u128 *A=enumsub(adim,&na_); int sameAB=(adim==bdim); u128 *Bs; if(sameAB){ Bs=A; nb_=na_; } else { Bs=enumsub(bdim,&nb_); } + SUB=A; NS=na_; + fprintf(stderr,"dirs %d gens %d V1 %d V2 %d\n",ND,NG,na_,nb_); + uf=malloc(sizeof(int)*NS); for(int i=0;icap[h]+thr1) continue; + int nt=0; for(int g=0;gcp) cp=c; } capr[na]=cp; act[na]=h; R1[na]=r; na++; } + fprintf(stderr,"rep %d setup done: active %d avgL %.1f\n",ri,na,na?(double)sumL/na:0.0); + for(int j=0;j1 && j%jmod!=jrem) continue; if(oid && oid[j]capr[a]+thr2) continue; int ok=0; u128 *L=LG[a]; for(int q=0;qthr2) continue; if(feasible(D,s,cdim)){ ok=1; break; } } + if(ok){ cand[nc]=act[a]; candi[nc]=a; R2[nc]=r; nc++; } } + npair++; if(nc==0) continue; if(pass1){ printf("HIT %d %d %d\n",ri,j,nc); continue; } + int ub=realrank(cand,nc); if(ubthr2) continue; int nk=reqs(D,s,cdim,tk,1024); for(int e=0;ecdim) continue; if(dn==wn) continue; grew=1; u64 nk=packkey(ob,dn); if(hs_add(&hs,nk)){ if(nw<(1<<21)) W[nw++]=nk; else overflow=1; } } + if(overflow) break; + if(!grew){ nleaf++; u64 mem[8]; membmap(wb,wn,mem); int list[512]; int n=0; + for(int ci=0;ci>6]>>(sb[i]&63))&1)){ inside=0; break; } if(inside) ok=1; } if(ok && n<512) list[n++]=cand[ci]; } + if(n){ int rk=realrank(list,n); hist[rk]++; if(rk>vmax) vmax=rk; if(rk>pairbest) pairbest=rk; + if(rk>=target){ printf("CRACK? target %d span %d rep %d V2idx %d X1=%016llx%016llx X2=%016llx%016llx Wkey=%llx dim %d n %d dirs:",target,rk,ri,j,(u64)(X1>>64),(u64)X1,(u64)(X2>>64),(u64)X2,wk,wn,n); for(int a2=0;a2>64),(u64)X1,(u64)(X2>>64),(u64)X2); + if(overflow){ nover++; printf("OVERFLOW rep %d V2idx %d ng %d\n",ri,j,ng); fflush(stdout); } + if(nw>maxcl) maxcl=nw; + free(hs.k); free(W); free(gk); } + if(vmax>overall) overall=vmax; + printf("rep %d lines %d orbit %d active %d surviving-pairs %lld maxclosure %lld maxrank %d\n",ri,pc(X1),osz[reps[ri]],na,ps,maxcl,vmax); fflush(stdout); + for(int a=0;a= orbit(V1)) when a==b; +// (2) V3 is NOT enumerated: for each direction h and 7-flat G, D = Off(h)\(X1 u X2 u G) must lie (minus s lines) in a c-dim flat, +// i.e. rank_F2(l(D\T)) <= c -> requirement subspace S_{h,G}. Per (V1,h) the G's are precomputed as maximal masks r1&G; +// (3) V3 = closure of sums of requirement subspaces (dim <= c); evaluated at leaves; incremental real rank stops at 8. +// usage: s3f data a b c s lim target mod rem [env NOSYM=1 disables pair symmetry; ONLY=ri,ri,..] +#include +#include +#include +int FREES=0; typedef unsigned __int128 u128; typedef unsigned long long u64; +int LAB[112]; int PC[112][8]; int ND; int hv[20000][8]; int hv2[20000][8]; int htyp[20000]; u128 OFF[20000]; int cap[20000]; +static inline int pc(u128 x){ return __builtin_popcountll((u64)x)+__builtin_popcountll((u64)(x>>64)); } +long long gcdll(long long a,long long b){ if(a<0)a=-a; if(b<0)b=-b; while(b){ long long t=a%b; a=b; b=t;} return a; } +// exact integer real rank of direction vectors (pencils contribute two vectors); stops at 8 +int realrank(int *list0,int n0){ long long Bm[8][8]; int piv[8]; int r=0; + for(int ii=0;ii1) for(int k=0;k<8;k++) v[k]/=g; again=1; } } } + int p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; + for(int k=0;k<8;k++) Bm[r][k]=v[k]; piv[r]=p; r++; if(r==8) return 8; } } + return r; } +// ---------- subspaces (dual enumeration as in s66.c) +u128 *SUB; int NS=0; +int cmp128(const void*a,const void*b){ u128 x=*(u128*)a,y=*(u128*)b; return xy; } +static inline int par(int x){ return __builtin_popcount(x)&1; } +int gens[16][112]; int NG=0; +u128 mapmask(u128 m,int g){ u128 o=0; for(int t=0;t<112;t++) if((m>>t)&1) o|=((u128)1)<=0;k--){ if(!((x>>k)&1)) continue; if(B[k]) x^=B[k]; else { B[k]=x; r++; break; } } } + for(int k=0;k<9;k++) if(B[k]) for(int j=k+1;j<9;j++) if(B[j]&&((B[j]>>k)&1)) B[j]^=B[k]; + int m=0; for(int k=8;k>=0;k--) if(B[k]) out[m++]=B[k]; return m; } +u64 packkey(int *b,int n){ u64 key=0; for(int i=0;i>=9; } for(int i=0;i c +int spankey(u128 D,int c,u64 *key){ int vs[112]; int n=0; for(int t=0;t<112;t++) if((D>>t)&1) vs[n++]=LAB[t]; int b[9]; int m=rrefv(vs,n,b); if(m>c) return 99; *key=packkey(b,m); return m; } +void membmap(int *b,int n,u64 *mem){ for(int i=0;i<8;i++) mem[i]=0; int el[64]; int ne=1; el[0]=0; for(int i=0;i>6]|=1ULL<<(el[j]&63); } +// requirement subspaces for (D, s, c): span(D) and spans after removing <= s (<=2) lines, those of dim <= c +int reqs(u128 D,int s,int c,u64 *outk,int maxo){ int no=0; u64 key; int d=spankey(D,c,&key); if(d<=c){ outk[no++]=key; if(s==0||d==0) return no; } + if(s==0) return no; + int lines[112]; int nl=0; for(int t=0;t<112;t++) if((D>>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;j>t)&1) lines[nl++]=t; + for(int i=0;i=2) for(int j=i+1;j>lead)&1) x^=b[i]; } return x==0; } +int cmpss(const void*a,const void*b){ u64 x=((SS*)a)->key,y=((SS*)b)->key; return xy; } +#define MAXFL 60000 +static SS FL[MAXFL]; +// returns number of flats (incl. empty) spanned by subsets of labels, dim<=c; -1 on overflow +int enum_flats(int*lab,int nl,int c){ int nf=1; FL[0].n=0; FL[0].key=0; int ls=0,le_=1; + for(int k=0;k=MAXFL) return -1; SS*o=&FL[nf]; o->n=rrefv(vs,FL[i].n+1,o->b); o->key=packkey(o->b,o->n); nf++; } + qsort(FL+start,nf-start,sizeof(SS),cmpss); int u=start; for(int i=start;i>t)&1) vs[nv++]=LAB[t]; + int bb[9]; int rk=rrefv(vs,nv,bb); if(rk>c+d) return no0; + // distinct labels + for(int i=0;id) continue; if(stopfirst) return 1; + OPT*o=&OP[no++]; o->k3=FL[f].key; o->n3=FL[f].n; memcpy(o->b3,FL[f].b,sizeof(int)*FL[f].n); o->k4=packkey(b4,m4); o->n4=m4; memcpy(o->b4,b4,sizeof(int)*m4); } + return no; } +int opts4(u128 D,int c,int d,int stopfirst){ int no=opts4c(D,c,d,stopfirst,0); if(stopfirst&&no>0) return 1; + if(FREES>=1){ int ln[112]; int nl=0; for(int t=0;t<112;t++) if((D>>t)&1) ln[nl++]=t; + for(int i=0;i0) return 1; + if(FREES>=2) for(int j=i+1;j0) return 1; } } } + // prune dominated + int *dead=calloc(no+1,sizeof(int)); + for(int i=0;iOP[i].n3||OP[j].n4>OP[i].n4) continue; if(OP[j].n3==OP[i].n3&&OP[j].n4==OP[i].n4) continue; // equal dims & subset => equal key (deduped), so strict only + int ok=1; for(int q=0;q>t)&1) vs[nv++]=LAB[t]; + int bb[9]; int rk=rrefv(vs,nv,bb); if(rk>c+d) return 0; if(FREES==0){ for(int i=0;i0; } +typedef struct { u128 *k; int cap; int n; } HS2; +void hs2_init(HS2*h,int cap){ h->cap=cap; h->n=0; h->k=calloc(cap,sizeof(u128)); } +int hs2_add(HS2*h,u128 key){ u128 kx=key+1; u64 x=((u64)kx*0x9E3779B97F4A7C15ULL ^ (u64)(kx>>64)*0xC2B2AE3D27D4EB4FULL)>>20; int p=x%h->cap; while(h->k[p]){ if(h->k[p]==kx) return 0; p=(p+1)%h->cap; } h->k[p]=kx; h->n++; return 1; } +typedef struct { u64 *k; int cap; int n; } HS; +void hs_init(HS*h,int cap){ h->cap=cap; h->n=0; h->k=calloc(cap,sizeof(u64)); } +int hs_add(HS*h,u64 key){ u64 kx=key+1; u64 x=(kx*0x9E3779B97F4A7C15ULL)>>20; int p=x%h->cap; while(h->k[p]){ if(h->k[p]==kx) return 0; p=(p+1)%h->cap; } h->k[p]=kx; h->n++; return 1; } +int cmpu64(const void*a,const void*b){ u64 x=*(u64*)a,y=*(u64*)b; return xy; } +int main(int argc,char**argv){ + const char*df=argv[1]; int adim=atoi(argv[2]), bdim=atoi(argv[3]), cdim=atoi(argv[4]), ddim=atoi(argv[5]), s=0, lim=atoi(argv[6]), target=atoi(argv[7]); + int mod=argc>8?atoi(argv[8]):1, rem=argc>9?atoi(argv[9]):0; int nosym=getenv("NOSYM")!=NULL; FREES=getenv("FREES")?atoi(getenv("FREES")):0; int nlo=getenv("NEWLO")?atoi(getenv("NEWLO")):-1; int pass1=getenv("PASS1")!=NULL; char*pf=getenv("PAIRS"); static char hitset[200][200000]; /*unused*/ + int only[200]; int nonly=0; if(getenv("ONLY")){ char*p=getenv("ONLY"); while(*p){ only[nonly++]=strtol(p,&p,10); if(*p==',') p++; } } + int gw[10]={0,1,2,4,8,12,20,36,64,112}; + FILE*f=fopen(df,"r"); for(int i=0;i<112;i++) fscanf(f,"%d",&LAB[i]); int z; for(int i=0;i<8;i++) fscanf(f,"%d",&z); + for(int i=0;i<112;i++) for(int k2=0;k2<8;k2++) fscanf(f,"%d",&PC[i][k2]); + int nn; fscanf(f,"%d",&nn); ND=0; + for(int i=0;inlo){ OFF[ND]=m; ND++; } } + fclose(f); + f=fopen("gens.txt","r"); while(1){ int ok=1; for(int t=0;t<112;t++) if(fscanf(f,"%d",&gens[NG][t])!=1){ok=0;break;} if(!ok) break; NG++; } fclose(f); + u128 *G7=malloc(sizeof(u128)*44000); int n7=0; + for(int w1=1;w1<512;w1++) for(int w2=w1+1;w2<512;w2++){ int w3=w1^w2; if(w3b) b=c; } cap[h]=b; } + int na_,nb_; u128 *A=enumsub(adim,&na_); int sameAB=(adim==bdim); u128 *Bs; if(sameAB){ Bs=A; nb_=na_; } else { Bs=enumsub(bdim,&nb_); } + SUB=A; NS=na_; + fprintf(stderr,"dirs %d gens %d V1 %d V2 %d\n",ND,NG,na_,nb_); + uf=malloc(sizeof(int)*NS); for(int i=0;icap[h]+thr1) continue; + int nt=0; for(int g=0;gcp) cp=c; } capr[na]=cp; act[na]=h; R1[na]=r; na++; } + fprintf(stderr,"rep %d setup done: active %d avgL %.1f\n",ri,na,na?(double)sumL/na:0.0); + for(int j=0;j1 && j%jmod!=jrem) continue; if(oid && oid[j]capr[a]+thr2) continue; int ok=0; u128 *L=LG[a]; for(int q=0;qthr2) continue; if(feas4(D,cdim,ddim)){ ok=1; break; } } + if(ok){ cand[nc]=act[a]; candi[nc]=a; R2[nc]=r; nc++; } } + npair++; if(nc==0) continue; if(pass1){ printf("HIT %d %d %d\n",ri,j,nc); continue; } + int ub=realrank(cand,nc); if(ubthr2) continue; int nk=opts4(D,cdim,ddim,0); for(int e=0;e>64); allS4[base+e]=(u64)tmpk[e]; } tot=base+u; free(tmpk); } } + Sstart[nc]=tot; + u128 *gk=malloc(sizeof(u128)*(tot+1)); for(int e=0;e>64),wb3); int wn4=unpackkey((u64)wk,wb4); int grew=0; + for(int e=0;e>64),sb3); int sn4=unpackkey((u64)gk[e],sb4); int vs[18]; int m=0; for(int i=0;icdim) continue; + m=0; for(int i=0;iddim) continue; if(dn3==wn3&&dn4==wn4) continue; grew=1; u128 nk=((u128)packkey(ob3,dn3)<<64)|packkey(ob4,dn4); if(hs2_add(&hs,nk)){ if(nw<(1<<21)) W[nw++]=nk; else overflow=1; } } + if(overflow) break; + if(!grew){ nleaf++; u64 mem[8],mem4[8]; membmap(wb3,wn3,mem); membmap(wb4,wn4,mem4); int list[512]; int n=0; + for(int ci=0;ci>6]>>(sb[i]&63))&1)){ inside=0; break; } if(inside){ sn=unpackkey(allS4[e],sb); for(int i=0;i>6]>>(sb[i]&63))&1)){ inside=0; break; } } if(inside) ok=1; } if(ok && n<512) list[n++]=cand[ci]; } + if(n){ int rk=realrank(list,n); hist[rk]++; if(rk>vmax) vmax=rk; if(rk>pairbest) pairbest=rk; + if(rk>=target){ printf("CRACK? target %d span %d rep %d V2idx %d X1=%016llx%016llx X2=%016llx%016llx Wkey=%llx dim %d n %d dirs:",target,rk,ri,j,(u64)(X1>>64),(u64)X1,(u64)(X2>>64),(u64)X2,(u64)(wk>>64),wn3,n); for(int a2=0;a2>64),(u64)X1,(u64)(X2>>64),(u64)X2); + if(overflow){ nover++; printf("OVERFLOW rep %d V2idx %d ng %d\n",ri,j,ng); fflush(stdout); } + if(nw>maxcl) maxcl=nw; + free(hs.k); free(W); free(gk); } + if(vmax>overall) overall=vmax; + printf("rep %d lines %d orbit %d active %d surviving-pairs %lld maxclosure %lld maxrank %d\n",ri,pc(X1),osz[reps[ri]],na,ps,maxcl,vmax); fflush(stdout); + for(int a=0;a +#include +#include +typedef unsigned __int128 u128; typedef __int128 i128; +int LAB[112]; int PC[112][8]; int ND; int hv[5000][8]; int hoff_n[5000]; u128 OFF[5000]; int cap[5000]; +int nd_use; +static inline int pc(u128 x){ return __builtin_popcountll((unsigned long long)x)+__builtin_popcountll((unsigned long long)(x>>64)); } +int f2rank_mask(u128 R){ int B[9]={0}; int r=0; for(int t=0;t<112;t++) if((R>>t)&1){ int x=LAB[t]; for(int k=8;k>=0;k--){ if(!((x>>k)&1)) continue; if(B[k]) x^=B[k]; else { B[k]=x; r++; break; } } } return r; } +// mode T: exists t in R with rank(R\t) <= 7 +int rank_minus_one_le7(u128 R){ int r=f2rank_mask(R); if(r<=7) return 1; if(r>8) return 0; for(int t=0;t<112;t++) if((R>>t)&1){ if(f2rank_mask(R&~(((u128)1)<1) for(int k=0;k<8;k++) v[k]/=g; } + int p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; // also need to clear p in earlier rows? not needed for rank (echelon by distinct pivots) + // ensure pivots distinct: v reduced against all earlier pivots, so its first nonzero may still coincide with no earlier pivot? reduce until first nonzero not a pivot + int again=1; while(again){ again=0; for(int j=0;j1) for(int k=0;k<8;k++) v[k]/=g; again=1; } } } + p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; + for(int k=0;k<8;k++) Bm[r][k]=v[k]; piv[r]=p; r++; if(r==8) return 8; } + return r; } +// subspaces +u128 *SUB; int NS=0; +int cmp128(const void*a,const void*b){ u128 x=*(u128*)a,y=*(u128*)b; return xy; } +int par(int x){ return __builtin_popcount(x)&1; } +int gens[16][112]; int NG=0; +u128 mapmask(u128 m,int g){ u128 o=0; for(int t=0;t<112;t++) if((m>>t)&1) o|=((u128)1)<2?atoi(argv[2]):6; // dim of V1,V2 + FILE*f=fopen("data.txt","r"); for(int i=0;i<112;i++) fscanf(f,"%d",&LAB[i]); int z; for(int i=0;i<8;i++) fscanf(f,"%d",&z); + for(int i=0;i<112;i++) for(int k=0;k<8;k++) fscanf(f,"%d",&PC[i][k]); + int nn; fscanf(f,"%d",&nn); ND=0; + for(int i=0;ib) b=c; } cap[h]=b; } + { int hist[200]={0}; for(int h=0;h=1 line: %d\n",NS); + qsort(SUB,NS,sizeof(u128),cmp128); int u=0; for(int i=0;icap[h]+slack) continue; int ok = (mode==0)? (f2rank_mask(r)<=7) : rank_minus_one_le7(r); if(ok) list[n++]=h; } + if(n>maxcnt) maxcnt=n; + if(n>=8){ int rk=realrank(list,n); if(rk>vmax) vmax=rk; if(rk==8){ nhits8++; if(nhits8<=20) printf("RANK8 rep %d j %d n %d\n",ri,j,n);} } else if(n>vmax){ int rk=realrank(list,n); if(rk>vmax) vmax=rk; } + } + if(vmax>overall) overall=vmax; + printf("rep %d lines %d orbit %d active %d maxrank %d\n",ri,pc(X1),osz[reps[ri]],na,vmax); fflush(stdout); + } + printf("OVERALL mode %d dim %d: max real rank %d, max #directions %d, rank-8 pairs %lld\n",mode,sdim,overall,maxcnt,nhits8); +} diff --git a/research/one-sided-residue-closures/provenance/src/s6x.c b/research/one-sided-residue-closures/provenance/src/s6x.c new file mode 100644 index 0000000000..62a702148a --- /dev/null +++ b/research/one-sided-residue-closures/provenance/src/s6x.c @@ -0,0 +1,101 @@ +// SIX: Lemma S66 (exact). For every 6-dim label subspace V1 (orbit reps) and V2 (all), X = Λ(V1) ∪ Λ(V2) [∪ {t} in mode T]: +// H = {directions h : rank_F2 lab(Off(h) \ X) <= 7} [mode T: some single line t removed additionally, per h (superset)]. +// Report max real rank of span H. Directions: data.txt (|Off|<=77 complete list); mode 0 uses |Off|<=76. +#include +#include +#include +typedef unsigned __int128 u128; typedef __int128 i128; +int LAB[112]; int PC[112][8]; int ND; int hv[7000][8]; int hv2[7000][8]; int htyp[7000]; int hoff_n[7000]; u128 OFF[7000]; int cap[7000]; +int nd_use; +static inline int pc(u128 x){ return __builtin_popcountll((unsigned long long)x)+__builtin_popcountll((unsigned long long)(x>>64)); } +int f2rank_mask(u128 R){ int B[9]={0}; int r=0; for(int t=0;t<112;t++) if((R>>t)&1){ int x=LAB[t]; for(int k=8;k>=0;k--){ if(!((x>>k)&1)) continue; if(B[k]) x^=B[k]; else { B[k]=x; r++; break; } } } return r; } +// mode T: exists t in R with rank(R\t) <= 7 +int rank_minus_one_le7(u128 R){ int r=f2rank_mask(R); if(r<=7) return 1; if(r>8) return 0; for(int t=0;t<112;t++) if((R>>t)&1){ if(f2rank_mask(R&~(((u128)1)<1) for(int k=0;k<8;k++) v[k]/=g; } + int p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; // also need to clear p in earlier rows? not needed for rank (echelon by distinct pivots) + // ensure pivots distinct: v reduced against all earlier pivots, so its first nonzero may still coincide with no earlier pivot? reduce until first nonzero not a pivot + int again=1; while(again){ again=0; for(int j=0;j1) for(int k=0;k<8;k++) v[k]/=g; again=1; } } } + p=-1; for(int k=0;k<8;k++) if(v[k]){p=k;break;} if(p<0) continue; + for(int k=0;k<8;k++) Bm[r][k]=v[k]; piv[r]=p; r++; if(r==8) return 8; } + return r; } +// subspaces +u128 *SUB; int NS=0; +int cmp128(const void*a,const void*b){ u128 x=*(u128*)a,y=*(u128*)b; return xy; } +int par(int x){ return __builtin_popcount(x)&1; } +int gens[16][112]; int NG=0; +u128 mapmask(u128 m,int g){ u128 o=0; for(int t=0;t<112;t++) if((m>>t)&1) o|=((u128)1)<cap[h]+s) return 0; int rk=f2rank_mask(r); if(rk<=7) return 1; if(s==0) return 0; + if(rk==8){ // coordinates in a basis of span(R); hyperplanes of span = nonzero functionals on F2^8 + int B[9]={0}; int bv[8]; int nb=0; int lst[112]; int nl=0; for(int t=0;t<112;t++) if((r>>t)&1){ lst[nl++]=t; } + // build basis with coordinate tracking + int piv[9]; int coordB[9]={0}; + for(int q=0;q=0;k2--){ if(!((x>>k2)&1)) continue; if(B[k2]){ x^=B[k2]; cx^=coordB[k2]; } else { B[k2]=x; coordB[k2]=cx^(1<=0;k2--){ if(!((x>>k2)&1)) continue; x^=B[k2]; cx^=coordB[k2]; } co[q]=cx; } + for(int phi=1;phi<256;phi++){ int bad=0; for(int q=0;qs) break; } if(bad<=s) return 1; } + return 0; } + int need=c-s; if(need>=THR){ int *L=GL[h]; for(int q=0;qcap[h]) continue; if(f2rank_mask(r)<=7) list[n++]=h; } + if(n){ int rk=realrank(list,n); if(rk>best) best=rk; } } + return best; } +int main(int argc,char**argv){ + const char*df=argv[1]; int adim=atoi(argv[2]), bdim=atoi(argv[3]), s=atoi(argv[4]), lim=atoi(argv[5]); + int gw[10]={0,1,2,4,8,12,20,36,64,112}; + FILE*f=fopen(df,"r"); for(int i=0;i<112;i++) fscanf(f,"%d",&LAB[i]); int z; for(int i=0;i<8;i++) fscanf(f,"%d",&z); + for(int i=0;i<112;i++) for(int k2=0;k2<8;k2++) fscanf(f,"%d",&PC[i][k2]); + int nn; fscanf(f,"%d",&nn); ND=0; + for(int i=0;ib) b=c; } cap[h]=b; + int tot=0; for(int c=THR;c<=112;c++) tot+=cnt[c]; GL[h]=malloc(sizeof(int)*(tot+1)); GC[h]=malloc(tot+1); GLn[h]=tot; + int pos[113]; int p=0; for(int c=112;c>=THR;c--){ pos[c]=p; p+=cnt[c]; } + for(int g=0;g=THR){ GL[h][pos[c]]=g; GC[h][pos[c]]=c; pos[c]++; } } } + int na_,nb_; u128 *A=enumsub(adim,&na_); u128 *Bs=enumsub(bdim,&nb_); SUB=A; NS=na_; + fprintf(stderr,"V1 line sets %d, V2 line sets %d\n",na_,nb_); + uf=malloc(sizeof(int)*NS); for(int i=0;i6){ char*p=argv[6]; while(*p){ only[nonly++]=strtol(p,&p,10); if(*p==',') p++; } } + if(argc>7){ RT=atoi(argv[7]); int c3; V3=enumsub(3,&c3); n3=c3; fprintf(stderr,"V3 line sets %d\n",n3); } + int overall=0; int maxcnt=0; long long hist[9]={0}; + int *act=malloc(sizeof(int)*ND); u128 *R1=malloc(sizeof(u128)*ND); + for(int ri=0;rimaxcnt) maxcnt=n; + if(n){ int rk=realrank(list,n); hist[rk]++; if(rk>vmax) vmax=rk; if(rk>=RT){ int e=refine(X1,X2,list,n); if(e>refmax) refmax=e; printf("REFINE rep %d j %d relaxed %d exact-with-3flat %d\n",ri,j,rk,e); fflush(stdout); } + if(rk>=7 && hist[rk]<=10){ printf("RANK%d rep %d j %d n %d :",rk,ri,j,n); for(int q=0;qoverall) overall=vmax; + printf("rep %d lines %d orbit %d active %d maxrank %d nfull %lld\n",ri,pc(X1),osz[reps[ri]],na,vmax,nfull); fflush(stdout); + } + printf("REFINE max exact rank %d\n",refmax); + printf("OVERALL %s V1dim %d V2dim %d s %d lim %d: max real rank %d, max #directions %d; rank histogram (nonempty pairs):",df,adim,bdim,s,lim,overall,maxcnt); + for(int r=1;r<=8;r++) printf(" %d:%lld",r,hist[r]); printf("\n"); +} diff --git a/research/one-sided-residue-closures/provenance/src/validate.sh b/research/one-sided-residue-closures/provenance/src/validate.sh new file mode 100755 index 0000000000..97b05d5519 --- /dev/null +++ b/research/one-sided-residue-closures/provenance/src/validate.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Compiles s3z/s4z and reproduces one known crack and one known pass of the (6,6,4) s0 span (s4z with d=0 is the 3-flat case). +set -e; cd "$(dirname "$0")"; B=$(mktemp -d); trap 'rm -rf "$B"' EXIT +gcc -O2 -march=native -o $B/s4z s4z.c; gcc -O2 -march=native -o $B/s3z s3z.c +# crack: V1 rep 82, T=5 -> "CRACK? target 5 span 5 ... V2idx 103676" +for p in s3z s4z; do + out=$(ONLY=82 EXITCRACK=1 timeout 100 $B/$p data88.txt 6 6 4 0 88 5 1 0 2>/dev/null) + echo "$out" | grep -q "CRACK? target 5 span 5 rep 82 V2idx 103676" || { echo "FAIL crack $p"; exit 1; } + echo "ok crack $p" +done +# pass: slice 3 of 50 of rep 82 at T=6 -> no crack, max span 4 (equal for s3z and s4z) +for p in s3z s4z; do + out=$(ONLY=82 JMOD=50 JREM=3 timeout 100 $B/$p data88.txt 6 6 4 0 88 6 1 0 2>/dev/null) + echo "$out" | grep -q "CRACK?" && { echo "FAIL pass $p (crack)"; exit 1; } + echo "$out" | grep OVERALL | grep -q "max span 4 " || { echo "FAIL pass $p"; exit 1; } + echo "ok pass $p" +done +echo VALIDATE OK diff --git a/research/one-sided-residue-closures/requirements.txt b/research/one-sided-residue-closures/requirements.txt new file mode 100644 index 0000000000..3067206937 --- /dev/null +++ b/research/one-sided-residue-closures/requirements.txt @@ -0,0 +1,3 @@ +# Tested with Python 3.14.7 (any recent 3.x). +numpy>=1.26 + diff --git a/research/one-sided-residue-closures/verify.sh b/research/one-sided-residue-closures/verify.sh new file mode 100644 index 0000000000..e791722259 --- /dev/null +++ b/research/one-sided-residue-closures/verify.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Verification of research/one-sided-residue-closures (no kappa claim). usage: bash verify.sh PYTHON=/path/to/python (needs numpy) FULL=1 for the heavy modes +# 0 MANIFEST.sha256 +# 1 constants: g(1..8) = 1,2,4,8,12,20,36,64 (all affine flats of F2^8), N_2 = 3, N_3 = 6 (exhaustive; N_4 = 12 with FULL=1), E8 model sanity [gtab.py, nj.py, e8.py] +# 2 P112 model, frame stabiliser (172032 elements, label-linear), complete direction list |Off| <= 89 (21340 non-E8 masks, 17 orbits), 6-flat masks [mkgroup.py dirs.py mkreps.py flats.py] +# 3 exact covering enumerations [cov.c]: root target always recomputed; the two non-trivial non-E8 targets (|Off| = 79, 80) recomputed; the other 15 are the shipped +# outputs (RECORDED) unless FULL=1, which recomputes all 17 (about 56 CPU-minutes more, three processes at a time) and also nj.py 4 +# 4 covering facts F3 (a)-(f), F4, D7 plane fact [anroot.py annon.py facts_check.py d7plane.py] +# 5 RRC engine, Lemma P / P', ledger recomputed from data/rows_input.csv and compared with the shipped ledger [run_rrc.py lemp_audit.py build_ledger.py check_ledger.py] +# 6 (FULL=1 only) provenance of data/rows_input.csv: the eight span facts rerun from source [provenance/replay_spanfacts.sh], the dominance filter and, with FULL=1, land7.py [provenance/reproduce.sh] +# Default runtime about 10 minutes; FULL=1 reruns every RECORDED covering run and the span-fact replay (see PROOF_MAP.md); at most 3 busy processes in steps 0-5 (4 in step 6); every process under timeout. A missing numpy or C compiler gives FAIL. +set -uo pipefail +HERE=$(cd "$(dirname "$0")" && pwd); C="$HERE/checks"; DATA="$HERE/data"; PY="${PYTHON:-python3}"; FULL="${FULL:-0}" +export PYTHONDONTWRITEBYTECODE=1 OMP_NUM_THREADS=1 VECLIB_MAXIMUM_THREADS=1 OPENBLAS_NUM_THREADS=1 +OUT=$(mktemp -d "${TMPDIR:-/tmp}/resclos.XXXXXX"); : > "$OUT/all.out"; T0=$SECONDS +note() { echo "$@" | tee -a "$OUT/all.out"; } +"$PY" -c "import numpy" 2>/dev/null || { echo "FAIL python needs numpy (PYTHON=...)"; exit 1; } +CC="${CC:-cc}"; command -v "$CC" >/dev/null || { echo "FAIL needs a C compiler (CC=...)"; exit 1; } +echo "== 0. manifest" +"$PY" -B "$C/manifest_check.py" | tee -a "$OUT/all.out" | sed 's/^/ /' +grep -q '^FAIL' "$OUT/all.out" && { echo "step 0 FAILED"; exit 1; } +cd "$OUT" +# run NAME TIMEOUT CMD... (output to NAME.log; PASS if exit 0, no FAIL line, at least one PASS line) +run() { local n=$1 to=$2; shift 2; timeout "$to" nice -n 10 "$@" > "$OUT/$n.log" 2>&1; local rc=$? + grep -E '^(PASS|FAIL)' "$OUT/$n.log" | sed 's/^/ /' + if [ $rc = 0 ] && ! grep -q '^FAIL' "$OUT/$n.log" && grep -q '^PASS' "$OUT/$n.log"; then note "PASS ran $n"; else note "FAIL ran $n (exit $rc)"; tail -3 "$OUT/$n.log"; fi; } +# expect NAME 'regex': PASS if the log of NAME matches +expect() { if grep -Eq "$2" "$OUT/$1.log"; then note "PASS $3"; else note "FAIL $3"; fi; } + +echo "== 1. constants" +timeout 600 "$PY" -B "$C/e8.py" > e8.log 2>&1 && note "PASS E8 model: 240 roots, 120 lines, det 1, labels distinct" || note "FAIL E8 model" +timeout 600 nice -n 10 "$PY" -B "$C/gtab.py" > gtab.log 2>&1; expect gtab '^\{1: 1, 2: 2, 3: 4, 4: 8, 5: 12, 6: 20, 7: 36, 8: 64\}$' "g(1..8) = 1,2,4,8,12,20,36,64 by exhaustive enumeration of all affine flats of F2^8" +NJ=3; [ "$FULL" = 1 ] && NJ=4 +timeout 3000 nice -n 10 "$PY" -B "$C/nj.py" $NJ > nj.log 2>&1 +expect nj 'j=2: .*max lines 3$' "N_2 = 3 (exhaustive over root-spanned planes)"; expect nj 'j=3: .*max lines 6$' "N_3 = 6 (exhaustive over root-spanned 3-spaces)" +if [ "$FULL" = 1 ]; then expect nj 'j=4: .*max lines 12$' "N_4 = 12 (exhaustive)"; else note "NOTE N_4 = 12 (and N_5 = 20, N_6 = 36) rest on the ADE classification; exhaustive N_4 log shipped in evidence/logs/nj4.out (FULL=1 recomputes)"; fi + +echo "== 2. P112, frame stabiliser, direction list" +timeout 900 nice -n 10 "$PY" -B "$C/mkgroup.py" > mkgroup.log 2>&1; expect mkgroup '^\|G\| = 172032$' "frame stabiliser generated: |G| = 172032" +timeout 900 nice -n 10 "$PY" -B "$C/dirs.py" > dirs.log 2>&1; expect dirs 'non-E8 21340' "direction list |Off| <= 89: 21460 masks, 120 E8-root/frame, 21340 non-E8" +run mkreps 900 "$PY" -B "$C/mkreps.py" +timeout 900 nice -n 10 "$PY" -B "$C/flats.py" > flats.log 2>&1; expect flats '3-dim dual subspaces: 788035' "6-flat masks: 788035 dual 3-spaces enumerated" + +echo "== 3. exact coverings" +"$CC" -O3 -o cov "$C/cov.c" 2> cc.log || { note "FAIL compile cov.c"; cat cc.log; } +for f in "$DATA"/left_*.gz; do b=$(basename "$f" .gz); gzip -dc "$f" > "shipped_$b"; done +covrun() { # name lo hi k forced + timeout 3000 nice -n 10 ./cov "$2" "$3" "$4" 9 "$5" "left_$1.txt" > "cov_$1.log" 2>&1 + if cmp -s <(sort "left_$1.txt") <(sort "shipped_left_$1.txt"); then echo "PASS covering $1 recomputed = shipped" > "covres_$1.txt"; else echo "FAIL covering $1 differs from shipped" > "covres_$1.txt"; fi; } +read -r _ RLO RHI RK RF < <(grep '^root' "$DATA/targets.txt") +covrun root "$RLO" "$RHI" "$RK" "$RF"; cat covres_root.txt | tee -a all.out | sed 's/^/ /' +if [ "$FULL" = 1 ]; then + grep '^non' "$DATA/targets.txt" | while read -r n lo hi k f; do echo "$n $lo $hi $k $f"; done > nonlist.txt + export -f covrun; export OUT + < nonlist.txt xargs -P 3 -L 1 bash -c 'covrun "$@"' _ +else + for n in non05_79 non06_80; do read -r _ lo hi k f < <(grep "^$n " "$DATA/targets.txt"); covrun "$n" "$lo" "$hi" "$k" "$f" & done # two background processes + for f in shipped_left_non*.txt; do b=${f#shipped_}; [ -e "$b" ] || cp "$f" "$b"; done +fi +NONLIST="non00_70 non01_73 non02_76 non03_77 non04_78 non05_79 non06_80 non07_82 non08_84 non09_84 non10_85 non11_85 non12_86 non13_87 non14_88 non15_88 non16_89" +echo "== 4. covering facts" +# (anroot runs now, concurrently with the two background covering processes: 3 busy processes in total) +timeout 3000 nice -n 10 "$PY" -B "$C/anroot.py" > anroot.log 2>&1 +wait +if [ "$FULL" != 1 ]; then for n in non05_79 non06_80; do cat "covres_$n.txt" | tee -a all.out | sed 's/^/ /'; done; else for n in $NONLIST; do cat "covres_$n.txt" | tee -a all.out | sed 's/^/ /'; done; fi +for n in $NONLIST; do [ -e "left_$n.txt" ] || echo "missing left_$n.txt"; done +# annon reads left_nonXX_SZ.txt +timeout 900 nice -n 10 "$PY" -B "$C/annon.py" > annon.log 2>&1 +run facts 600 "$PY" -B "$C/facts_check.py" anroot.log annon.log +run d7plane 600 "$PY" -B "$C/d7plane.py" + +echo "== 5. RRC, Lemma P, ledger" +timeout 900 "$PY" -B "$C/run_rrc.py" > rrc.log 2>&1; expect rrc '^Counter' "RRC engine ran; every certificate re-verified by verify() (no assertion error)" +timeout 900 "$PY" -B "$C/lemp_audit.py" > lemp.log 2>&1; expect lemp 'Lemma P kills \(all 603 rows\): 375' "Lemma P at T-level kills 375 of the 603 rows"; expect lemp 'reproduced: 74 / 74' "all 74 original class-A kills reproduced" +timeout 900 "$PY" -B "$C/build_ledger.py" > ledger.log 2>&1 +run ledger 600 "$PY" -B "$C/check_ledger.py" +if [ "$FULL" = 1 ]; then + echo "== 6. provenance of rows_input.csv: span facts rerun from source, dominance filter, land7.py" + PROV="$HERE/provenance"; mkdir -p "$OUT/replay_logs" + LOGDIR="${REPLAY_LOGDIR:-$OUT/replay_logs}" PYTHON="$PY" JOBS=4 timeout 7200 bash "$PROV/replay_spanfacts.sh" > replay.log 2>&1; grep -E '^(PASS|FAIL|CPU|REPLAY)' replay.log | sed 's/^/ /' + if grep -q '^REPLAY PASS' replay.log && ! grep -q '^FAIL' replay.log; then note "PASS ran replay_spanfacts.sh (all eight span facts rerun from source, equal to the shipped logs)"; else note "FAIL replay_spanfacts.sh"; tail -3 replay.log; fi + FULL=1 PYTHON="$PY" timeout 3600 bash "$PROV/reproduce.sh" > reproduce.log 2>&1; grep -E '^(PASS|FAIL)' reproduce.log | sed 's/^/ /' + if ! grep -q '^FAIL' reproduce.log && [ "$(grep -c '^PASS' reproduce.log)" -ge 2 ]; then note "PASS ran reproduce.sh (land7.py rerun identical, dominance filter gives rows_input.csv)"; else note "FAIL reproduce.sh"; tail -3 reproduce.log; fi +fi +npass=$(grep -c '^PASS' all.out); nfail=$(grep -c '^FAIL' all.out) +echo "== done in $((SECONDS - T0))s: $npass PASS, $nfail FAIL; logs in $OUT" +[ "$nfail" = 0 ] && { echo "PASS: all assertions hold"; exit 0; } +echo "FAIL"; exit 1