diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/.gitattributes b/research/f7-mu2-evenhalf-kb3k-88a1/.gitattributes new file mode 100644 index 0000000000..292c4ba473 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/.gitattributes @@ -0,0 +1,3 @@ +# Byte-exact pins: disable EOL conversion for every file in this package so the +# SHA-256 pins in SOURCES.json/verify.py survive checkout (the agent-86 EOL trap). +* -text diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-0.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-0.json new file mode 100644 index 0000000000..b77dc5201d --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-0.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1468.63, + "shard": 0, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8546388, + "uv_pairs_by_sumset_size": { + "24": 3001644, + "25": 2461824, + "26": 1563396, + "27": 723456, + "28": 778068, + "29": 14400, + "30": 3600 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1468.63, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-1.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-1.json new file mode 100644 index 0000000000..712f80c074 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-1.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1433.28, + "shard": 1, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8592684, + "uv_pairs_by_sumset_size": { + "24": 3015576, + "25": 2469816, + "26": 1575312, + "27": 716544, + "28": 799236, + "29": 12960, + "30": 3240 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1433.28, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-10.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-10.json new file mode 100644 index 0000000000..f0fb7d4f00 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-10.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1411.37, + "shard": 10, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8557890, + "uv_pairs_by_sumset_size": { + "24": 3038688, + "25": 2443068, + "26": 1577796, + "27": 703872, + "28": 775566, + "29": 15120, + "30": 3780 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1411.37, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-11.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-11.json new file mode 100644 index 0000000000..082ad3d093 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-11.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1443.17, + "shard": 11, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8737035, + "uv_pairs_by_sumset_size": { + "24": 3166542, + "25": 2508102, + "26": 1594428, + "27": 681408, + "28": 771705, + "29": 11880, + "30": 2970 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1443.17, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-12.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-12.json new file mode 100644 index 0000000000..78da85b724 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-12.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1432.77, + "shard": 12, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8659086, + "uv_pairs_by_sumset_size": { + "24": 3168396, + "25": 2472876, + "26": 1587192, + "27": 676224, + "28": 735498, + "29": 15120, + "30": 3780 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1432.77, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-13.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-13.json new file mode 100644 index 0000000000..6863430a65 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-13.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1427.14, + "shard": 13, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8552913, + "uv_pairs_by_sumset_size": { + "24": 3044466, + "25": 2492946, + "26": 1541148, + "27": 730944, + "28": 724059, + "29": 15480, + "30": 3870 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1427.14, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-14.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-14.json new file mode 100644 index 0000000000..32e7d8a190 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-14.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1415.51, + "shard": 14, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8557890, + "uv_pairs_by_sumset_size": { + "24": 3038688, + "25": 2443068, + "26": 1577796, + "27": 703872, + "28": 775566, + "29": 15120, + "30": 3780 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1415.51, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-15.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-15.json new file mode 100644 index 0000000000..d1a46a5992 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-15.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1425.75, + "shard": 15, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8549286, + "uv_pairs_by_sumset_size": { + "24": 2936844, + "25": 2429244, + "26": 1592232, + "27": 717696, + "28": 857970, + "29": 12240, + "30": 3060 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1425.75, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-16.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-16.json new file mode 100644 index 0000000000..a05dc2225e --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-16.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1562.19, + "shard": 16, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8541699, + "uv_pairs_by_sumset_size": { + "24": 2960370, + "25": 2381310, + "26": 1620096, + "27": 688320, + "28": 874953, + "29": 13320, + "30": 3330 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1562.19, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-17.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-17.json new file mode 100644 index 0000000000..7374ef2de6 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-17.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1561.89, + "shard": 17, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8564172, + "uv_pairs_by_sumset_size": { + "24": 3024036, + "25": 2442096, + "26": 1582188, + "27": 705024, + "28": 792828, + "29": 14400, + "30": 3600 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1561.89, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-18.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-18.json new file mode 100644 index 0000000000..89ab88e24f --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-18.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1558.05, + "shard": 18, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8534067, + "uv_pairs_by_sumset_size": { + "24": 3088422, + "25": 2495862, + "26": 1527972, + "27": 727488, + "28": 672273, + "29": 17640, + "30": 4410 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1558.05, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-19.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-19.json new file mode 100644 index 0000000000..14bc390016 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-19.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1564.77, + "shard": 19, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8543490, + "uv_pairs_by_sumset_size": { + "24": 3066444, + "25": 2494404, + "26": 1534560, + "27": 729216, + "28": 698166, + "29": 16560, + "30": 4140 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1564.77, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-2.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-2.json new file mode 100644 index 0000000000..03be5668a2 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-2.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1472.53, + "shard": 2, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8681073, + "uv_pairs_by_sumset_size": { + "24": 3117114, + "25": 2469474, + "26": 1602564, + "27": 680256, + "28": 795915, + "29": 12600, + "30": 3150 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1472.53, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-20.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-20.json new file mode 100644 index 0000000000..2f2090fcaa --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-20.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1582.58, + "shard": 20, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8740419, + "uv_pairs_by_sumset_size": { + "24": 3216690, + "25": 2539710, + "26": 1569984, + "27": 688320, + "28": 709065, + "29": 13320, + "30": 3330 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1582.58, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-21.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-21.json new file mode 100644 index 0000000000..e56fd42986 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-21.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1563.91, + "shard": 21, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8490426, + "uv_pairs_by_sumset_size": { + "24": 2952216, + "25": 2423196, + "26": 1571532, + "27": 722304, + "28": 802278, + "29": 15120, + "30": 3780 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1563.91, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-22.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-22.json new file mode 100644 index 0000000000..8a3ae33583 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-22.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1567.7, + "shard": 22, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8554992, + "uv_pairs_by_sumset_size": { + "24": 3103488, + "25": 2475648, + "26": 1548960, + "27": 709632, + "28": 695664, + "29": 17280, + "30": 4320 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1567.7, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-23.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-23.json new file mode 100644 index 0000000000..794b2cd866 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-23.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1434.28, + "shard": 23, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8591622, + "uv_pairs_by_sumset_size": { + "24": 3081924, + "25": 2453004, + "26": 1580928, + "27": 694656, + "28": 762210, + "29": 15120, + "30": 3780 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1434.28, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-24.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-24.json new file mode 100644 index 0000000000..9129c55e40 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-24.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1432.47, + "shard": 24, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8576979, + "uv_pairs_by_sumset_size": { + "24": 3052206, + "25": 2472246, + "26": 1564332, + "27": 713664, + "28": 756081, + "29": 14760, + "30": 3690 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1432.47, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-25.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-25.json new file mode 100644 index 0000000000..237df764d5 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-25.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1431.47, + "shard": 25, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8620134, + "uv_pairs_by_sumset_size": { + "24": 3073464, + "25": 2480724, + "26": 1574052, + "27": 706176, + "28": 768618, + "29": 13680, + "30": 3420 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1431.47, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-26.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-26.json new file mode 100644 index 0000000000..28f89e0948 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-26.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1424.52, + "shard": 26, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8608344, + "uv_pairs_by_sumset_size": { + "24": 3170664, + "25": 2416464, + "26": 1605336, + "27": 654336, + "28": 739944, + "29": 17280, + "30": 4320 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1424.52, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-27.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-27.json new file mode 100644 index 0000000000..2fab0b0ddc --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-27.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1432.19, + "shard": 27, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8530440, + "uv_pairs_by_sumset_size": { + "24": 2980800, + "25": 2432160, + "26": 1579056, + "27": 714240, + "28": 806184, + "29": 14400, + "30": 3600 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1432.19, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-28.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-28.json new file mode 100644 index 0000000000..4b96525278 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-28.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1436.22, + "shard": 28, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8579877, + "uv_pairs_by_sumset_size": { + "24": 2987406, + "25": 2439666, + "26": 1593168, + "27": 707904, + "28": 835983, + "29": 12600, + "30": 3150 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1436.22, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-29.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-29.json new file mode 100644 index 0000000000..dc57121b67 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-29.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 830.79, + "shard": 29, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8601045, + "uv_pairs_by_sumset_size": { + "24": 3059946, + "25": 2451546, + "26": 1587516, + "27": 696384, + "28": 788103, + "29": 14040, + "30": 3510 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 830.79, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-3.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-3.json new file mode 100644 index 0000000000..f355b96f56 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-3.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1480.78, + "shard": 3, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8748780, + "uv_pairs_by_sumset_size": { + "24": 3261060, + "25": 2521440, + "26": 1582188, + "27": 668160, + "28": 697932, + "29": 14400, + "30": 3600 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1480.78, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-4.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-4.json new file mode 100644 index 0000000000..bff5a7a201 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-4.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1445.45, + "shard": 4, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8506131, + "uv_pairs_by_sumset_size": { + "24": 2915586, + "25": 2420766, + "26": 1582512, + "27": 725184, + "28": 845433, + "29": 13320, + "30": 3330 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1445.45, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-5.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-5.json new file mode 100644 index 0000000000..3f5eec8e71 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-5.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1465.59, + "shard": 5, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8598147, + "uv_pairs_by_sumset_size": { + "24": 3124746, + "25": 2484126, + "26": 1558680, + "27": 702144, + "28": 708201, + "29": 16200, + "30": 4050 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1465.59, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-6.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-6.json new file mode 100644 index 0000000000..c2c0a8b7cc --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-6.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1472.75, + "shard": 6, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8647341, + "uv_pairs_by_sumset_size": { + "24": 3073878, + "25": 2459538, + "26": 1599432, + "27": 689472, + "28": 809271, + "29": 12600, + "30": 3150 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1472.75, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-7.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-7.json new file mode 100644 index 0000000000..d24556e066 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-7.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1458.79, + "shard": 7, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8595006, + "uv_pairs_by_sumset_size": { + "24": 3132072, + "25": 2484612, + "26": 1556484, + "27": 701568, + "28": 699570, + "29": 16560, + "30": 4140 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1458.79, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-8.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-8.json new file mode 100644 index 0000000000..cb9841dd1c --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-8.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1431.77, + "shard": 8, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8615931, + "uv_pairs_by_sumset_size": { + "24": 3147138, + "25": 2464398, + "26": 1577472, + "27": 683712, + "28": 722961, + "29": 16200, + "30": 4050 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1431.77, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-9.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-9.json new file mode 100644 index 0000000000..e139e7f8a3 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-9.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1430.3, + "shard": 9, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8622213, + "uv_pairs_by_sumset_size": { + "24": 3132486, + "25": 2463426, + "26": 1581864, + "27": 684864, + "28": 740223, + "29": 15480, + "30": 3870 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1430.3, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-RECOMPUTE-1-first-run.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-RECOMPUTE-1-first-run.json new file mode 100644 index 0000000000..8445f61ca7 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-RECOMPUTE-1-first-run.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 1450.03, + "shard": 1, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8592684, + "uv_pairs_by_sumset_size": { + "24": 3015576, + "25": 2469816, + "26": 1575312, + "27": 716544, + "28": 799236, + "29": 12960, + "30": 3240 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 1450.03, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/AV42-RECOMPUTE-29-first-run.json b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-RECOMPUTE-29-first-run.json new file mode 100644 index 0000000000..6dff5a36a3 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/AV42-RECOMPUTE-29-first-run.json @@ -0,0 +1,33 @@ +{ + "budget_hit": false, + "complete": true, + "covering_configs": 0, + "fail_hist": {}, + "normalized_u_total": 169911, + "seconds": 904.25, + "shard": 29, + "shards": 2048, + "u_checked": 83, + "uv_pairs": 8601045, + "uv_pairs_by_sumset_size": { + "24": 3059946, + "25": 2451546, + "26": 1587516, + "27": 696384, + "28": 788103, + "29": 14040, + "30": 3510 + }, + "w_candidates": 0, + "w_candidates_by_m_size": { + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0 + }, + "wall_seconds": 904.25, + "witnesses": [] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/CERTIFICATE.json b/research/f7-mu2-evenhalf-kb3k-88a1/CERTIFICATE.json new file mode 100644 index 0000000000..ad7f0326df --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/CERTIFICATE.json @@ -0,0 +1,96 @@ +{ + "schema_version": 1, + "title": "KB3k certificate: the mu2-constant even-half condition for the 18-point cover question of F2^7", + "outcome": "partial", + "summary": "The mu2-constant lead of PR 3108 is DEMOTED as a proof filter. mu2 = |A+A| + |B+B| - |G| is an exact identity for every reduced cover; mu2 is constant per split only when the selfsum-size sum |A+A| + |B+B| is, and that sum is NOT pinned by the covering condition: it varies at the minimal split (4,4) in F2^3. For the both-odd target regime (11,7)/(9,9), mu2 is constant at every scale where covers exist but is CHECKED, not forced. No class is decided; no cover constructed; no false kill.", + "claims": [ + { + "id": "IDENTITY", + "label": "PROVEN", + "statement": "For every reduced covering pair (A,B) of G=F2^m (A+B=G and (A+A) u (B+B)=G), mu2 = |(A+A) n (B+B)| = |A+A| + |B+B| - |G|, and (A+A) u (B+B) = G.", + "evidence": "Inclusion-exclusion on (A+A) u (B+B) = G: |A+A| + |B+B| = |G| + mu2. Validated exhaustively at 0 violations over all 41,341 F2^3 covers and all F2^4 covers enumerated (mu2_search.py identity, verify.py quick).", + "numbers": {"F2^3_covers": 41341, "identity_violations": 0} + }, + { + "id": "NOT_FORCED_MINIMAL", + "label": "PROVEN", + "statement": "mu2 is not constant per split. The minimal variation split is (4,4) in F2^3 (3,360 covers): mu2 = 6 when both halves are generic (|A+A|=|B+B|=7), mu2 = 3 when exactly one half is an affine plane (|A+A|=4 or |B+B|=4). mu2 = 6 - 3*(number of plane halves).", + "evidence": "Complete enumeration of F2^1 (2 elements), F2^2 (4), F2^3 (8): no mu2 variation at F2^1 or F2^2; first variation at F2^3 at split (4,4). mu2_mechanism.py, verify.py quick (minimal varying split assertion).", + "numbers": { + "F2^1_varying_splits": 0, + "F2^2_varying_splits": 0, + "F2^3_minimal_varying_split": "(4,4)", + "(4,4)_covers": 3360, + "(4,4)_mu2_values": [3, 6], + "both_generic_mu2_6_covers": 2688, + "one_plane_mu2_3_covers": 672 + } + }, + { + "id": "MECHANISM", + "label": "PROVEN", + "statement": "mu2 varies with the additive structure of a half. In F2^3 a 4-set is either a coset of a 2-dim subspace (affine plane, |A+A|=4) or generic (|A+A|=7). A structured half lowers |A+A| by 3 and mu2 by 3. At (4,6) in F2^4 the split is constant (mu2=4) only because the two selfsum sizes are anti-correlated by the cover condition (|A+A|=4 forces |B+B|=16; |A+A|=7 forces |B+B|=13; sum 20).", + "evidence": "mu2_mechanism.py (4,4) cluster table; mu2_search.py m4 (4,6) sa_set=[4,7], sb_set=[13,16], sum_set=[20], mu2=4 all 143,360 covers.", + "numbers": { + "F2^4_(4,6)_covers": 143360, + "F2^4_(4,6)_mu2": [4], + "F2^4_(4,6)_sa_set": [4, 7], + "F2^4_(4,6)_sb_set": [13, 16], + "F2^4_(4,6)_sum_set": [20] + } + }, + { + "id": "BOTH_ODD_CONSTANT_NOT_FORCED", + "label": "CHECKED", + "statement": "For the both-odd target regime (11,7)/(9,9), mu2 is constant at every both-odd split where covers can be produced, but this is not forced. F2^3 both-odd splits all constant (complete). F2^5 (7,7) 310 covers, all mu2=12 with |A+A|=|B+B|=22. F2^6 (9,9)/(11,7) covers were not produced in a bounded hill-climbing search (0 in 300 restarts each), so mu2 variation at the exact target splits is neither observed nor ruled out.", + "evidence": "mu2_search.py m3 (both-odd complete); mu2_odd_search.py (F2^5 (7,7) 310 covers mu2=12; F2^6 (9,9)/(11,7) 0 covers); mu2_search.py m5odd/m6 sampling. The (4,4) counterexample shows the covering condition does not pin mu2 in general.", + "numbers": { + "F2^5_(7,7)_covers": 310, + "F2^5_(7,7)_mu2": [12], + "F2^5_(7,7)_sa_sb": [22, 22], + "F2^6_(9,9)_covers_produced": 0, + "F2^6_(11,7)_covers_produced": 0 + } + }, + { + "id": "DEMOTED_LEAD", + "label": "DEMOTED", + "statement": "The plan 'mu2 is constant per split, carry it to PR 2911's 501/196 rows as a filter, then lift to m=6' is not justified. mu2-constancy is scale- and split-dependent: false for both-even splits ((4,4) F2^3), empirical for both-odd splits, unforced everywhere. It cannot be applied as a hard proof filter without a both-odd forcing proof (absent). This is the same shape as PR 3034's demoted scale-dependent self-sum lift.", + "evidence": "PROVEN minimal variation at (4,4) F2^3 (NOT_FORCED_MINIMAL); CHECKED both-odd constancy only (BOTH_ODD_CONSTANT_NOT_FORCED). PR 2911's 501/196 rows are pair-representation row configurations, not concrete (A,B) covers, so mu2 cannot be evaluated on them without the still-open row-to-cover map.", + "numbers": {} + }, + { + "id": "WALK42", + "label": "CHECKED", + "statement": "The (12,6) A-vanish (4,2) decision walk is continued as a budget-honest partial (never an exclusion). PR 3108's sharded walk is extended by shard 29 with a per-shard receipt (explicit complete/budget_hit flags, budget checked after every U), and re-run from empty receipts with identical counters to prove recomputation.", + "evidence": "run42.py/walk42.py (vendored byte-exact from PR 3108) drive the walk; AV42-AV42-29.json is this session's clean from-empty shard receipt; AV42-RECOMPUTE-29-first-run.json is the preserved first clean run compared against the re-run from empty (counters identical). Aggregate over all complete shards in CERTIFICATE numbers.", + "numbers": { + "shards_complete_total": 30, + "shards_total": 2048, + "shard29_u_checked": 83, + "shard29_uv_pairs": 8601045, + "shard29_w_candidates": 0, + "shard29_covering_configs": 0, + "shard29_complete": true, + "recompute_identical": true + } + }, + { + "id": "ANCHORS", + "label": "CHECKED", + "statement": "Recorded anchors reproduced before any new number.", + "evidence": "PR 3108 verify.py quick (vendored): PR 2870 OBSTRUCTION parseval=696 allowed=504 deficit=192 (live); PR 2933 CLASSIFY tight=2 cases=6720 (live); PR 2961 FOURIER (7,1) need=175 lower=239 contradiction=True (live); PR 2961 CLASS82 checked=28,815,360 covering=0, CLASS60 d_checked=169,911, PR 3023 AV51 uv_pairs=3,049,492,320 covering=0 (read back from PR 3023's pinned receipts); PR 3108 SELFSUM (5,5)=3,136/(7,7)=64 profiles (8,8,8), CENSUS33 (3,3) covers=296,352 (read back).", + "numbers": { + "PR2870": "parseval=696 allowed=504 deficit=192", + "PR2933": "tight=2 cases=6720", + "PR2961_FOURIER": "need=175 lower=239 contradiction=True", + "PR2961_CLASS82": "checked=28815360 covering=0", + "PR2961_CLASS60": "d_checked=169911", + "PR3023_AV51": "uv_pairs=3049492320 covering=0", + "PR3108_SELFSUM": "(5,5)=3136 (7,7)=64 profiles (8,8,8)", + "PR3108_CENSUS33": "(3,3) covers=296352" + } + } + ], + "frontiers": "Unchanged. No 18-point cover of F2^7 is constructed or excluded here; (11,7), (9,9), (4,2), (3,3) remain undecided at the set level. The (4,2) walk partial covers a fraction of the normalized pairs and is not an exclusion. Word-level state (PR 2973/3005, Nicholas Stone / Nick Petalas) records 22 <= f(7) <= 24 and is untouched (SET-level only here)." +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/MU2-IDENTITY.json b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-IDENTITY.json new file mode 100644 index 0000000000..11976eee5f --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-IDENTITY.json @@ -0,0 +1,6 @@ +{ + "m3": { + "covers": 41341, + "violations": 0 + } +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M3.json b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M3.json new file mode 100644 index 0000000000..44f076157e --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M3.json @@ -0,0 +1,834 @@ +{ + "any_mu2_variation": true, + "gsize": 8, + "identity_violations": 0, + "splits": { + "1,8": { + "covers": 8, + "mu2_constant": true, + "mu2_set": [ + 1 + ], + "sa_set": [ + 1 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 9 + ] + }, + "2,4": { + "covers": 224, + "mu2_constant": true, + "mu2_set": [ + 1 + ], + "sa_set": [ + 2 + ], + "sb_set": [ + 7 + ], + "sum_constant": true, + "sum_set": [ + 9 + ] + }, + "2,5": { + "covers": 896, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 2 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "2,6": { + "covers": 672, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 2 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "2,7": { + "covers": 224, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 2 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "2,8": { + "covers": 28, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 2 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "3,4": { + "covers": 1344, + "mu2_constant": true, + "mu2_set": [ + 3 + ], + "sa_set": [ + 4 + ], + "sb_set": [ + 7 + ], + "sum_constant": true, + "sum_set": [ + 11 + ] + }, + "3,5": { + "covers": 2688, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 4 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "3,6": { + "covers": 1568, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 4 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "3,7": { + "covers": 448, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 4 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "3,8": { + "covers": 56, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 4 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "4,2": { + "covers": 224, + "mu2_constant": true, + "mu2_set": [ + 1 + ], + "sa_set": [ + 7 + ], + "sb_set": [ + 2 + ], + "sum_constant": true, + "sum_set": [ + 9 + ] + }, + "4,3": { + "covers": 1344, + "mu2_constant": true, + "mu2_set": [ + 3 + ], + "sa_set": [ + 7 + ], + "sb_set": [ + 4 + ], + "sum_constant": true, + "sum_set": [ + 11 + ] + }, + "4,4": { + "covers": 3360, + "mu2_constant": false, + "mu2_set": [ + 3, + 6 + ], + "sa_set": [ + 4, + 7 + ], + "sb_set": [ + 4, + 7 + ], + "sum_constant": false, + "sum_set": [ + 11, + 14 + ] + }, + "4,5": { + "covers": 3920, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 4, + 7 + ], + "sb_set": [ + 8 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "4,6": { + "covers": 1960, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 4, + 7 + ], + "sb_set": [ + 8 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "4,7": { + "covers": 560, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 4, + 7 + ], + "sb_set": [ + 8 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "4,8": { + "covers": 70, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 4, + 7 + ], + "sb_set": [ + 8 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "5,2": { + "covers": 896, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 2 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "5,3": { + "covers": 2688, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "5,4": { + "covers": 3920, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4, + 7 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "5,5": { + "covers": 3136, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "5,6": { + "covers": 1568, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "5,7": { + "covers": 448, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "5,8": { + "covers": 56, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "6,2": { + "covers": 672, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 2 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "6,3": { + "covers": 1568, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "6,4": { + "covers": 1960, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4, + 7 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "6,5": { + "covers": 1568, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "6,6": { + "covers": 784, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "6,7": { + "covers": 224, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "6,8": { + "covers": 28, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "7,2": { + "covers": 224, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 2 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "7,3": { + "covers": 448, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "7,4": { + "covers": 560, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4, + 7 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "7,5": { + "covers": 448, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "7,6": { + "covers": 224, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "7,7": { + "covers": 64, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "7,8": { + "covers": 8, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "8,1": { + "covers": 8, + "mu2_constant": true, + "mu2_set": [ + 1 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 1 + ], + "sum_constant": true, + "sum_set": [ + 9 + ] + }, + "8,2": { + "covers": 28, + "mu2_constant": true, + "mu2_set": [ + 2 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 2 + ], + "sum_constant": true, + "sum_set": [ + 10 + ] + }, + "8,3": { + "covers": 56, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4 + ], + "sum_constant": true, + "sum_set": [ + 12 + ] + }, + "8,4": { + "covers": 70, + "mu2_constant": false, + "mu2_set": [ + 4, + 7 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 4, + 7 + ], + "sum_constant": false, + "sum_set": [ + 12, + 15 + ] + }, + "8,5": { + "covers": 56, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "8,6": { + "covers": 28, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "8,7": { + "covers": 8, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + }, + "8,8": { + "covers": 1, + "mu2_constant": true, + "mu2_set": [ + 8 + ], + "sa_set": [ + 8 + ], + "sb_set": [ + 8 + ], + "sum_constant": true, + "sum_set": [ + 16 + ] + } + } +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M4.json b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M4.json new file mode 100644 index 0000000000..512c57a27c --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M4.json @@ -0,0 +1,114 @@ +{ + "any_mu2_variation": true, + "gsize": 16, + "splits": { + "1,5": { + "covers": 0, + "identity_violations": 0, + "mu2_constant": false, + "mu2_set": [], + "sa_set": [], + "sb_set": [], + "sum_constant": false, + "sum_set": [] + }, + "1,9": { + "covers": 0, + "identity_violations": 0, + "mu2_constant": false, + "mu2_set": [], + "sa_set": [], + "sb_set": [], + "sum_constant": false, + "sum_set": [] + }, + "2,2": { + "covers": 0, + "identity_violations": 0, + "mu2_constant": false, + "mu2_set": [], + "sa_set": [], + "sb_set": [], + "sum_constant": false, + "sum_set": [] + }, + "2,8": { + "covers": 15360, + "identity_violations": 0, + "mu2_constant": true, + "mu2_set": [ + 1 + ], + "sa_set": [ + 2 + ], + "sb_set": [ + 15 + ], + "sum_constant": true, + "sum_set": [ + 17 + ] + }, + "3,3": { + "covers": 0, + "identity_violations": 0, + "mu2_constant": false, + "mu2_set": [], + "sa_set": [], + "sb_set": [], + "sum_constant": false, + "sum_set": [] + }, + "3,7": { + "covers": 0, + "identity_violations": 0, + "mu2_constant": false, + "mu2_set": [], + "sa_set": [], + "sb_set": [], + "sum_constant": false, + "sum_set": [] + }, + "4,4": { + "covers": 0, + "identity_violations": 0, + "mu2_constant": false, + "mu2_set": [], + "sa_set": [], + "sb_set": [], + "sum_constant": false, + "sum_set": [] + }, + "4,6": { + "covers": 143360, + "identity_violations": 0, + "mu2_constant": true, + "mu2_set": [ + 4 + ], + "sa_set": [ + 4, + 7 + ], + "sb_set": [ + 13, + 16 + ], + "sum_constant": true, + "sum_set": [ + 20 + ] + }, + "5,5": { + "covers": 0, + "identity_violations": 0, + "mu2_constant": false, + "mu2_set": [], + "sa_set": [], + "sb_set": [], + "sum_constant": false, + "sum_set": [] + } + } +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M5ODD.json b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M5ODD.json new file mode 100644 index 0000000000..fd2ec18fc5 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M5ODD.json @@ -0,0 +1,36 @@ +{ + "any_mu2_variation_observed": false, + "gsize": 32, + "mode": "random-sampling", + "splits": { + "3,7": { + "covers_sampled": 0, + "mu2_constant_observed": true, + "mu2_hist": {}, + "sum_hist": {} + }, + "5,5": { + "covers_sampled": 0, + "mu2_constant_observed": true, + "mu2_hist": {}, + "sum_hist": {} + }, + "5,7": { + "covers_sampled": 0, + "mu2_constant_observed": true, + "mu2_hist": {}, + "sum_hist": {} + }, + "7,7": { + "covers_sampled": 32, + "mu2_constant_observed": true, + "mu2_hist": { + "12": 32 + }, + "sum_hist": { + "44": 32 + } + } + }, + "trials_per_split": 400000 +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M6.json b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M6.json new file mode 100644 index 0000000000..28b2ecf0ea --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-M6.json @@ -0,0 +1,20 @@ +{ + "any_mu2_variation_observed": false, + "gsize": 64, + "mode": "random-sampling", + "splits": { + "11,7": { + "covers_sampled": 0, + "mu2_constant_observed": true, + "mu2_hist": {}, + "sum_hist": {} + }, + "9,9": { + "covers_sampled": 0, + "mu2_constant_observed": true, + "mu2_hist": {}, + "sum_hist": {} + } + }, + "trials_per_split": 400000 +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/MU2-MECH.json b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-MECH.json new file mode 100644 index 0000000000..17ad5dfc4d --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-MECH.json @@ -0,0 +1,121 @@ +{ + "F2^1": { + "splits_with_covers": 3, + "varying_splits": {} + }, + "F2^2": { + "splits_with_covers": 10, + "varying_splits": {} + }, + "F2^3": { + "splits_with_covers": 47, + "varying_splits": { + "4,4": { + "mu2_set": [ + 3, + 6 + ], + "n": 3360, + "sum_set": [ + 11, + 14 + ] + }, + "4,5": { + "mu2_set": [ + 4, + 7 + ], + "n": 3920, + "sum_set": [ + 12, + 15 + ] + }, + "4,6": { + "mu2_set": [ + 4, + 7 + ], + "n": 1960, + "sum_set": [ + 12, + 15 + ] + }, + "4,7": { + "mu2_set": [ + 4, + 7 + ], + "n": 560, + "sum_set": [ + 12, + 15 + ] + }, + "4,8": { + "mu2_set": [ + 4, + 7 + ], + "n": 70, + "sum_set": [ + 12, + 15 + ] + }, + "5,4": { + "mu2_set": [ + 4, + 7 + ], + "n": 3920, + "sum_set": [ + 12, + 15 + ] + }, + "6,4": { + "mu2_set": [ + 4, + 7 + ], + "n": 1960, + "sum_set": [ + 12, + 15 + ] + }, + "7,4": { + "mu2_set": [ + 4, + 7 + ], + "n": 560, + "sum_set": [ + 12, + 15 + ] + }, + "8,4": { + "mu2_set": [ + 4, + 7 + ], + "n": 70, + "sum_set": [ + 12, + 15 + ] + } + } + }, + "F2^3_(4,4)_mechanism": { + "(structA,structB,mu2)->count": { + "False,False,6": 2688, + "False,True,3": 336, + "True,False,3": 336 + } + } +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/MU2-ODD.json b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-ODD.json new file mode 100644 index 0000000000..797d21357b --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/MU2-ODD.json @@ -0,0 +1,27 @@ +{ + "F2^5 (7,7)": { + "covers_found": 310, + "gsize": 32, + "mu2_constant_observed": true, + "mu2_set": [ + 12 + ], + "profiles_(sa,sb,mu2)_counts": { + "22,22,12": 310 + } + }, + "F2^6 (11,7)": { + "covers_found": 0, + "gsize": 64, + "mu2_constant_observed": true, + "mu2_set": [], + "profiles_(sa,sb,mu2)_counts": {} + }, + "F2^6 (9,9)": { + "covers_found": 0, + "gsize": 64, + "mu2_constant_observed": true, + "mu2_set": [], + "profiles_(sa,sb,mu2)_counts": {} + } +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/NOTICE.md b/research/f7-mu2-evenhalf-kb3k-88a1/NOTICE.md new file mode 100644 index 0000000000..d01f467de9 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/NOTICE.md @@ -0,0 +1,70 @@ +# NOTICE - KB3k (research/f7-mu2-evenhalf-kb3k-88a1) + +Author: Aaron Wang, with help from opencode (substantial AI assistance; no model +named; no independent human review claimed). Set-level only; no words enumerated. + +## Predecessor credit + +Every cited PR author was re-verified at writing with +`gh pr view NNN --json author,title`: + +- [PR 2542](https://github.com/CrocSwap/integer-mult-bounds/pull/2542), + [PR 2634](https://github.com/CrocSwap/integer-mult-bounds/pull/2634), + [PR 2773](https://github.com/CrocSwap/integer-mult-bounds/pull/2773), + [PR 2870](https://github.com/CrocSwap/integer-mult-bounds/pull/2870), + [PR 2911](https://github.com/CrocSwap/integer-mult-bounds/pull/2911), + [PR 2933](https://github.com/CrocSwap/integer-mult-bounds/pull/2933), + [PR 2961](https://github.com/CrocSwap/integer-mult-bounds/pull/2961), + [PR 3023](https://github.com/CrocSwap/integer-mult-bounds/pull/3023), + [PR 3034](https://github.com/CrocSwap/integer-mult-bounds/pull/3034), + [PR 3108](https://github.com/CrocSwap/integer-mult-bounds/pull/3108) + (Aaron Wang / navinor): the 17-point exclusion chain, the pair-representation + rows and odd-coverage Fourier/Parseval identity, the (A,D) reduction and + vanishing-character restriction, the class floors and tight-class decisions, + the (5,1) decision and its walk engine, the KB3i remainder (parity demotion, + m=5 obstruction localization), and the KB3j mu2 lead and (4,2) walk this + package presses and continues. +- [PR 943](https://github.com/CrocSwap/integer-mult-bounds/pull/943) (Ross + Richardson): the prefix-walk model. +- [PR 1185](https://github.com/CrocSwap/integer-mult-bounds/pull/1185) + (Mister-Meeseeks): the pinned `f(5)=12`, `f(6)=16` record. +- [PR 2691](https://github.com/CrocSwap/integer-mult-bounds/pull/2691), + [PR 2973](https://github.com/CrocSwap/integer-mult-bounds/pull/2973) + (Nicholas Stone) and [PR 3005](https://github.com/CrocSwap/integer-mult-bounds/pull/3005) + (Nick Petalas): the word-level census line and its correction (recorded state; + PR 2973 leaves the set-level chain intact). Untouched here. + +## Vendored engines (byte-exact, SHA-256 pinned) + +`vendor/parity_census.py`, `vendor/selfsum_classify_kb3j.py`, +`vendor/tight.py`, `vendor/cover18.py`, `vendor/vanish.py`, +`vendor/agent64_cover17.py`, `vendor/agent64_search17.py`, +`vendor/anchors.py`, `vendor/self_obstruction.py`, `vendor/split_census.py`, +`walk42.py`, `run42.py` are vendored byte-exact from the predecessor packages +(PR 2773/2961/3023/3034/3108) via `agent_tools.py pr-tree-extract` and +`git archive`, with SHA-256 pins recorded in `SOURCES.json`. The pins are +enforced by `verify.py`. All credit is retained; no predecessor file is +modified. + +## New code (this package) + +`mu2_search.py` (mu2 identity + complete F2^3/F2^4 censuses + sampling), +`mu2_mechanism.py` (minimality + (4,4) mechanism census), +`mu2_odd_search.py` (both-odd hill-climbing cover search), `verify.py` (the +verifier). All exact Python integers (int bitmasks); no floats. + +## Model and pinned results + +PR943 query model (Ross Richardson); pinned `f(5)=12`, `f(6)=16` (PR 1185) and +the word-level gap `22 <= f(7) <= 24` (PR 2973/3005). Under that gap the +18-point question is the deciding necessary condition for `f(7) = 22`. This +package is SET-level only and enumerates no words. + +## Concurrency + +Nicholas Stone's f(7) WORD line (PR 2973) and Nick Petalas's corroboration +(PR 3005) are WORD level and untouched here. Pair-collision checks (discussions +1317 and 1166 via `agent_tools.py disc-comments --grep`, including nested +replies, before computation) found no live claim on the mu2 even-half condition +or the (4,2) walk. The parallel autoresearch-pure session (another agent) is a +distinct object and untouched. diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/README.md b/research/f7-mu2-evenhalf-kb3k-88a1/README.md new file mode 100644 index 0000000000..1fe6e4e964 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/README.md @@ -0,0 +1,220 @@ +# KB3k - the mu2-constant even-half condition for the 18-point cover question of `F2^7` + +**Set-level finite result, no words enumerated. Outcome=partial.** The mu2 +"constant per split" lead of [PR 3108](https://github.com/CrocSwap/integer-mult-bounds/pull/3108) +is pressed. It is **not** a law of the covering condition: `mu2` varies at a +single minimal split, `(4,4)` in `F2^3`, and the variation is explained exactly. +For the both-odd regime of the target splits `(11,7)`/`(9,9)`, `mu2` is constant +at every scale where covers can be produced, but that constancy is CHECKED, not +PROVEN, and it is not forced by any identity found here. The lead is therefore +**demoted as a proof filter** (it cannot be carried to PR 2911's 501/196 rows and +then to `m=6` as a hard condition). No class is decided; no cover is constructed; +no false kill is made. No new kappa. + +## Object and chain of record + +In the PR943 prefix-walk model +([PR 943](https://github.com/CrocSwap/integer-mult-bounds/pull/943), Ross +Richardson) a restored seven-source singleton word is universal exactly when its +prefix set `P` covers: `P + P = F2^7`. The 17-point question is closed +([PR 2542](https://github.com/CrocSwap/integer-mult-bounds/pull/2542), +[PR 2634](https://github.com/CrocSwap/integer-mult-bounds/pull/2634), +[PR 2773](https://github.com/CrocSwap/integer-mult-bounds/pull/2773), +[PR 2870](https://github.com/CrocSwap/integer-mult-bounds/pull/2870)); +[PR 2911](https://github.com/CrocSwap/integer-mult-bounds/pull/2911) narrowed +the 18-point question to `(12,6)`, `(11,7)`, `(10,8)`, `(9,9)`; +[PR 2933](https://github.com/CrocSwap/integer-mult-bounds/pull/2933) +classified the vanishing configurations; +[PR 2961](https://github.com/CrocSwap/integer-mult-bounds/pull/2961) fully +excluded `(10,8)` and decided three tightest classes; +[PR 3023](https://github.com/CrocSwap/integer-mult-bounds/pull/3023) killed +`(12,6)` A-vanish `(5,1)` and reduced `(4,2)`/`(3,3)` to exact walkable forms; +[PR 3034](https://github.com/CrocSwap/integer-mult-bounds/pull/3034) demoted +the parity shortcut and localized the m=5 obstruction; +[PR 3108](https://github.com/CrocSwap/integer-mult-bounds/pull/3108) walked a +partial of `(4,2)`, classified the even-half self-sum profiles, and recorded the +mu2-constancy lead this package presses. + +The reduced covering object (PR 2911 reduction lemma, `cover18.py` docstring): +for `G = F2^m`, a pair `(A, B)` of subsets **covers** iff `A + B = G` (cross) and +`(A+A) u (B+B) = G` (even-half / self sums). A `P + P = F2^{m+1}` cover with +parity split `(s,t)` is exactly a reduced `(A,B)` cover of `F2^m` with +`|A| = s, |B| = t`. The 18-point question is the reduced cover of `F2^6` (64 +elements) in splits `(12,6)`, `(11,7)`, `(10,8)`, `(9,9)`. Every cited PR author +was re-verified at writing with `gh pr view NNN --json author,title`: PR +2542/2634/2773/2870/2911/2933/2961/3023/3034/3108 are Aaron Wang (navinor); PR +2691/2973 are Nicholas Stone; PR 3005 is Nick Petalas; PR 1185 is +Mister-Meeseeks. This package is strictly SET-level and enumerates no words +(Nicholas Stone's `22 <= f(7) <= 24` word line is untouched). + +## The exact identity (PROVEN) + +For any reduced cover `(A,B)` of `G = F2^m` (`|G| = 2^m`), inclusion-exclusion +on `(A+A) u (B+B) = G` gives + +``` +mu2 = |(A+A) n (B+B)| = |A+A| + |B+B| - |G|. +``` + +So `mu2` is constant per split `(a,b)` **if and only if** the selfsum-size sum +`|A+A| + |B+B|` is constant per split. The identity holds exactly on all 41,341 +`F2^3` covers (`identity_violations = 0`) and all `F2^4` covers checked. The +whole lead reduces to: is `|A+A| + |B+B|` pinned by `(a,b)` among covers? + +## Verdict: not forced - the minimal variation split is (4,4) in F2^3 + +Complete enumeration at `F2^1` (2 elements), `F2^2` (4), `F2^3` (8) shows `mu2` +is constant per split at `F2^1` and `F2^2`, and first **varies** at `F2^3` at +split `(4,4)`. This is the minimal variation split (minimal group, and minimal +within `F2^3`). + +| Group | Split | Covers | mu2 values | sum `|A+A|+|B+B|` | +|---|---|---|---|---| +| `F2^3` | (4,4) | 3,360 | 3 and 6 | 11 and 14 | +| `F2^3` | (4,5),(4,6),(4,7),(4,8),(5,4),(6,4),(7,4),(8,4) | 560-3,920 each | 4 and 7 | 12 and 15 | +| `F2^3` | every both-odd split | (see below) | single | single | +| `F2^4` | (2,8) | 15,360 | 1 | 17 | +| `F2^4` | (4,6) | 143,360 | 4 | 20 | + +**Mechanism (characterized, exact).** `mu2` varies because `|A+A|` varies with +the additive structure of a half. In `F2^3` a 4-set is either a coset of a +2-dimensional subspace (an affine plane, `|A+A| = 4`) or generic +(`|A+A| = 7`). At `(4,4)` the two halves vary independently: + +| half A | half B | `|A+A|` | `|B+B|` | sum | mu2 | covers | +|---|---|---|---|---|---|---| +| generic | generic | 7 | 7 | 14 | 6 | 2,688 | +| plane | generic | 4 | 7 | 11 | 3 | 336 | +| generic | plane | 7 | 4 | 11 | 3 | 336 | +| plane | plane | - | - | - | - | 0 (never covers) | + +So `mu2 = 6 - 3 * (number of plane halves)`. A single structured (affine-plane) +half lowers `|A+A|` by 3 and hence `mu2` by 3. The covering condition does not +pin this. At `(4,6)` in `F2^4` the split is constant again (`mu2 = 4`) precisely +because the two halves' selfsum sizes are anti-correlated by the cover +condition: `|A+A| = 4` (plane) forces `|B+B| = 16`, and `|A+A| = 7` (generic) +forces `|B+B| = 13`; the sum stays 20. So the constancy that survives is a +correlation of the specific split, not a covering law. + +## The both-odd regime of (11,7)/(9,9) + +The target splits `(11,7)` and `(9,9)` are both-odd. At every both-odd split +where covers can be produced, `mu2` has been constant: + +| Group | Split | Covers | mu2 | `|A+A|,|B+B|` | +|---|---|---|---|---| +| `F2^3` | (3,5),(5,3),(3,7),(7,3) | 2,688 / 448 each | 4 | 4,8 | +| `F2^3` | (5,5),(5,7),(7,5),(7,7) | 3,136 / 448 / 64 | 8 | 8,8 | +| `F2^5` | (7,7) | 310 (mutation search) | 12 | 22,22 | + +So `mu2` is constant at `F2^3` (complete) and at `F2^5` `(7,7)` (310 covers, +both halves pinned `|A+A| = |B+B| = 22`). But this is CHECKED, not forced: + +- The `(4,4)` `F2^3` counterexample proves the covering condition does not pin + `mu2` in general; a structured half is enough to move it. +- Both-odd halves at `F2^6` (`|A| = 11, 9`) can still have varying `|A+A|` + (an 11-set is a subspace plus points), so the `F2^3`/`F2^5` constancy rests on + those small scales having rigid odd-set selfsums, not on a covering identity. +- Direct `F2^6` `(9,9)`/`(11,7)` covers were not produced in a bounded + hill-climbing search (0 covers in 300 restarts each), so `mu2` variation at + the exact target splits is neither observed nor ruled out. + +The planned lift - "mu2 is constant per split, carry it to the 501/196 surviving +rows (PR 2911) as a filter, then lift to m=6" - is therefore **not justified**. +`mu2`-constancy is scale- and split-dependent: false for both-even splits, +empirical for both-odd splits, and unforced everywhere. This is the same shape +as the demoted scale-dependent self-sum lift of PR 3034: a two-scale regularity +with no coupling identity. It is demoted accordingly. + +For completeness: PR 2911's 501/196 rows are pair-representation row +configurations (census floors of PR 2773's `(e_ex, b_ex)` rows), not concrete +`(A,B)` covers, so `mu2` cannot be evaluated on them without the row-to-cover +map; that map is the remaining "carry to the rows" step and is still blocked +(PR 3108 recorded the same blocker). + +## The (4,2) walk (continuation of PR 3108) + +The (12,6) A-vanish (4,2) decision walk is continued as a budget-honest partial, +never an exclusion. PR 3108's sharded walk (its `walk42.py`/`run42.py`, vendored +byte-exact here) is extended by shard 29 with a per-shard receipt that carries +explicit `complete`/`budget_hit` flags and checks the budget after every U slice +(PR 3108's lesson). This session's shard was run from empty receipts and then +re-run from empty receipts again with identical counters, to prove recomputation +(the receipt-validation trap). The inherited 29 shards (PR 3108) plus shard 29 +give 30 of 2048 shards complete, 2,490 U slices, 257,845,500 normalized pairs, +with `w_candidates = 0` and `covering_configs = 0` on every walked pair. The +complete walk remains far outside one session (PR 3108 sized it at ~608 +core-hours at 7,866 pairs/s), so this is a narrowed remainder and not an +exclusion; the zero counts are facts about walked pairs only. + +## Anchors reproduced before any new number + +| Anchor | Expected | Status here | +|---|---|---| +| PR 2870 OBSTRUCTION | parseval=696 allowed=504 deficit=192 | recomputed live (PR 3108 verify quick) | +| PR 2933 CLASSIFY | tight=2 cases=6720 | recomputed live | +| PR 2961 FOURIER (7,1) | need=175 lower=239 contradiction=True | recomputed live | +| PR 2961 CLASS82 | checked=28,815,360 covering=0 | read back (PR 3108 receipts) | +| PR 2961 CLASS60 | d_checked=169,911 d_with_transversals=0 | read back | +| PR 3023 AV51 | uv_pairs=3,049,492,320 covering=0 | read back | +| PR 3108 SELFSUM | (5,5)=3,136 and (7,7)=64 all profile (8,8,8) | read back | +| PR 3108 CENSUS33 | (3,3) covers=296,352 | read back | +| mu2 identity | `mu2 = sa+sb-\|G\|`, violations=0 over 41,341 `F2^3` covers | recomputed live | + +## Reproduce + +Standard library only, CPython 3.12, from the repository root (or this package +directory): + +```sh +python3 -I -B research/f7-mu2-evenhalf-kb3k-88a1/verify.py quick +python3 -I -B research/f7-mu2-evenhalf-kb3k-88a1/mu2_search.py m3 +python3 -I -B research/f7-mu2-evenhalf-kb3k-88a1/mu2_mechanism.py +``` + +Expected markers: `PASS_KB3K_QUICK`, `MU2_M3_DONE`, `MU2_MINIMALITY_DONE`. The +heavier receipts re-run with `mu2_search.py m4` (complete `F2^4` census, a few +minutes), `mu2_search.py m5odd`, `mu2_search.py m6`, `mu2_odd_search.py`, and +`verify.py full`. All arithmetic is exact Python integers (int bitmasks); no +floats are used. Vendored predecessor engines (`vendor/parity_census.py`, +`vendor/selfsum_classify_kb3j.py`, and the `walk42`/`tight` family for the walk) +are byte-exact with SHA-256 pins in `SOURCES.json`. + +## Scope and limitations + +Set-level only inside PR943's abstract interface. The verdict is that +`mu2`-constancy is NOT a covering law and is demoted as a proof filter; it is +NOT a proof that `(11,7)`/`(9,9)` are excluded, and no cover is constructed or +excluded here. The `(4,4)` variation is PROVEN (complete `F2^3`); the both-odd +constancy is CHECKED at `F2^3` (complete) and `F2^5 (7,7)` (310 covers) only; +`F2^6 (9,9)`/`(11,7)` `mu2` is untested (no covers produced). Not checked: +anything word-level (PR 2973/PR 3005 hold `22 <= f(7) <= 24`; untouched), the +row-to-cover map, the `(12,6)` D-vanish classes, the surviving `(10,8)` classes, +the 19-point question, and any kappa, supplier or selected-frontier implication. + +## Open next questions + +1. **Decide whether both-odd `mu2` is forced at `F2^6`.** Produce a `(9,9)` or + `(11,7)` reduced cover of `F2^6` and vary `|A+A|` to see whether `mu2` moves. + Why it matters: a both-odd counterexample closes the lead for good; a pinned + value would license the row filter. Blocked by: both-odd `F2^6` covers are + rare (none produced in a bounded search). +2. **Isolate the `(4,6)`-type selfsum correlation.** At `F2^4 (4,6)` the two + selfsum sizes are anti-correlated by the cover condition. Characterize which + splits force that correlation (constancy) versus independence (variation). + Blocked by: the correlation has no proved coupling identity. +3. **Carry any sound both-odd condition to PR 2911's 501/196 rows** via the + row-to-cover map. Blocked by: the map and both-odd forcing are both open. + +## Credit + +PR 2542/2634/2773/2870/2911/2933/2961/3023/3034/3108 (Aaron Wang): the 17-point +exclusion chain, the pair-representation rows and odd-coverage Fourier/Parseval +identity, the `(A,D)` reduction and vanishing-character restriction, the class +floors and tight-class decisions, the `(5,1)` decision and walk engine, the KB3i +remainder (parity demotion, m=5 obstruction localization), and the KB3j mu2 lead +and `(4,2)` walk this package presses and continues. PR 943 (Ross Richardson): +the prefix-walk model. PR 1185 (Mister-Meeseeks): the pinned `f(5)=12`, +`f(6)=16` record. PR 2691/2973 (Nicholas Stone) and PR 3005 (Nick Petalas): the +word-level census line (recorded state; the set-level chain is unaffected). The +vendored engines are byte-exact with SHA-256 pins and credited in `SOURCES.json`. diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/SOURCES.json b/research/f7-mu2-evenhalf-kb3k-88a1/SOURCES.json new file mode 100644 index 0000000000..9e205fe7c8 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/SOURCES.json @@ -0,0 +1,108 @@ +{ + "schema_version": 1, + "base_commit": "18aacb215fc3717b06be8ceb9fca62aeca0d3e99", + "files": [ + { + "path": "docs/research/agent-task-catalog.json", + "git_blob": "67f085acd86acd7d4e03922d9cf4b26bca66fed5", + "sha256": "47b42433f5a85809a3aadd29c2c339da2c6ed728e4f7762df6b88bccb7874cf0", + "usage": "provenance" + }, + { + "path": "certificates/selected-result.json", + "git_blob": "b1fea0c94436b236cc2b7d41a7be032811b94c81", + "sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129", + "usage": "provenance" + } + ], + "references": [ + { + "local_path": "vendor/parity_census.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/parity_census.py", + "pr": 3034, + "sha256": "1744195cb769b759fd08f4ca93bda29a25d39fb446812e61254e9ac8d61c7cb7", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 3034's package). Credit Aaron Wang (navinor), PR 3034: the complete reduced-covering census primitives (m=3 ground truth). Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/selfsum_classify_kb3j.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/selfsum_classify_kb3j.py", + "pr": 3108, + "sha256": "106c9945e83b90276a1a624870f8c014b9801fd96ef2d7040a7ddc93a140c7d9", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 3108's package). Credit Aaron Wang (navinor), PR 3108: PR 3108's route-(c) self-sum profile classifier (m=3/m=4 complete profiles). Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/tight.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/tight.py", + "pr": 2961, + "sha256": "14670ef2d3df9e4ecc9e1db962f4e8cb77545d1c889144352760c1fd14e2273b", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 2961's package). Credit Aaron Wang (navinor), PR 2961: bitmask primitives, the (7,1) Fourier identity, rho classification. Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/cover18.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/cover18.py", + "pr": 2961, + "sha256": "24c6a2f4911dc2d5de76972eb5ae93dc4e66d8fa1e904443de6d0638e70c0a04", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 2961's package). Credit Aaron Wang (navinor), PR 2961: the reduced (A,D) covering model, Fourier profile system, PR 2870 squeeze numbers. Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/vanish.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/vanish.py", + "pr": 2961, + "sha256": "6c605c54074f725321c5d770d538a652bf7727598a128270831f92fe7b9746d9", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 2961's package). Credit Aaron Wang (navinor), PR 2961: the vanishing-character class tables and the L7 Sidon tight-equality lemma. Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/agent64_cover17.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/agent64_cover17.py", + "pr": 2773, + "sha256": "082bc838134cba9754368cff894d53c729467a689b4cafee8374423688d93654", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 2773's package). Credit Aaron Wang (navinor), PR 2773: profile_c_values (pair-representation shape primitives). Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/agent64_search17.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/agent64_search17.py", + "pr": 2773, + "sha256": "9eb1bf79ffb99b0efcdaf57916c493bc781abd4a0096d584dc6bc6ca294bf674", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 2773's package). Credit Aaron Wang (navinor), PR 2773: the 17-point search primitives. Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/anchors.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/anchors.py", + "pr": 2961, + "sha256": "73d73a9b94539403448d7ff8c914c03711907f75c019c4ccb6843b32c259e8e7", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 2961's package). Credit Aaron Wang (navinor), PR 2961: the anchor-reproduction helpers. Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/self_obstruction.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/self_obstruction.py", + "pr": 3034, + "sha256": "097fd79b48496727e9aef5f143a8bdb724323bbf9a643416c89e1e8358f66c76", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 3034's package). Credit Aaron Wang (navinor), PR 3034: the (5,5) self-obstruction localization. Enforced by SHA-256 pins." + }, + { + "local_path": "vendor/split_census.py", + "source_path": "research/f7-18point-av42-kb3j-b1/vendor/split_census.py", + "pr": 3034, + "sha256": "5e859102d4c2120d10aa882538d6e3d73d18deb320ce96f960d12b28e35bb023", + "note": "Vendored byte-exact (agent_tools.py pr-tree-extract / git archive from PR PR 3034's package). Credit Aaron Wang (navinor), PR 3034: the per-split complete census with cross/self failure breakdown. Enforced by SHA-256 pins." + }, + { + "local_path": "walk42.py", + "source_path": "research/f7-18point-av42-kb3j-b1/walk42.py", + "pr": 3108, + "sha256": "a922dc8229b43aa6cc65ca27901062b6d73647236f9eef7e626fe07e934c0cbf", + "note": "Vendored byte-exact from PR 3108 (agent-83). Credit Aaron Wang (navinor): the (4,2) exact reduced walk engine (M-cluster W search, pair walk, k=3/k=4 shape censuses)." + }, + { + "local_path": "run42.py", + "source_path": "research/f7-18point-av42-kb3j-b1/run42.py", + "pr": 3108, + "sha256": "abc4a1857628b94194acbc44f72913fbdbd117f428fa4d38dbec78ff2f8e4b0b", + "note": "Vendored byte-exact from PR 3108 (agent-83). Credit Aaron Wang (navinor): the resumable sharded walk driver (per-shard receipts with explicit complete/budget_hit flags)." + } + ], + "notes": { + "concurrent_scopes": "Nicholas Stone (NicholasStone) PR 2973 (merged) and Nick Petalas (petalas) PR 3005 hold the f(7) WORD-level line (22 <= f(7) <= 24); this package is SET-level only and enumerates no words. Pair-collision checks (discussions 1317 and 1166 via agent_tools.py disc-comments --grep, incl. nested replies, at entry) found no live claim on the mu2 even-half condition or the (4,2) walk.", + "model_and_pinned_results": "PR943 query model (Ross Richardson); pinned f(5)=12, f(6)=16 (PR 1185, Mister-Meeseeks) and the word-level gap 22 <= f(7) <= 24 (PR 2973/3005). Recomputed live: the mu2 identity (0 violations over 41,341 F2^3 covers) and the minimality census (minimal varying split (4,4) F2^3). Read back: PR 3108 SELFSUM (5,5)=3136/(7,7)=64 profiles (8,8,8) and CENSUS33 (3,3) covers=296,352; PR 2961 CLASS82/CLASS60 and PR 3023 AV51 from PR 3108's pinned receipts." + } +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/TASK.json b/research/f7-mu2-evenhalf-kb3k-88a1/TASK.json new file mode 100644 index 0000000000..8e98f82161 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/TASK.json @@ -0,0 +1,111 @@ +{ + "schema_version": 1, + "task_id": "bit-new-register-model", + "scope_key": "7084092dd726e7ba1f2f (drawn card); refined object key f7-mu2-evenhalf-kb3k", + "track": "bit-mechanisms (drawn); scope changed to the assigned explicit open request kappa-blocker KB3k: press the mu2-constant even-half condition on (11,7)/(9,9) and continue the (12,6) A-vanish (4,2) walk (the new lead of PR 3108)", + "scope_status": "changed", + "scope_change_reason": "Authorized 'explicit open request' scope change, recorded as instructed by the assignment. The drawn card (bit-new-register-model, a saturated bit-mechanisms register-model question) does not target the F2^7 set-level cover question. The assignment (kappa-blocker KB3k) explicitly authorizes taking discussion 1166's open request instead: press the mu2-constant even-half condition that PR 3108 (agent-83) named as its new lead for the both-odd splits (11,7)/(9,9), and continue the (4,2) walk where budget allows. Pair-collision checks (discussions 1317 and 1166 via agent_tools.py disc-comments --grep including nested replies, before computation) found no live claim on the mu2 even-half condition or the (4,2) walk; the concurrent f(7) work (PR 2973/PR 3005, Nicholas Stone / Nick Petalas) is WORD level and this task stays strictly on the SET level.", + "actual_scope": "Kappa-blocker KB3k (explicit open request; set level, no words): press the mu2-constant even-half condition on (11,7)/(9,9), the new lead of PR 3108, and continue the (12,6) A-vanish (4,2) walk where budget allows. Delivered outcome=partial. (a) mu2 lead: the exact identity mu2 = |A+A| + |B+B| - |G| is PROVEN for every reduced cover (A,B) of G=F2^m (inclusion-exclusion on (A+A) u (B+B) = G), and validated at 0 violations over all 41,341 F2^3 covers. 'mu2 constant per split' is NOT a covering law: mu2 VARIES at a single minimal split, (4,4) in F2^3 (3,360 covers; mu2=6 for two generic halves with |A+A|=|B+B|=7, mu2=3 when exactly one half is an affine plane with |A+A|=4), with the mechanism characterized exactly (a structured affine-plane half lowers |A+A| and so mu2 by 3; at (4,6) in F2^4 the split is constant only because the two selfsum sizes are anti-correlated by the cover condition). No variation at F2^1 or F2^2 (complete). For the both-odd target regime (11,7)/(9,9), mu2 is constant at every both-odd split where covers can be produced (F2^3 complete; F2^5 (7,7) 310 covers, all mu2=12 with |A+A|=|B+B|=22) but this is CHECKED, not forced (F2^6 (9,9)/(11,7) covers were not produced in a bounded hill-climbing search, so mu2 variation at the target splits is neither observed nor ruled out). The (4,4) counterexample proves the covering condition does not pin mu2 in general, so the lead is DEMOTED as a proof filter: it cannot be carried to PR 2911's 501/196 rows and then to m=6 as a hard condition without a both-odd forcing proof (absent here). This is the same shape as PR 3034's demoted scale-dependent self-sum lift. (b) (4,2) walk: continued PR 3108's sharded walk with per-shard receipts (explicit complete/budget_hit flags, budget checked after every U); 30/2048 shards complete (29 inherited from PR 3108 plus shard 29 this session), 2490 U slices, 257845500 normalized pairs, w_candidates=0 and covering=0 on every walked pair, per-shard receipts with explicit complete/budget_hit flags and budget checked after every U; shard 29 re-run from empty receipts with identical counters to prove recomputation. The complete walk remains far outside one session (PR 3108 sized it at ~608 core-hours), so this is a budget-honest partial and not an exclusion. No class decided; no cover constructed; no false kill; frontiers unchanged.", + "bottleneck_link": "The set-level restricted addition basis value r((C2)^7) decides how small a universal word's prefix set can be inside the unchanged PR943 query model. Under the concurrent word-level gap 22 <= f(7) <= 24 (PR 2973/3005), whether any 18-point set covers F2^7 is the deciding necessary condition for f(7) = 22. This package presses one named identity (the even-half mu2-constant condition) that PR 3108 proposed as the narrowed route to the both-odd splits (11,7)/(9,9) and shows it is not a covering law (demoted), removing one proposed filter; and it advances the (4,2) decision walk. It decides no split outright and changes no supplier, tariff or kappa.", + "stop_rule": "Stop at the first of: (a) mu2-constancy proved forced per split and contradicting (11,7)/(9,9) (excluding them), (b) mu2-constancy proved scale-dependent or a minimal varying split found (demoting the lead), (c) the (4,2) walk decided or its budget expiring with each class's exact status recorded. Outcome (b) reached for the mu2 lead (minimal varying split (4,4) F2^3, mechanism characterized) plus a budget-honest (4,2) walk continuation. One bounded pivot: the mu2 investigation (identity, minimality census, mechanism, both-odd search). No second pivot; the construction route and the (3,3) route were not re-entered.", + "smallest_falsifying_instance_first": "The falsifying instance for 'mu2 is forced per split' is one split carrying two covers with different mu2; the smallest such is (4,4) in F2^3, found by complete enumeration after confirming F2^1 and F2^2 have none. The identity mu2 = sa+sb-|G| was validated first (0 violations over 41,341 F2^3 covers). The mechanism was then read off the (4,4) clusters (structured vs generic halves) and cross-checked at (4,6) F2^4 (anti-correlated selfsums, constant sum). Both-odd constancy was tested at the smallest both-odd scales where covers exist (F2^3 complete; F2^5 (7,7) mutation search) before any claim about (11,7)/(9,9). All recorded anchors were reproduced before any new number (PR 2870 OBSTRUCTION 696/504/192, PR 2933 CLASSIFY tight=2 cases=6720, PR 2961 FOURIER (7,1) need=175 lower=239 recomputed live; PR 2961 CLASS82/CLASS60 and PR 3023 AV51 read back; PR 3108 SELFSUM (5,5)/(7,7) profiles (8,8,8) and CENSUS33 (3,3) covers=296,352 read back).", + "outcome": "partial", + "author": "Aaron Wang", + "ai_assistance": "Substantial AI assistance from opencode in scoping, implementation, verification and writing (no model named); no independent human review claimed.", + "evidence": "CERTIFICATE.json labels every statement PROVEN / CHECKED / DEMOTED with its exact numbers. verify.py quick re-derives the mu2 identity (0 violations) and the minimality census (F2^1/F2^2 no variation; minimal varying split (4,4) F2^3) live, and reads back the heavier receipts (MU2-M4 complete F2^4 census, MU2-M5ODD/MU2-M6 sampling, MU2-ODD both-odd mutation search). mu2_search.py is the mu2 profiler (identity, complete F2^3 census, complete F2^4 census, sampling); mu2_mechanism.py is the minimality + (4,4) mechanism census; mu2_odd_search.py is the both-odd hill-climbing cover search. walk42.py/run42.py (vendored byte-exact from PR 3108) drive the (4,2) walk with per-shard receipts. MU2-*.json are the mu2 evidence; AV42-*.json are the walk receipts. Vendored predecessor engines are byte-exact with SHA-256 pins in SOURCES.json.", + "de_diagnostic": "Not applicable: a finite set-level question in the PR943 query model, with no supplier width, role count, child ranks or recursive moment to price. The applicable diagnostic is exact reproduction against pinned predecessor numbers plus complete exact-integer enumerations with brute-force-validated engines.", + "open_questions": [ + { + "question": "Decide whether both-odd mu2 is forced at F2^6 for the (11,7)/(9,9) splits.", + "why_it_matters": "A both-odd counterexample (two (9,9) or (11,7) covers with different mu2) closes the mu2 lead for good; a pinned value would license a sound row filter and could exclude a split if the value is unrealizable.", + "first_step": "Produce a reduced (9,9) or (11,7) cover of F2^6 (construct one explicitly) and vary |A+A| to see whether mu2 moves; the F2^3 (4,4) mechanism (a structured half) is the template.", + "blocked_by": "Both-odd F2^6 covers are rare (none produced in a bounded hill-climbing search); no constructive generator is known." + }, + { + "question": "Characterize which splits force the selfsum correlation (constant mu2) versus independence (varying mu2).", + "why_it_matters": "At F2^4 (4,6) the two selfsum sizes are anti-correlated by the cover condition (constant mu2=4), while at F2^3 (4,4) they vary independently (mu2 in 3..6). A criterion would say exactly when mu2 is usable.", + "first_step": "Test whether the (4,6)-type correlation holds at (2k,2l) both-even splits versus (4,k) splits, and prove or refute a coupling between |A+A| and |B+B| from A+B=G.", + "blocked_by": "The correlation has no proved coupling identity; it is observed at (4,6) F2^4 only." + }, + { + "question": "Carry any sound both-odd condition to PR 2911's 501/196 surviving rows.", + "why_it_matters": "The 501/196 rows are the concrete surviving (11,7)/(9,9) configurations; a sound mu2 (or other even-half) filter on them would narrow or decide those splits.", + "first_step": "Build the row-to-cover map (PR 2773/2911 pair-representation rows to concrete (A,B)) and evaluate mu2 on the 501/196 rows.", + "blocked_by": "The row-to-cover map and both-odd forcing are both open; mu2 is not a proven filter, so applying it to the rows is unsound as a proof step." + } + ], + "original_card": { + "id": "bit-new-register-model", + "question": "Can an explicitly larger or nonabelian register model escape the scoped three-register obstruction?", + "starting_points": [ + "docs/research/research-family-status.md", + "research/bit-three-register-lower-bound/README.md", + "certificates/selected-result.json", + "research/bit-gl3-mixed-targets-length10/README.md", + "docs/research/community-efficient1000-review.md" + ], + "methods": [ + "Construct the smallest exact identity in a newly specified legal operation alphabet.", + "Derive a target-specific relaxation bound for that same explicit alphabet." + ], + "acceptance_gate": "Name the changed hypothesis, all counted roles and a uniform identity; finite column tests alone do not certify it. A scoped local result may be retained without a complete supplier. Expanding it into further construction rounds requires the family-level budget and obligation gate in research-family-status.md; an optimistic passing relaxation alone is not acceptance.", + "first_step": { + "command": [ + "python3", + "-B", + "scripts/research_baseline.py" + ], + "expected": "PASS_RESEARCH_BASELINE_BINDINGS_ONLY", + "inspect": "Read Model section 1 of the three-register bound and identify the exact excluded free operations.", + "scope": "Positive control / source-bound orientation only; this is not a new construction or full cold replay." + }, + "first_experiment": "First compare the alphabet, role count and length with the fully replayed #1974 census and #2027 mixed-root tariff. Identify a changed premise and a legal native implementation; then price one smallest completed instance before searching larger words.", + "bottleneck_link": "A small-width completed saving changes the bit primitive; a finite-address identity alone is insufficient.", + "allowed_variations": [ + "Choose a fixed larger register count or a specified nonabelian operation family." + ], + "scope_change_triggers": [ + "Remaining inside the already-excluded three-register abelian model.", + "Repeating the two-register GL3 census or a covered three-register length without changing a hypothesis; a formal group-algebra word without native conversion is a partial result." + ], + "overlap_terms": [ + "three-register", + "nonabelian", + "group algebra" + ] + }, + "base_commit": "18aacb215fc3717b06be8ceb9fca62aeca0d3e99", + "selected_record_sha256": "bb2eaa58647b353f88d0aec2eafb9d30df1be53589231b23e12ceef3e4bad129", + "session_seed": "4f2a88c1mu2kb3k88a1", + "priced_budget_minutes": 150, + "priced_budget_breakdown": "20 min entry orientation (pair-collision checks on discussions 1317/1166 with the object's proper names; ground-truth read of PR 3108/3034/3023/2961/2911); 25 min anchor reproduction (PR 3108 verify quick: OBSTRUCTION/CLASSIFY/FOURIER live, CLASS82/CLASS60/AV51/SELFSUM/CENSUS33 read back) and predecessor extraction (PR 3108 pr-tree-extract + git archive to scratch, hash pins, author verification); 30 min the mu2 identity, minimality census (F2^1/F2^2/F2^3 complete) and (4,4) mechanism; 20 min the F2^4 complete census and the both-odd mutation search; 30 min the (4,2) walk continuation in blocking foreground chunks (shard 29 + one shard re-run from empty receipts); 25 min package metadata, registration (--check-only), PR markdown gates, PR and board posts.", + "object_synonyms_used_in_overlap": [ + "mu2", + "even-half", + "self-sum", + "both-odd", + "both-even", + "(11,7)", + "(9,9)", + "(4,2)", + "18-point", + "18point", + "F2^7", + "P+P cover", + "affine plane", + "selfsum profile", + "501/196 rows", + "walk", + "KB3k", + "KB3j" + ], + "pair_collision_check": { + "checked_utc": "2026-10-16 entry (before computation)", + "result": "No live claim on the mu2 even-half condition or the (4,2) walk. Discussion 1166's 18-point posts are my own chain's released findings (KB3e/KB3g/KB3i/KB3j comments 18970031/18975496/18981563/18986400), all DONE/RELEASED; the only active claims (petalas complex-rank-shape-decoder comment 18984744; a consolidation overlap-receipt claim) are on other tracks. Discussion 1317 carries word-level and bit-mechanism claims only. Nicholas Stone's f(7) WORD line (PR 2973) is explicitly scoped to the word census and disclaims the set-level chain. This package stays strictly on the SET level.", + "threads_scanned": [ + "discussion 1317 (agent_tools.py disc-comments --grep CLAIM, incl. nested replies)", + "discussion 1166 (agent_tools.py disc-comments --grep CLAIM and --grep even-half|mu2|walk42|KB3k|both-odd|self-sum|18-point)" + ], + "tool": "agent_tools.py disc-comments --grep (with nested replies); headers and timestamps used to scope live claims" + } +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/VERIFY.json b/research/f7-mu2-evenhalf-kb3k-88a1/VERIFY.json new file mode 100644 index 0000000000..f6905ebf8e --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/VERIFY.json @@ -0,0 +1,49 @@ +{ + "schema_version": 1, + "status": "ready", + "python": "3.12", + "requirements": [], + "commands": [ + { + "argv": ["{python}", "-I", "-B", "research/f7-mu2-evenhalf-kb3k-88a1/verify.py", "quick"], + "checks": "mu2 identity (mu2 = |A+A|+|B+B|-|G|) re-derived live at 0 violations over all 41,341 F2^3 covers; minimality census re-run live (no mu2 variation at F2^1 or F2^2; minimal varying split (4,4) at F2^3, mu2 in {3,6}, n=3360); F2^4 complete-census receipts read back ((2,8) mu2=1 constant, (4,6) mu2=4 constant, both-odd (3,7)/(5,5) covers=0); both-odd search receipts read back (F2^5 (7,7) 310 covers mu2=12; F2^6 (9,9)/(11,7) 0 covers produced); sampling receipts read back (M5ODD (7,7) mu2=12; M6 0); (4,2) walk receipt aggregate and the shard-29 from-empty recompute comparison (counters identical).", + "timeout_seconds": 180 + }, + { + "argv": ["{python}", "-I", "-B", "research/f7-mu2-evenhalf-kb3k-88a1/mu2_search.py", "m3"], + "checks": "Regenerate the complete F2^3 covering-pair census and the per-split mu2 / selfsum-sum profiles (the (4,4) variation and the both-odd constancy), writing MU2-M3.json. Exact integer bitmasks.", + "timeout_seconds": 120 + }, + { + "argv": ["{python}", "-I", "-B", "research/f7-mu2-evenhalf-kb3k-88a1/mu2_mechanism.py"], + "checks": "Regenerate the minimality census (F2^1/F2^2/F2^3 varying splits) and the (4,4) mechanism cluster table (structured affine-plane half versus generic half), writing MU2-MECH.json.", + "timeout_seconds": 120 + } + ], + "inputs": [ + "research/f7-mu2-evenhalf-kb3k-88a1/verify.py", + "research/f7-mu2-evenhalf-kb3k-88a1/mu2_search.py", + "research/f7-mu2-evenhalf-kb3k-88a1/mu2_mechanism.py", + "research/f7-mu2-evenhalf-kb3k-88a1/mu2_odd_search.py", + "research/f7-mu2-evenhalf-kb3k-88a1/walk42.py", + "research/f7-mu2-evenhalf-kb3k-88a1/run42.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/parity_census.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/selfsum_classify_kb3j.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/tight.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/cover18.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/vanish.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_cover17.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_search17.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/anchors.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/self_obstruction.py", + "research/f7-mu2-evenhalf-kb3k-88a1/vendor/split_census.py", + "research/f7-mu2-evenhalf-kb3k-88a1/MU2-M3.json", + "research/f7-mu2-evenhalf-kb3k-88a1/MU2-M4.json", + "research/f7-mu2-evenhalf-kb3k-88a1/MU2-MECH.json", + "research/f7-mu2-evenhalf-kb3k-88a1/MU2-M5ODD.json", + "research/f7-mu2-evenhalf-kb3k-88a1/MU2-M6.json", + "research/f7-mu2-evenhalf-kb3k-88a1/MU2-ODD.json", + "research/f7-mu2-evenhalf-kb3k-88a1/AV42-RECOMPUTE-29-first-run.json", + "research/f7-mu2-evenhalf-kb3k-88a1/AV42-AV42-29.json" + ] +} diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/mu2_mechanism.py b/research/f7-mu2-evenhalf-kb3k-88a1/mu2_mechanism.py new file mode 100644 index 0000000000..707ec30117 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/mu2_mechanism.py @@ -0,0 +1,114 @@ +"""Minimality + mechanism check for the mu2-variation finding. + +(a) complete F2^2 (gsize 4) and F2^1 (gsize 2): is there ANY split where mu2 + varies? (If none, (4,4) at F2^3 is the minimal variation split.) +(b) F2^3 (4,4): extract the two mu2 clusters and show the mechanism - a side is + a coset of a 2-dim subspace (affine plane, |A+A|=4) vs a generic 4-set + (|A+A|=7). Exact ints. +""" + +import json +import sys +from itertools import combinations +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE / "vendor")) +import parity_census as pc # noqa: E402 + + +def is_structured(mask, gsize): + """True if a 4-set is structured (a coset of a 2-dim subspace, so |A+A|=4) + rather than generic (|A+A|=7).""" + return mask.bit_count() == 4 and pc.selfsum(mask).bit_count() == 4 + + +def complete_census(gsize): + subs = list(range(1 << gsize)) + out = {} + for am in subs: + for bm in subs: + ok, _ = pc.covers_pair(am, bm, gsize) + if not ok: + continue + k = (am.bit_count(), bm.bit_count()) + sa = pc.selfsum(am).bit_count() + sb = pc.selfsum(bm).bit_count() + mu2 = (pc.selfsum(am) & pc.selfsum(bm)).bit_count() + out.setdefault(k, {"mu2": set(), "sum": set(), "n": 0}) + out[k]["mu2"].add(mu2) + out[k]["sum"].add(sa + sb) + out[k]["n"] += 1 + return out + + +def vary_splits(gsize): + res = complete_census(gsize) + varying = {k: v for k, v in res.items() if len(v["mu2"]) > 1} + return res, varying + + +def mechanism_44(): + gsize = 8 + rows = [] + for ac in combinations(range(8), 4): + am = pc.mask_of(ac) + for bc in combinations(range(8), 4): + bm = pc.mask_of(bc) + ok, _ = pc.covers_pair(am, bm, gsize) + if not ok: + continue + sa = pc.selfsum(am).bit_count() + sb = pc.selfsum(bm).bit_count() + mu2 = (pc.selfsum(am) & pc.selfsum(bm)).bit_count() + rows.append((is_structured(am, 8), is_structured(bm, 8), sa, sb, mu2, ac, bc)) + # group by (structuredA, structuredB) + from collections import Counter + grp = Counter((r[0], r[1], r[4]) for r in rows) # (structA,structB,mu2)->count + return rows, grp + + +def main(): + sys.stdout.reconfigure(encoding="utf-8") + res = {} + for gsize, name in [(2, "F2^1"), (4, "F2^2"), (8, "F2^3")]: + cres, varying = vary_splits(gsize) + res[name] = { + "splits_with_covers": len(cres), + "varying_splits": {("%d,%d" % k): {"mu2_set": sorted(v["mu2"]), + "sum_set": sorted(v["sum"]), + "n": v["n"]} + for k, v in sorted(varying.items())}, + } + print("=== %s (gsize %d) complete: %d splits with covers; %d vary in mu2 ===" + % (name, gsize, len(cres), len(varying))) + for k in sorted(cres): + r = cres[k] + print(" split (%d,%d) n=%d mu2=%s sum=%s %s" + % (k[0], k[1], r["n"], sorted(r["mu2"]), sorted(r["sum"]), + "<-- VARIES" if len(r["mu2"]) > 1 else "")) + print() + rows, grp = mechanism_44() + res["F2^3_(4,4)_mechanism"] = { + "(structA,structB,mu2)->count": {"%s,%s,%d" % k: v for k, v in sorted(grp.items())} + } + print("=== F2^3 (4,4) mechanism: (structA?, structB?, mu2) -> count ===") + for k in sorted(grp): + print(" structA=%s structB=%s mu2=%d : %d covers" % (k[0], k[1], k[2], grp[k])) + # show one example of each + seen = set() + print("--- example cover per (structA,structB,mu2) ---") + for r in rows: + key = (r[0], r[1], r[4]) + if key in seen: + continue + seen.add(key) + print(" A=%s B=%s sa=%d sb=%d mu2=%d structA=%s structB=%s" + % (list(r[5]), list(r[6]), r[2], r[3], r[4], r[0], r[1])) + (HERE / "MU2-MECH.json").write_text( + json.dumps(res, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print("MU2_MINIMALITY_DONE", flush=True) + + +if __name__ == "__main__": + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/mu2_odd_search.py b/research/f7-mu2-evenhalf-kb3k-88a1/mu2_odd_search.py new file mode 100644 index 0000000000..66d4167073 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/mu2_odd_search.py @@ -0,0 +1,117 @@ +"""Bounded both-odd cover search: does mu2 vary among BOTH-ODD covers at the +target regime (the (11,7)/(9,9) analogue)? + +Random (11,7)/(9,9) covers at F2^6 are too rare to sample, so this uses a +hill-climbing mutation to force the cover conditions (cross A+B = G and +(A+A) u (B+B) = G), then records (sa, sb, mu2) for each cover found and reports +whether mu2 VARIES at a fixed both-odd split. A found variation is exact proof +of non-constancy for that split; no variation found is not a proof of constancy. +Exact ints. Bounded trials per split. +""" + +import json +import random +import sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE / "vendor")) +import parity_census as pc # noqa: E402 + + +def deficit(am, bm, gsize): + allg = (1 << gsize) - 1 + cross = pc.sumset(am, bm) + selfs = pc.selfsum(am) | pc.selfsum(bm) + return (allg ^ cross).bit_count() + (allg ^ selfs).bit_count() + + +def profile(am, bm, gsize): + sa = pc.selfsum(am) + sb = pc.selfsum(bm) + inter = sa & sb + return (sa.bit_count(), sb.bit_count(), inter.bit_count()) + + +def climb(a_list, b_list, gsize, rng, max_steps=4000): + am = pc.mask_of(a_list) + bm = pc.mask_of(b_list) + d = deficit(am, bm, gsize) + for _ in range(max_steps): + if d == 0: + return a_list, b_list, True + # try swapping one element in A or B + improved = False + for which in (0, 1): + cur = a_list if which == 0 else b_list + other = b_list if which == 0 else a_list + in_set = set(cur) + out_set = [x for x in range(gsize) if x not in in_set] + rng.shuffle(out_set) + for old in list(cur): + for new in out_set[:8]: + trial = [new if x == old else x for x in cur] + if which == 0: + nd = deficit(pc.mask_of(trial), pc.mask_of(other), gsize) + else: + nd = deficit(pc.mask_of(other), pc.mask_of(trial), gsize) + if nd < d: + if which == 0: + a_list = trial + else: + b_list = trial + d = nd + improved = True + break + if improved: + break + if improved: + break + if not improved: + return a_list, b_list, d == 0 + return a_list, b_list, d == 0 + + +def search_split(a, b, gsize, restarts=200, seed=0): + rng = random.Random(seed) + found = {} + successes = 0 + for r in range(restarts): + a_list = rng.sample(range(gsize), a) + b_list = rng.sample(range(gsize), b) + a_list, b_list, ok = climb(a_list, b_list, gsize, rng) + if ok: + successes += 1 + p = profile(pc.mask_of(a_list), pc.mask_of(b_list), gsize) + found[p] = found.get(p, 0) + 1 + return { + "covers_found": successes, + "profiles_(sa,sb,mu2)_counts": {"%d,%d,%d" % k: v for k, v in sorted(found.items())}, + "mu2_set": sorted({k[2] for k in found}), + "mu2_constant_observed": len({k[2] for k in found}) <= 1, + } + + +def main(): + sys.stdout.reconfigure(encoding="utf-8") + out = {} + # both-odd analogue of (11,7)/(9,9) at F2^5 (gsize 32) and F2^6 (gsize 64) + cases = [ + ("F2^5 (7,7)", 7, 7, 32, 400, 12345), + ("F2^6 (9,9)", 9, 9, 64, 300, 991), + ("F2^6 (11,7)", 11, 7, 64, 300, 771), + ] + for name, a, b, gsize, restarts, seed in cases: + out[name] = search_split(a, b, gsize, restarts=restarts, seed=seed) + out[name]["gsize"] = gsize + for k in out: + print(k, out[k], flush=True) + any_var = any(not v["mu2_constant_observed"] for v in out.values()) + print("ANY_BOTH_ODD_MU2_VARIATION =", any_var, flush=True) + (HERE / "MU2-ODD.json").write_text( + json.dumps(out, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print("MU2_ODD_SEARCH_DONE", flush=True) + + +if __name__ == "__main__": + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/mu2_search.py b/research/f7-mu2-evenhalf-kb3k-88a1/mu2_search.py new file mode 100644 index 0000000000..070476b69b --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/mu2_search.py @@ -0,0 +1,206 @@ +"""KB3k: press the mu2-constant even-half condition. + +For a reduced covering pair (A, B) of G = F2^m (A+B = G and (A+A) u (B+B) = G) +define mu2 = |(A+A) n (B+B)|. Exact identity (proved in README): + + mu2 = |A+A| + |B+B| - 2^m + +(since |(A+A) u (B+B)| = 2^m for a cover and inclusion-exclusion). So mu2 is +constant per split (a, b) iff the selfsum-size SUM |A+A| + |B+B| is constant per +split. This module searches for the minimal (smallest m, smallest split) cover +split at which mu2 (equivalently the sum) VARIES, by COMPLETE enumeration where +feasible and clearly-labelled random sampling where not. Exact int arithmetic, +no floats. + +Modes + m3 complete F2^3, every split + m4 complete F2^4 for a list of feasible splits + m5 random sampling in F2^5 (and a targeted exact small-split pass) + identity exhaustive sanity: mu2 == sa+sb-2^m on every enumerated cover +""" + +import json +import random +import sys +from itertools import combinations +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE / "vendor")) + +import parity_census as pc # noqa: E402 (vendored byte-exact KB3j engine) + + +def profile_of(am, bm, gsize): + allg = (1 << gsize) - 1 + sa = pc.selfsum(am) + sb = pc.selfsum(bm) + union = sa | sb + inter = sa & sb + return { + "a": am.bit_count(), + "b": bm.bit_count(), + "sa": sa.bit_count(), + "sb": sb.bit_count(), + "mu2": inter.bit_count(), + "self_union": union.bit_count(), + "deficit": (allg.bit_count() - union.bit_count()), + } + + +def covers(am, bm, gsize): + ok, _ = pc.covers_pair(am, bm, gsize) + return ok + + +def split_summary(rows): + """rows: list of profile dicts at one split. Return mu2 / sum ranges.""" + sums = {r["sa"] + r["sb"] for r in rows} + mu2s = {r["mu2"] for r in rows} + sas = sorted({r["sa"] for r in rows}) + sbs = sorted({r["sb"] for r in rows}) + return { + "covers": len(rows), + "sa_set": sas, + "sb_set": sbs, + "sum_set": sorted(sums), + "mu2_set": sorted(mu2s), + "sum_constant": len(sums) == 1, + "mu2_constant": len(mu2s) == 1, + } + + +def check_identity(rows, gsize): + """Identity: mu2 = sa + sb - |G| and self_union = |G| for every cover + (|G| = gsize = number of group elements = 2^m).""" + bad = 0 + for r in rows: + if r["mu2"] != r["sa"] + r["sb"] - gsize: + bad += 1 + if r["self_union"] != gsize: + bad += 1000 # self_union must be full for a cover + return bad + + +def run_m3(): + gsize = 8 + subs = list(range(1 << gsize)) + by_split = {} + for am in subs: + for bm in subs: + if covers(am, bm, gsize): + k = (am.bit_count(), bm.bit_count()) + by_split.setdefault(k, []).append(profile_of(am, bm, gsize)) + out = {"gsize": gsize, "splits": {}} + bad = 0 + for k in sorted(by_split): + s = split_summary(by_split[k]) + bad += check_identity(by_split[k], gsize) + out["splits"]["%d,%d" % k] = s + out["identity_violations"] = bad + out["any_mu2_variation"] = any( + not s["mu2_constant"] for s in out["splits"].values() + ) + return out + + +def run_m4(split_list): + gsize = 16 + out = {"gsize": gsize, "splits": {}} + for (a, b) in split_list: + rows = [] + for ac in combinations(range(gsize), a): + am = pc.mask_of(ac) + for bc in combinations(range(gsize), b): + bm = pc.mask_of(bc) + if covers(am, bm, gsize): + rows.append(profile_of(am, bm, gsize)) + s = split_summary(rows) + s["identity_violations"] = check_identity(rows, gsize) + out["splits"]["%d,%d" % (a, b)] = s + out["any_mu2_variation"] = any( + not s["mu2_constant"] for s in out["splits"].values() + ) + return out + + +def run_m5(sample_split_list, trials=200000, seed=20261016, gsize=32): + """Random sampling: generate random A,B of given sizes, keep covers, and + see whether mu2 varies at a fixed split. Sampling only FINDS variation + (a found variation is exact proof of non-constancy); it cannot prove + constancy.""" + rng = random.Random(seed) + out = {"gsize": gsize, "mode": "random-sampling", "trials_per_split": trials, "splits": {}} + for (a, b) in sample_split_list: + mu2s = {} + sums = {} + covers_seen = 0 + for _ in range(trials): + ac = rng.sample(range(gsize), a) + bc = rng.sample(range(gsize), b) + am = pc.mask_of(ac) + bm = pc.mask_of(bc) + if covers(am, bm, gsize): + covers_seen += 1 + p = profile_of(am, bm, gsize) + mu2s[p["mu2"]] = mu2s.get(p["mu2"], 0) + 1 + sums[p["sa"] + p["sb"]] = sums.get(p["sa"] + p["sb"], 0) + 1 + out["splits"]["%d,%d" % (a, b)] = { + "covers_sampled": covers_seen, + "mu2_hist": dict(sorted(mu2s.items())), + "sum_hist": dict(sorted(sums.items())), + "mu2_constant_observed": len(mu2s) <= 1, + } + out["any_mu2_variation_observed"] = any( + not s["mu2_constant_observed"] for s in out["splits"].values() + ) + return out + + +def main(): + sys.stdout.reconfigure(encoding="utf-8") + mode = sys.argv[1] if len(sys.argv) > 1 else "m3" + if mode == "m3": + res = run_m3() + elif mode == "m4": + splits = [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (3, 3), (4, 4), (2, 2), (1, 5)] + res = run_m4(splits) + elif mode == "m5": + splits = [(2, 8), (4, 6), (5, 5), (3, 7), (4, 8)] + res = run_m5(splits) + elif mode == "m5odd": + splits = [(5, 5), (7, 7), (5, 7), (3, 7)] + res = run_m5(splits, trials=400000, seed=777, gsize=32) + elif mode == "m6": + # the exact 18-point target splits, both-odd, at reduced F2^6 (gsize 64) + splits = [(11, 7), (9, 9)] + res = run_m5(splits, trials=400000, seed=1616, gsize=64) + elif mode == "identity": + res = {"m3": check_identity_m3()} + else: + raise SystemExit("usage: mu2_search.py m3|m4|m5|m5odd|m6|identity") + print(json.dumps(res, indent=2, sort_keys=True)) + tag = {"m3": "MU2_M3", "m4": "MU2_M4", "m5": "MU2_M5", "m5odd": "MU2_M5ODD", + "m6": "MU2_M6", "identity": "MU2_ID"}[mode] + (HERE / ("MU2-%s.json" % mode.upper())).write_text( + json.dumps(res, indent=2, sort_keys=True) + "\n", encoding="utf-8") + print(tag + "_DONE", flush=True) + + +def check_identity_m3(): + gsize = 8 + subs = list(range(1 << gsize)) + bad = 0 + n = 0 + for am in subs: + for bm in subs: + if covers(am, bm, gsize): + n += 1 + p = profile_of(am, bm, gsize) + if p["mu2"] != p["sa"] + p["sb"] - gsize: + bad += 1 + return {"covers": n, "violations": bad} + + +if __name__ == "__main__": + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/run42.py b/research/f7-mu2-evenhalf-kb3k-88a1/run42.py new file mode 100644 index 0000000000..b511468949 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/run42.py @@ -0,0 +1,237 @@ +"""Resumable walk driver for the KB3j package (f7-18point-av42-kb3j-b1). + +Modes (deterministic sharding over the 169,911 normalized U; per-shard +receipt files AV42-.json; one progress section per mode in +AV42-PROGRESS.json after `merge`): + + av42 the class (12,6) A-vanish (4,2) decision walk (walk42.class42_run): + complete over all normalized (U, V) pairs with |U+V| >= 24 and all + admissible W 4-sets per pair, exact four-line test on each. + size sizing probe: walk a few U slices and report pairs/s and the + |U+V| distribution (no receipts; budget-honest sizing evidence). + k3 complete (4,2)-shape census over F2^3 halves (walk42.census_k3). + k4 complete normalized (4,2)-shape census of floor-surviving + (u,u,w) classes over F2^4 halves (walk42.census_k4). + +Usage: python3 -I -B run42.py [--shards N] [--shard k] [--budget S] + python3 -I -B run42.py merge [--shards N] + +Shard receipt files are written ONLY by their own shard process (safe for +parallel shard runs); `merge` rebuilds AV42-PROGRESS.json from the shard +files (idempotent, run after all shards finish). A shard is processed only +if its receipt file is absent or incomplete; re-invoke to continue. +Receipts carry explicit complete/budget_hit flags (a partial walk is never +recorded as complete). Starting a mode with no receipt prints 'fresh +receipts confirmed' (the receipt-validation trap: replaying against a +committed receipt validates nothing). +""" + +import json +import sys +import time +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE)) +sys.path.insert(0, str(HERE / "vendor")) + +import walk42 # noqa: E402 + +PROGRESS = HERE / "AV42-PROGRESS.json" +MODES = ("av42", "size", "k3", "k4") +TAGS = {"av42": "AV42"} + + +def shard_file(mode, k): + return HERE / ("AV42-%s-%d.json" % (TAGS.get(mode, mode.upper()), k)) + + +def load_shard(mode, k): + p = shard_file(mode, k) + if p.exists(): + return json.loads(p.read_text(encoding="utf-8")) + return None + + +def aggregate(shards): + keys = set() + for rec in shards: + keys |= set(rec) + tot = {} + for k in sorted(keys): + vals = [ + rec[k] + for rec in shards + if isinstance(rec.get(k), (int, float)) + and k not in ("shard", "shards", "seconds", "wall_seconds") + ] + if vals: + if k.endswith("_total") and len(set(vals)) == 1: + tot[k] = vals[0] + else: + tot[k] = sum(vals) + dicts = [rec[k] for rec in shards if isinstance(rec.get(k), dict)] + if dicts: + merged = {} + for d in dicts: + for kk, vv in d.items(): + merged[kk] = merged.get(kk, 0) + vv + tot[k] = merged + return tot + + +def run_shard(mode, k, shards, budget): + rec = load_shard(mode, k) + if rec and rec.get("complete"): + print("SKIP %s shard=%d already complete" % (mode, k), flush=True) + return rec + t0 = time.time() + rec = walk42.class42_run(budget=budget, shard=k, shards=shards) + rec["wall_seconds"] = round(time.time() - t0, 2) + rec["complete"] = not rec.get("budget_hit", False) + shard_file(mode, k).write_text( + json.dumps(rec, indent=2, sort_keys=True) + "\n", encoding="utf-8" + ) + print( + "RECEIPT %s shard=%d/%d wall=%.1fs complete=%s budget_hit=%s u=%d pairs=%d w_cand=%d covering=%d" + % ( + mode, + k, + shards, + rec["wall_seconds"], + rec["complete"], + rec.get("budget_hit"), + rec["u_checked"], + rec["uv_pairs"], + rec["w_candidates"], + rec["covering_configs"], + ), + flush=True, + ) + return rec + + +def merge(mode, shards): + recs = [] + done = [] + for k in range(shards): + rec = load_shard(mode, k) + if rec and rec.get("complete"): + recs.append(rec) + done.append(k) + prog = ( + json.loads(PROGRESS.read_text(encoding="utf-8")) + if PROGRESS.exists() + else {"modes": {}} + ) + sec = { + "shards": {str(k): r for k, r in zip(done, recs)}, + "shards_count": shards, + "complete": len(done) == shards, + } + sec["total"] = aggregate(recs) + prog["modes"][mode] = sec + PROGRESS.write_text( + json.dumps(prog, indent=2, sort_keys=True) + "\n", encoding="utf-8" + ) + print( + "MERGE %s shards=%d/%d complete=%s total=%s" + % (mode, len(done), shards, sec["complete"], json.dumps(sec["total"], sort_keys=True)[:400]), + flush=True, + ) + return sec + + +def size_probe(budget): + """Budget-honest sizing: walk a bounded number of normalized U slices + with the real engine and report pairs/s plus the |U+V| histogram + (need 24).""" + t0 = time.time() + rec = walk42.class42_run(budget=budget, shard=0, shards=2048, u_limit=64, progress=True) + el = max(time.time() - t0, 1e-9) + print( + "SIZE u_checked=%d uv_pairs=%d w_candidates=%d covering=%d pairs_per_s=%.1f hist=%s seconds=%.1f" + % ( + rec["u_checked"], + rec["uv_pairs"], + rec["w_candidates"], + rec["covering_configs"], + rec["uv_pairs"] / el, + json.dumps(rec["uv_pairs_by_sumset_size"], sort_keys=True), + el, + ), + flush=True, + ) + if rec["u_checked"] > 0: + per_u = rec["uv_pairs"] / rec["u_checked"] + est_pairs = per_u * 169911 + print( + "SIZE estimate total_pairs=%.3e total_core_hours_at_probe_rate=%.1f" + % (est_pairs, el / rec["u_checked"] * 169911 / 3600.0), + flush=True, + ) + + +def main(): + sys.stdout.reconfigure(encoding="utf-8") + if len(sys.argv) < 2: + raise SystemExit("usage: run42.py %s [--shards N] [--shard k]" % "|".join(MODES)) + mode = sys.argv[1] + args = sys.argv[2:] + if mode == "merge": + target = args[0] + shards = int(args[args.index("--shards") + 1]) if "--shards" in args else 8 + merge(target, shards) + return + if mode not in MODES: + raise SystemExit("usage: run42.py %s [--shards N] [--shard k]" % "|".join(MODES)) + budget = float(args[args.index("--budget") + 1]) if "--budget" in args else 3600.0 + if mode == "size": + size_probe(budget) + return + if mode == "k3": + t0 = time.time() + res = walk42.census_k3() + out = HERE / "CENSUS-K3.json" + out.write_text(json.dumps(res, indent=2, sort_keys=True) + "\n", encoding="utf-8") + n_cover = sum(1 for r in res.values() if r["covers"] > 0) + n_pair = sum(1 for r in res.values() if r["kill_shape"] == "pair") + print( + "CENSUS_K3 classes=%d cover=%d pair_killed=%d seconds=%.1f" + % (len(res), n_cover, n_pair, time.time() - t0), + flush=True, + ) + return + if mode == "k4": + t0 = time.time() + res = walk42.census_k4(u_max=4, w_max=6) + out = HERE / "CENSUS-K4.json" + out.write_text(json.dumps(res, indent=2, sort_keys=True) + "\n", encoding="utf-8") + n_cover = sum(1 for r in res.values() if r.get("pairs_with_cover", 0) > 0) + n_pair = sum(1 for r in res.values() if r["kill_shape"] == "pair") + print( + "CENSUS_K4 classes=%d cover=%d pair_killed=%d seconds=%.1f" + % (len(res), n_cover, n_pair, time.time() - t0), + flush=True, + ) + return + shards = int(args[args.index("--shards") + 1]) if "--shards" in args else 8 + if not any(shard_file(mode, k).exists() for k in range(shards)) and not PROGRESS.exists(): + print("fresh receipts confirmed (%s: no receipt file existed)" % mode, flush=True) + if "--shard" in args: + run_shard(mode, int(args[args.index("--shard") + 1]), shards, budget) + return + for k in range(shards): + rec = load_shard(mode, k) + if rec and rec.get("complete"): + continue + run_shard(mode, k, shards, budget) + sec = merge(mode, shards) + if sec["complete"]: + print("PASS_RUN %s" % mode, flush=True) + else: + print("PARTIAL_RUN %s complete=false" % mode, flush=True) + + +if __name__ == "__main__": + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_cover17.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_cover17.py new file mode 100644 index 0000000000..5add3747a3 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_cover17.py @@ -0,0 +1,263 @@ +"""17-point cover audit engine: pair-representation identity, sharp rows, +coverage primitives and exact small controls. + +Object (KB3c, pair-collision object change recorded in TASK.json): the status +of PR 2542's claim "No 17-point set covers F2^7" against its own lemma table. +PR 2542's `lemma_a_table` (vendored byte-exact as vendor/pr2542_engine.py, +credit PR 2542, package research/universal-f7-singleton-seedb859517b) only +contradicts the (9,8)/(8,9) split rows; the counting-feasible 17-point splits +(10,7)/(7,10)/(11,6)/(6,11) survive it. This module extends the identity +with the sharp collision-multiplicity constraint and computes exactly which +(e_ex, b_ex, c) rows survive per split. + +Definitions. S = A u B with A = S int E (s points, even weight), B = S int O +(t points, odd weight), s + t = 17. A_x = #unordered pairs of A summing to +x, B_x likewise (x even nonzero). e_ex = C(s,2) - |supp(A)|, b_ex likewise. +Cross sums a+b (a in A, b in B) hit the odd masks with multiplicities r_o, so + + odd excess sum_o (r_o - 1) = s*t - 2^(n-1) =: E_o + colliding pairs sum_o C(r_o,2) = 2 * sum_x A_x B_x =: 2c + +with C(r,2) >= r-1 per mask. A collision profile is a partition of E_o into +j = r_o - 1 parts; it needs sigma = sum j(j+1)/2 = 2c even. A row (e_ex, +b_ex) is multiset-feasible for profile c iff c is exactly attainable as the +sum of shared products A_x B_x over the shared = C(s,2)+C(t,2)-e_ex-b_ex- +(2^(n-1)-1) support positions (multiplicity shapes from partitions of e_ex +resp. b_ex). This refines PR 2542's closed-form upper bound. +""" + +from functools import lru_cache + +VENDOR_PIN_PR2542 = ( + "82e4c407b58864c74ffd14d47f00b6b1675005ee0e0173909b7bd092491175e4" +) + + +# ------------------------------------------------------- counting bounds + + +def counting_ok(n, s, t): + odd_masks = 1 << (n - 1) + even_nonzero = odd_masks - 1 + return ( + s * t >= odd_masks + and s * (s - 1) // 2 + t * (t - 1) // 2 >= even_nonzero + ) + + +# ------------------------------------------- collision-multiplicity identity + + +def _partitions(total): + """Integer partitions of total as tuples (non-increasing).""" + if total == 0: + yield () + return + for part in range(total, 0, -1): + for rest in _partitions(total - part): + if not rest or rest[0] <= part: + yield (part,) + rest + + +def odd_profiles(excess): + """Collision profiles for odd excess `excess`: partitions j of it with + sigma = sum j(j+1)/2 even (= 2c for integer c). Each j is one odd mask + with r = j + 1 cross representations.""" + out = [] + for parts in _partitions(excess): + sigma = sum(j * (j + 1) // 2 for j in parts) + if sigma % 2 == 0: + out.append(sorted(parts)) + return sorted(out) + + +def profile_c_values(n, s, t): + """c = sum_x A_x B_x forced by each integer collision profile.""" + excess = s * t - (1 << (n - 1)) + if excess < 0: + return [] + return sorted( + {sum(j * (j + 1) // 2 for j in parts) // 2 for parts in odd_profiles(excess)} + ) + + +def _shapes(total_pairs, excess): + """Multiplicity shapes: A_x values summing to total_pairs with support + size total_pairs - excess (the excess parts carry the collisions).""" + if excess > total_pairs: + return + for parts in _partitions(excess): + yield tuple(sorted((1 + p for p in parts), reverse=True)) + ( + 1, + ) * (total_pairs - excess - len(parts)) + + +def _draws(shape, shared): + """All multisets of `shared` values drawn from a multiplicity shape.""" + if shared == 0: + yield () + return + counts = {} + for v in shape: + counts[v] = counts.get(v, 0) + 1 + vals = sorted(counts) + limits = [counts[v] for v in vals] + + def rec(i, remaining, acc): + if i == len(vals): + if remaining == 0: + yield tuple(acc) + return + for take in range(min(limits[i], remaining) + 1): + yield from rec(i + 1, remaining - take, acc + [vals[i]] * take) + + yield from rec(0, shared, []) + + +def _pairing_sums(a_draw, b_draw): + """All dot products sum a_i b_pi(i) over pairings of two draws.""" + if len(a_draw) <= 1: + yield sum(x * y for x, y in zip(a_draw, b_draw)) + return + a0 = a_draw[0] + for i in range(len(b_draw)): + rest = b_draw[:i] + b_draw[i + 1 :] + for tail in _pairing_sums(a_draw[1:], rest): + yield a0 * b_draw[i] + tail + + +def attainable_c(n, s, t, e_ex, b_ex): + """Exact attainable values of sum_x A_x B_x on the shared support + positions for one (e_ex, b_ex) row.""" + odd_masks = 1 << (n - 1) + even_nonzero = odd_masks - 1 + A = s * (s - 1) // 2 + B = t * (t - 1) // 2 + shared = A + B - e_ex - b_ex - even_nonzero + if shared < 0: + return set() + out = set() + for sa in _shapes(A, e_ex): + for sb in _shapes(B, b_ex): + for da in _draws(sa, shared): + for db in _draws(sb, shared): + out.update(_pairing_sums(da, db)) + return out + + +def sharp_rows(n, s, t): + """Sharp pair-representation rows for one parity split. + + Returns {feasible, rows: [{e_ex, b_ex, shared, c}], best, need}: a row + survives iff some integer collision profile's c is exactly attainable. + `best` is the largest attainable c (PR 2542's closed-form comparison + quantity), `need` = ceil((s*t - 2^(n-1))/2) the profile-level necessity. + """ + odd_masks = 1 << (n - 1) + even_nonzero = odd_masks - 1 + A = s * (s - 1) // 2 + B = t * (t - 1) // 2 + excess = s * t - odd_masks + need = (excess + 1) // 2 if excess > 0 else 0 + rows = [] + best = -1 + if excess < 0 or A + B < even_nonzero: + return dict(feasible=False, rows=[], best=best, need=need) + c_vals = set(profile_c_values(n, s, t)) + for e_ex in range(A + 1): + for b_ex in range(B + 1): + shared = A + B - e_ex - b_ex - even_nonzero + if shared < 0: + continue + attain = attainable_c(n, s, t, e_ex, b_ex) + if not attain: + continue + best = max(best, max(attain)) + for c in sorted(attain & c_vals): + rows.append(dict(e_ex=e_ex, b_ex=b_ex, shared=shared, c=c)) + return dict(feasible=bool(rows), rows=rows, best=best, need=need) + + +def surviving_rows(n, s, t, min_e_ex=0, min_b_ex=0): + """Sharp rows filtered by census-implied minimum excesses (min excess of + s-point sets resp. t-point sets in F2^(n-1)).""" + sharp = sharp_rows(n, s, t) + rows = [ + r + for r in sharp["rows"] + if r["e_ex"] >= min_e_ex and r["b_ex"] >= min_b_ex + ] + return dict( + feasible=bool(rows), + rows=rows, + best=sharp["best"], + need=sharp["need"], + ) + + +# ------------------------------------------------------ coverage primitives + + +def coverage_mask(pts): + """Bitmask of {a ^ b : a, b in pts} (self-pairs give mask 0).""" + mask = 1 # zero via a = b + for i in range(len(pts)): + pi = pts[i] + for j in range(i): + mask |= 1 << (pi ^ pts[j]) + return mask + + +def coverage_mask_dual(pts): + """Dual predicate (PR 2542's independent check): mask m is covered iff + (pts xor m) meets pts.""" + pset = set(pts) + limit = 1 << max(pts).bit_length() if pts else 1 + mask = 0 + for m in range(limit): + if any((p ^ m) in pset for p in pts): + mask |= 1 << m + return mask + + +# --------------------------------------------------- exact small controls + + +@lru_cache(maxsize=None) +def brute_force_set_census(n, k): + """Exact census of k-point sets S (0 in S, translation WLOG) over F2^n: + returns (number of covering sets, max |S+S|). Incremental DFS over + combinations with the pair-count upper-bound prune.""" + N = 1 << n + full_mask = (1 << N) - 1 + pairs_total = k * (k - 1) // 2 + state = {"covers": 0, "best": 0} + + sums = [0] + masks = [1] # stack of coverage masks + + def rec(next_pt, depth): + size = depth + 1 + if size == k: + mask = masks[-1] + covered = mask.bit_count() + if covered > state["best"]: + state["best"] = covered + if mask == full_mask: + state["covers"] += 1 + return + remaining_pairs = pairs_total - size * (size - 1) // 2 + if masks[-1].bit_count() + remaining_pairs < N: + return + for p in range(next_pt, N): + new = 1 << p + for q in sums: + new |= 1 << (p ^ q) + sums.append(p) + masks.append(masks[-1] | new) + rec(p + 1, depth + 1) + masks.pop() + sums.pop() + + rec(1, 0) + return state["covers"], state["best"] diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_search17.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_search17.py new file mode 100644 index 0000000000..ef17635967 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/agent64_search17.py @@ -0,0 +1,330 @@ +"""Exact Sidon/near-Sidon census for the 17-point cover question (F2^7). + +Established here (receipt in SIDON-RECEIPT.json): + + * F2^6 has no Sidon 10-set. A complete DFS of all 10-subsets of the even + group E (= F2^6) containing {0, 3} finds none; Sidon-ness is translation- + invariant and GL(6,2)-invariant, and GL(6,2) is transitive on nonzero + elements, so one shard decides existence. Consequences (recorded in the + package README with the removal argument): every 10-point set has + pair-sum excess >= 1, every 11-point set has excess >= 2. This kills + the extremal (10,7) row of cover17.sharp_rows (e_ex = 0) and the (11,6) + rows e_ex in {0, 1}. + +Remaining exact search domains (row-restricted; the handoff object): + + rows (10,7): (e_ex, b_ex, c) in {(1,0,3), (1,1,4), (2,0,3)} + rows (11,6): (e_ex, b_ex, c) = (e, 6-e, 1) with e in {2,3,4,5,6} + +`enumerate_sets` is the enumeration primitive a row-restricted search builds +on (per-A constrained B-side DFS; the B side is far too large to enumerate +outright: ~3.1e8 Sidon 7-sets in the odd coset). Domain completeness for a +search: fix 0, 3 in A (GL(6,2) transitivity + stabilizer arguments, see +README); do NOT fix any element of B (the stabilizer extension fixes the +coset shift u and cannot move B's elements to it). Standard library only. +""" + +import json +import sys +import time +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE)) + +N = 128 +EVEN = [x for x in range(N) if x.bit_count() % 2 == 0] +ODD = [x for x in range(N) if x.bit_count() % 2 == 1] +EVEN_NZ = sum(1 << x for x in EVEN if x) # 63 even nonzero masks +ODD_ALL = sum(1 << x for x in ODD) # 64 odd masks +RECEIPT = HERE / "SIDON-RECEIPT.json" + + +# ------------------------------------------------------------ enumeration + + +def enumerate_sets(pool, k, budget, fixed=()): + """All k-subsets of `pool` containing `fixed`, of pair-sum excess + <= budget. Yields (pts, support_mask, mult) where mult maps each + supported even mask to its pair multiplicity A_x. Free elements are + chosen in increasing pool order, so each set is yielded once.""" + fixed = tuple(sorted(fixed)) + pts = list(fixed) + mult = {} + for i in range(len(pts)): + for j in range(i): + x = pts[i] ^ pts[j] + mult[x] = mult.get(x, 0) + 1 + supp = 0 + for x in mult: + supp |= 1 << x + excess = sum(mult.values()) - bin(supp).count("1") + + def rec(idx, supp, excess): + if len(pts) == k: + yield (tuple(pts), supp, dict(mult)) + return + need = k - len(pts) + for p in range(idx, len(pool) - need + 1): + v = pool[p] + if v in pts: + continue + new_sums = [v ^ q for q in pts] if pts else [] + add = 0 + coll = 0 + for x in new_sums: + if supp >> x & 1: + coll += 1 + else: + add |= 1 << x + new_excess = excess + coll + if new_excess > budget: + continue + for x in new_sums: + mult[x] = mult.get(x, 0) + 1 + pts.append(v) + yield from rec(p + 1, supp | add, new_excess) + pts.pop() + for x in new_sums: + mult[x] -= 1 + if mult[x] == 0: + del mult[x] + + yield from rec(0, supp, excess) + + +def count_sets(pool, k, budget, fixed=(), exclude=()): + """(count, first) for the same domain as enumerate_sets, without + materializing leaves (fast path for receipts).""" + fixed = tuple(sorted(fixed)) + pts = list(fixed) + supp = 0 + excess = 0 + for i in range(len(pts)): + for j in range(i): + x = pts[i] ^ pts[j] + if supp >> x & 1: + excess += 1 + else: + supp |= 1 << x + state = {"count": 0, "first": None} + + def rec(idx, supp, excess): + if len(pts) == k: + state["count"] += 1 + if state["first"] is None: + state["first"] = tuple(pts) + return + need = k - len(pts) + for p in range(idx, len(pool) - need + 1): + v = pool[p] + if v in pts: + continue + add = 0 + coll = 0 + for q in pts: + x = v ^ q + if supp >> x & 1: + coll += 1 + else: + add |= 1 << x + new_excess = excess + coll + if new_excess > budget: + continue + pts.append(v) + rec(p + 1, supp | add, new_excess) + pts.pop() + + rec(0, supp, excess) + return state["count"], state["first"] + + +def hist_sets(pool, k, budget, fixed=(), exclude=(), floor=None): + """Exact-excess histogram over the same domain: dict excess -> count, + plus one example per excess value. `floor` restricts free elements to + values > floor (sub-shard partition by the smallest free element).""" + fixed = tuple(sorted(fixed)) + excl = set(exclude) + pts = list(fixed) + supp = 0 + excess = 0 + for i in range(len(pts)): + for j in range(i): + x = pts[i] ^ pts[j] + if supp >> x & 1: + excess += 1 + else: + supp |= 1 << x + hist = {} + examples = {} + + def rec(idx, supp, excess): + if len(pts) == k: + hist[excess] = hist.get(excess, 0) + 1 + if str(excess) not in examples: + examples[str(excess)] = tuple(pts) + return + need = k - len(pts) + for p in range(idx, len(pool) - need + 1): + v = pool[p] + if v in pts or v in excl: + continue + if floor is not None and v <= floor: + continue + add = 0 + coll = 0 + for q in pts: + x = v ^ q + if supp >> x & 1: + coll += 1 + else: + add |= 1 << x + new_excess = excess + coll + if new_excess > budget: + continue + pts.append(v) + rec(p + 1, supp | add, new_excess) + pts.pop() + + rec(0, supp, excess) + return hist, examples + + +# --------------------------------------------------------------- receipt + + +def sidon_receipt(): + """The load-bearing exact counts. Shard = sets through {0, 3} in E + (complete for existence by GL(6,2) transitivity) and through {1} in O + (B-side feasibility/sizing only, not used for completeness).""" + out = {"shard_e03": {}, "shard_o1": {}} + for k, budget in ((10, 0), (9, 0), (10, 1)): + t1 = time.time() + n, first = count_sets(EVEN, k, budget, fixed=(0, 3)) + out["shard_e03"][f"k{k}_budget{budget}"] = { + "count": n, + "first": first, + "seconds": round(time.time() - t1, 1), + } + RECEIPT.write_text(json.dumps(out, indent=2, sort_keys=True), encoding="utf-8") + print(f"SIDON k={k} budget={budget} shard(0,3) n={n}", flush=True) + t1 = time.time() + n, first = count_sets(ODD, 7, 0, fixed=(1,)) + out["shard_o1"]["k7_budget0"] = { + "count": n, + "first": first, + "seconds": round(time.time() - t1, 1), + } + out["controls"] = { + "small_space_agreement": "enumerate_sets == naive brute force on the " + "even subgroup < 32: k=4 420/420, k=5 840/840, k=6 168/168" + } + RECEIPT.write_text(json.dumps(out, indent=2, sort_keys=True), encoding="utf-8") + print(f"SIDON k=7 budget=0 shard(1) odd n={n}", flush=True) + return out + + +def raw11_census(budget=4): + """Raw-domain census of 11-sets through {0, 3} with pair-sum excess + <= budget, counting by exact excess (the histogram yields the level-3 + and level-4 counts in one walk). Sub-sharded by the smallest free + element (disjoint, complete), resumable via RAW11-PROGRESS.json.""" + prog_path = HERE / "RAW11-PROGRESS.json" + prog = {"budget": budget, "shards": {}} + if prog_path.exists(): + old = json.loads(prog_path.read_text(encoding="utf-8")) + if old.get("budget") == budget: + prog = old + for v0 in EVEN: + if v0 in (0, 3): + continue + key = f"v0={v0}" + if key in prog["shards"]: + continue + t1 = time.time() + hist, examples = hist_sets( + EVEN, 11, budget, fixed=(0, 3, v0), floor=v0 + ) + prog["shards"][key] = { + "hist": {str(k): v for k, v in sorted(hist.items())}, + "examples": examples, + "seconds": round(time.time() - t1, 1), + } + prog_path.write_text( + json.dumps(prog, indent=2, sort_keys=True), encoding="utf-8" + ) + print(f"RAW11 {key} hist={hist} seconds={prog['shards'][key]['seconds']}", flush=True) + total = {} + for rec in prog["shards"].values(): + for e, n in rec["hist"].items(): + total[e] = total.get(e, 0) + n + prog["total_hist"] = {str(k): v for k, v in sorted(total.items())} + prog["complete"] = True + prog_path.write_text(json.dumps(prog, indent=2, sort_keys=True), encoding="utf-8") + print(f"RAW11 total_hist={prog['total_hist']}", flush=True) + return prog + + +def main(): + mode = sys.argv[1] if len(sys.argv) > 1 else "receipt" + if mode == "receipt": + sidon_receipt() + elif mode == "deeper": + # Follow-up census: decide whether excess 2 is attainable at all for + # 10-sets (kills the last (10,7) row (2,0,3) if not) and size the + # 11-set side (rows (11,6) with e_ex in {2, 3}). + out = {} + if RECEIPT.exists(): + out = json.loads(RECEIPT.read_text(encoding="utf-8")) + out.setdefault("shard_e03", {}) + for k, budget in ((10, 2), (11, 2)): + t1 = time.time() + n, first = count_sets(EVEN, k, budget, fixed=(0, 3)) + out["shard_e03"][f"k{k}_budget{budget}"] = { + "count": n, + "first": first, + "seconds": round(time.time() - t1, 1), + } + RECEIPT.write_text( + json.dumps(out, indent=2, sort_keys=True), encoding="utf-8" + ) + print(f"SIDON k={k} budget={budget} shard(0,3) n={n}", flush=True) + elif mode == "deeper2": + # Pin min excess(10) exactly and push the (11,6) A-side rows: + # k=11 budget b decides rows (e, 6-e, 1) with e = b. + out = {} + if RECEIPT.exists(): + out = json.loads(RECEIPT.read_text(encoding="utf-8")) + out.setdefault("shard_e03", {}) + for k, budget in ((10, 3), (11, 3), (11, 4)): + t1 = time.time() + n, first = count_sets(EVEN, k, budget, fixed=(0, 3)) + out["shard_e03"][f"k{k}_budget{budget}"] = { + "count": n, + "first": first, + "seconds": round(time.time() - t1, 1), + } + RECEIPT.write_text( + json.dumps(out, indent=2, sort_keys=True), encoding="utf-8" + ) + print(f"SIDON k={k} budget={budget} shard(0,3) n={n}", flush=True) + elif mode == "raw11": + prog = raw11_census() + if RECEIPT.exists(): + out = json.loads(RECEIPT.read_text(encoding="utf-8")) + else: + out = {} + out["k11_raw_budget4"] = { + "domain": "11-sets through {0,3} (complete by GL(6,2) " + "transitivity), sub-sharded by the smallest free element", + "total_hist": prog["total_hist"], + "sub_shards": len(prog["shards"]), + "complete": True, + } + RECEIPT.write_text(json.dumps(out, indent=2, sort_keys=True), encoding="utf-8") + else: + raise SystemExit(f"unknown mode {mode}") + + +if __name__ == "__main__": + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/anchors.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/anchors.py new file mode 100644 index 0000000000..d07fa31100 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/anchors.py @@ -0,0 +1,128 @@ +"""Resumable recomputation of the two heavy PR 2773 census anchors (KB3d). + +Established method (PR 2773, package research/f7-17point-cover-audit-seedcfa215c2, +Aaron Wang): raw-domain walk over the even group E = F2^6, complete +GL(6,2)-transitive domain through {0, 3}, sub-sharded by the smallest free +element (disjoint and complete), resumable with per-sub-shard receipts in +ANCHOR-PROGRESS.json. The enumeration itself is the vendored PR 2773 engine +(vendor/agent64_search17.py, byte-pinned; credit: Aaron Wang, PR 2773). + + anchors.py k10b3 [--seconds S] 10-sets through {0,3}, excess <= 3 + (recorded anchor: 149,990,400) + anchors.py k11b4 [--seconds S] 11-sets through {0,3}, excess <= 4 + (recorded anchor: level3 = level4 = 0) + +Each invocation processes sub-shards until the elapsed budget (default 540 s), +writes receipts after every sub-shard, and exits 0; re-invoke to continue. +A completed run prints PASS_ANCHORS_ with the exact totals and compares +them with the recorded anchor values. +""" + +import json +import sys +import time +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE / "vendor")) + +import agent64_search17 as s17 + +PROGRESS = HERE / "ANCHOR-PROGRESS.json" + +MODES = { + "k10b3": { + "k": 10, + "budget": 3, + "anchor_count": 149990400, + "description": "10-sets through {0,3}, pair-sum excess <= 3", + }, + "k11b4": { + "k": 11, + "budget": 4, + "anchor_count": 0, + "description": "11-sets through {0,3}, pair-sum excess <= 4", + }, +} + + +def load_progress(mode): + """Per-mode sections in one file (v1 kept one mode per file and lost the + other mode's receipts when switching; migrated on read).""" + data = {"modes": {}} + if PROGRESS.exists(): + old = json.loads(PROGRESS.read_text(encoding="utf-8")) + if "modes" in old: + data = old + elif "mode" in old: + data["modes"][old["mode"]] = { + k: v for k, v in old.items() if k != "mode" + } + return data["modes"].setdefault(mode, {"shards": {}}) + + +def save_progress(mode, prog): + data = {"modes": {}} + if PROGRESS.exists(): + old = json.loads(PROGRESS.read_text(encoding="utf-8")) + if "modes" in old: + data = old + elif "mode" in old: + data["modes"][old["mode"]] = { + k: v for k, v in old.items() if k != "mode" + } + data["modes"][mode] = prog + PROGRESS.write_text(json.dumps(data, indent=2, sort_keys=True), encoding="utf-8") + + +def main(): + mode = sys.argv[1] if len(sys.argv) > 1 else "" + if mode not in MODES: + raise SystemExit("usage: anchors.py k10b3|k11b4 [--seconds S]") + budget_seconds = 540.0 + if "--seconds" in sys.argv: + budget_seconds = float(sys.argv[sys.argv.index("--seconds") + 1]) + spec = MODES[mode] + prog = load_progress(mode) + prog["spec"] = {k: v for k, v in spec.items()} + t_start = time.time() + for v0 in sorted(s17.EVEN): + if v0 in (0, 3): + continue + key = f"v0={v0}" + if key in prog["shards"]: + continue + t1 = time.time() + hist, examples = s17.hist_sets( + s17.EVEN, spec["k"], spec["budget"], fixed=(0, 3, v0), floor=v0 + ) + prog["shards"][key] = { + "hist": {str(e): n for e, n in sorted(hist.items())}, + "examples": examples, + "seconds": round(time.time() - t1, 2), + } + save_progress(mode, prog) + print( + f"ANCHOR {mode} {key} hist={prog['shards'][key]['hist']}" + f" seconds={prog['shards'][key]['seconds']}" + f" done={len(prog['shards'])}/62", + flush=True, + ) + if time.time() - t_start > budget_seconds: + print(f"RECEIPT {mode} checkpoint shards={len(prog['shards'])}/62", flush=True) + return + total = {} + for rec in prog["shards"].values(): + for e, n in rec["hist"].items(): + total[e] = total.get(e, 0) + n + count = sum(total.values()) + prog["total_hist"] = {str(e): n for e, n in sorted(total.items())} + prog["complete"] = True + save_progress(mode, prog) + assert count == spec["anchor_count"], (mode, count, spec["anchor_count"]) + print(f"PASS_ANCHORS_{mode.upper()} count={count} total_hist={prog['total_hist']} shards=62", flush=True) + + +if __name__ == "__main__": + sys.stdout.reconfigure(encoding="utf-8") + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/cover18.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/cover18.py new file mode 100644 index 0000000000..3faa640d79 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/cover18.py @@ -0,0 +1,741 @@ +"""KB3e engine: the 18-point cover question for F2^7. + +Object. In the PR943 prefix-walk model (Ross Richardson, +`research/universal-connector-boundary`, PR 943) a restored seven-source +singleton word is universal exactly when its prefix set `P` covers: +`P + P = F2^7` (every mask of F2^7 is a pair-sum `a + b` of two elements of the +set; self-pairs `a + a` cover mask 0, and the sumset is translation-invariant +so WLOG `0 in S`). PR 2542 (Aaron Wang) excludes length 18 and asserts "no +17-point set covers F2^7"; PR 2773 (Aaron Wang) audits it split-by-split and +PR 2870 (Aaron Wang) closes the remainder rows (5,1),(6,0) with an exact +odd-coverage Fourier/Parseval identity. This module asks the immediate +successor question: **does any 18-point set cover F2^7?** + +Parity splits. S = A u B with A = S int E (s points, even-weight coset) and +B = S int O (t points, odd-weight coset), s + t = 18. The counting-feasible +splits are (12,6), (11,7), (10,8), (9,9) and their mirrors; every 18-point +split has s and t of EQUAL parity (18 is even), which is exactly the case the +PR 2870 squeeze does not reach (its hypothesis is opposite parity). + +Three layers of evidence are computed here, all exact integer arithmetic: + +1. `fourier_profile_feasibility(n, s, t)` -- a per-character profile system + (necessary conditions for a cover): parity of characters, the odd-half + bound |f_hat g_hat| = |rho_hat| <= E_o with rho_hat == E_o (mod 2), the + even-half bound f_hat^2 + g_hat^2 <= s + t + 2*P - 2^n (P = C(s,2)+C(t,2)), + Parseval on both sides, and the exact attainable sums of squares of rho. + Infeasibility of the system PROVES the split impossible; feasibility only + says the Fourier layer does not exclude it. The system reproduces the + PR 2870 exclusion of (11,6)/(6,11) (control in test_engine.py). +2. `sharp_rows_fast(n, s, t)` -- PR 2773's pair-representation rows + (e_ex, b_ex, c), reusing its byte-vendored shape/draw primitives with a + contingency-table pairing-sums replacement that the vendored O(m!) pairing + loop cannot run at the 18-point row sizes. Census floors (min pair-sum + excess of k-sets in F2^6) demote rows exactly as in PR 2773. +3. `search_split(...)` / `search_direct(...)` -- a bounded, seeded local + search for a covering pair (A, D) resp. an 18-point set. A found cover is + a falsifying instance for "no 18-point cover exists"; a failed bounded + search is recorded as a scoped search failure, never as an exclusion. + +Reduction lemma (checked exhaustively at n = 3 in test_engine.py). Fix an +odd mask p and set D = p + B (a subset of E). Then S = A u B covers F2^n iff +(i) A + D = E and (ii) (A + A) u (D + D) = E. So every split (s, t) is a +two-set covering problem in the even group E =~ F2^6. + +All arithmetic is exact Python integers; no floats are used. +""" + +import random +import time +from collections import Counter +from functools import lru_cache +from itertools import combinations +from pathlib import Path +import sys + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE / "vendor")) + +import agent64_cover17 as c17 # noqa: E402 + +# Byte pins of the vendored PR 2773 engine (credit: Aaron Wang, PR 2773, +# head 6739c799799621878a9249c93e2b12cc799c1482; extracted with +# agent_tools.py pr-tree-extract from PR 2870's hash-pinned vendor/). +VENDOR_PIN_COVER17 = ( + "082bc838134cba9754368cff894d53c729467a689b4cafee8374423688d93654" +) +VENDOR_PIN_SEARCH17 = ( + "9eb1bf79ffb99b0efcdaf57916c493bc781abd4a0096d584dc6bc6ca294bf674" +) + + +# ------------------------------------------------------------- coverage + + +def dot(s, x): + return (s & x).bit_count() & 1 + + +def coverage_mask(pts): + """Bitmask of {a ^ b : a, b in pts} (self-pairs give mask 0).""" + mask = 1 + for i in range(len(pts)): + pi = pts[i] + for j in range(i): + mask |= 1 << (pi ^ pts[j]) + return mask + + +def covers(pts, n=7): + return coverage_mask(pts) == (1 << (1 << n)) - 1 + + +def split_of(pts): + e = sum(1 for p in pts if not dot(127, p)) + return (e, len(pts) - e) + + +def even_masks(n=7): + return [x for x in range(1 << n) if not dot((1 << n) - 1, x)] + + +def odd_masks(n=7): + return [x for x in range(1 << n) if dot((1 << n) - 1, x)] + + +def _pair_mask(pts): + """Bitmask over the 128 masks of {a ^ b : a, b in pts} (0 via a = b).""" + return coverage_mask(pts) + + +def _covers_all(mask, universe): + return (mask & universe) == universe + + +def reduction_conditions(A, B, n=7): + """(odd_ok, even_ok) of the (A, D) reduction. D = p + B for an odd p; + A u B covers F2^n iff odd_ok and even_ok both hold.""" + p = 1 + D = [p ^ b for b in B] + ev = even_masks(n) + universe = 0 + for x in ev: + universe |= 1 << x + cross = 0 + for a in A: + for d in D: + cross |= 1 << (a ^ d) + selfs = _pair_mask(A) | _pair_mask(D) + return _covers_all(cross, universe), _covers_all(selfs, universe) + + +# ------------------------------------------------------- rho bookkeeping + + +def _partitions(total): + if total == 0: + yield () + return + for part in range(total, 0, -1): + for rest in _partitions(total - part): + if not rest or rest[0] <= part: + yield (part,) + rest + + +@lru_cache(maxsize=None) +def rho_square_values(excess): + """Attainable sums of squares sum rho_x^2 over integer rho >= 0 with + sum rho_x = excess (partition square sums). Domain guard: excess <= 24 + (all splits this package decides have E_o <= 17); beyond that the + partition enumeration is out of budget and callers must treat the split + as not attempted, never as excluded.""" + if excess > 24: + raise ValueError("rho_square_values: excess %d out of budget" % excess) + return sorted({sum(j * j for j in parts) for parts in _partitions(excess)}) + + +# ------------------------------------------------- Fourier profile system + + +def even_half_max(n, s, t): + """Max of f_hat^2 + g_hat^2 off the all-ones hyperplane, from the even + half of the covering condition: s + t + 2*P - 2^n, P = C(s,2)+C(t,2).""" + P = s * (s - 1) // 2 + t * (t - 1) // 2 + return s + t + 2 * P - (1 << n) + + +def shapes_fourier(n, s, t, nonzero_both=False): + """Admissible per-character shapes (f2, g2, p2) = (f_hat^2, g_hat^2, + (f_hat*g_hat)^2) off {0, 1}: character parities, |rho_hat| <= E_o with + rho_hat == E_o (mod 2), and the even-half bound. nonzero_both restricts + to shapes with both characters nonzero (the no-vanishing sub-case).""" + eo = s * t - (1 << (n - 1)) + if eo < 0: + return [] + bound = even_half_max(n, s, t) + out = [] + for a in range(0, s + 1): + if a % 2 != s % 2: + continue + if nonzero_both and a == 0: + continue + for b in range(0, t + 1): + if b % 2 != t % 2: + continue + if nonzero_both and b == 0: + continue + prod = a * b + if prod > eo or prod % 2 != eo % 2: + continue + if a * a + b * b > bound: + continue + out.append((a * a, b * b, prod * prod)) + return out + + +def _solve_counts(shapes, U, RF, RG, RP, cap=4000000): + """First nonneg integer solution of sum n_i = U, sum n_i f2_i = RF, + sum n_i g2_i = RG, sum n_i p2_i = RP, or None. Returns (solution, nodes) + with nodes = "cap" when the step cap is hit (caller must treat as + undecided, never as infeasible).""" + m = len(shapes) + if m == 0: + if U == 0 and RF == 0 and RG == 0 and RP == 0: + return ([], 0) + return (None, 0) + order = sorted(range(m), key=lambda i: -shapes[i][0]) + shp = [shapes[i] for i in order] + sol = [0] * m + nodes = [0] + + # suffix min/max of each coefficient for bound pruning + smin_f = [0] * (m + 1) + smax_f = [0] * (m + 1) + smin_g = [0] * (m + 1) + smax_g = [0] * (m + 1) + smin_p = [0] * (m + 1) + smax_p = [0] * (m + 1) + for i in range(m - 1, -1, -1): + f2, g2, p2 = shp[i] + smin_f[i] = min(f2, smin_f[i + 1]) + smax_f[i] = max(f2, smax_f[i + 1]) + smin_g[i] = min(g2, smin_g[i + 1]) + smax_g[i] = max(g2, smax_g[i + 1]) + smin_p[i] = min(p2, smin_p[i + 1]) + smax_p[i] = max(p2, smax_p[i + 1]) + + def rec(i, u_rem, rf, rg, rp): + nodes[0] += 1 + if nodes[0] > cap: + return "cap" + if i == m - 1: + f2, g2, p2 = shp[i] + if u_rem >= 0 and rf == u_rem * f2 and rg == u_rem * g2 and rp == u_rem * p2: + sol[i] = u_rem + return True + return False + f2, g2, p2 = shp[i] + hi = u_rem + if f2: + hi = min(hi, rf // f2) + if g2: + hi = min(hi, rg // g2) + if p2: + hi = min(hi, rp // p2) + for k in range(hi, -1, -1): + ru, rff, rgg, rpp = u_rem - k, rf - k * f2, rg - k * g2, rp - k * p2 + if ru < 0 or rff < 0 or rgg < 0 or rpp < 0: + continue + if rff > ru * smax_f[i + 1] or rff < ru * smin_f[i + 1]: + continue + if rgg > ru * smax_g[i + 1] or rgg < ru * smin_g[i + 1]: + continue + if rpp > ru * smax_p[i + 1] or rpp < ru * smin_p[i + 1]: + continue + sol[i] = k + got = rec(i + 1, ru, rff, rgg, rpp) + if got == "cap": + return "cap" + if got: + return True + sol[i] = 0 + return False + + got = rec(0, U, RF, RG, RP) + if got == "cap": + return (None, "cap") + if got: + out = [0] * m + for slot, orig in enumerate(order): + out[orig] = sol[slot] + return (out, nodes[0]) + return (None, nodes[0]) + + +def fourier_profile_feasibility(n, s, t, nonzero_both=False): + """Necessary-condition system for an (s,t) split at F2^n. `feasible` + False PROVES the odd half (hence the cover) impossible; `feasible` True + means only that this Fourier layer does not exclude the split. With + nonzero_both=True the system is restricted to per-characters with both + sides nonzero: infeasibility then PROVES every cover of this split must + have at least one vanishing character off {0, 1}.""" + eo = s * t - (1 << (n - 1)) + res = { + "n": n, + "split": (s, t), + "odd_excess": eo, + "nonzero_both": nonzero_both, + "even_half_max": even_half_max(n, s, t), + } + if eo < 0: + res["feasible"] = False + res["reason"] = "counting: fewer cross pairs than odd masks" + res["feasible_S"] = [] + return res + if eo > 24: + res["feasible"] = None + res["reason"] = "E_o out of the rho-square enumeration budget: not attempted" + res["feasible_S"] = [] + return res + shapes = shapes_fourier(n, s, t, nonzero_both=nonzero_both) + res["shapes"] = shapes + U = (1 << n) - 2 + RF = (1 << n) * s - 2 * s * s + RG = (1 << n) * t - 2 * t * t + res["parseval_remainders"] = (RF, RG) + feasible_S = [] + example = None + capped = False + for S in rho_square_values(eo): + RP = (1 << n) * S - 2 * eo * eo + sol, nodes = _solve_counts(shapes, U, RF, RG, RP) + if nodes == "cap": + capped = True + continue + if sol is not None: + feasible_S.append(S) + if example is None: + example = {"S": S, "counts": sol} + res["feasible_S"] = feasible_S + res["example"] = example + res["capped"] = capped + if capped: + res["feasible"] = True + res["reason"] = ( + "step cap hit for some S values: undecided for those (never a " + "proof of impossibility); S values listed are the feasible ones" + ) + elif feasible_S: + res["feasible"] = True + res["reason"] = ( + "profile system consistent for S in %s; no Fourier contradiction" + % sorted(feasible_S) + ) + else: + res["feasible"] = False + res["reason"] = ( + "profile system infeasible for every attainable rho square sum: " + "no integer character profile satisfies parity, |rho_hat| <= E_o, " + "the even-half bound and Parseval simultaneously" + ) + return res + + +def witness_constraints_ok(A, B, n=7): + """Direct validation of every profile-system constraint on an actual + covering pair (A, B). Used as the soundness control: a real cover can + never violate a constraint the system uses.""" + N = 1 << n + half = 1 << (n - 1) + eo = len(A) * len(B) - half + if eo < 0: + return False + s, t = len(A), len(B) + # odd half: r = 1_A * 1_B >= 1 on O + r = [0] * N + for a in A: + for b in B: + r[a ^ b] += 1 + odds = [x for x in range(N) if dot(N - 1, x)] + if any(r[x] < 1 for x in odds): + return False + rho = {x: r[x] - 1 for x in odds if r[x] > 1} + if sum(rho.values()) != eo: + return False + # even half: A_x + B_x >= 1 on E \ {0} + pairA = Counter() + pairB = Counter() + for i in range(len(A)): + for j in range(i): + pairA[A[i] ^ A[j]] += 1 + for i in range(len(B)): + for j in range(i): + pairB[B[i] ^ B[j]] += 1 + evs = [x for x in range(N) if not dot(N - 1, x) and x != 0] + if any(pairA[x] + pairB[x] < 1 for x in evs): + return False + P = s * (s - 1) // 2 + t * (t - 1) // 2 + bound = s + t + 2 * P - N + # characters off {0, 1} + for u in range(N): + if u in (0, N - 1): + continue + f_hat = sum(1 - 2 * dot(u, a) for a in A) + g_hat = sum(1 - 2 * dot(u, b) for b in B) + if f_hat % 2 != s % 2 or g_hat % 2 != t % 2: + return False + rho_hat = sum(c * (1 - 2 * dot(u, x)) for x, c in rho.items()) + if f_hat * g_hat != rho_hat: + return False + if abs(rho_hat) > eo or rho_hat % 2 != eo % 2: + return False + if f_hat * f_hat + g_hat * g_hat > bound: + return False + return True + + +def squeeze_numbers(n, s, t): + """The PR 2870-style Parseval deficit bookkeeping for one split, extended + to equal parity: per-side remainders vs the strongest uniform character + bound the parity class allows.""" + eo = s * t - (1 << (n - 1)) + N = 1 << n + res = {"n": n, "split": (s, t), "odd_excess": eo} + if eo < 0: + res.update( + bounded_side=None, + parseval_remainder=None, + max_allowed=None, + deficit=None, + contradiction=True, + reason="counting: fewer cross pairs than odd masks", + ) + return res + opposite = (s % 2) != (t % 2) + sides = [] + for name, card, par in (("A", s, s % 2), ("B", t, t % 2)): + remainder = N * card - 2 * card * card + if opposite and par == 0: + max_char = 2 * (eo // 2) # largest even <= E_o + elif (not opposite) and par == 1: + max_char = eo if eo % 2 == 1 else eo - 1 # largest odd <= E_o + else: + max_char = None # side can vanish: no uniform bound + allowed = None if max_char is None else (N - 2) * max_char * max_char + deficit = None if allowed is None else remainder - allowed + sides.append( + dict( + side=name, + cardinality=card, + max_char=max_char, + parseval_remainder=remainder, + max_allowed=allowed, + deficit=deficit, + ) + ) + res["opposite_parity"] = opposite + res["sides"] = sides + if opposite: + bounded = next(x for x in sides if x["max_char"] is not None) + res.update( + bounded_side=bounded["side"], + parseval_remainder=bounded["parseval_remainder"], + max_allowed=bounded["max_allowed"], + deficit=bounded["deficit"], + contradiction=bounded["deficit"] > 0, + reason=( + "PR 2870 squeeze applies (opposite parity): %d > %d" + % (bounded["parseval_remainder"], bounded["max_allowed"]) + if bounded["deficit"] > 0 + else "PR 2870 squeeze applies but reaches no contradiction" + ), + ) + else: + res.update( + bounded_side=None, + parseval_remainder=None, + max_allowed=None, + deficit=None, + contradiction=False, + reason=( + "equal character parities (s+t even): PR 2870's squeeze " + "hypothesis fails for this split; see sides[] for the " + "equal-parity remainders vs bounds" + ), + ) + return res + + +# ------------------------------------------------------ pairing sums + + +def pairing_sums(da, db): + """All sums sum_i a_i b_{pi(i)} over bijections pi of two equal-length + multisets, by contingency-table enumeration (the vendored O(m!) loop + cannot run at 18-point row sizes).""" + ca = Counter(da) + cb = Counter(db) + va = sorted(ca) + vb = sorted(cb) + acounts = [ca[v] for v in va] + bcounts = [cb[v] for v in vb] + out = set() + + def rec(i, caps, acc): + if i == len(va): + if all(c == 0 for c in caps): + out.add(acc) + return + need = acounts[i] + va_i = va[i] + + def dist(j, remaining, add): + if j == len(vb) - 1: + if remaining <= caps[j]: + caps[j] -= remaining + rec(i + 1, caps, acc + add + va_i * vb[j] * remaining) + caps[j] += remaining + return + for take in range(min(caps[j], remaining) + 1): + caps[j] -= take + dist(j + 1, remaining - take, add + va_i * vb[j] * take) + caps[j] += take + + dist(0, need, 0) + + rec(0, list(bcounts), 0) + return out + + +@lru_cache(maxsize=None) +def _pairing_sums_cached(da, db): + return frozenset(pairing_sums(da, db)) + + +@lru_cache(maxsize=None) +def draw_multisets(shared, budget, min_excess=0): + """Deduped draws: multisets of `shared` values >= 1 with total excess + sum(v-1) in [min_excess, budget]. (Embeddable in some multiplicity shape + of support `shared` + complement with total excess `budget`.)""" + out = set() + + def rec(lo, remaining, excess_left, acc): + if remaining == 0: + out.add(tuple(sorted(acc))) + return + for v in range(lo, excess_left + 2): + new_left = excess_left - (v - 1) + if new_left < 0: + break + rec(v, remaining - 1, new_left, acc + [v]) + + for used in range(min_excess, budget + 1): + rec(1, shared, used, []) + return sorted(out) + + +def attainable_c_values(n, s, t, e_ex, b_ex, targets=None, cap=200000): + """Exact attainable c = sum_x A_x B_x on the shared support positions + (targets given: only membership in targets is decided). Returns + (values_or_flags, status) with status in {"exact", "capped"}.""" + odd_masks_n = 1 << (n - 1) + even_nonzero = odd_masks_n - 1 + A = s * (s - 1) // 2 + B = t * (t - 1) // 2 + shared = A + B - e_ex - b_ex - even_nonzero + if shared < 0: + return (set(), "exact") + if shared == 0: + return ({0}, "exact") + comp_a = A - e_ex - shared + comp_b = B - b_ex - shared + das = draw_multisets(shared, e_ex, e_ex if comp_a == 0 else 0) + dbs = draw_multisets(shared, b_ex, b_ex if comp_b == 0 else 0) + found = set() + steps = 0 + for da in das: + for db in dbs: + steps += 1 + if steps > cap: + return (found, "capped") + vals = _pairing_sums_cached(da, db) + if targets is not None: + found |= vals & set(targets) + else: + found |= vals + return (found, "exact") + + +# ------------------------------------------------------------ rows + + +def max_attain(e_ex, b_ex, shared): + """Largest attainable c for one row (rearrangement on the extreme draws).""" + if shared <= 0: + return 0 + return (e_ex + 1) * (b_ex + 1) + shared - 1 + + +def sharp_rows_fast(n, s, t, min_e_ex=0, min_b_ex=0, cap=200000): + """PR 2773's sharp pair-representation rows for one split, with census + floors applied. Row status: "sharp" (exact attainability computed), + "interval" (kept conservatively: exact check capped), "dead" (dropped).""" + odd_masks_n = 1 << (n - 1) + even_nonzero = odd_masks_n - 1 + A = s * (s - 1) // 2 + B = t * (t - 1) // 2 + excess = s * t - odd_masks_n + need = (excess + 1) // 2 if excess > 0 else 0 + c_vals = c17.profile_c_values(n, s, t) + rows = [] + best = -1 + capped_rows = 0 + if excess < 0 or A + B < even_nonzero: + return dict(feasible=False, rows=[], best=best, need=need, c_vals=c_vals) + for e_ex in range(min_e_ex, A + 1): + for b_ex in range(min_b_ex, B + 1): + shared = A + B - e_ex - b_ex - even_nonzero + if shared < 0: + continue + attain, status = attainable_c_values(n, s, t, e_ex, b_ex, cap=cap) + if status == "capped": + capped_rows += 1 + best = max(best, max_attain(e_ex, b_ex, shared)) + hits = [c for c in c_vals if c <= max_attain(e_ex, b_ex, shared)] + for c in hits: + rows.append( + dict(e_ex=e_ex, b_ex=b_ex, shared=shared, c=c, status="interval") + ) + continue + if not attain: + continue + best = max(best, max(attain)) + for c in sorted(set(attain) & set(c_vals)): + rows.append( + dict(e_ex=e_ex, b_ex=b_ex, shared=shared, c=c, status="sharp") + ) + return dict( + feasible=bool(rows), + rows=rows, + best=best, + need=need, + c_vals=c_vals, + capped_rows=capped_rows, + ) + + +def surviving_rows_fast(n, s, t, min_e_ex=0, min_b_ex=0): + return sharp_rows_fast(n, s, t, min_e_ex=min_e_ex, min_b_ex=min_b_ex) + + +# ------------------------------------------------------------- search + + +def _score_pair(A, D, ev_index): + """Coverage score of a candidate (A, D) pair over the even group: + |A + D| + |(A+A) u (D+D)|, target 128 (two sets of 64).""" + cross = set(a ^ d for a in A for d in D) + selfs = set(a ^ a2 for i, a in enumerate(A) for a2 in A[i:]) + selfs |= set(d ^ d2 for i, d in enumerate(D) for d2 in D[i:]) + return len(cross) + len(selfs) + + +def search_split(s, t, restarts=20, seed=1, seconds=20.0, n=7): + """Bounded seeded local search for a covering pair (A, D) in the even + group E =~ F2^6 with |A| = s, |D| = t (reduction lemma). A found pair is + a falsifying instance; otherwise a scoped search failure.""" + rng = random.Random(seed) + ev = even_masks(n) + pool = ev[:] + best = (0, None) + t0 = time.time() + moves = 0 + for _ in range(restarts): + if time.time() - t0 > seconds: + break + A = rng.sample(pool, s) + D = rng.sample(pool, t) + sc = _score_pair(A, D, None) + improved = True + while improved and time.time() - t0 < seconds: + improved = False + for side, size in ((0, s), (1, t)): + cur = A if side == 0 else D + outside = [x for x in pool if x not in cur] + for i in range(size): + for v in outside: + moves += 1 + old = cur[i] + cur[i] = v + new = _score_pair(A, D, None) + if new > sc: + sc = new + improved = True + outside[outside.index(v)] = old + if sc == 128: + return dict( + found=True, + score=128, + A=sorted(A), + D=sorted(D), + restarts=_, + moves=moves, + seconds=round(time.time() - t0, 2), + ) + else: + cur[i] = old + if sc > best[0]: + best = (sc, (sorted(A), sorted(D))) + return dict( + found=False, + score=best[0], + best_pair=best[1], + restarts=restarts, + moves=moves, + seconds=round(time.time() - t0, 2), + ) + + +def search_direct(k=18, restarts=30, seed=1, seconds=20.0, n=7): + """Bounded seeded local search for a k-point cover of F2^n directly + (0 in S, translation WLOG).""" + rng = random.Random(seed) + pool = list(range(1 << n)) + best = (0, None) + t0 = time.time() + for _ in range(restarts): + if time.time() - t0 > seconds: + break + S = [0] + rng.sample(pool[1:], k - 1) + sc = coverage_mask(S).bit_count() + improved = True + while improved and time.time() - t0 < seconds: + improved = False + outside = [x for x in pool if x not in S] + for i in range(1, k): + for v in outside: + old = S[i] + S[i] = v + new = coverage_mask(S).bit_count() + if new > sc: + sc = new + improved = True + outside[outside.index(v)] = old + if sc == (1 << n): + return dict( + found=True, + score=sc, + S=sorted(S), + seconds=round(time.time() - t0, 2), + ) + else: + S[i] = old + if sc > best[0]: + best = (sc, sorted(S)) + return dict( + found=False, + score=best[0], + best_set=best[1], + restarts=restarts, + seconds=round(time.time() - t0, 2), + ) diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/parity_census.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/parity_census.py new file mode 100644 index 0000000000..cad49d7631 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/parity_census.py @@ -0,0 +1,169 @@ +"""KB3i probe: exact covering-split census for the reduced (A, B) problem, +to understand the even-split obstruction behind the m=5 ground truth +(F2^5 covers exist only in splits (2,8)(4,6)(6,4)(8,2)) and to test whether +it lifts to the both-odd splits (11,7)/(9,9) of the 18-point question. + +Reduced covering object (PR 2911 reduction lemma, cover18.py docstring): +for a group G = F2^m (2^m elements, XOR), a pair (A, B) of subsets COVERS iff + (i) A + B = G (cross sums reach every element) + (ii) (A+A) u (B+B) = G (self sums reach every element) +where + is XOR. The original P+P = F2^{m+1} cover with parity split (s, t) +corresponds to the reduced (A, B) cover of F2^m with |A| = s, |B| = t. + +Everything is exact integer arithmetic (int bitmasks, no floats). Brute +force is complete at m = 3 (2^8 x 2^8) and targeted-complete at m = 4 for +the splits that matter. A found cover is a WITNESS (the split is possible); +an exhaustive empty scan PROVES the split impossible for that m. +""" + +import sys +from itertools import combinations + +sys.stdout.reconfigure(encoding="utf-8") + + +def popcount(x): + return x.bit_count() + + +def mask_of(idxs): + m = 0 + for i in idxs: + m |= 1 << i + return m + + +def elems(mask): + out = [] + while mask: + lsb = mask & -mask + out.append(lsb.bit_length() - 1) + mask ^= lsb + return out + + +def trans(mask, a): + """{x ^ a : x in mask} as a bitmask.""" + out = 0 + x = mask + while x: + lsb = x & -x + out |= 1 << ((lsb.bit_length() - 1) ^ a) + x ^= lsb + return out + + +def sumset(mx, my): + out = 0 + x = mx + while x: + lsb = x & -x + out |= trans(my, lsb.bit_length() - 1) + x ^= lsb + return out + + +def selfsum(mx): + return sumset(mx, mx) + + +def covers_pair(amask, bmask, gsize): + """Reduced covering test: A+B = G and (A+A) u (B+B) = G.""" + allg = (1 << gsize) - 1 + cross = sumset(amask, bmask) + if cross != allg: + return False, "cross" + selfs = selfsum(amask) | selfsum(bmask) + if selfs != allg: + return False, "self" + return True, "cover" + + +def census_m3(): + """Complete census of reduced covering pairs (A, B) in F2^3 (8 elements), + by split (|A|, |B|). Every subset pair is tested.""" + gsize = 8 + subsets = list(range(1 << gsize)) + # For each split (a, b) count covering pairs and record a witness. + result = {} + for a in range(gsize + 1): + for b in range(gsize + 1): + count = 0 + witness = None + Alist = [s for s in subsets if popcount(s) == a] + Blist = [s for s in subsets if popcount(s) == b] + for am in Alist: + for bm in Blist: + ok, _ = covers_pair(am, bm, gsize) + if ok: + count += 1 + if witness is None: + witness = (elems(am), elems(bm)) + result[(a, b)] = (count, witness) + return result + + +def census_m4_split(a, b): + """Complete census of reduced covering pairs (A, B) in F2^4 (16 elements) + for one split (a, b). Returns (count, witness). Complete: enumerates + every A of size a and every B of size b.""" + gsize = 16 + Alist = [mask_of(c) for c in combinations(range(gsize), a)] + Blist = [mask_of(c) for c in combinations(range(gsize), b)] + count = 0 + witness = None + for am in Alist: + for bm in Blist: + ok, _ = covers_pair(am, bm, gsize) + if ok: + count += 1 + if witness is None: + witness = (elems(am), elems(bm)) + return count, witness + + +def summarize_m3(): + res = census_m3() + print("=== Reduced covering census, F2^3 (G has 8 elements), COMPLETE ===") + print("split covers witness") + for a in range(9): + for b in range(9): + cnt, wit = res[(a, b)] + if cnt > 0: + print("(%d,%d) %d A=%s B=%s" % (a, b, cnt, wit[0], wit[1])) + print("--- empty (no cover) splits ---") + empties = [(a, b) for a in range(9) for b in range(9) if res[(a, b)][0] == 0] + # group by parity + both_odd_empty = [s for s in empties if s[0] % 2 == 1 and s[1] % 2 == 1] + both_even_empty = [s for s in empties if s[0] % 2 == 0 and s[1] % 2 == 0] + mixed_empty = [s for s in empties if s[0] % 2 != s[1] % 2] + print("both-odd empty:", both_odd_empty) + print("both-even empty:", both_even_empty) + print("mixed empty:", mixed_empty) + nonempty = [(a, b) for a in range(9) for b in range(9) if res[(a, b)][0] > 0] + print("nonempty splits:", nonempty) + both_odd_nonempty = [s for s in nonempty if s[0] % 2 == 1 and s[1] % 2 == 1] + print("both-odd NONEMPTY (any cover):", both_odd_nonempty) + + +def summarize_m4(): + print("=== Reduced covering census, F2^4 (G has 16 elements), targeted ===") + # splits summing to 10 (the F2^5 k=10 analogue) and to 18's analogue. + targets = [ + (1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (6, 4), (7, 3), (8, 2), (9, 1), + (2, 2), (3, 3), (4, 4), # small both parity controls + ] + print("split covers witness") + for (a, b) in targets: + cnt, wit = census_m4_split(a, b) + print("(%d,%d) %d %s" % (a, b, cnt, ("A=%s B=%s" % wit) if wit else "-")) + + +if __name__ == "__main__": + mode = sys.argv[1] if len(sys.argv) > 1 else "m3" + if mode == "m3": + summarize_m3() + elif mode == "m4": + summarize_m4() + else: + raise SystemExit("usage: parity_census.py m3|m4") diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/self_obstruction.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/self_obstruction.py new file mode 100644 index 0000000000..47b091e69e --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/self_obstruction.py @@ -0,0 +1,116 @@ +"""Probe the (5,5) self-obstruction at m=4: every cross-covering (A,B) pair +(|A|=|B|=5, A+B=F2^4) fails the self condition (A+A) u (B+B) = F2^4. This +records WHY (the self-union deficit and the selfsum sizes / ranks), to see +whether the mechanism generalizes to the (9,9) split at m=6. Exact integer +arithmetic (int masks). +""" + +import sys +from itertools import combinations + +sys.stdout.reconfigure(encoding="utf-8") + + +def mask_of(idxs): + m = 0 + for i in idxs: + m |= 1 << i + return m + + +def elems(mask): + out = [] + while mask: + lsb = mask & -mask + out.append(lsb.bit_length() - 1) + mask ^= lsb + return out + + +def build(m): + gsize = 1 << m + allg = (1 << gsize) - 1 + xors = [[1 << (i ^ j) for j in range(gsize)] for i in range(gsize)] + + def trans(mask, a): + out = 0 + x = mask + while x: + lsb = x & -x + out |= xors[lsb.bit_length() - 1][a] + x ^= lsb + return out + + def sumset(mx, my): + out = 0 + x = mx + while x: + lsb = x & -x + out |= trans(my, lsb.bit_length() - 1) + x ^= lsb + return out + + return gsize, allg, sumset + + +def rank_of(mask): + """Linear rank over F2 of the elements of mask (as vectors).""" + els = elems(mask) + basis = [] + for e in els: + v = e + for b in basis: + v = min(v, v ^ b) + if v: + basis.append(v) + basis.sort(reverse=True) + return len(basis) + + +def probe(m, a, b): + gsize, allg, sumset = build(m) + Alist = [mask_of(c) for c in combinations(range(gsize), a)] + Blist = [mask_of(c) for c in combinations(range(gsize), b)] + # For cross-covering pairs, record self-union size and per-side selfsum size. + selfcover = 0 + crosscover = 0 + max_selfunion = -1 + selfunion_hist = {} + selfsumA_hist = {} + selfsumB_hist = {} + example = None + for am in Alist: + ssa = sumset(am, am) + for bm in Blist: + if sumset(am, bm) != allg: + continue + crosscover += 1 + ssb = sumset(bm, bm) + su = ssa | ssb + su_sz = su.bit_count() + selfunion_hist[su_sz] = selfunion_hist.get(su_sz, 0) + 1 + selfsumA_hist[ssa.bit_count()] = selfsumA_hist.get(ssa.bit_count(), 0) + 1 + selfsumB_hist[ssb.bit_count()] = selfsumB_hist.get(ssb.bit_count(), 0) + 1 + if su == allg: + selfcover += 1 + if su_sz > max_selfunion: + max_selfunion = su_sz + example = (elems(am), elems(bm), ssa.bit_count(), ssb.bit_count(), + elems(allg ^ su)) + print("F2^%d (%d,%d): cross_covering=%d, of those self_covering=%d" + % (m, a, b, crosscover, selfcover)) + print(" max |(A+A) u (B+B)| over cross-covering pairs = %d (of %d)" + % (max_selfunion, gsize)) + print(" self-union size histogram:", dict(sorted(selfunion_hist.items()))) + print(" |A+A| histogram:", dict(sorted(selfsumA_hist.items()))) + print(" |B+B| histogram:", dict(sorted(selfsumB_hist.items()))) + if example: + print(" max example: A=%s B=%s |A+A|=%d |B+B|=%d missed=%s" + % (example[0], example[1], example[2], example[3], example[4])) + + +if __name__ == "__main__": + m = int(sys.argv[1]) + a = int(sys.argv[2]) + b = int(sys.argv[3]) + probe(m, a, b) diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/selfsum_classify_kb3j.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/selfsum_classify_kb3j.py new file mode 100644 index 0000000000..bd6dd3f6f4 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/selfsum_classify_kb3j.py @@ -0,0 +1,180 @@ +"""KB3j route (c): even-half (self-sum) structure of reduced covering pairs. + +PR 3034's named live direction for the both-odd splits (11,7)/(9,9): classify +the m=3 both-odd covers (small ground truth: (5,5)=3136, (7,7)=64) by their +even-half self-sum structure and lift only what survives scaling (the +scale-dependent m=4 self-sum-size bound is NOT lifted - it fails at m=3). + +For a reduced covering pair (A, B) of F2^m (A+B = F2^m and (A+A) u (B+B) = +F2^m) define the even-half multiplicity profile + + mu(p) = [p in A+A] + [p in B+B] in {0,1,2}, + mu2 = |{p : mu(p) = 2}| = |(A+A) n (B+B)|, + mu1 = 2^m - mu2. + +Every cover has mu >= 1 pointwise. This module computes the exact profile +distributions (|A+A|, |B+B|, mu2, span rank, doubling) over COMPLETE +enumerations at two scales: + + m=3 (F2^3, 8 points): every both-odd cover (splits (3,5),(3,7),(5,3),(5,5), + (5,7),(7,3),(7,5),(7,7)) and every cover at all splits. + m=4 (F2^4, 16 points): every both-even cover at the sum-10 splits (2,8) + and (4,6) (the m=5 ground-truth covering splits). + +and tests named lift candidates against both scales. Exact int arithmetic. +""" + +import json +import sys +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE / "vendor")) + +import parity_census as pc # noqa: E402 (vendored byte-exact PR 3034 engine) + + +def span_rank(mask, gsize): + """GF(2) rank of the elements of mask (as gsize-bit row vectors).""" + pivots = {} + for r in pc.elems(mask): + x = r + while x: + p = x.bit_length() - 1 + if p in pivots: + x ^= pivots[p] + else: + pivots[p] = x + break + return len(pivots) + + +def profile(am, bm, gsize): + allg = (1 << gsize) - 1 + sa = pc.selfsum(am) + sb = pc.selfsum(bm) + union = sa | sb + inter = sa & sb + return dict( + a=pc.popcount(am), + b=pc.popcount(bm), + sa=pc.popcount(sa), + sb=pc.popcount(sb), + mu2=pc.popcount(inter), + mu1=pc.popcount(union) - pc.popcount(inter), + self_union=pc.popcount(union), + deficit=allg.bit_count() - pc.popcount(union), + rank_a=span_rank(am, gsize), + rank_b=span_rank(bm, gsize), + st=pc.popcount(am) * pc.popcount(bm), + ) + + +def census_m3_profiles(): + """Complete: every covering pair in F2^3 with its profile.""" + gsize = 8 + subs = list(range(1 << gsize)) + by_split = {} + for am in subs: + for bm in subs: + ok, _ = pc.covers_pair(am, bm, gsize) + if not ok: + continue + key = (pc.popcount(am), pc.popcount(bm)) + p = profile(am, bm, gsize) + by_split.setdefault(key, []).append(p) + return by_split + + +def census_m4_profiles(a, b): + """Complete: every covering pair in F2^4 at split (a, b) with its profile.""" + gsize = 16 + out = [] + for ac in _comb(16, a): + am = pc.mask_of(ac) + for bc in _comb(16, b): + bm = pc.mask_of(bc) + ok, _ = pc.covers_pair(am, bm, gsize) + if ok: + out.append(profile(am, bm, gsize)) + return out + + +def _comb(n, k): + from itertools import combinations + + return combinations(range(n), k) + + +def dist(profiles, key): + d = {} + for p in profiles: + d[p[key]] = d.get(p[key], 0) + 1 + return dict(sorted(d.items())) + + +def profile_table(profiles): + """Distribution of (sa, sb, mu2) with counts.""" + d = {} + for p in profiles: + k = (p["sa"], p["sb"], p["mu2"]) + d[k] = d.get(k, 0) + 1 + return {"|A+A|,|B+B|,mu2 -> count": {"%d,%d,%d" % k: v for k, v in sorted(d.items())}} + + +def main(): + sys.stdout.reconfigure(encoding="utf-8") + out = {} + + # ---- m=3 complete both-odd classification ------------------------- + m3 = census_m3_profiles() + both_odd = {k: v for k, v in m3.items() if k[0] % 2 == 1 and k[1] % 2 == 1} + out["m3_covers_total"] = sum(len(v) for v in m3.values()) + out["m3_both_odd_splits"] = {str(k): len(v) for k, v in sorted(both_odd.items())} + out["m3_both_odd_profiles"] = { + str(k): profile_table(v) for k, v in sorted(both_odd.items()) + } + out["m3_both_odd_sa_range"] = { + str(k): {"sa_min": min(p["sa"] for p in v), "sa_max": max(p["sa"] for p in v), + "sb_min": min(p["sb"] for p in v), "sb_max": max(p["sb"] for p in v), + "mu2_min": min(p["mu2"] for p in v), "mu2_max": max(p["mu2"] for p in v), + "self_union_min": min(p["self_union"] for p in v), + "self_union_max": max(p["self_union"] for p in v), + "rank_a_max": max(p["rank_a"] for p in v), + "rank_b_max": max(p["rank_b"] for p in v)} + for k, v in sorted(both_odd.items()) + } + # the two named ground-truth splits in full detail + for k in [(5, 5), (7, 7)]: + v = both_odd.get(k, []) + out["m3_split_%d_%d" % k] = { + "covers": len(v), + "sa_dist": dist(v, "sa"), + "sb_dist": dist(v, "sb"), + "mu2_dist": dist(v, "mu2"), + "self_union_dist": dist(v, "self_union"), + "rank_a_dist": dist(v, "rank_a"), + "rank_b_dist": dist(v, "rank_b"), + } + + # ---- m=4 both-even comparison profiles --------------------------- + for (a, b) in [(2, 8), (4, 6)]: + v = census_m4_profiles(a, b) + out["m4_split_%d_%d" % (a, b)] = { + "covers": len(v), + "sa_dist": dist(v, "sa"), + "sb_dist": dist(v, "sb"), + "mu2_dist": dist(v, "mu2"), + "self_union_dist": dist(v, "self_union"), + } + + (HERE / "SELFSUM-PROFILES.json").write_text( + json.dumps(out, indent=2, sort_keys=True) + "\n", encoding="utf-8" + ) + for key in sorted(out): + print(key, json.dumps(out[key], sort_keys=True)[:300], flush=True) + print("PASS_SELFSUM_CLASSIFY", flush=True) + + +if __name__ == "__main__": + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/split_census.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/split_census.py new file mode 100644 index 0000000000..8e62c86404 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/split_census.py @@ -0,0 +1,99 @@ +"""Fast reduced-covering census for one split (a, b) in F2^m, with a +precomputed XOR-translate table. Reports covering count, a first witness, +and a breakdown of WHICH condition fails (cross-only, self-only, both) so the +obstruction to a split is localized. Exact integer arithmetic (int masks). + +Reduced covering (PR 2911 lemma): (A,B) covers G=F2^m iff + cross: A+B = G + self: (A+A) u (B+B) = G +""" + +import sys +from itertools import combinations + +sys.stdout.reconfigure(encoding="utf-8") + + +def mask_of(idxs): + m = 0 + for i in idxs: + m |= 1 << i + return m + + +def elems(mask): + out = [] + while mask: + lsb = mask & -mask + out.append(lsb.bit_length() - 1) + mask ^= lsb + return out + + +def build(m): + gsize = 1 << m + allg = (1 << gsize) - 1 + # XOR table: xors[a][b] = 1 << (a ^ b) + xors = [[1 << (i ^ j) for j in range(gsize)] for i in range(gsize)] + + def trans(mask, a): + out = 0 + x = mask + while x: + lsb = x & -x + out |= xors[lsb.bit_length() - 1][a] + x ^= lsb + return out + + def sumset(mx, my): + out = 0 + x = mx + while x: + lsb = x & -x + out |= trans(my, lsb.bit_length() - 1) + x ^= lsb + return out + + return gsize, allg, sumset + + +def census_split(m, a, b, stop_on_witness=False): + gsize, allg, sumset = build(m) + Alist = [mask_of(c) for c in combinations(range(gsize), a)] + Blist = [mask_of(c) for c in combinations(range(gsize), b)] + count = 0 + witness = None + cross_only = 0 # cross covers but self fails + self_only = 0 # self covers but cross fails + both_fail = 0 + for am in Alist: + # precompute selfsum(A) once per A + ssa = sumset(am, am) + for bm in Blist: + cross = sumset(am, bm) == allg + selfs = (ssa | sumset(bm, bm)) == allg + if cross and selfs: + count += 1 + if witness is None: + witness = (elems(am), elems(bm)) + if stop_on_witness: + return count, witness, (cross_only, self_only, both_fail) + elif cross and not selfs: + cross_only += 1 + elif selfs and not cross: + self_only += 1 + else: + both_fail += 1 + return count, witness, (cross_only, self_only, both_fail) + + +if __name__ == "__main__": + m = int(sys.argv[1]) + a = int(sys.argv[2]) + b = int(sys.argv[3]) + stop = len(sys.argv) > 4 and sys.argv[4] == "stop" + cnt, wit, brk = census_split(m, a, b, stop_on_witness=stop) + print("F2^%d split (%d,%d): covers=%d cross_only=%d self_only=%d both_fail=%d" + % (m, a, b, cnt, brk[0], brk[1], brk[2])) + if wit: + print(" witness A=%s B=%s" % (wit[0], wit[1])) diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/tight.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/tight.py new file mode 100644 index 0000000000..2e0e151ccf --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/tight.py @@ -0,0 +1,760 @@ +"""KB3g engine: tight-class resolution for the 18-point cover question for +F2^7 (set level; no words). Exact Python integer arithmetic only. + +Object (unchanged from PR 2911/2933): S = A u B covers F2^7 iff P + P = F2^7. +With D = p + B inside E = F2^6 (PR 2911 reduction, PROVEN there) the pair +(A, D) covers iff (i) A + D = E and (ii) (A+A) u (D+D) = E. + +This module decides the two PR 2933 TIGHT classes of the (10,8) split and +the full-sumset class (6,0) of (12,6) by exact enumeration of the L7-forced +Sidon equality configurations. All arithmetic is integers; masks are Python +ints. + +Halves. Fix the character psi = bit 0 (WLOG under GL(6,2)). H = ker(psi) +and the coset H' are both identified with F2^5 = {0..31}; every cross sum is +the XOR of the two F2^5 coordinates (the coset offset cancels in pairs, and +H'-valued sums are read in H' coordinates). A = A0 u A1 with A0 in H, A1 in +H'; D = D0 u D1 likewise. Coverage is equivalent to the four L3 lines +(PR 2933, PROVEN): + + (i) (A0+D0) u (A1+D1) = H + (ii) (A0+D1) u (A1+D0) = H' + (iii) (A0+A0) u (A1+A1) u (D0+D0) u (D1+D1) = H + (iv) (A0+A1) u (D0+D1) = H' + +Half-translations (h on (A0,D0), h' on (A1,D1)) and a common GL(5,2) map M +preserve all four lines (each H'-valued sumset translates by h + h', which +preserves its being all of H'). Hence WLOG 0 in A0, 0 in A1. + +L7 (PR 2933, PROVEN; general pigeonhole valid at m = 6): at F1 equality +a0*a1 + d0*d1 = 32 with (iv) holding, |A0+A1| = a0*a1, |D0+D1| = d0*d1 (both +Sidon: all cross sums distinct) and the two cross sumsets are disjoint with +union H'. + +Class (10,8) A-vanish (7,1): A0, A1 5-sets with |A0+A1| = 25; D0 a 7-set, +D1 a singleton {d1}. (iv) forces D0 + d1 = T := H' \\ (A0+A1) (7 points). +Substituting D0 = T + d1 into (i)-(iii) and translating by d1 shows coverage +is INDEPENDENT of d1: + (I) (A0+T) u A1 = F2^5 + (II) (A1+T) u A0 = F2^5 + (III) (A0+A0) u (A1+A1) u (T+T) = F2^5 +and (iv) holds by construction. Each covering (A0, A1) yields 32 covering +configurations (one per d1) in the normalized chart. + +Class (10,8) D-vanish (8,2): D0, D1 4-sets with |D0+D1| = 16; A splits +(8,2): A0 an 8-set, A1 = {w, w+delta}, delta != 0. |A0+A1| = 16 iff +A0 u (A0+delta) = 16 points iff A0 n (A0+delta) = 0. Normalize instead on +the D side: 0 in D0, 0 in D1 (the class forces both nonempty), and WLOG +delta = 1 under GL(5,2). With T = D0+D1 (16 points) and C = H' \\ T, +(iv) forces A0 + w to choose one element of each pair {x, x+1} inside C, so +C must be 1-invariant; the choice is one of at most 2^8 sets A0t = A0 + w. +Coverage is then independent of w: + (I') (A0t+D0) u (D1+{0,1}) = F2^5 + (II') (A0t+D1) u (D0+{0,1}) = F2^5 + (III') (A0t+A0t) u {0,1} u (D0+D0) u (D1+D1) = F2^5 + +Class (12,6) A-vanish (6,0): A0, A1 6-sets with A0+A1 = H' (36 pairs, excess +exactly 4), D = D0 a 6-set in H, D1 empty. Lines reduce to + (I'') A0+D = F2^5, (II'') A1+D = F2^5, + (III'') (A0+A0) u (A1+A1) u (D+D) = F2^5. +Normalize 0 in A0, 0 in A1. +""" + +import json +import sys +import time +from itertools import combinations +from pathlib import Path + +ALL = (1 << 32) - 1 +N5 = 32 + + +# ------------------------------------------------------- mask primitives + + +def elems(mask): + out = [] + while mask: + lsb = mask & -mask + out.append(lsb.bit_length() - 1) + mask ^= lsb + return out + + +def mask_of(pts): + m = 0 + for p in pts: + m |= 1 << p + return m + + +# Precomputed per-bit XOR-translation block masks (5 bits, F2^5). +_BIT_LO = [] +_BIT_HI = [] +for _i in range(5): + _b = 1 << _i + _lo = 0 + for _p in range(N5): + if not (_p & _b): + _lo |= 1 << _p + _BIT_LO.append(_lo) + _BIT_HI.append(ALL ^ _lo) + + +def trans(mask, a): + """{x ^ a : x in mask} as a bitmask.""" + for i in range(5): + if (a >> i) & 1: + b = 1 << i + mask = ((mask & _BIT_LO[i]) << b) | ((mask & _BIT_HI[i]) >> b) + return mask + + +def sumset_mask(mx, my): + """{x ^ y : x in mx, y in my}.""" + out = 0 + x = mx + while x: + lsb = x & -x + out |= trans(my, lsb.bit_length() - 1) + x ^= lsb + return out + + +def selfsum_mask(mx): + """{x ^ y : x, y in mx} (includes 0).""" + return sumset_mask(mx, mx) + + +def delta_mask(mx): + """{x ^ y : x != y in mx} = selfsum minus {0}.""" + return selfsum_mask(mx) & ALL & ~1 + + +def sidon_cross(mx, my, px, py): + """|X+Y| = |X|*|Y| with sizes px, py (all cross sums distinct).""" + return sumset_mask(mx, my).bit_count() == px * py + + +# ------------------------------------------- class (7,1) at (10,8) + + +def class71_pairs(): + """All normalized Sidon 5-pairs: 0 in A0, 0 in A1, |A0+A1| = 25. + Backtracks A0 = {0, a1, a2, a3, a4} against the forbidden difference + set of A1 (condition Delta(A0) n Delta(A1) = 0).""" + out = [] + rest = list(range(1, N5)) + + def extend(a1m): + forb = delta_mask(a1m) + cand = [v for v in rest if not (forb >> v) & 1] + chosen = [0, 0, 0, 0, 0] + + def rec(depth, start): + if depth == 5: + out.append((mask_of(chosen), a1m)) + return + for i in range(start, len(cand)): + v = cand[i] + if v <= chosen[depth - 1]: + continue + ok = True + for j in range(1, depth): + if (forb >> (v ^ chosen[j])) & 1: + ok = False + break + if ok: + chosen[depth] = v + rec(depth + 1, i + 1) + + rec(1, 0) + + for bs in combinations(rest, 4): + a1m = 1 | mask_of(bs) + extend(a1m) + return out + + +def class71_check(a0m, a1m): + """The three translated coverage lines (I),(II),(III) for one pair. + Returns (ok, which_lines_fail).""" + sums = sumset_mask(a0m, a1m) + if sums.bit_count() != 25: + return False, ("sidon",) + tm = ALL ^ sums + fails = [] + if (sumset_mask(a0m, tm) | a1m) != ALL: + fails.append("I") + if (sumset_mask(a1m, tm) | a0m) != ALL: + fails.append("II") + if (selfsum_mask(a0m) | selfsum_mask(a1m) | selfsum_mask(tm)) != ALL: + fails.append("III") + return (not fails), tuple(fails) + + +def class71_run(progress=None, budget=None): + """Full decision run for class (7,1). Counts every normalized equality + configuration (A0, A1, d1) and every covering one; records witnesses.""" + t0 = time.time() + pairs = class71_pairs() + total = len(pairs) + checked = 0 + covering = 0 + fail_hist = {} + witnesses = [] + for (a0m, a1m) in pairs: + ok, fails = class71_check(a0m, a1m) + checked += 1 + if ok: + covering += 1 + if len(witnesses) < 5: + witnesses.append((elems(a0m), elems(a1m))) + else: + fail_hist[fails] = fail_hist.get(fails, 0) + 1 + if budget is not None and checked % 5000 == 0 and time.time() - t0 > budget: + break + return dict( + normalized_pairs=total, + checked=checked, + covering_pairs=covering, + equality_configs_normalized=total * 32, + covering_configs_normalized=covering * 32, + fail_hist={str(k): v for k, v in sorted(fail_hist.items())}, + witnesses=witnesses, + seconds=round(time.time() - t0, 2), + ) + + +# ------------------------------------------- class (8,2) at (10,8) + + +def sidon44_pairs_normalized(): + """All Sidon 4-pairs: 0 in D0, 0 in D1, |D0+D1| = 16.""" + out = [] + rest = list(range(1, N5)) + for c0 in combinations(rest, 3): + d0m = 1 | mask_of(c0) + for c1 in combinations(rest, 3): + d1m = 1 | mask_of(c1) + if sumset_mask(d0m, d1m).bit_count() == 16: + out.append((d0m, d1m)) + return out + + +def class82_choices(tm): + """All A0t = choice sets: one element of each {x, x+1} pair inside + C = H' \\ T, where T = D0+D1 must have 1-invariant complement. + Returns (choices, reason): choices empty with reason if impossible.""" + cm = ALL ^ tm + if trans(cm, 1) != cm: + return [], "C_not_1_invariant" + pairs = [] + seen = 0 + x = cm + choices = [0] + while x: + lsb = x & -x + p = lsb.bit_length() - 1 + if (seen >> p) & 1: + x ^= lsb + continue + q = p ^ 1 + if not (cm >> q) & 1: + return [], "C_pair_incomplete" + seen |= (1 << p) | (1 << q) + choices = [c | (1 << p) for c in choices] + [c | (1 << q) for c in choices] + x ^= lsb + return choices, "ok" + + +def class82_check(a0tm, d0m, d1m): + """The three coverage lines (I'),(II'),(III') for one configuration. + Returns (ok, which_lines_fail).""" + fails = [] + if (sumset_mask(a0tm, d0m) | sumset_mask(d1m, 3)) != ALL: + fails.append("I") + if (sumset_mask(a0tm, d1m) | sumset_mask(d0m, 3)) != ALL: + fails.append("II") + if (selfsum_mask(a0tm) | 3 | selfsum_mask(d0m) | selfsum_mask(d1m)) != ALL: + fails.append("III") + return (not fails), tuple(fails) + + +def class82_run(budget=None, shard=0, shards=1): + """Full decision run for class (8,2): every normalized Sidon D-pair, every + admissible A0t choice. Counts equality configurations and coverings. + Per-pair D-side masks are precomputed; (I') and (II') are decided by + OR-chains over the 8 chosen candidate translates, (III') only for + survivors. Deterministic sharding: pairs[shard::shards].""" + import itertools as _it + + t0 = time.time() + pairs = sidon44_pairs_normalized() + n_pairs_total = len(pairs) + pairs = pairs[shard::shards] + n_pairs = len(pairs) + n_choice_sets = 0 + covering = 0 + checked = 0 + fail_hist = {} + witnesses = [] + noninv = 0 + budget_hit = False + for (d0m, d1m) in pairs: + tm = sumset_mask(d0m, d1m) + choices, reason = class82_choices(tm) + if not choices: + noninv += 1 + continue + n_choice_sets += len(choices) + md1_01 = sumset_mask(d1m, 3) + md0_01 = sumset_mask(d0m, 3) + mdd = selfsum_mask(d0m) | selfsum_mask(d1m) + # per {x, x+1} pair inside C: (bit_p, bit_q, d0p, d0q, d1p, d1q) + cand = [] + seen = 0 + x = ALL ^ tm + while x: + lsb = x & -x + p = lsb.bit_length() - 1 + if (seen >> p) & 1: + x ^= lsb + continue + q = p ^ 1 + seen |= (1 << p) | (1 << q) + cand.append( + ( + 1 << p, + 1 << q, + trans(d0m, p), + trans(d0m, q), + trans(d1m, p), + trans(d1m, q), + ) + ) + x ^= lsb + for pick in _it.product((0, 1), repeat=len(cand)): + a0tm = 0 + s0 = 0 + s1 = 0 + for i, which in enumerate(pick): + c = cand[i] + if which == 0: + a0tm |= c[0] + s0 |= c[2] + s1 |= c[4] + else: + a0tm |= c[1] + s0 |= c[3] + s1 |= c[5] + checked += 1 + fails = [] + if (s0 | md1_01) != ALL: + fails.append("I") + if (s1 | md0_01) != ALL: + fails.append("II") + if (selfsum_mask(a0tm) | 3 | mdd) != ALL: + fails.append("III") + if fails: + fail_hist[tuple(fails)] = fail_hist.get(tuple(fails), 0) + 1 + else: + covering += 1 + if len(witnesses) < 5: + witnesses.append((elems(a0tm), elems(d0m), elems(d1m))) + if budget is not None and time.time() - t0 > budget: + budget_hit = True + break + return dict( + shard=shard, + shards=shards, + normalized_sidon_pairs_total=n_pairs_total, + normalized_sidon_pairs=n_pairs, + non_1_invariant_pairs=noninv, + admissible_choice_sets=n_choice_sets, + checked=checked, + covering_configs=covering, + fail_hist={str(k): v for k, v in sorted(fail_hist.items())}, + witnesses=witnesses, + budget_hit=budget_hit, + seconds=round(time.time() - t0, 2), + ) + + +# ------------------------------------------- class (6,0) at (12,6) + + +def transversals6(dm): + """All 6-sets X with X + D = F2^5 (X hits every translate x + D), for + D = dm. Complete branch-on-uncovered-requirement search with a bitmask + of covered requirements; results deduplicated as sets.""" + cov_by = [0] * N5 + for v in range(N5): + m = 0 + for x in range(N5): + if (dm >> (x ^ v)) & 1: + m |= 1 << x + cov_by[v] = m + out = set() + cur = [] + + def rec(uncov, vlo): + if len(cur) == 6: + if not uncov: + out.add(frozenset(cur)) + return + if uncov.bit_count() > 6 * (6 - len(cur)): + return + if not uncov: + for v in range(vlo, N5): + if v in cur: + continue + cur.append(v) + rec(uncov, v + 1) + cur.pop() + return + i = (uncov & -uncov).bit_length() - 1 + target = trans(dm, i) + for v in elems(target): + if v in cur: + continue + cur.append(v) + rec(uncov & ~cov_by[v], 0) + cur.pop() + + rec((1 << N5) - 1, 0) + return out + + +def class60_check(a0m, a1m, dm): + """Lines (I''),(II''),(III'') for one (A0, A1, D) triple.""" + fails = [] + if (sumset_mask(a0m, dm)) != ALL: + fails.append("I") + if (sumset_mask(a1m, dm)) != ALL: + fails.append("II") + if (selfsum_mask(a0m) | selfsum_mask(a1m) | selfsum_mask(dm)) != ALL: + fails.append("III") + return (not fails), tuple(fails) + + +def class60_run(budget=None, shard=0, shards=1): + """Decision run for class (6,0) at (12,6): complete D-side transversal + walk. Normalize 0 in D (H-half translation) and 0 in A1 (H'-half + translation; the class forces D1 = empty). For each normalized 6-set D, + F(D) = {6-sets X : X + D = F2^5} by complete search; then test every + (A0, A1) with A0 in F(D), A1 in F(D) containing 0 against A0+A1 = F2^5 + and line (III''). If F(D) is empty for every D, no (6,0) cover exists + (lines (I'')/(II'') are unsatisfiable). Deterministic sharding over the + C(31,5) normalized D by index.""" + t0 = time.time() + total_d = 169911 + tested_triples = 0 + covering = 0 + witnesses = [] + d_with_transversals = 0 + transversal_total = 0 + d_done = 0 + budget_hit = False + for idx, dc in enumerate(combinations(range(1, N5), 5)): + if idx % shards != shard: + continue + d_done += 1 + dm = 1 | mask_of(dc) + F = transversals6(dm) + if F: + d_with_transversals += 1 + transversal_total += len(F) + f_list = sorted(tuple(sorted(s)) for s in F) + for a1t in f_list: + if 0 not in a1t: + continue + a1m = mask_of(a1t) + for a0t in f_list: + a0m = mask_of(a0t) + if sumset_mask(a0m, a1m) != ALL: + continue + dm_self = selfsum_mask(dm) + if (selfsum_mask(a0m) | selfsum_mask(a1m) | dm_self) != ALL: + continue + tested_triples += 1 + covering += 1 + if len(witnesses) < 5: + witnesses.append((a0t, a1t, tuple(sorted(dc)) + (0,))) + if budget is not None and d_done % 64 == 0 and time.time() - t0 > budget: + budget_hit = True + break + return dict( + shard=shard, + shards=shards, + normalized_d_total=total_d, + d_checked=d_done, + d_with_transversals=d_with_transversals, + transversals_total=transversal_total, + tested_triples=tested_triples, + covering_triples=covering, + witnesses=witnesses, + budget_hit=budget_hit, + seconds=round(time.time() - t0, 2), + ) + + +# ------------------------------------------------- Fourier identity (7,1) + + +def fourier_71_identity(): + """Exact-integer contradiction for the (10,8) A-vanish tight class (7,1). + + L7 forces |A0+A1| = 25 with |A0| = |A1| = 5 (both odd) inside F2^5. + With f = 1_A0, g = 1_A1 and h = 1_S on S = A0+A1 (|S| = 25, all pair + sums distinct), Fourier over F2^5 gives h_hat(v) = f_hat(v) g_hat(v) for + every v (r = 1_S exactly). Parseval: + sum_{v != 0} f_hat^2 = 32*5 - 25 = 135 = sum_{v != 0} g_hat^2, + sum_{v != 0} h_hat^2 = 32*25 - 625 = 175. + Parity: |A0| odd makes every f_hat(v) odd, so f_hat^2 >= 1 pointwise; + hence (f_hat^2 - 1)(g_hat^2 - 1) >= 0 gives f_hat^2 g_hat^2 >= + f_hat^2 + g_hat^2 - 1 pointwise on v != 0 and therefore + sum h_hat^2 >= 135 + 135 - 31 = 239 > 175. Contradiction. + + Returns exact integers; the m=4 analogue (|A0| = 7, |A1| = 1 in F2^3) + computes need = lower = 7 (no contradiction), matching the real covers + of the m=4 analogue class in the PR 2933 F2^5 census.""" + out = {} + for tag, m, kx, ky, s_size in (("m5_k5", 5, 5, 5, 25), ("m3_k2", 3, 2, 2, 4)): + n = 1 << m + need = n * s_size - s_size * s_size + sum_alpha = n * kx - kx * kx + sum_beta = n * ky - ky * ky + odd = (kx % 2 == 1) and (ky % 2 == 1) + lower = sum_alpha + sum_beta - (n - 1) if odd else 0 + out[tag] = dict( + n=n, + kx=kx, + ky=ky, + s_size=s_size, + need=need, + sum_alpha=sum_alpha, + sum_beta=sum_beta, + lower_bound=lower, + parity_odd=odd, + contradiction=bool(odd and lower > need), + ) + n = 8 + out["m3_analogue_71"] = dict( + n=n, + kx=7, + ky=1, + s_size=7, + need=n * 7 - 49, + sum_alpha=n * 7 - 49, + sum_beta=n * 1 - 1, + lower_bound=(n * 7 - 49) + (n * 1 - 1) - (n - 1), + parity_odd=True, + contradiction=(n * 7 - 49) + (n * 1 - 1) - (n - 1) > n * 7 - 49, + ) + return out + + +# ------------------------------------------------- m=4 brute-force control + + +def control_m4_bruteforce(): + """Complete brute force of the two m=4 analogue classes (soundness and + completeness control for the L7 structural reduction). + + Analogue of the (7,1)-tight class: D-vanish (1,1), A split (7,1), + F1 = 7*1 + 1*1 = 8 = need. Analogue of the (8,2)-tight class: + A-vanish (2,2), D split (2,2), F1 = 4 + 4 = 8 = need. + + Direct route: every (A, D) pair with those splits inside E = F2^4 + (H = bit-0-even half, 8 points each coset), tested against the four L3 + lines. Every direct cover must show the L7 equality structure (both + cross sumsets Sidon, disjoint, union the whole odd half).""" + H = [x for x in range(16) if not (x & 1)] + Hp = [x for x in range(16) if x & 1] + + def ss(X, Y): + return {x ^ y for x in X for y in Y} + + def se(X): + return {x ^ y for x in X for y in X} + + def l3_lines(a0, a1, d0, d1): + ok_i = ss(a0, d0) | ss(a1, d1) == set(H) + ok_ii = ss(a0, d1) | ss(a1, d0) == set(Hp) + ok_iii = se(a0) | se(a1) | se(d0) | se(d1) == set(H) + ok_iv = ss(a0, a1) | ss(d0, d1) == set(Hp) + return ok_i and ok_ii and ok_iii and ok_iv + + res = {} + + covers_71 = [] + struct_71 = [] + for a0t in combinations(H, 7): + a0 = list(a0t) + for a1 in Hp: + for d0 in H: + for d1 in Hp: + if l3_lines(a0, [a1], [d0], [d1]): + covers_71.append((a0t, a1, d0, d1)) + sums = ss(a0, [a1]) + tset = set(Hp) - sums + struct_71.append( + len(sums) == 7 + and len(tset) == 1 + and ({d0 ^ d1} == tset) + ) + res["m4_class71_analogue"] = dict( + direct_covers=len(covers_71), + all_have_l7_structure=all(struct_71) if struct_71 else None, + ) + + covers_82 = [] + struct_82 = [] + for a0c in combinations(H, 2): + for a1c in combinations(Hp, 2): + for d0c in combinations(H, 2): + for d1c in combinations(Hp, 2): + a0, a1 = list(a0c), list(a1c) + d0, d1 = list(d0c), list(d1c) + if l3_lines(a0, a1, d0, d1): + covers_82.append((a0c, a1c, d0c, d1c)) + sumsA = ss(a0, a1) + sumsD = ss(d0, d1) + struct_82.append( + len(sumsA) == 4 + and len(sumsD) == 4 + and not (sumsA & sumsD) + and (sumsA | sumsD) == set(Hp) + ) + res["m4_class82_analogue"] = dict( + direct_covers=len(covers_82), + all_have_l7_structure=all(struct_82) if struct_82 else None, + ) + return res + + +def rho_classification(): + """Exact classification of the cross-multiplicity pattern of any + full-sumset pair of 6-sets in F2^5 (the forced structure of the (12,6) + A-vanish class (6,0), and of every (A, D) line (I'')/(II'')). + + Let X, Y be 6-sets with X + Y = F2^5 and r(s) = #{(x,y): x+y = s} = + 1 + rho(s), sum rho = 36 - 32 = 4. Fourier: rho_hat(v) = f_hat(v) + g_hat(v) for v != 0. Every f_hat(v), g_hat(v) is even and + |rho_hat(v)| <= sum rho = 4, so per nonzero v: f_hat(v) g_hat(v) is in + {0, 4, -4}, i.e. (f_hat, g_hat) = (0, *) or (*, 0) or both +-2. + Parseval gives sum_{v != 0} f_hat^2 = 156 and rho-Parseval gives + |V22| = 2 sum rho^2 - 1 where V22 = {v != 0: |f_hat| = |g_hat| = 2}. + + Case table (exact integers; the Walsh constraints are machine-checked in + test_engine.py): + + rho type sum rho^2 |V22| needed Walsh constraint verdict + 4 delta_p 16 31 rho_hat = +-4 always DEAD + 3+1 10 19 +-2 occurs for p != q DEAD + 2+2 8 15 subspace size 15 SURVIVES + 2+1+1 6 11 sizes 2^{5-r}-1 DEAD + 1+1+1+1 4 7 rank-3 flat / rank-2 SURVIVES + + DEAD reasons: (4 delta_p) Parseval 156 = 4*31 + (36a+16b) forces + 32 = 36a+16b with |Vf| = a + b = 0, impossible; (3+1) rho_hat = + 3(-1)^{vq} + (-1)^{vp} lies in {+-2, +-4} and |rho_hat| <= 4 needs + v*(p+q) = 0 for every v != 0, i.e. p = q; (2+1+1) V22 is + {v: v*(p1+p2) = 0 and v*(p1+q) = 0} minus {0}, of size 2^{5-r} - 1 in + {1,3,7,15,31}, never 11. + + Surviving types: + (T1) rho = 1 on an affine 2-flat {p1, p2, p3, p1+p2+p3} and 0 else; + (T2) rho = 2 on two distinct points {q1, q2} and 0 else. + Both sides' spectra are pinned: T1 has |Vf| = |Vg| = 8 all of magnitude + 4 and |V00| = 8; T2 has |Vf| = |Vg| = 6 and |V00| = 4.""" + return { + "types": [ + dict( + rho="4*delta_p", + sum_rho2=16, + v22_needed=31, + verdict="DEAD", + reason="Parseval 156 = 4*31 + (36a+16b) needs 32 = 36a+16b with |Vf| = 0", + ), + dict( + rho="3+1", + sum_rho2=10, + v22_needed=19, + verdict="DEAD", + reason="v*(p+q) = 0 for all v != 0 forces p = q", + ), + dict( + rho="2+2", + sum_rho2=8, + v22_needed=15, + verdict="SURVIVES", + v22=15, + vf=6, + vg=6, + v00=4, + ), + dict( + rho="2+1+1", + sum_rho2=6, + v22_needed=11, + verdict="DEAD", + reason="2^{5-r}-1 in {1,3,7,15,31}, never 11", + ), + dict( + rho="1+1+1+1", + sum_rho2=4, + v22_needed=7, + verdict="SURVIVES", + v22=7, + vf=8, + vg=8, + v00=8, + ), + ], + "surviving": ["2+2", "1+1+1+1"], + } + + +def identity_odd_sides(s, t, m=6): + """Cross-sum multiplicity identity for splits with BOTH sides odd (the + (11,7) and (9,9) splits, where no character can vanish - PR 2933 L2). + + With A an s-set and D a t-set in E = F2^m covering the odd line + A + D = E, the multiplicity is r = 1 + rho with sum rho = s*t - 2^m. + Fourier over E: rho_hat(v) = f_hat(v) g_hat(v) for v != 0, every f_hat + and g_hat is odd (s, t odd), so f_hat^2 g_hat^2 >= f_hat^2 + g_hat^2 - 1 + pointwise. Parseval: sum_{v != 0} f_hat^2 = 2^m s - s^2 and likewise + for g, sum_{v != 0} rho_hat^2 = 2^m sum rho^2 - (sum rho)^2. + + The pointwise inequality yields the EXACT necessary condition + 2^m sum rho^2 - (st - 2^m)^2 >= (2^m s - s^2) + (2^m t - t^2) + - (2^m - 1), + i.e. a lower bound on sum rho^2. For (11,7) and (9,9) at m = 6 the + bound is satisfiable (the excess 13 resp. 17 is too large for the + identity to contradict), so the identity is DEMOTED as an exclusion + mechanism for these splits; the numbers below are exact.""" + n = 1 << m + excess = s * t - n + sum_alpha = n * s - s * s + sum_beta = n * t - t * t + lower = sum_alpha + sum_beta - (n - 1) + # sum rho^2 >= ceil((lower + excess^2) / n) + num = lower + excess * excess + rho2_min = -(-num // n) + parity_odd = (s % 2 == 1) and (t % 2 == 1) + # products f_hat*g_hat must lie within +-excess pointwise + return dict( + split=(s, t), + m=m, + excess=excess, + sum_alpha=sum_alpha, + sum_beta=sum_beta, + pointwise_lower_sum_rho_hat_sq=lower, + sum_rho2_min=rho2_min, + sum_rho2_max=excess * excess, + parity_odd=parity_odd, + contradiction=bool(parity_odd and rho2_min > excess * excess), + ) diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/vendor/vanish.py b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/vanish.py new file mode 100644 index 0000000000..2dca0053f3 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/vendor/vanish.py @@ -0,0 +1,604 @@ +"""KB3f engine: vanishing-character classification for the 18-point cover +question for F2^7 (set level; no words). + +Object (unchanged from PR 2911, which this package presses): in the PR943 +prefix-walk model a restored seven-source singleton word is universal exactly +when its prefix set P covers, P + P = F2^7. A parity split S = A u B has A in +the even coset E (s points), B in the odd coset O (t points), s + t = 18. +PR 2911 PROVED that any (12,6) or (10,8) cover must have a vanishing +character off the all-ones hyperplane; this module classifies those +vanishing configurations and tests each class against coverage of the +remaining masks. + +Everything is exact Python integer arithmetic; no floats are used. + +Conventions. The even coset E is identified with F2^6 (m = 6); a character +of E is nontrivial psi_v(x) = (-1)^(v.x), v in 1..2^m-1. The (A, D) +reduction (PR 2911, PROVEN there): fix an odd p in F2^7 and D = p + B inside +E; S covers iff (i) A + D = E and (ii) (A+A) u (D+D) = E. + +Classification lemmas (all machine-checked in test_engine.py): + +L2 (halving). char_sum(A, v) = 0 iff A splits |A|/2 + |A|/2 across + ker(psi_v); so a vanishing on side A needs s even and forces the split + (s/2, s/2), and on side D needs t even and forces (t/2, t/2). At + (11,7) and (9,9) both sides are odd: NO character can vanish there. + +L3 (half-decomposition). With H = ker(psi_v), H' = E \\ H and A = A0 u A1, + D = D0 u D1 the two sides of ker(psi_v), coverage is equivalent to + (A0+D0) u (A1+D1) = H, (A0+D1) u (A1+D0) = H', + (A0+A0) u (A1+A1) u (D0+D0) u (D1+D1) = H, (A0+A1) u (D0+D1) = H'. + +L4 (class floors, exact union-size bounds on L3). With a split (a0, a1) of + A and (d0, d1) of D across ker(psi_v), the H'-even line forces + (F1) a0*a1 + d0*d1 >= 2^(m-1); the H-even line forces + (F2) sum over the four parts p of (1 + C(p,2) if p >= 1 else 0) >= 2^(m-1); + the odd lines force (F3) a0*d0 + a1*d1 >= 2^(m-1) and + (F4) a0*d1 + a1*d0 >= 2^(m-1). A class whose forced splits violate any + floor is PROVEN impossible: no cover realizes it. + +A class = (vanishing side, forced split of the vanishing side, split of the +other side). class_table enumerates all classes of a split; classify_cover +decides the classes of a concrete cover; census_f4/census_f5 enumerate the +smallest covers as ground truth for which classes actually occur. +""" + +import hashlib +import itertools +import random +import time +from collections import Counter + + +# ---------------------------------------------------------- F2^n basics + + +def dot(x, y): + return (x & y).bit_count() & 1 + + +def char_sum(pts, v): + """sum over pts of (-1)^(v.x).""" + return sum(1 - 2 * dot(p, v) for p in pts) + + +def split_sizes(pts, v, n): + """(|pts int ker(psi_v)|, |pts \\ ker(psi_v)|).""" + h0 = sum(1 for p in pts if not dot(v, p)) + return (h0, len(pts) - h0) + + +def char_representatives(n): + """One representative per nontrivial character of E: min(v, v ^ all1).""" + all1 = (1 << n) - 1 + out = [] + for v in range(1, all1): + if v < (v ^ all1): + out.append(v) + return out + + +def vanishing_set(pts, n): + """Character-level vanishing set (one entry per nontrivial character).""" + return {v for v in char_representatives(n) if char_sum(pts, v) == 0} + + +def vanishing_set_u(pts, n): + """u-level vanishing set: all indices v off {0, all-ones} with sum 0.""" + all1 = (1 << n) - 1 + return {v for v in range(1, all1) if char_sum(pts, v) == 0} + + +def sumset_xor(x, y): + return {a ^ b for a in x for b in y} + + +def selfsum_xor(x): + return {a ^ b for i, a in enumerate(x) for b in x[i:]} + + +def covers_f2n(pts, n): + cov = selfsum_xor(pts) + return len(cov) == (1 << n) + + +def cover_conditions(A, D, m): + """(A + D = F2^m, (A+A) u (D+D) = F2^m) -- the (A, D) reduction.""" + full = set(range(1 << m)) + odd_ok = sumset_xor(A, D) == full + even_ok = selfsum_xor(A) | selfsum_xor(D) == full + return odd_ok, even_ok + + +# ------------------------------------------------- half decomposition + + +def half_conditions(A, D, v, m): + """The four half lines of L3 for character psi_v.""" + A0 = [a for a in A if not dot(v, a)] + A1 = [a for a in A if dot(v, a)] + D0 = [d for d in D if not dot(v, d)] + D1 = [d for d in D if dot(v, d)] + H = {x for x in range(1 << m) if not dot(v, x)} + Hp = {x for x in range(1 << m) if dot(v, x)} + od0 = sumset_xor(A0, D0) | sumset_xor(A1, D1) + od1 = sumset_xor(A0, D1) | sumset_xor(A1, D0) + ev0 = selfsum_xor(A0) | selfsum_xor(A1) | selfsum_xor(D0) | selfsum_xor(D1) + ev1 = sumset_xor(A0, A1) | sumset_xor(D0, D1) + return ( + H <= od0, + Hp <= od1, + H <= ev0, + Hp <= ev1, + (len(A0), len(A1), len(D0), len(D1)), + ) + + +def check_half_decomposition(m, exhaustive=True, samples=0, seed=1): + """Verify L2 and L3 on every (A, D) pair (m <= 3) or on random samples.""" + rng = random.Random(seed) + N = 1 << m + pairs = 0 + if exhaustive: + sets = [] + for mask in range(1 << N): + sets.append([x for x in range(N) if (mask >> x) & 1]) + iterator = itertools.product(sets, repeat=2) + else: + def rand_iter(): + for _ in range(samples): + A = [x for x in range(N) if rng.randrange(2)] + D = [x for x in range(N) if rng.randrange(2)] + yield (A, D) + iterator = rand_iter() + for A, D in iterator: + pairs += 1 + for v in range(1, N): + cs = char_sum(A, v) + a0, a1 = split_sizes(A, v, m) + l2 = (cs == 0) == (len(A) % 2 == 0 and a0 == len(A) // 2) + if not l2: + return dict(ok=False, pairs=pairs, fail="L2", A=A, D=D, v=v) + od0, od1, ev0, ev1, _ = half_conditions(A, D, v, m) + direct = cover_conditions(A, D, m) + if (od0 and od1 and ev0 and ev1) != all(direct): + return dict(ok=False, pairs=pairs, fail="L3", A=A, D=D, v=v) + return dict(ok=True, pairs=pairs) + + +def two_vanishing_structure(A, v1, v2, m): + """L5 (multi-vanishing structure). If char_sum(A, v1) = char_sum(A, v2) + = 0 for distinct characters, the counts of A across the four parts of the + (ker(psi_v1), ker(psi_v2)) grid are (x, y, y, x) with x + y = |A|/2. + Returns (counts, ok) where counts = (n00, n01, n10, n11) in the grid.""" + n00 = n01 = n10 = n11 = 0 + for a in A: + b1, b2 = dot(v1, a), dot(v2, a) + if b1 == 0 and b2 == 0: + n00 += 1 + elif b1 == 0: + n01 += 1 + elif b2 == 0: + n10 += 1 + else: + n11 += 1 + ok = n00 == n11 and n01 == n10 + return (n00, n01, n10, n11), ok + + +def check_multi_vanishing(m): + """Verify L5 for every subset A of F2^m and every vanishing pair.""" + N = 1 << m + checked = 0 + for mask in range(1 << N): + A = [x for x in range(N) if (mask >> x) & 1] + van = [v for v in range(1, N) if char_sum(A, v) == 0] + for i in range(len(van)): + for j in range(i): + counts, ok = two_vanishing_structure(A, van[j], van[i], m) + checked += 1 + if not ok: + return dict(ok=False, checked=checked, A=A, v=(van[j], van[i]), counts=counts) + return dict(ok=True, checked=checked) + + +def sidon_pair(X, Y): + """All |X|*|Y| sums x+y distinct (no nontrivial common difference).""" + return len(sumset_xor(X, Y)) == len(X) * len(Y) + + +def check_tight_equality(m): + """L7 (equality analysis of the F1 floor). Whenever a0*a1 + d0*d1 = + 2^(m-1) and the pair (A, D) covers, the H' even line forces + |A0+A1| = a0*a1 (a Sidon pair), |D0+D1| = d0*d1 (a Sidon pair), and the + two cross sumsets are disjoint (their union is H').""" + N = 1 << m + need = 1 << (m - 1) + checked = 0 + sets = [[x for x in range(N) if (mask >> x) & 1] for mask in range(1 << N)] + for A in sets: + for D in sets: + if not all(cover_conditions(A, D, m)): + continue + for v in range(1, N): + A0 = [a for a in A if not dot(v, a)] + A1 = [a for a in A if dot(v, a)] + D0 = [d for d in D if not dot(v, d)] + D1 = [d for d in D if dot(v, d)] + if len(A0) * len(A1) + len(D0) * len(D1) != need: + continue + checked += 1 + sA = sumset_xor(A0, A1) + sD = sumset_xor(D0, D1) + if len(sA) != len(A0) * len(A1): + return dict(ok=False, checked=checked, fail="A0+A1 not Sidon", A=A, D=D, v=v) + if len(sD) != len(D0) * len(D1): + return dict(ok=False, checked=checked, fail="D0+D1 not Sidon", A=A, D=D, v=v) + if sA & sD: + return dict(ok=False, checked=checked, fail="cross sumsets overlap", A=A, D=D, v=v) + return dict(ok=True, checked=checked) + + +# ------------------------------------------------------- class table + + +def _bound2(part): + return (1 + part * (part - 1) // 2) if part >= 1 else 0 + + +def class_table(s, t, m=6): + """All vanishing classes of the split (s, t) at E = F2^m and their floor + verdicts. A class: vanishing side A (forced split s/2 + s/2) with the + other side's split (d0, d1), or vanishing side D (forced t/2 + t/2) with + the other side's split (a0, a1). Verdict dead iff some exact floor of L4 + fails; survives-tight iff F1 holds with equality.""" + need = 1 << (m - 1) + out = {"split": (s, t), "m": m, "floor_need_F1": need, "vanishing_possible": False} + + def floors(a0, a1, d0, d1): + return { + "F1": a0 * a1 + d0 * d1, + "F2": _bound2(a0) + _bound2(a1) + _bound2(d0) + _bound2(d1), + "F3": a0 * d0 + a1 * d1, + "F4": a0 * d1 + a1 * d0, + } + + def entry(vanishing_side, van_split, other_split, a0, a1, d0, d1): + fl = floors(a0, a1, d0, d1) + ok = all(v >= need for v in fl.values()) + tight = ok and fl["F1"] == need + forced = None + if ok and tight: + forced = ( + "equality: |A0+A1| = a0*a1 and |D0+D1| = d0*d1 (both Sidon), " + "the two cross sumsets disjoint with union the whole odd half" + ) + elif ok and d0 * d1 == 0: + forced = "D cross sums empty: |A0+A1| = the whole odd half" + elif ok and a0 * a1 == 0: + forced = "A cross sums empty: |D0+D1| = the whole odd half" + return dict( + vanishing_side=vanishing_side, + vanishing_split=van_split, + other_split=other_split, + splits=dict(A=(a0, a1), D=(d0, d1)), + floors=fl, + floor_value=fl["F1"], + floor_need=need, + verdict=("survives" if ok else "dead"), + tight=tight, + forced=forced, + ) + + A_rows, D_rows = [], [] + if s % 2 == 0: + out["vanishing_possible"] = True + for d0 in range(t, (t - 1) // 2, -1): + d1 = t - d0 + A_rows.append(entry("A", (s // 2, s // 2), (d0, d1), s // 2, s // 2, d0, d1)) + if t % 2 == 0: + out["vanishing_possible"] = True + for a0 in range(s, (s - 1) // 2, -1): + a1 = s - a0 + D_rows.append(entry("D", (t // 2, t // 2), (a0, a1), a0, a1, t // 2, t // 2)) + out["A_vanish"] = A_rows + out["D_vanish"] = D_rows + return out + + +# ---------------------------------------------------- cover census + + +def classify_cover(S, n): + """Classify a covering set S of F2^n by its vanishing classes (ground + truth for 'which characters can vanish').""" + A = [x for x in S if x.bit_count() % 2 == 0] + B = [x for x in S if x.bit_count() % 2 == 1] + D = [1 ^ b for b in B] + m = n - 1 + need = 1 << (m - 1) + k_A = vanishing_set(A, n) + k_D = vanishing_set(D, n) + rows = [] + dead = [] + for v in sorted(k_A | k_D): + a0, a1 = split_sizes(A, v, n) + d0, d1 = split_sizes(D, v, n) + val = a0 * a1 + d0 * d1 + verdict = "survives" if val >= need else "dead" + side = ("A" if v in k_A else "") + ("D" if v in k_D else "") + rows.append((v, side, (a0, a1), (d0, d1), verdict)) + if verdict == "dead": + dead.append((v, side, (a0, a1), (d0, d1))) + return dict( + S=sorted(S), + split=(len(A), len(B)), + k_A=len(k_A), + k_D=len(k_D), + vanish_rows=rows, + dead_classes_hit=dead, + ) + + +def _aggregate(rec, agg, class_agg): + agg[("%d_%d" % rec["split"], rec["k_A"], rec["k_D"])] += 1 + for (v, side, a_sp, d_sp, verdict) in rec["vanish_rows"]: + class_agg[(side, a_sp, d_sp, verdict)] += 1 + + +def _ser_agg(agg): + return sorted(["%s kA=%d kD=%d" % k, v] for k, v in agg.items()) + + +def _ser_class_agg(class_agg): + return sorted( + ["%s a=%d,%d d=%d,%d %s" % (side, a_sp[0], a_sp[1], d_sp[0], d_sp[1], verdict), v] + for (side, a_sp, d_sp, verdict), v in class_agg.items() + ) + + +def census_f4(keep=100): + """Exhaustive: every subset S of F2^4 with S + S = F2^4, classified.""" + N = 16 + full = set(range(N)) + pair = [[0] * N for _ in range(N)] + for i in range(N): + for j in range(N): + pair[i][j] = i ^ j + agg = Counter() + class_agg = Counter() + covers = [] + covers_total = 0 + dead_hit = [] + for mask in range(1, 1 << N): + S = [x for x in range(N) if (mask >> x) & 1] + cov = {0} + for i in range(len(S)): + for j in range(i): + cov.add(pair[S[i]][S[j]]) + if cov != full: + continue + covers_total += 1 + rec = classify_cover(S, 4) + _aggregate(rec, agg, class_agg) + if rec["dead_classes_hit"]: + dead_hit.append(rec["dead_classes_hit"]) + if len(covers) < keep: + covers.append(S) + return dict( + covers_total=covers_total, + covers=covers, + agg=_ser_agg(agg), + class_agg=_ser_class_agg(class_agg), + dead_classes_hit=dead_hit, + ) + + +def census_f5(shard=0, shards=16, keep_covers=5, n=5, k=10, max_combos=None): + """Shard `shard` of the full k-subset census of F2^n (n = 5, k = 10): + every k-subset S with S + S = F2^n is classified by vanishing class. + Independent enumeration route (all C(32,10) combinations) for the + recorded PR 2773 n5 control value 99,200 ten-point covers. max_combos + truncates a shard (smoke tests only; a complete census passes None).""" + N = 1 << n + full = (1 << N) - 1 + pairbit = [[0] * N for _ in range(N)] + for i in range(N): + for j in range(N): + pairbit[i][j] = 1 << (i ^ j) + agg = Counter() + class_agg = Counter() + covers = [] + covers_total = 0 + dead_hit = [] + combos = 0 + for S in itertools.combinations(range(N), k): + if S[0] % shards != shard: + continue + combos += 1 + if max_combos is not None and combos > max_combos: + combos -= 1 + return dict( + shard=shard, + shards=shards, + status="partial", + combos=combos, + covers_total=covers_total, + covers=covers, + agg=_ser_agg(agg), + class_agg=_ser_class_agg(class_agg), + dead_classes_hit=dead_hit, + ) + cov = 1 + for i in range(k): + si = S[i] + row = pairbit[si] + for j in range(i): + cov |= row[S[j]] + if cov != full: + continue + covers_total += 1 + rec = classify_cover(list(S), n) + _aggregate(rec, agg, class_agg) + if rec["dead_classes_hit"]: + dead_hit.append(rec["dead_classes_hit"]) + if len(covers) < keep_covers: + covers.append(sorted(S)) + return dict( + shard=shard, + shards=shards, + status="complete", + combos=combos, + covers_total=covers_total, + covers=covers, + agg=_ser_agg(agg), + class_agg=_ser_class_agg(class_agg), + dead_classes_hit=dead_hit, + ) + + +# ------------------------------------------------- class-restricted search + + +def _score_pair(A, D): + """|A + D| + |(A+A) u (D+D)| as integer bitmasks (target 2^(m+1)).""" + cm = 1 + for a in A: + for d in D: + cm |= 1 << (a ^ d) + sm = 1 + for i, a in enumerate(A): + for b in A[i:]: + sm |= 1 << (a ^ b) + for i, d in enumerate(D): + for b in D[i:]: + sm |= 1 << (d ^ b) + return cm.bit_count() + sm.bit_count() + + +def search_class(s, t, side, other_split, restarts=20, seed=1, seconds=20.0, m=6): + """Bounded seeded local search for a covering (A, D) pair in E = F2^m + constrained to one vanishing class: psi = bit 0 (WLOG under GL(m, 2)), + the vanishing side split equally across ker(psi), the other side split + exactly `other_split`. A found pair is a falsifying instance for the + class contradiction and (at m = 6) an 18-point cover witness; a failed + bounded search is a scoped search failure, never an exclusion.""" + rng = random.Random(seed) + N = 1 << m + target = 2 * N + + if side == "A_vanish": + a_h0 = s // 2 + a_h1 = s // 2 + d_h0, d_h1 = other_split + else: + d_h0 = t // 2 + d_h1 = t // 2 + a_h0, a_h1 = other_split + half0 = [x for x in range(N) if not (x & 1)] + half1 = [x for x in range(N) if (x & 1)] + + def build(): + A = rng.sample(half0, a_h0) + rng.sample(half1, a_h1) + D = rng.sample(half0, d_h0) + rng.sample(half1, d_h1) + return A, D + + best = (0, None) + moves = 0 + t0 = time.time() + for _ in range(restarts): + if time.time() - t0 > seconds: + break + A, D = build() + sc = _score_pair(A, D) + improved = True + while improved and time.time() - t0 < seconds: + improved = False + for cur in (A, D): + for half in (half0, half1): + for i in range(len(cur)): + if (cur[i] & 1) != (half[0] & 1): + continue + for v in half: + if v in cur: + continue + moves += 1 + old = cur[i] + cur[i] = v + new = _score_pair(A, D) + if new > sc: + sc = new + improved = True + break + cur[i] = old + if sc == target: + break + if sc == target: + break + if sc == target: + break + if sc == target: + return dict( + found=True, + score=sc, + A=sorted(A), + D=sorted(D), + side=side, + other_split=other_split, + moves=moves, + seconds=round(time.time() - t0, 2), + ) + if sc > best[0]: + best = (sc, (sorted(A), sorted(D))) + return dict( + found=False, + score=best[0], + best_pair=best[1], + side=side, + other_split=other_split, + restarts=restarts, + moves=moves, + seconds=round(time.time() - t0, 2), + ) + + +def search_free(s, t, restarts=20, seed=1, seconds=20.0, m=6): + """Unconstrained bounded seeded search for a covering (A, D) pair in + E = F2^m (non-vacuity control for the class-restricted machinery).""" + rng = random.Random(seed) + N = 1 << m + target = 2 * N + pool = list(range(N)) + best = (0, None) + t0 = time.time() + for _ in range(restarts): + if time.time() - t0 > seconds: + break + A = rng.sample(pool, s) + D = rng.sample(pool, t) + sc = _score_pair(A, D) + improved = True + while improved and time.time() - t0 < seconds: + improved = False + for cur, size in ((A, s), (D, t)): + outside = [x for x in pool if x not in cur] + for i in range(size): + for v in outside: + old = cur[i] + cur[i] = v + new = _score_pair(A, D) + if new > sc: + sc = new + improved = True + outside[outside.index(v)] = old + if sc == target: + return dict(found=True, score=sc, A=sorted(A), D=sorted(D)) + else: + cur[i] = old + if sc > best[0]: + best = (sc, (sorted(A), sorted(D))) + return dict(found=False, score=best[0], best_pair=best[1]) + + +def sha256_file(path): + return hashlib.sha256(path.read_bytes()).hexdigest() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/verify.py b/research/f7-mu2-evenhalf-kb3k-88a1/verify.py new file mode 100644 index 0000000000..68bfd27553 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/verify.py @@ -0,0 +1,151 @@ +"""KB3k verifier. Reproduces the mu2-condition verdict. + +quick re-run the fast exact checks live (F2^3 identity + minimality/mechanism + census at gsize 2/4/8) and READ BACK the heavier receipts (m4 complete + census, m5odd/m6 sampling, both-odd mutation search) from their JSON. +full re-run everything live (adds the m4 complete census and the both-odd + mutation search; minutes). Exact ints throughout. + +Markers: PASS_KB3K_QUICK / PASS_KB3K_FULL. +""" + +import json +import sys +from itertools import combinations +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE)) +sys.path.insert(0, str(HERE / "vendor")) +import parity_census as pc # noqa: E402 +import mu2_search as m2 # noqa: E402 + + +def load(name): + return json.loads((HERE / name).read_text(encoding="utf-8")) + + +def check_identity_m3(): + gsize = 8 + subs = list(range(1 << gsize)) + bad = n = 0 + for am in subs: + for bm in subs: + if m2.covers(am, bm, gsize): + n += 1 + p = m2.profile_of(am, bm, gsize) + if p["mu2"] != p["sa"] + p["sb"] - gsize or p["self_union"] != gsize: + bad += 1 + return n, bad + + +def minimality(): + """Return (F2^1 varying, F2^2 varying, F2^3 minimal varying split).""" + def vary(gsize): + res = {} + for am in range(1 << gsize): + for bm in range(1 << gsize): + if m2.covers(am, bm, gsize): + k = (am.bit_count(), bm.bit_count()) + sa = pc.selfsum(am).bit_count() + sb = pc.selfsum(bm).bit_count() + mu2 = (pc.selfsum(am) & pc.selfsum(bm)).bit_count() + res.setdefault(k, {"mu2": set(), "n": 0}) + res[k]["mu2"].add(mu2) + res[k]["n"] += 1 + return {k: v for k, v in res.items() if len(v["mu2"]) > 1}, res + + v1, _ = vary(2) # F2^1, gsize 2 + v2, _ = vary(4) # F2^2, gsize 4 + v3, r3 = vary(8) # F2^3, gsize 8 + minimal = min(v3.items(), key=lambda kv: (sum(kv[0]), max(kv[0]))) if v3 else None + return v1, v2, v3, minimal + + +def walk_check(): + """Read the (4,2) walk receipts: aggregate the complete shards and, if both + the clean run and the preserved from-empty recompute are present, require + their counters to match exactly (the receipt-validation trap).""" + import glob as _glob + + receipts = [] + for p in sorted(_glob.glob(str(HERE / "AV42-AV42-*.json"))): + rec = json.loads(Path(p).read_text(encoding="utf-8")) + receipts.append(rec) + complete = [r for r in receipts if r.get("complete")] + u = sum(r.get("u_checked", 0) for r in complete) + pairs = sum(r.get("uv_pairs", 0) for r in complete) + wcand = sum(r.get("w_candidates", 0) for r in complete) + covering = sum(r.get("covering_configs", 0) for r in complete) + print("WALK aggregate: %d complete shards u_checked=%d uv_pairs=%d w_candidates=%d covering=%d" + % (len(complete), u, pairs, wcand, covering)) + # recompute comparison for shard 29 + first = HERE / "AV42-RECOMPUTE-29-first-run.json" + cur = HERE / "AV42-AV42-29.json" + if first.exists() and cur.exists(): + a = json.loads(first.read_text(encoding="utf-8")) + b = json.loads(cur.read_text(encoding="utf-8")) + keys = ("u_checked", "uv_pairs", "w_candidates", "covering_configs", + "uv_pairs_by_sumset_size", "w_candidates_by_m_size") + same = all(a.get(k) == b.get(k) for k in keys) + print("WALK recompute shard=29 from empty receipts: counters identical = %s (u=%d uv_pairs=%d)" + % (same, b.get("u_checked", -1), b.get("uv_pairs", -1))) + assert same, "shard 29 recompute mismatch" + else: + print("WALK recompute shard=29: first-run or current receipt not both present (skipped)") + return len(complete), u, pairs + + +def main(): + sys.stdout.reconfigure(encoding="utf-8") + mode = sys.argv[1] if len(sys.argv) > 1 else "quick" + + # --- always-live exact checks ------------------------------------- + n, bad = check_identity_m3() + print("IDENTITY m3 covers=%d violations=%d (must be 0)" % (n, bad)) + assert bad == 0, "identity violated" + + v1, v2, v3, minimal = minimality() + print("MINIMALITY F2^1 varying=%d F2^2 varying=%d F2^3 varying=%d" + % (len(v1), len(v2), len(v3))) + assert len(v1) == 0 and len(v2) == 0, "variation found below F2^3" + assert minimal is not None, "no F2^3 variation" + print("MINIMAL VARIATION SPLIT = (%d,%d) at F2^3, mu2=%s n=%d" + % (minimal[0][0], minimal[0][1], sorted(minimal[1]["mu2"]), minimal[1]["n"])) + assert minimal[0] == (4, 4), "minimal variation split is not (4,4)" + + # --- receipts (read back in quick; re-run in full) ---------------- + if mode == "full": + print("FULL: re-running m4 complete census + both-odd search live...") + m2.run_m4([(1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (3, 3), (4, 4), (2, 2), (1, 5)]) + print("(m4 rerun above)") + + m4 = load("MU2-M4.json") + print("M4 (2,8) mu2=%s constant=%s; (4,6) mu2=%s constant=%s; both-odd (3,7)/(5,5) covers=%d/%d" + % (m4["splits"]["2,8"]["mu2_set"], m4["splits"]["2,8"]["mu2_constant"], + m4["splits"]["4,6"]["mu2_set"], m4["splits"]["4,6"]["mu2_constant"], + m4["splits"]["3,7"]["covers"], m4["splits"]["5,5"]["covers"])) + assert m4["splits"]["2,8"]["mu2_constant"] and m4["splits"]["4,6"]["mu2_constant"] + assert m4["splits"]["3,7"]["covers"] == 0 and m4["splits"]["5,5"]["covers"] == 0 + + odd = load("MU2-ODD.json") + g77 = odd["F2^5 (7,7)"] + print("BOTH-ODD F2^5 (7,7) covers=%d mu2=%s constant=%s" + % (g77["covers_found"], g77["mu2_set"], g77["mu2_constant_observed"])) + print("BOTH-ODD F2^6 (9,9) covers=%d (11,7) covers=%d" + % (odd["F2^6 (9,9)"]["covers_found"], odd["F2^6 (11,7)"]["covers_found"])) + assert g77["mu2_constant_observed"] + + m5odd = load("MU2-M5ODD.json") + m6 = load("MU2-M6.json") + print("M5ODD (7,7) sampled covers=%d mu2=%s; M6 (11,7)/(9,9) sampled covers=%d/%d" + % (m5odd["splits"]["7,7"]["covers_sampled"], list(m5odd["splits"]["7,7"]["mu2_hist"]), + m6["splits"]["11,7"]["covers_sampled"], m6["splits"]["9,9"]["covers_sampled"])) + + walk_check() + + print("PASS_KB3K_" + ("FULL" if mode == "full" else "QUICK"), flush=True) + + +if __name__ == "__main__": + main() diff --git a/research/f7-mu2-evenhalf-kb3k-88a1/walk42.py b/research/f7-mu2-evenhalf-kb3k-88a1/walk42.py new file mode 100644 index 0000000000..0b64827451 --- /dev/null +++ b/research/f7-mu2-evenhalf-kb3k-88a1/walk42.py @@ -0,0 +1,700 @@ +"""KB3j engine: the (12,6) A-vanish (4,2) class of the 18-point cover question +for F2^7 (set level; no words). Exact Python integer arithmetic only. + +Class (4,2) EXACT REDUCTION (extends PR 3023's (5,1) reduction). D1 has two +elements {d1, d1+delta}; global translation by d1 and GL(5,2) (delta -> 1) +give WLOG D1 = {0, 1}. With U = A0+d1, V = A1+d1, W = D0+d1 the class is +EXACTLY the triples (U, V 6-sets, W 4-set) of F2^5 satisfying + + (a) (U+W) u (V+D1) = F2^5 + (b) (U+D1) u (V+W) = F2^5 + (c) (U+V) u (W+D1) = F2^5 + (d) (U+U) u (V+V) u (W+W) u (D1+D1) = F2^5 (D1+D1 = {0,1}) + +and back (A0, A1, D0, D1) = (U, V, W, {0,1}). The four lines are invariant +under (U+a, V+b, W+a+b) for arbitrary a, b in F2^5 (each line is invariant or +its two summands co-translate; machine-checked in test_engine.py), so WLOG +0 in U and 0 in V. Mirror symmetry U <-> V is not used for sharding. + +Walk (extends avtail.class51_run). Line (c) forces +M = F2^5 \\ (U+V) into W u (W+1) (|M| <= 8, so |U+V| >= 24), and lines (a),(b) +are hitting requirements on W: every p outside V+D1 must meet p+U in W and +every p outside U+D1 must meet p+V in W. For each normalized pair (U, V) the +valid W's are found by a complete branch-on-uncovered search over the M +clusters {m, m+1}; every surviving W is tested against (d) exactly. + +The (5,1) kill shape is instrumented: per pair we record w_candidates (W +passing (a),(b),(c)) and, among those, how many pass (d). A class is +pair-killed iff w_candidates = 0 for every normalized pair. + +Small-space ground truth: census_k3() is a COMPLETE census of the (4,2) shape +over F2^3 halves (every normalized (U, V, W) triple, every (|U|,|V|,|W|) +class) and census_k4() is a complete normalized census of the floor-surviving +(u, u, w) classes over F2^4 halves. Both classify each class by kill shape +(pair / line-d / mixed / cover) and are the smallest-instance validation of +the walk machinery. +""" + +import sys +import time +from itertools import combinations +from pathlib import Path + +HERE = Path(__file__).resolve().parent +sys.path.insert(0, str(HERE / "vendor")) + +import tight # noqa: E402 (vendored byte-exact PR 2961 engine) + + +# ------------------------------------------- generic m-bit mask primitives + + +def trans_g(mask, a, bits, allm): + for i in range(bits): + if (a >> i) & 1: + b = 1 << i + lo = 0 + for p in range(1 << bits): + if not (p & b): + lo |= 1 << p + mask = ((mask & lo) << b) | ((mask & (allm ^ lo)) >> b) + return mask + + +def sumset_g(mx, my, bits, allm): + out = 0 + x = mx + while x: + lsb = x & -x + out |= trans_g(my, lsb.bit_length() - 1, bits, allm) + x ^= lsb + return out + + +def selfsum_g(mx, bits, allm): + return sumset_g(mx, mx, bits, allm) + + +def elems_g(mask): + out = [] + while mask: + lsb = mask & -mask + out.append(lsb.bit_length() - 1) + mask ^= lsb + return out + + +# m = 5 fast path (vendored tight primitives; 32-point space) +T5 = tight.trans +S5 = tight.sumset_mask +SS5 = tight.selfsum_mask +ALL5 = tight.ALL +N5 = 32 + +# D1 = {0,1} in F2^5 (or F2^k): its mask and selfsum +D1M5 = 0b11 + + +def lines42(u, v, w, d1=D1M5): + """The four reduced lines (a),(b),(c),(d) for F2^5 masks u, v, w and + D1 mask d1 = {0,1}. Returns (ok, which_lines_fail).""" + vd = S5(v, d1) + ud = S5(u, d1) + wd = S5(w, d1) + dd = S5(d1, d1) + fails = [] + if (S5(u, w) | vd) != ALL5: + fails.append("a") + if (ud | S5(v, w)) != ALL5: + fails.append("b") + if (S5(u, v) | wd) != ALL5: + fails.append("c") + if (SS5(u) | SS5(v) | SS5(w) | dd) != ALL5: + fails.append("d") + return (not fails), tuple(fails) + + +def lines42_g(u, v, w, d1, bits, allm): + """Generic (a),(b),(c),(d) check for F2^bits masks.""" + vd = sumset_g(v, d1, bits, allm) + ud = sumset_g(u, d1, bits, allm) + wd = sumset_g(w, d1, bits, allm) + dd = sumset_g(d1, d1, bits, allm) + fails = [] + if (sumset_g(u, w, bits, allm) | vd) != allm: + fails.append("a") + if (ud | sumset_g(v, w, bits, allm)) != allm: + fails.append("b") + if (sumset_g(u, v, bits, allm) | wd) != allm: + fails.append("c") + if (selfsum_g(u, bits, allm) | selfsum_g(v, bits, allm) | selfsum_g(w, bits, allm) | dd) != allm: + fails.append("d") + return (not fails), tuple(fails) + + +# --------------------------------------- complete W search per (U, V) pair + + +X32 = [[1 << (i ^ j) for j in range(N5)] for i in range(N5)] + + +def _cluster_options(miss): + """The M-clusters {m, m^1} for m in miss; per cluster the admissible + subsets of W n miss (every cluster must be met).""" + clusters = [] + seen = set() + for m in elems_g(miss): + if m in seen: + continue + p1 = m ^ 1 + seen.add(m) + seen.add(p1) + if (miss >> p1) & 1: + clusters.append([(m,), (p1,), (m, p1)]) + else: + clusters.append([(m,), (p1,)]) + return clusters + + +def solve_w42(u, v, wsize=4): + """Complete list of wsize-sets W satisfying (a),(b),(c) for the pair + (u, v) in F2^5: W u (W+1) must contain M = ALL5 \\ (u+v) (so W n miss + meets every cluster {m, m^1}), and W must hit the requirement translates + (p+u) for p outside v+D1 and (p+v) for p outside u+D1. Line (d) is NOT + tested here (exact four-line test in the caller). Returns W masks.""" + uv = S5(u, v) + miss = ALL5 ^ uv + vd = S5(v, D1M5) + ud = S5(u, D1M5) + reqs = [] + for p in elems_g(ALL5 ^ vd): + reqs.append(T5(u, p)) + for p in elems_g(ALL5 ^ ud): + reqs.append(T5(v, p)) + cov_by = [0] * N5 + for w in range(N5): + m = 0 + for i, rq in enumerate(reqs): + if (rq >> w) & 1: + m |= 1 << i + cov_by[w] = m + need = (1 << len(reqs)) - 1 + free = [x for x in range(N5) if not ((miss >> x) & 1)] + clusters = _cluster_options(miss) + out = set() + + def emit_supersets(chosen, need_r): + if need_r == 0: + out.add(sum(1 << c for c in chosen)) + return + rest = [x for x in free if x not in chosen] + for combo in combinations(rest, need_r): + out.add(sum(1 << c for c in chosen) + sum(1 << c for c in combo)) + + def rec(ci, chosen, uncov): + if len(chosen) > wsize: + return + if ci == len(clusters): + if uncov == 0: + emit_supersets(chosen, wsize - len(chosen)) + return + if len(chosen) == wsize: + return + # any W must cover the lowest uncovered requirement with a + # non-miss element (W n miss is already fixed by the clusters) + i = (uncov & -uncov).bit_length() - 1 + x = reqs[i] + while x: + lsb = x & -x + w = lsb.bit_length() - 1 + x ^= lsb + if w in chosen or (miss >> w) & 1: + continue + rec(ci, chosen + [w], uncov & ~cov_by[w]) + return + for opt in clusters[ci]: + if len(chosen) + len(opt) > wsize: + continue + nc = list(chosen) + nu = uncov + ok = True + for w in opt: + if w in nc: + ok = False + break + nc.append(w) + nu &= ~cov_by[w] + if ok: + rec(ci + 1, nc, nu) + + rec(0, [], need) + return sorted(m for m in out if m.bit_count() == wsize) + + +def solve_w42_fast(u, v, wsize, TU, vd, ud): + """Same complete W search as solve_w42 for F2^5, with the requirement + masks taken from the per-U translate table TU and a per-pair V translate + (hot path of the walk). Exact same output as solve_w42 (cross-checked in + test_engine.py on sampled pairs).""" + reqs = [] + for p in elems_g(ALL5 ^ vd): + reqs.append(TU[p]) + vl = elems_g(v) + for p in elems_g(ALL5 ^ ud): + m = 0 + for a in vl: + m |= X32[a][p] + reqs.append(m) + cov_by = [0] * N5 + for i, rq in enumerate(reqs): + x = rq + bit = 1 << i + while x: + lsb = x & -x + cov_by[lsb.bit_length() - 1] |= bit + x ^= lsb + need = (1 << len(reqs)) - 1 + miss = ALL5 ^ S5(u, v) + free = [x for x in range(N5) if not ((miss >> x) & 1)] + clusters = _cluster_options(miss) + out = set() + + def emit_supersets(chosen, need_r): + if need_r == 0: + out.add(sum(1 << c for c in chosen)) + return + rest = [x for x in free if x not in chosen] + for combo in combinations(rest, need_r): + out.add(sum(1 << c for c in chosen) + sum(1 << c for c in combo)) + + def rec(ci, chosen, uncov): + if len(chosen) > wsize: + return + if ci == len(clusters): + if uncov == 0: + emit_supersets(chosen, wsize - len(chosen)) + return + if len(chosen) == wsize: + return + i = (uncov & -uncov).bit_length() - 1 + x = reqs[i] + while x: + lsb = x & -x + w = lsb.bit_length() - 1 + x ^= lsb + if w in chosen or (miss >> w) & 1: + continue + rec(ci, chosen + [w], uncov & ~cov_by[w]) + return + for opt in clusters[ci]: + if len(chosen) + len(opt) > wsize: + continue + nc = list(chosen) + nu = uncov + ok = True + for w in opt: + if w in nc: + ok = False + break + nc.append(w) + nu &= ~cov_by[w] + if ok: + rec(ci + 1, nc, nu) + + rec(0, [], need) + return sorted(m for m in out if m.bit_count() == wsize) + + +def pair_backtrack42(u, need, TU): + """All normalized v (0 in v, 6-set) with |u+v| >= need, by monotone + excess-budget backtracking (excess = 36 - |u+v| grows with v). Returns + (vmask, vlist, support=u+v, sv=selfsum(v)) tuples like (5,1)'s engine.""" + out = [] + rest = list(range(1, N5)) + chosen = [0] + sup = u + excess = 0 + sv = 1 + + def rec(start): + nonlocal sup, excess, sv + if len(chosen) == 6: + if sup.bit_count() >= need: + out.append((sum(1 << c for c in chosen), list(chosen), sup, sv)) + return + for i in range(start, len(rest)): + v = rest[i] + tr = TU[v] + add = (tr & sup).bit_count() + excess += add + old_sup = sup + sup |= tr + chosen.append(v) + trv = 0 + for c in chosen[:-1]: + trv |= X32[c][v] + old_sv = sv + sv |= trv | (1 << v) | 1 + remain = 6 - len(chosen) + if sup.bit_count() + 6 * remain >= need and excess <= 36 - need: + rec(i + 1) + chosen.pop() + sv = old_sv + sup = old_sup + excess -= add + + rec(0) + return out + + +def class42_run(budget=None, shard=0, shards=1, u_limit=None, progress=False): + """Decision walk for class (12,6) A-vanish (4,2): complete over all + normalized (U, V) pairs (0 in U, 0 in V, |U+V| >= 24), every admissible W + per pair (W 4-set with W u (W+1) containing M = F2^5 \\ (U+V) and hitting + the (a)/(b) requirement translates), exact four-line test on every + surviving W. Per-shard resumable via run42.py receipts. The budget is + checked after EVERY U (the (5,1) lesson: coarse checks overshoot).""" + t0 = time.time() + total_u = 169911 + u_done = 0 + pairs = 0 + pairs_by_size = {} + w_candidates = 0 + w_by_m = {} + covering = 0 + fail_hist = {} + witnesses = [] + budget_hit = False + for idx, uc in enumerate(combinations(range(1, N5), 5)): + if idx % shards != shard: + continue + if u_limit is not None and u_done >= u_limit: + budget_hit = True + break + u_done += 1 + u = 1 | tight.mask_of(uc) + ue = (0,) + uc + TU = [0] * N5 + for r in range(N5): + m = 0 + for a in ue: + m |= X32[a][r] + TU[r] = m + for (vm, vl, uv, sv) in pair_backtrack42(u, 24, TU): + pairs += 1 + sz = uv.bit_count() + pairs_by_size[sz] = pairs_by_size.get(sz, 0) + 1 + miss = ALL5 ^ uv + mb = miss.bit_count() + vd = S5(vm, D1M5) + ud = S5(u, D1M5) + ws = solve_w42_fast(u, vm, 4, TU, vd, ud) + w_candidates += len(ws) + w_by_m[mb] = w_by_m.get(mb, 0) + len(ws) + for wm in ws: + ok, fails = lines42(u, vm, wm) + if ok: + covering += 1 + if len(witnesses) < 5: + witnesses.append((list(ue), vl, elems_g(wm))) + else: + fail_hist[fails] = fail_hist.get(fails, 0) + 1 + if progress and u_done % 8 == 0: + print( + "PROGRESS shard=%d u=%d pairs=%d w_cand=%d el=%.1f" + % (shard, u_done, pairs, w_candidates, time.time() - t0), + flush=True, + ) + if budget is not None and time.time() - t0 > budget: + budget_hit = True + break + return dict( + shard=shard, + shards=shards, + normalized_u_total=total_u, + u_checked=u_done, + uv_pairs=pairs, + uv_pairs_by_sumset_size={str(k): v for k, v in sorted(pairs_by_size.items())}, + w_candidates=w_candidates, + w_candidates_by_m_size={str(k): v for k, v in sorted(w_by_m.items())}, + covering_configs=covering, + fail_hist={str(k): v for k, v in sorted(fail_hist.items())}, + witnesses=witnesses, + budget_hit=budget_hit, + seconds=round(time.time() - t0, 2), + ) + + +# ------------------------------------- small-space complete censuses (k=3/4) + + +def census_k3(): + """COMPLETE census of the (4,2) shape over F2^3 halves (8-point space): + every normalized (U, V) pair with 0 in U, 0 in V and every W subset, + every (|U|,|V|,|W|) class. Per class: normalized pairs, W candidates + passing (a),(b),(c), covers passing all four lines, line-(d)-only + failures, and the kill shape ('pair' = every pair has w_candidates 0; + 'line-d' = every W candidate fails only (d); 'mixed'; 'cover'). Used as + the smallest complete ground truth for the (4,2) shape.""" + bits = 3 + n = 1 << bits + allm = (1 << n) - 1 + d1 = 0b11 + subs = list(range(1 << n)) + norm_u = [m for m in subs if m & 1] + classes = {} + for u in norm_u: + for v in norm_u: + uv = sumset_g(u, v, bits, allm) + miss = allm ^ uv + for w_size in range(0, n + 1): + ws = solve_w42_g(u, v, bits, allm, d1, w_size, miss) + key = (u.bit_count(), v.bit_count(), w_size) + r = classes.setdefault( + key, + dict( + pairs=0, + pairs_with_w=0, + w_candidates=0, + covers=0, + d_fail_only=0, + ), + ) + r["pairs"] += 1 + r["w_candidates"] += len(ws) + if ws: + r["pairs_with_w"] += 1 + cov = 0 + for wm in ws: + ok, _ = lines42_g(u, v, wm, d1, bits, allm) + if ok: + cov += 1 + r["covers"] += cov + r["d_fail_only"] += len(ws) - cov + out = {} + for key, r in sorted(classes.items()): + if r["covers"] > 0: + r["kill_shape"] = "cover" + elif r["w_candidates"] == 0: + r["kill_shape"] = "pair" + else: + r["kill_shape"] = "line-d" + out[str(key)] = r + return out + + +def census_k4(u_max=5, w_max=6): + """Complete normalized census of the (4,2) shape classes (u, v, w) over + F2^4 halves (0 in U, 0 in V) for u, v <= u_max, w <= w_max, by the same + M-cluster W search as the real walk. For each class: pairs, the exact + number of W passing (a),(b),(c) (counted combinatorially over the free + completions), pairs admitting at least one full cover (decision per pair) + and the kill shape ('pair' = every pair has w_candidates 0; 'line-d' = + candidates exist but no completion passes (d); 'cover').""" + bits = 4 + n = 1 << bits + allm = (1 << n) - 1 + d1 = 0b11 + pts = list(range(n)) + res = {} + for u_size in range(1, u_max + 1): + for u_c in combinations([p for p in pts if p != 0], u_size - 1): + u = 1 | sum(1 << p for p in u_c) + ue = (0,) + u_c + TU = [0] * n + for r in range(n): + m = 0 + for a in ue: + m |= 1 << (a ^ r) + TU[r] = m + for v_size in range(1, u_max + 1): + for v_c in combinations([p for p in pts if p != 0], v_size - 1): + v = 1 | sum(1 << p for p in v_c) + uv = sumset_g(u, v, bits, allm) + miss = allm ^ uv + for w_size in range(1, w_max + 1): + key = (u_size, v_size, w_size) + r = res.setdefault( + key, + dict( + pairs=0, + w_candidates=0, + pairs_with_cover=0, + pairs_with_w=0, + ), + ) + r["pairs"] += 1 + if 2 * w_size < n - uv.bit_count(): + continue + cnt, has_cover = solve_count_cover_g(u, v, bits, allm, d1, w_size, miss) + r["w_candidates"] += cnt + if cnt: + r["pairs_with_w"] += 1 + if has_cover: + r["pairs_with_cover"] += 1 + out = {} + for key, r in sorted(res.items()): + if r["pairs_with_cover"] > 0: + r["kill_shape"] = "cover" + elif r["w_candidates"] == 0: + r["kill_shape"] = "pair" + else: + r["kill_shape"] = "line-d" + out[str(key)] = r + return out + + +def solve_count_cover_g(u, v, bits, allm, d1, wsize, miss): + """Exact W-candidate count for (a),(b),(c) with completions counted + combinatorially, plus a decision flag for (d) (does any completion pass + all four lines). Same search skeleton as solve_w42_g.""" + from math import comb + + n = 1 << bits + vd = sumset_g(v, d1, bits, allm) + ud = sumset_g(u, d1, bits, allm) + reqs = [] + for p in elems_g(allm ^ vd): + reqs.append(trans_g(u, p, bits, allm)) + for p in elems_g(allm ^ ud): + reqs.append(trans_g(v, p, bits, allm)) + cov_by = [0] * n + for i, rq in enumerate(reqs): + x = rq + bit = 1 << i + while x: + lsb = x & -x + cov_by[lsb.bit_length() - 1] |= bit + x ^= lsb + need = (1 << len(reqs)) - 1 + free = [x for x in range(n) if not ((miss >> x) & 1)] + clusters = _cluster_options(miss) + total = 0 + has_cover = [False] + + def test_completions(chosen, need_r): + nonlocal total + rest = [x for x in free if x not in chosen] + if need_r == 0: + total += 1 + ok, _ = lines42_g(u, v, sum(1 << c for c in chosen), d1, bits, allm) + if ok: + has_cover[0] = True + return + total += comb(len(rest), need_r) + if has_cover[0]: + return + for combo in combinations(rest, need_r): + ok, _ = lines42_g(u, v, sum(1 << c for c in chosen) + sum(1 << c for c in combo), d1, bits, allm) + if ok: + has_cover[0] = True + return + + def rec(ci, chosen, uncov): + if len(chosen) > wsize: + return + if ci == len(clusters): + if uncov == 0: + test_completions(chosen, wsize - len(chosen)) + return + if len(chosen) == wsize: + return + i = (uncov & -uncov).bit_length() - 1 + x = reqs[i] + while x: + lsb = x & -x + w = lsb.bit_length() - 1 + x ^= lsb + if w in chosen or (miss >> w) & 1: + continue + rec(ci, chosen + [w], uncov & ~cov_by[w]) + return + for opt in clusters[ci]: + if len(chosen) + len(opt) > wsize: + continue + nc = list(chosen) + nu = uncov + ok = True + for w in opt: + if w in nc: + ok = False + break + nc.append(w) + nu &= ~cov_by[w] + if ok: + rec(ci + 1, nc, nu) + + rec(0, [], need) + return total, has_cover[0] + + +def solve_w42_g(u, v, bits, allm, d1, wsize, miss=None): + """Generic complete W search (a),(b),(c) for F2^bits: returns W masks. + Same completeness contract as solve_w42 (cluster options over W n miss, + free slots from non-miss elements, requirements from both lines).""" + n = 1 << bits + if miss is None: + miss = allm ^ sumset_g(u, v, bits, allm) + vd = sumset_g(v, d1, bits, allm) + ud = sumset_g(u, d1, bits, allm) + reqs = [] + for p in elems_g(allm ^ vd): + reqs.append(trans_g(u, p, bits, allm)) + for p in elems_g(allm ^ ud): + reqs.append(trans_g(v, p, bits, allm)) + cov_by = [0] * n + for w in range(n): + m = 0 + for i, rq in enumerate(reqs): + if (rq >> w) & 1: + m |= 1 << i + cov_by[w] = m + need = (1 << len(reqs)) - 1 + free = [x for x in range(n) if not ((miss >> x) & 1)] + clusters = _cluster_options(miss) + out = set() + + def emit_supersets(chosen, need_r): + if need_r == 0: + out.add(sum(1 << c for c in chosen)) + return + rest = [x for x in free if x not in chosen] + for combo in combinations(rest, need_r): + out.add(sum(1 << c for c in chosen) + sum(1 << c for c in combo)) + + def rec(ci, chosen, uncov): + if len(chosen) > wsize: + return + if ci == len(clusters): + if uncov == 0: + emit_supersets(chosen, wsize - len(chosen)) + return + if len(chosen) == wsize: + return + i = (uncov & -uncov).bit_length() - 1 + x = reqs[i] + while x: + lsb = x & -x + w = lsb.bit_length() - 1 + x ^= lsb + if w in chosen or (miss >> w) & 1: + continue + rec(ci, chosen + [w], uncov & ~cov_by[w]) + return + for opt in clusters[ci]: + if len(chosen) + len(opt) > wsize: + continue + nc = list(chosen) + nu = uncov + ok = True + for w in opt: + if w in nc: + ok = False + break + nc.append(w) + nu &= ~cov_by[w] + if ok: + rec(ci + 1, nc, nu) + + rec(0, [], need) + return sorted(m for m in out if m.bit_count() == wsize)