diff --git a/research/prime-power-newton-audit/CLAIM.json b/research/prime-power-newton-audit/CLAIM.json new file mode 100644 index 0000000000..9de147d1a9 --- /dev/null +++ b/research/prime-power-newton-audit/CLAIM.json @@ -0,0 +1,35 @@ +{ + "track": "Adversarial mathematical audit", + "assignment_seed": 68, + "randomness": "secrets.randbelow(100), operating-system randomness", + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "source_pr": 621, + "source_head": "520774462b19b29af41554b74def31f9d01e997e", + "scope": "Audit the prime-ideal nonunit lemma by deriving the complete p-adic Newton polygon of the integral q-Pochhammer kernel; no complex conditioning or kappa improvement claim.", + "hypothesis": "Vertices (r-p^k, k*(p-1)*p^(k-1)) give root valuations 1+(k-1)*(p-1)/p with multiplicities (p-1)*p^(k-1), normalized by v(1-u)=1.", + "candidates": [ + { + "task": "Cold-helper lifetime assumption", + "decision": "Not selected: overlaps PR702/712/729." + }, + { + "task": "Fourier inverse transfer for weighted strides", + "decision": "Not selected: overlaps PR692 and rounded PR628." + }, + { + "task": "Prime-power root nonunit lemma via exact Newton polygon", + "decision": "Selected: different proof obligation and valuation method from PR668 CRT resultant and PR666 composite lifting." + } + ], + "method": "Written uniform proof plus independent integer valuation / convex-hull implementations; bounded complete domain prime powers r<=68, with higher-power and primitive-root controls as appropriate. Seed sets upper radix 68.", + "stopping_rule": "One fixed finite domain; reject or narrow the formula if a counterexample appears; no adaptive record search.", + "expected_deliverable": "Research audit note, exact deterministic receipt, standard-library verifier and negative controls.", + "expected_finish": "2026-10-13T13:38:00+08:00", + "coordination": "Open-issue search returned only issue650, no pinned sprint issue; local claim.", + "status": "completed", + "completed_at": "2026-10-13T13:11:33+08:00", + "result": "Uniform exact Newton polygon and p-adic root-valuation formula; no defect found in PR621 nonunit lemma; 28 radices, 697 primitive embeddings, 30224 coefficient obligations, 9 rejecting controls, 8 focused tests. No new kappa.", + "result_url": "https://github.com/FanPUYen/integer-mult-bounds/tree/audit/seed68-cyclic-inverse/research/prime-power-newton-audit", + "overlap_refresh": "Newest 100 open PRs through #757, earlier 200 entries, targeted Newton-polygon/p-adic/valuation searches, and open issues. #736 affects old replay performance only. No overlapping root-valuation audit or pinned sprint issue found.", + "delegation": "Two scoped Codex workers: one proof derivation/review, one independent cyclotomic implementation; no repository-wide delegated investigation." +} diff --git a/research/prime-power-newton-audit/EXPECTED.json b/research/prime-power-newton-audit/EXPECTED.json new file mode 100644 index 0000000000..e64a6a94ba --- /dev/null +++ b/research/prime-power-newton-audit/EXPECTED.json @@ -0,0 +1,3230 @@ +{ + "schema": 1, + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "assignment_seed": 68, + "scope": "Finite coefficient/polygon audit; the separate written proof gives the uniform statement.", + "domain": "Every prime power 2 <= r <= 68 and every primitive exponent 1 <= t < r.", + "radices": 28, + "primitive_embeddings": 697, + "coefficient_obligations": 30224, + "independent_valuation_sha256": "925781d995aa5629eb7859605f9bf3578d2b684bb3994ff5212f2dc54fb31605", + "negative_controls": [ + "unit_constant_changes_root_polygon", + "omitted_ramified_factor", + "mixed_valuation_normalizations", + "reversed_coefficient_order", + "nonunit_leading_coefficient", + "nonprimitive_root", + "composite_base", + "zero_exponent", + "vertices_are_not_all_contacts" + ], + "cases": [ + { + "p": 2, + "a": 1, + "r": 2, + "ramification_index": 1, + "coefficient_valuations": [ + 1, + 0 + ], + "vertices": [ + [ + 0, + 1 + ], + [ + 1, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 1, + "valuation_with_vp_p_1": "1", + "contacts": [ + 0, + 1 + ] + } + ], + "edge_contact_count": 2, + "primitive_powers": [ + 1 + ] + }, + { + "p": 2, + "a": 2, + "r": 4, + "ramification_index": 2, + "coefficient_valuations": [ + 4, + 3, + 1, + 0 + ], + "vertices": [ + [ + 0, + 4 + ], + [ + 2, + 1 + ], + [ + 3, + 0 + ] + ], + "segments": [ + { + "valuation": "3/2", + "multiplicity": 2, + "valuation_with_vp_p_1": "3/4", + "contacts": [ + 0, + 2 + ] + }, + { + "valuation": "1", + "multiplicity": 1, + "valuation_with_vp_p_1": "1/2", + "contacts": [ + 2, + 3 + ] + } + ], + "edge_contact_count": 3, + "primitive_powers": [ + 1, + 3 + ] + }, + { + "p": 2, + "a": 3, + "r": 8, + "ramification_index": 4, + "coefficient_valuations": [ + 12, + 11, + 9, + 8, + 4, + 3, + 1, + 0 + ], + "vertices": [ + [ + 0, + 12 + ], + [ + 4, + 4 + ], + [ + 6, + 1 + ], + [ + 7, + 0 + ] + ], + "segments": [ + { + "valuation": "2", + "multiplicity": 4, + "valuation_with_vp_p_1": "1/2", + "contacts": [ + 0, + 4 + ] + }, + { + "valuation": "3/2", + "multiplicity": 2, + "valuation_with_vp_p_1": "3/8", + "contacts": [ + 4, + 6 + ] + }, + { + "valuation": "1", + "multiplicity": 1, + "valuation_with_vp_p_1": "1/4", + "contacts": [ + 6, + 7 + ] + } + ], + "edge_contact_count": 4, + "primitive_powers": [ + 1, + 3, + 5, + 7 + ] + }, + { + "p": 2, + "a": 4, + "r": 16, + "ramification_index": 8, + "coefficient_valuations": [ + 32, + 31, + 29, + 28, + 24, + 23, + 21, + 20, + 12, + 11, + 9, + 8, + 4, + 3, + 1, + 0 + ], + "vertices": [ + [ + 0, + 32 + ], + [ + 8, + 12 + ], + [ + 12, + 4 + ], + [ + 14, + 1 + ], + [ + 15, + 0 + ] + ], + "segments": [ + { + "valuation": "5/2", + "multiplicity": 8, + "valuation_with_vp_p_1": "5/16", + "contacts": [ + 0, + 8 + ] + }, + { + "valuation": "2", + "multiplicity": 4, + "valuation_with_vp_p_1": "1/4", + "contacts": [ + 8, + 12 + ] + }, + { + "valuation": "3/2", + "multiplicity": 2, + "valuation_with_vp_p_1": "3/16", + "contacts": [ + 12, + 14 + ] + }, + { + "valuation": "1", + "multiplicity": 1, + "valuation_with_vp_p_1": "1/8", + "contacts": [ + 14, + 15 + ] + } + ], + "edge_contact_count": 5, + "primitive_powers": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15 + ] + }, + { + "p": 2, + "a": 5, + "r": 32, + "ramification_index": 16, + "coefficient_valuations": [ + 80, + 79, + 77, + 76, + 72, + 71, + 69, + 68, + 60, + 59, + 57, + 56, + 52, + 51, + 49, + 48, + 32, + 31, + 29, + 28, + 24, + 23, + 21, + 20, + 12, + 11, + 9, + 8, + 4, + 3, + 1, + 0 + ], + "vertices": [ + [ + 0, + 80 + ], + [ + 16, + 32 + ], + [ + 24, + 12 + ], + [ + 28, + 4 + ], + [ + 30, + 1 + ], + [ + 31, + 0 + ] + ], + "segments": [ + { + "valuation": "3", + "multiplicity": 16, + "valuation_with_vp_p_1": "3/16", + "contacts": [ + 0, + 16 + ] + }, + { + "valuation": "5/2", + "multiplicity": 8, + "valuation_with_vp_p_1": "5/32", + "contacts": [ + 16, + 24 + ] + }, + { + "valuation": "2", + "multiplicity": 4, + "valuation_with_vp_p_1": "1/8", + "contacts": [ + 24, + 28 + ] + }, + { + "valuation": "3/2", + "multiplicity": 2, + "valuation_with_vp_p_1": "3/32", + "contacts": [ + 28, + 30 + ] + }, + { + "valuation": "1", + "multiplicity": 1, + "valuation_with_vp_p_1": "1/16", + "contacts": [ + 30, + 31 + ] + } + ], + "edge_contact_count": 6, + "primitive_powers": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31 + ] + }, + { + "p": 2, + "a": 6, + "r": 64, + "ramification_index": 32, + "coefficient_valuations": [ + 192, + 191, + 189, + 188, + 184, + 183, + 181, + 180, + 172, + 171, + 169, + 168, + 164, + 163, + 161, + 160, + 144, + 143, + 141, + 140, + 136, + 135, + 133, + 132, + 124, + 123, + 121, + 120, + 116, + 115, + 113, + 112, + 80, + 79, + 77, + 76, + 72, + 71, + 69, + 68, + 60, + 59, + 57, + 56, + 52, + 51, + 49, + 48, + 32, + 31, + 29, + 28, + 24, + 23, + 21, + 20, + 12, + 11, + 9, + 8, + 4, + 3, + 1, + 0 + ], + "vertices": [ + [ + 0, + 192 + ], + [ + 32, + 80 + ], + [ + 48, + 32 + ], + [ + 56, + 12 + ], + [ + 60, + 4 + ], + [ + 62, + 1 + ], + [ + 63, + 0 + ] + ], + "segments": [ + { + "valuation": "7/2", + "multiplicity": 32, + "valuation_with_vp_p_1": "7/64", + "contacts": [ + 0, + 32 + ] + }, + { + "valuation": "3", + "multiplicity": 16, + "valuation_with_vp_p_1": "3/32", + "contacts": [ + 32, + 48 + ] + }, + { + "valuation": "5/2", + "multiplicity": 8, + "valuation_with_vp_p_1": "5/64", + "contacts": [ + 48, + 56 + ] + }, + { + "valuation": "2", + "multiplicity": 4, + "valuation_with_vp_p_1": "1/16", + "contacts": [ + 56, + 60 + ] + }, + { + "valuation": "3/2", + "multiplicity": 2, + "valuation_with_vp_p_1": "3/64", + "contacts": [ + 60, + 62 + ] + }, + { + "valuation": "1", + "multiplicity": 1, + "valuation_with_vp_p_1": "1/32", + "contacts": [ + 62, + 63 + ] + } + ], + "edge_contact_count": 7, + "primitive_powers": [ + 1, + 3, + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19, + 21, + 23, + 25, + 27, + 29, + 31, + 33, + 35, + 37, + 39, + 41, + 43, + 45, + 47, + 49, + 51, + 53, + 55, + 57, + 59, + 61, + 63 + ] + }, + { + "p": 3, + "a": 1, + "r": 3, + "ramification_index": 2, + "coefficient_valuations": [ + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 2 + ], + [ + 2, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 2, + "valuation_with_vp_p_1": "1/2", + "contacts": [ + 0, + 1, + 2 + ] + } + ], + "edge_contact_count": 3, + "primitive_powers": [ + 1, + 2 + ] + }, + { + "p": 3, + "a": 2, + "r": 9, + "ramification_index": 6, + "coefficient_valuations": [ + 12, + 11, + 10, + 7, + 6, + 5, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 12 + ], + [ + 6, + 2 + ], + [ + 8, + 0 + ] + ], + "segments": [ + { + "valuation": "5/3", + "multiplicity": 6, + "valuation_with_vp_p_1": "5/18", + "contacts": [ + 0, + 3, + 6 + ] + }, + { + "valuation": "1", + "multiplicity": 2, + "valuation_with_vp_p_1": "1/6", + "contacts": [ + 6, + 7, + 8 + ] + } + ], + "edge_contact_count": 5, + "primitive_powers": [ + 1, + 2, + 4, + 5, + 7, + 8 + ] + }, + { + "p": 3, + "a": 3, + "r": 27, + "ramification_index": 18, + "coefficient_valuations": [ + 54, + 53, + 52, + 49, + 48, + 47, + 44, + 43, + 42, + 33, + 32, + 31, + 28, + 27, + 26, + 23, + 22, + 21, + 12, + 11, + 10, + 7, + 6, + 5, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 54 + ], + [ + 18, + 12 + ], + [ + 24, + 2 + ], + [ + 26, + 0 + ] + ], + "segments": [ + { + "valuation": "7/3", + "multiplicity": 18, + "valuation_with_vp_p_1": "7/54", + "contacts": [ + 0, + 9, + 18 + ] + }, + { + "valuation": "5/3", + "multiplicity": 6, + "valuation_with_vp_p_1": "5/54", + "contacts": [ + 18, + 21, + 24 + ] + }, + { + "valuation": "1", + "multiplicity": 2, + "valuation_with_vp_p_1": "1/18", + "contacts": [ + 24, + 25, + 26 + ] + } + ], + "edge_contact_count": 7, + "primitive_powers": [ + 1, + 2, + 4, + 5, + 7, + 8, + 10, + 11, + 13, + 14, + 16, + 17, + 19, + 20, + 22, + 23, + 25, + 26 + ] + }, + { + "p": 5, + "a": 1, + "r": 5, + "ramification_index": 4, + "coefficient_valuations": [ + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 4 + ], + [ + 4, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 4, + "valuation_with_vp_p_1": "1/4", + "contacts": [ + 0, + 1, + 2, + 3, + 4 + ] + } + ], + "edge_contact_count": 5, + "primitive_powers": [ + 1, + 2, + 3, + 4 + ] + }, + { + "p": 5, + "a": 2, + "r": 25, + "ramification_index": 20, + "coefficient_valuations": [ + 40, + 39, + 38, + 37, + 36, + 31, + 30, + 29, + 28, + 27, + 22, + 21, + 20, + 19, + 18, + 13, + 12, + 11, + 10, + 9, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 40 + ], + [ + 20, + 4 + ], + [ + 24, + 0 + ] + ], + "segments": [ + { + "valuation": "9/5", + "multiplicity": 20, + "valuation_with_vp_p_1": "9/100", + "contacts": [ + 0, + 5, + 10, + 15, + 20 + ] + }, + { + "valuation": "1", + "multiplicity": 4, + "valuation_with_vp_p_1": "1/20", + "contacts": [ + 20, + 21, + 22, + 23, + 24 + ] + } + ], + "edge_contact_count": 9, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 11, + 12, + 13, + 14, + 16, + 17, + 18, + 19, + 21, + 22, + 23, + 24 + ] + }, + { + "p": 7, + "a": 1, + "r": 7, + "ramification_index": 6, + "coefficient_valuations": [ + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 6 + ], + [ + 6, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 6, + "valuation_with_vp_p_1": "1/6", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ] + } + ], + "edge_contact_count": 7, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6 + ] + }, + { + "p": 7, + "a": 2, + "r": 49, + "ramification_index": 42, + "coefficient_valuations": [ + 84, + 83, + 82, + 81, + 80, + 79, + 78, + 71, + 70, + 69, + 68, + 67, + 66, + 65, + 58, + 57, + 56, + 55, + 54, + 53, + 52, + 45, + 44, + 43, + 42, + 41, + 40, + 39, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 84 + ], + [ + 42, + 6 + ], + [ + 48, + 0 + ] + ], + "segments": [ + { + "valuation": "13/7", + "multiplicity": 42, + "valuation_with_vp_p_1": "13/294", + "contacts": [ + 0, + 7, + 14, + 21, + 28, + 35, + 42 + ] + }, + { + "valuation": "1", + "multiplicity": 6, + "valuation_with_vp_p_1": "1/42", + "contacts": [ + 42, + 43, + 44, + 45, + 46, + 47, + 48 + ] + } + ], + "edge_contact_count": 13, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 9, + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 22, + 23, + 24, + 25, + 26, + 27, + 29, + 30, + 31, + 32, + 33, + 34, + 36, + 37, + 38, + 39, + 40, + 41, + 43, + 44, + 45, + 46, + 47, + 48 + ] + }, + { + "p": 11, + "a": 1, + "r": 11, + "ramification_index": 10, + "coefficient_valuations": [ + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 10 + ], + [ + 10, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 10, + "valuation_with_vp_p_1": "1/10", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ] + } + ], + "edge_contact_count": 11, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ] + }, + { + "p": 13, + "a": 1, + "r": 13, + "ramification_index": 12, + "coefficient_valuations": [ + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 12 + ], + [ + 12, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 12, + "valuation_with_vp_p_1": "1/12", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ] + } + ], + "edge_contact_count": 13, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ] + }, + { + "p": 17, + "a": 1, + "r": 17, + "ramification_index": 16, + "coefficient_valuations": [ + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 16 + ], + [ + 16, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 16, + "valuation_with_vp_p_1": "1/16", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ] + } + ], + "edge_contact_count": 17, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ] + }, + { + "p": 19, + "a": 1, + "r": 19, + "ramification_index": 18, + "coefficient_valuations": [ + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 18 + ], + [ + 18, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 18, + "valuation_with_vp_p_1": "1/18", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18 + ] + } + ], + "edge_contact_count": 19, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18 + ] + }, + { + "p": 23, + "a": 1, + "r": 23, + "ramification_index": 22, + "coefficient_valuations": [ + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 22 + ], + [ + 22, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 22, + "valuation_with_vp_p_1": "1/22", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22 + ] + } + ], + "edge_contact_count": 23, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22 + ] + }, + { + "p": 29, + "a": 1, + "r": 29, + "ramification_index": 28, + "coefficient_valuations": [ + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 28 + ], + [ + 28, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 28, + "valuation_with_vp_p_1": "1/28", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28 + ] + } + ], + "edge_contact_count": 29, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28 + ] + }, + { + "p": 31, + "a": 1, + "r": 31, + "ramification_index": 30, + "coefficient_valuations": [ + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 30 + ], + [ + 30, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 30, + "valuation_with_vp_p_1": "1/30", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ] + } + ], + "edge_contact_count": 31, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ] + }, + { + "p": 37, + "a": 1, + "r": 37, + "ramification_index": 36, + "coefficient_valuations": [ + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 36 + ], + [ + 36, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 36, + "valuation_with_vp_p_1": "1/36", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36 + ] + } + ], + "edge_contact_count": 37, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36 + ] + }, + { + "p": 41, + "a": 1, + "r": 41, + "ramification_index": 40, + "coefficient_valuations": [ + 40, + 39, + 38, + 37, + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 40 + ], + [ + 40, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 40, + "valuation_with_vp_p_1": "1/40", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40 + ] + } + ], + "edge_contact_count": 41, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40 + ] + }, + { + "p": 43, + "a": 1, + "r": 43, + "ramification_index": 42, + "coefficient_valuations": [ + 42, + 41, + 40, + 39, + 38, + 37, + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 42 + ], + [ + 42, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 42, + "valuation_with_vp_p_1": "1/42", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42 + ] + } + ], + "edge_contact_count": 43, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42 + ] + }, + { + "p": 47, + "a": 1, + "r": 47, + "ramification_index": 46, + "coefficient_valuations": [ + 46, + 45, + 44, + 43, + 42, + 41, + 40, + 39, + 38, + 37, + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 46 + ], + [ + 46, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 46, + "valuation_with_vp_p_1": "1/46", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46 + ] + } + ], + "edge_contact_count": 47, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46 + ] + }, + { + "p": 53, + "a": 1, + "r": 53, + "ramification_index": 52, + "coefficient_valuations": [ + 52, + 51, + 50, + 49, + 48, + 47, + 46, + 45, + 44, + 43, + 42, + 41, + 40, + 39, + 38, + 37, + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 52 + ], + [ + 52, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 52, + "valuation_with_vp_p_1": "1/52", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ] + } + ], + "edge_contact_count": 53, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52 + ] + }, + { + "p": 59, + "a": 1, + "r": 59, + "ramification_index": 58, + "coefficient_valuations": [ + 58, + 57, + 56, + 55, + 54, + 53, + 52, + 51, + 50, + 49, + 48, + 47, + 46, + 45, + 44, + 43, + 42, + 41, + 40, + 39, + 38, + 37, + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 58 + ], + [ + 58, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 58, + "valuation_with_vp_p_1": "1/58", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58 + ] + } + ], + "edge_contact_count": 59, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58 + ] + }, + { + "p": 61, + "a": 1, + "r": 61, + "ramification_index": 60, + "coefficient_valuations": [ + 60, + 59, + 58, + 57, + 56, + 55, + 54, + 53, + 52, + 51, + 50, + 49, + 48, + 47, + 46, + 45, + 44, + 43, + 42, + 41, + 40, + 39, + 38, + 37, + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 60 + ], + [ + 60, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 60, + "valuation_with_vp_p_1": "1/60", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60 + ] + } + ], + "edge_contact_count": 61, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60 + ] + }, + { + "p": 67, + "a": 1, + "r": 67, + "ramification_index": 66, + "coefficient_valuations": [ + 66, + 65, + 64, + 63, + 62, + 61, + 60, + 59, + 58, + 57, + 56, + 55, + 54, + 53, + 52, + 51, + 50, + 49, + 48, + 47, + 46, + 45, + 44, + 43, + 42, + 41, + 40, + 39, + 38, + 37, + 36, + 35, + 34, + 33, + 32, + 31, + 30, + 29, + 28, + 27, + 26, + 25, + 24, + 23, + 22, + 21, + 20, + 19, + 18, + 17, + 16, + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + ], + "vertices": [ + [ + 0, + 66 + ], + [ + 66, + 0 + ] + ], + "segments": [ + { + "valuation": "1", + "multiplicity": 66, + "valuation_with_vp_p_1": "1/66", + "contacts": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66 + ] + } + ], + "edge_contact_count": 67, + "primitive_powers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66 + ] + } + ] +} diff --git a/research/prime-power-newton-audit/NOTICE.md b/research/prime-power-newton-audit/NOTICE.md new file mode 100644 index 0000000000..15935a4e01 --- /dev/null +++ b/research/prime-power-newton-audit/NOTICE.md @@ -0,0 +1,31 @@ +# Attribution, license, and assistance + +Prepared for Hao Yan (@FanPUYen), with substantial OpenAI Codex assistance +in research selection, proof derivation, implementation, verification, and +writing. Separate Codex agents derived the valuation proof and implemented +the cyclotomic arithmetic; further review is recorded in VALIDATION.md. +Independent implementations do not imply independent human peer review. + +Ali Romman's incorporated PR621, at +`520774462b19b29af41554b74def31f9d01e997e`, supplies the integral kernel, +prime-ideal nonunit lemma, and complex-conditioning context being audited. +Its upstream and classical credits remain: OpenAI's exact-DFT preprint at +`adc7f1241b42e322a6451854ab7e4b4c146bf78a`, sections `loc:newton` and +`loc:fourier-factorization`, and Alexey Kuznetsov's classical q-calculus +Vandermonde factorization work. No predecessor code is copied or imported. +PR621's source-specific notice remains in place and is source-pinned here. + +The Newton polygon theorem and cyclotomic ramification facts are standard; +J. S. Milne and Keith Conrad references are recorded in SOURCE.json. This +package claims no literature priority for the derived specialized formula. +Scott Woolsey Biggart's PR668 CRT-resultant checks, Jason Willems's PR666 +composite lifting, Chafik Boukhalfa's PR628 rounded inversion, and Ryan +Pinto's PR692 weighted-stride audit provide related, distinct evidence. +Their pending changes are not imported or certified by this package. + +The selected frontier remains Chafik Boukhalfa's PR626 on Jeremy Kothe's +PR622/623 with eumemic's PR543 and their cumulative predecessor work. The +selected construction is context, not the object of this narrow audit. + +New code and prose use the repository's Apache-2.0 license. This is not a +formal proof or an independent human verification of integer multiplication. diff --git a/research/prime-power-newton-audit/PROOF.md b/research/prime-power-newton-audit/PROOF.md new file mode 100644 index 0000000000..211610353e --- /dev/null +++ b/research/prime-power-newton-audit/PROOF.md @@ -0,0 +1,144 @@ +# The coefficient polygon and all root valuations + +The object under audit is the “Integral polynomial and unit roots” section +of Ali Romman's PR621, source head +`520774462b19b29af41554b74def31f9d01e997e`. Keep its notation + + r = p^a, n = r-1, + f(z) = r P(z) = sum_(j=0)^n a_j z^j, + a_j = product_(s=j+1)^n (1-u^s), + +where p is prime, a >= 1, and u is a primitive r-th root. We include r=2, +which PR621 treats separately. The leading coefficient is one and a_0=r. +We prove a more precise version of its nonunit statement. This is a written +proof, not a proof-assistant formalization. + +## Valuation and coefficient identity + +Work in the complete field K = Q_p(u). Let pi=1-u. The polynomial +Phi_(p^a)(1-X), up to its leading sign, is Eisenstein at p: its constant +coefficient is p, and modulo p it is a unit times X^e, where + + e = phi(r) = (p-1)p^(a-1). + +Thus pi is a uniformizer and v(pi)=1 implies v(p)=e. Extend this valuation +to an algebraic closure without renormalizing it. This standard total +ramification fact is also recorded in Keith Conrad's +[Kummer's Lemma, p. 8](https://kconrad.math.uconn.edu/blurbs/gradnumthy/kummer.pdf). + +For 1 <= s < r, write s=p^h t with p not dividing t. Then + + v(1-u^s) = p^h. + +Here is a direct justification. For every b prime to p, the quotient +(1-u^b)/(1-u) is a unit: its residue is b modulo pi. For h=1. Counting the integers divisible +by each power of p gives A(p^k)=H_k. More generally, for +p^(k-1) <= m <= p^k, + + A(m) = (m-1) + (p-1) sum_(h=1)^(k-1) p^(h-1) floor((m-1)/p^h). + +Use floor((m-1)/p^h) >= m/p^h - 1 in every summand. Then + + A(m) >= lambda_k m - p^(k-1), + lambda_k = 1 + (k-1)(p-1)/p. (2) + +The line in (2) joins (p^(k-1),H_(k-1)) to (p^k,H_k). All weights in the +floor sum are positive. Equality holds exactly when p^(k-1) divides m; +for k=1 the empty sum makes every integer m in the interval an equality. + +Consequently, in the ascending coefficient coordinates (j,v(a_j)), the +lower convex hull has exactly the vertices + + (r-p^k, H_k), k=a,a-1,...,0. (3) + +Its slopes, read left to right, are -lambda_a,...,-lambda_1, which strictly +increase. Equation (2) places every other coefficient on or above the +corresponding segment, so none can create a lower vertex. For odd p there +are additional collinear coefficient points: on segment k these have +r-j = t p^(k-1), with t=1,...,p. They are contacts, not additional vertices. + +## Root multiset and the audited implication + +The Newton polygon theorem now gives, for each k=1,...,a, + + root valuation lambda_k = 1 + (k-1)(p-1)/p, + multiplicity p^k-p^(k-1) = (p-1)p^(k-1). (4) + +See J. S. Milne, [Algebraic Number Theory, Proposition 7.44](https://www.jmilne.org/math/CourseNotes/ANTc.pdf), +printed p. 125. Milne orders coefficients from leading to constant, whereas +(3) orders them from constant to leading; this reverses the slope sign. +Roots are counted with multiplicity. Two useful checks on (4) are + + sum_(k=1)^a (p-1)p^(k-1) = r-1, + sum_(k=1)^a lambda_k (p-1)p^(k-1) = a phi(r) = v(a_0). + +Every lambda_k is positive. Since f is monic with algebraic integer +coefficients, all its roots are algebraic integers. Each has positive +valuation at a prime above p, so its inverse is not integral there and +it is not an algebraic unit. This confirms PR621's nonunit lemma. + +For global roots, choose a prime of a splitting field above p to assign +individual valuations. The multiset is unchanged; individual assignments +need not be canonical. Under the convention v_p(p)=1, (4) is divided by e. +For example r=8 has valuations 2 (four roots), 3/2 (two), and 1 (one) +in the pi convention; its conventional values are 1/2, 3/8, and 1/4. + +PR621 further excludes complex unit-circle roots because a complex +algebraic integer of modulus one has an integral inverse (its complex +conjugate), hence is a unit. Our audit confirms that implication. Positive +p-adic valuation alone is not a claim about a root's complex modulus. +We do not improve PR621's quantitative complex-circle or operator bound. + +## Independent coefficient reconstruction + +The second arithmetic implementation constructs a_j in Z[u]/(u^r-1) +by sparse polynomial multiplication, reduces modulo Phi_r(u), and makes +the exact integer basis substitution u=1-pi. Its result is + + a_j = sum_(i=0)^(e-1) c_i pi^i, c_i in Z. + +The nonzero summands have valuations e v_p(c_i)+i, which have distinct +residues modulo e. Therefore their minimum is unique and + + v(a_j) = min_(c_i != 0) [e v_p(c_i)+i]. (5) + +This method does not sum individual factor valuations or use (1) or (2). +It checks every coefficient of every primitive embedding in the finite +r<=68 domain against (1), and a convex-hull algorithm checks (3), (4), and +the full equality locus in (2). Exact Eisenstein and small dense-polynomial +checks test the independent engine's algebraic assumptions and reduction. +Finite replay tests these implementations; the preceding argument supplies +the uniform proof. + +## Scope and attribution + +This is a scoped strengthening and audit of an incorporated lemma, with no +counterexample to the accepted result. A modified constant a_0=r+1 is a +unit and produces the horizontal polygon: that negative control explains +why the original tail-product hypothesis cannot simply be omitted. + +Credit Ali Romman for the kernel-conditioning and nonunit argument, OpenAI +and the classical q-Pochhammer/Newton sources for the kernel, and the +standard cyclotomic and Newton-polygon theorems cited above. No literature +priority claim is made. This supplies no paid inverse or supplier, improved +κ, common-label realization, all-size compiler, precision/tape schedule, or +complete multiplication theorem. See NOTICE.md for assistance disclosure. diff --git a/research/prime-power-newton-audit/README.md b/research/prime-power-newton-audit/README.md new file mode 100644 index 0000000000..0161f7e08f --- /dev/null +++ b/research/prime-power-newton-audit/README.md @@ -0,0 +1,67 @@ +# Exact Newton polygon audit of the prime-power nonunit lemma + +This **mathematical audit / research note** corroborates the nonunit-root +lemma in Ali Romman's incorporated [PR621](https://github.com/CrocSwap/integer-mult-bounds/pull/621) +and gives the complete p-adic root-valuation multiset for its kernel. No defect +was found in that lemma. The result does not change the selected exponent, +complex conditioning bound, supplier, or inverse implementation. + +For a prime power `r = p^a`, normalize the valuation by `v(1-u) = 1`, where +`u` is any primitive r-th root. For each `k = 1,...,a`, the integral kernel +has exactly + + (p-1) p^(k-1) roots of valuation 1 + (k-1)(p-1)/p, + +counting multiplicity. These positive valuations imply that every root is +an algebraic nonunit. With the alternative convention `v_p(p)=1`, divide +all displayed valuations by `phi(r)`. These are **p-adic valuations**, not +complex absolute values. They do not distinguish roots inside and outside +the complex unit circle. + +The [written proof](PROOF.md) establishes the all-prime-power statement. +The finite checker tests its coefficient, polygon, normalization, and +multiplicity obligations using two different implementations: factor-valuation +counting and exact cyclotomic polynomial multiplication followed by a +uniformizer-basis change. Neither imports PR621's verifier. + +```sh +python3 -I -O -B research/prime-power-newton-audit/verify.py +python3 -I -B research/prime-power-newton-audit/test_verify.py +``` + +Python 3.9+; standard library only. The first command checks the source pins +and complete frozen receipt. Expected: + + PASS_NEWTON_NONUNIT_AUDIT: 28 radices; 697 primitive embeddings; 30224 coefficient obligations; 9 negative controls + +The fixed finite domain is every prime power `2 <= r <= 68` and every +primitive exponent `1 <= t < r`. The OS assignment seed 68 selected the +upper endpoint. This is a completed exhaustive finite audit, not a search +for better κ. The explicit controls include a unit constant, an omitted +ramified factor, mixed valuation normalizations, reversed coefficients, +a nonunit leading coefficient, invalid field/root inputs, and lost +collinear contacts. A unit-constant mutation really changes the polygon +to a horizontal edge: it is a counterexample to dropping the original +coefficient hypothesis, not to PR621. + +To regenerate a separate receipt: + +```sh +python3 -I -O -B research/prime-power-newton-audit/verify.py --write-receipt /tmp/newton-audit.json +cmp research/prime-power-newton-audit/EXPECTED.json /tmp/newton-audit.json +``` + +[CLAIM.json](CLAIM.json) records track selection, three candidate tasks, +coordination, and the stopping rule. [SOURCE.json](SOURCE.json) pins the +base `66849e1475c930fd7732b1a0067ffee7e1e95f60`, PR621 source head, exact +contextual files, and mathematical references. [VALIDATION.md](VALIDATION.md) +records executed checks and limitations. [NOTICE.md](NOTICE.md) preserves +attribution and substantial AI assistance disclosure. + +The existing PR668 CRT audit checks resultants, Bezout identities, and norms; +PR666 studies composite-radix lifting; PR628 and PR692 study rounded inverses +and weighted cyclic closures. This package instead determines every root's +nonarchimedean valuation for prime powers. It does not import or certify those +pending changes, claim literature priority, or replace the accepted PR621 +circle-bound proof. No paid preparation, rounding/restoration, tape/compiler, +precision, all-size supplier, or analytic multiplication obligation is discharged. diff --git a/research/prime-power-newton-audit/SOURCE.json b/research/prime-power-newton-audit/SOURCE.json new file mode 100644 index 0000000000..375eb2d730 --- /dev/null +++ b/research/prime-power-newton-audit/SOURCE.json @@ -0,0 +1,42 @@ +{ + "base_commit": "66849e1475c930fd7732b1a0067ffee7e1e95f60", + "audited_pr": 621, + "audited_head": "520774462b19b29af41554b74def31f9d01e997e", + "audited_statement": "Integral polynomial and unit roots, research/prime-power-cyclic-inverse/PROOF.md", + "inherited_kernel_source": { + "repository": "openai/math", + "commit": "adc7f1241b42e322a6451854ab7e4b4c146bf78a", + "path": "preprints/An-explicit-power-saving-for-the-exact-discrete-Fourier-transform-September-25-2026/build/sections/local.tex", + "git_blob": "260a19bd8f7189afbe89b0af0508d979cd1e1ca6", + "sha256": "616e2707aabf2f7591a687331d4cb0f2fa486f92c3f7fe96a133b90faff60561", + "anchor": "loc:newton; loc:fourier-factorization", + "reused_scope": "Kernel definition only. No external code is imported or run." + }, + "sha256": { + "research/prime-power-cyclic-inverse/PROOF.md": "2b8056c88e66f692f407450fff0414d41bcd09db8597be22e274a6c3dc20eb9e", + "research/prime-power-cyclic-inverse/SOURCE.json": "81217e4ecbb1da767d6a23f043d66e69d53c9001c056176efc641ddadea275f2", + "research/prime-power-cyclic-inverse/NOTICE.md": "96111c95cfec3c03a6f69c8e02c5d0bceff957d187e638d0534c676d6e3ffd77", + "certificates/selected-result.json": "b3bf402f31a69bde0629936a9b569bed48281568d7b16d5fba120b5311ea1f53", + "docs/research/community-k492-review.md": "3b731d30e80010b15408a289b0b32192700885474c8b36d48ee3320a7a8c5c47", + "research/complex-k492-owner-repair/PROOF-NOTE.md": "337d70fe7abd9afca1d90954c23bde87f4dc27888cc1a6b4bb80506fd6fbf8c5" + }, + "arithmetic_dependencies": "Python standard library only. No predecessor verifier is imported.", + "mathematical_dependencies": [ + "Cyclotomic prime-power total ramification / Eisenstein polynomial Phi_(p^a)(1-X).", + "Newton polygon theorem: root valuations are negative edge slopes with horizontal-length multiplicities." + ], + "references": [ + { + "author": "J. S. Milne", + "title": "Algebraic Number Theory", + "url": "https://www.jmilne.org/math/CourseNotes/ANTc.pdf", + "anchor": "Proposition 7.44, printed page 125; uses descending coefficient order, opposite to this package." + }, + { + "author": "Keith Conrad", + "title": "Kummer\u2019s Lemma", + "url": "https://kconrad.math.uconn.edu/blurbs/gradnumthy/kummer.pdf", + "anchor": "Page 8, total ramification of p in Q(zeta_(p^a))." + } + ] +} diff --git a/research/prime-power-newton-audit/VALIDATION.md b/research/prime-power-newton-audit/VALIDATION.md new file mode 100644 index 0000000000..a8b3f4c8df --- /dev/null +++ b/research/prime-power-newton-audit/VALIDATION.md @@ -0,0 +1,57 @@ +# Local validation and review scope + +Executed on 2026-10-13, macOS arm64 (Darwin 25.5.0), CPython 3.9.6. +Base: `66849e1475c930fd7732b1a0067ffee7e1e95f60`. +Only `research/prime-power-newton-audit/` is added. + +- The complete frozen replay passes under `python3 -I -O -B`: 28 prime-power + radices, all 697 primitive embeddings, 30,224 independently reconstructed + coefficient valuations, all polygon edges and contacts, degree/product + identities, both valuation normalizations, and nine rejecting controls. +- Eight focused tests pass under isolated optimized Python. They check all + domain Eisenstein polynomials; a separate dense multiplication/long-division + reference on small fields; literal radix-four coefficients; signed and + periodic primitive exponents; strict malformed-input rejection; odd-prime + collinear contacts; receipt numeric-type distinctions; and relocated + source-pin verification with actual corrupted-source rejection. +- A minimal export containing this package and only its six pinned context + files passes the full replay without Git, network, or installed packages. + Changing its frozen coefficient-obligation count causes a nonzero exit with + `frozen receipt mismatch` under `-I -O -B`. +- The unchanged PR621 primary verifier was freshly executed with `-I -O -B`. + Its output is byte-identical to + `research/prime-power-cyclic-inverse/EXPECTED.json`. +- `python3 -B scripts/verify_selected_result.py` passes, including exact κ, + original source inventory, and proof-supplement checks. The selected record + and `upstream/` have no diff from the base. + +A separate Codex agent first derived the complete floor inequality and +valuation formula independently, then reviewed the final proof and both +implementations. No actionable correctness finding was reported. Review +covered slope signs, multiplicities, equality cases, π versus p normalization, +cyclic-ring reduction, basis substitution, primitive exponents, and controls. +The reviewer also replayed the frozen receipt and checked the radix-two sign, +basis-change involution, constant/leading coefficients, and malformed inputs. +This is AI-assisted review, not independent human peer review or formalization. + +The contribution is additive research: no existing generator, supplier, +certificate, or selected construction changes. The repository-wide `make +verify`, selected cold replay `make frontier626-verify`, optional SymPy engine, +Lean, Linux execution, and remote CI were not run or claimed for this package. +The affected arithmetic and source-binding checks above were run directly; +no unrelated artifacts were globally regenerated. + +The finite domain is fixed by assignment seed 68. No early-success stopping, +adaptive extra search, or empirical impossibility claim is involved. The +all-prime-power conclusion relies on the written proof and the standard +Eisenstein and Newton-polygon theorems, not on extrapolating the receipt. +Paid preparation, restoration, source access, physical hosting, compilation, +precision, tape, and analytic multiplication assumptions remain untouched. + +Overlap inspection read the review ledger and the first 200 open-PR entries +at orientation, then refreshed the newest 100 through PR757. Targeted searches +for “Newton polygon”, “p-adic”, and “valuation” found no competing package +with this scope. No open sprint issue was found (only issue650). Related +PR666/668/628/692 are credited in NOTICE.md; PR736 changes the old replay's +zero-row-update performance, not the root-valuation obligation audited here. +This is a scoped queue check, not a claim of exhaustive literature novelty. diff --git a/research/prime-power-newton-audit/cyclotomic.py b/research/prime-power-newton-audit/cyclotomic.py new file mode 100644 index 0000000000..9bfc0339af --- /dev/null +++ b/research/prime-power-newton-audit/cyclotomic.py @@ -0,0 +1,124 @@ +"""Recover tail valuations from exact cyclotomic-ring coefficients. + +For r = p**a and gcd(t, r) = 1, entry j is + + a_j = product(1 - u**(t*s) for s in range(j + 1, r)), + +where u is a primitive r-th root. This module does not use a formula for +the valuation of an individual factor or sum factor valuations. It builds +the products in Z[u]/(u**r - 1), reduces modulo Phi_r, and changes basis to +pi = 1 - u. All coefficient calculations use Python integers. + +The mathematical input is that Phi_{p**a}(1 - X) is Eisenstein at p (up to +its leading sign). Thus pi is a uniformizer in the p-adic cyclotomic field, +and v(p) = e = phi(r) for the normalization v(pi) = 1. For a reduced +coefficient expansion sum(c_i*pi**i), the nonzero summands have valuations +e*v_p(c_i) + i with distinct residues modulo e. The minimum is unique, so +the ultrametric inequality is an equality there. This theorem, rather than +finite enumeration, justifies the valuation extraction. +""" + +from math import comb, isqrt + + +def _prime_power(p: int, a: int) -> tuple[int, int, int]: + """Validate the parameters and return (r, r/p, phi(r)).""" + if isinstance(p, bool) or not isinstance(p, int): + raise TypeError("p must be an integer prime") + if p < 2 or any(p % d == 0 for d in range(2, isqrt(p) + 1)): + raise ValueError("p must be prime") + if isinstance(a, bool) or not isinstance(a, int): + raise TypeError("a must be a positive integer") + if a < 1: + raise ValueError("a must be positive") + q = p ** (a - 1) + return p * q, q, (p - 1) * q + + +def _primitive_exponent(t: int, p: int, r: int) -> int: + if isinstance(t, bool) or not isinstance(t, int): + raise TypeError("t must be an integer primitive exponent") + if t % p == 0: + raise ValueError("t must be coprime to p**a") + return t % r + + +def _one_minus_variable(coefficients: tuple[int, ...]) -> tuple[int, ...]: + """Return exact coefficients of f(1-X), in ascending degree order.""" + return tuple( + (-1) ** i + * sum(comb(k, i) * coefficients[k] for k in range(i, len(coefficients))) + for i in range(len(coefficients)) + ) + + +def cyclotomic_pi_polynomial(p: int, a: int) -> tuple[int, ...]: + """Return coefficients of Phi_{p**a}(1-X), including its leading term. + + Coefficients are in ascending degree order. The polynomial is kept + with its actual leading sign, which is -1 when p**a = 2. + """ + _, q, e = _prime_power(p, a) + coefficients = tuple(int(i % q == 0) for i in range(e + 1)) + return _one_minus_variable(coefficients) + + +def tail_coefficients(p: int, a: int, t: int, *, basis: str = "pi") -> list[tuple[int, ...]]: + """Return a_j for j=0,...,r-1 in the u or pi=1-u power basis. + + Each tuple has e=phi(r) entries in ascending degree order, including + trailing zeros. The empty tail a_{r-1} is 1. Any integer t coprime to + p is accepted; exponents are normalized modulo r. The algorithm works + for prime powers beyond the audit range, but no performance bound is + promised for large inputs. + """ + r, q, e = _prime_power(p, a) + t = _primitive_exponent(t, p, r) + if basis not in ("u", "pi"): + raise ValueError("basis must be 'u' or 'pi'") + + # A cyclic vector represents a polynomial modulo u**r - 1. Since + # Phi_r divides u**r - 1, this intermediate quotient preserves the + # subsequent reduction modulo Phi_r. + cyclic = [1] + [0] * (r - 1) + tails: list[tuple[int, ...]] = [()] * r + for j in range(r - 1, -1, -1): + if j < r - 1: + shift = (t * (j + 1)) % r + cyclic = [cyclic[k] - cyclic[(k - shift) % r] for k in range(r)] + + # Phi_r(u) = sum(u**(k*q) for k=0,...,p-1). Eliminating + # u**(e+h), 0<=h int: + """Return v_p(value) for a nonzero integer.""" + if value == 0: + raise ValueError("zero has no finite integer p-adic valuation") + value = abs(value) + valuation = 0 + while value % p == 0: + value //= p + valuation += 1 + return valuation + + +def tail_valuations(p: int, a: int, t: int) -> list[int]: + """Return v(a_j), j=0,...,p**a-1, normalized by v(1-u)=1. + + Recover each valuation directly from its exact reduced pi-basis + coefficients. A primitive exponent makes every tail nonzero. + """ + _, _, e = _prime_power(p, a) + result = [] + for coefficients in tail_coefficients(p, a, t): + weights = [e * _integer_p_valuation(c, p) + i + for i, c in enumerate(coefficients) if c != 0] + if not weights: + raise ArithmeticError("a primitive tail unexpectedly reduced to zero") + result.append(min(weights)) + return result diff --git a/research/prime-power-newton-audit/test_verify.py b/research/prime-power-newton-audit/test_verify.py new file mode 100644 index 0000000000..650515693e --- /dev/null +++ b/research/prime-power-newton-audit/test_verify.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +"""Obligation tests for the exact coefficient and Newton-polygon audit.""" +import importlib.util +import json +from pathlib import Path +import shutil +import tempfile +import unittest + +HERE = Path(__file__).resolve().parent +spec = importlib.util.spec_from_file_location('newton_audit', HERE / 'verify.py') +audit = importlib.util.module_from_spec(spec) +spec.loader.exec_module(audit) +c = audit.cyclotomic + + +def dense_remainder(poly, divisor): + poly = list(poly) + while len(poly) >= len(divisor): + shift = len(poly) - len(divisor) + scale = poly[-1] # divisor is monic + for j, value in enumerate(divisor): + poly[j + shift] -= scale * value + poly.pop() + return tuple(poly + [0] * (len(divisor) - 1 - len(poly))) + + +def dense_tail_coefficients(p, a, t): + r, q = p ** a, p ** (a - 1) + divisor = [int(i % q == 0) for i in range((p - 1) * q + 1)] + result = [] + # Deliberately rebuild each product, with ordinary polynomial multiplication + # and monic long division; no cyclic shifts or cyclotomic shortcut. + for j in range(r): + poly = (1,) + for s in range(j + 1, r): + factor = [0] * (t * s + 1) + factor[0], factor[-1] = 1, -1 + product = [0] * (len(poly) + len(factor) - 1) + for x, u in enumerate(poly): + for y, v in enumerate(factor): + product[x + y] += u * v + poly = dense_remainder(product, divisor) + result.append(dense_remainder(poly, divisor)) + return result + + +class Obligations(unittest.TestCase): + def test_all_domain_eisenstein(self): + for p, a, r in audit.domain(): + poly = c.cyclotomic_pi_polynomial(p, a) + self.assertEqual(len(poly), (p - 1) * p ** (a - 1) + 1) + self.assertEqual(poly[0], p) + self.assertEqual(abs(poly[-1]), 1) + self.assertTrue(all(x % p == 0 for x in poly[:-1])) + self.assertNotEqual(poly[0] % (p * p), 0) + + def test_dense_polynomial_reference(self): + for p, a in [(2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (5, 1)]: + r = p ** a + for t in range(1, r): + if t % p: + self.assertEqual(c.tail_coefficients(p, a, t, basis='u'), dense_tail_coefficients(p, a, t)) + + def test_radix_four_literal_coefficients(self): + # u=i, pi=1-i: [4,2+2i,1+i,1] in the u basis. + self.assertEqual(c.tail_coefficients(2, 2, 1, basis='u'), [(4, 0), (2, 2), (1, 1), (1, 0)]) + self.assertEqual(c.tail_coefficients(2, 2, 1), [(4, 0), (4, -2), (2, -1), (1, 0)]) + self.assertEqual(c.tail_valuations(2, 2, 1), [4, 3, 1, 0]) + + def test_signed_primitive_choices(self): + for p, a in [(2, 3), (3, 2), (5, 1)]: + r = p ** a + self.assertEqual(c.tail_coefficients(p, a, -1), c.tail_coefficients(p, a, r - 1)) + self.assertEqual(c.tail_coefficients(p, a, r + 1), c.tail_coefficients(p, a, 1)) + + def test_strict_input_admission(self): + for args in [(True, 1, 1), (2, True, 1), (2, 1, True), (2.0, 1, 1), + (1, 2, 1), (6, 1, 1), (2, -1, 1), (3, 2, 0), (3, 2, 3)]: + with self.assertRaises((ValueError, TypeError)): + c.tail_valuations(*args) + with self.assertRaises(ValueError): + c.tail_coefficients(2, 2, 1, basis='unknown') + + def test_controls_and_extra_contacts(self): + self.assertEqual(len(audit.controls()), 9) + vals = audit.counting_valuations(3, 2) + self.assertEqual(audit.lower_hull(vals), [(0, 12), (6, 2), (8, 0)]) + record = audit.polygon_record(vals, 3, 2) + self.assertEqual(record['segments'][0]['contacts'], [0, 3, 6]) + self.assertEqual(record['segments'][1]['contacts'], [6, 7, 8]) + + def test_receipt_types_are_not_coerced(self): + self.assertNotEqual(audit.canonical({'x': 1}), audit.canonical({'x': True})) + self.assertNotEqual(audit.canonical({'x': 1}), audit.canonical({'x': 1.0})) + + def test_source_drift_fails_and_relocation_works(self): + manifest = json.loads((HERE / 'SOURCE.json').read_text()) + original = audit.HERE + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + relocated = root / 'research' / HERE.name + relocated.mkdir(parents=True) + shutil.copyfile(HERE / 'SOURCE.json', relocated / 'SOURCE.json') + for name in manifest['sha256']: + target = root / name + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(HERE.parent.parent / name, target) + try: + audit.HERE = relocated + self.assertEqual(audit.check_sources(), manifest['base_commit']) + changed = root / 'research/prime-power-cyclic-inverse/PROOF.md' + changed.write_bytes(changed.read_bytes() + b'\ncorrupted source\n') + with self.assertRaisesRegex(ValueError, 'source drift'): + audit.check_sources() + finally: + audit.HERE = original + + +if __name__ == '__main__': + unittest.main() diff --git a/research/prime-power-newton-audit/verify.py b/research/prime-power-newton-audit/verify.py new file mode 100644 index 0000000000..ba92642449 --- /dev/null +++ b/research/prime-power-newton-audit/verify.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python3 +"""Exact finite audit of the written prime-power Newton-polygon formula.""" +import argparse +from fractions import Fraction +import hashlib +import importlib.util +import json +from math import gcd, isqrt +from pathlib import Path + +HERE = Path(__file__).resolve().parent +spec = importlib.util.spec_from_file_location('newton_cyclotomic', HERE / 'cyclotomic.py') +cyclotomic = importlib.util.module_from_spec(spec) +spec.loader.exec_module(cyclotomic) + + +def require(ok, message): + if not ok: + raise ValueError(message) + + +def canonical(value): + return json.dumps(value, sort_keys=True, separators=(',', ':'), ensure_ascii=True) + + +def prime(n): + return n >= 2 and all(n % d for d in range(2, isqrt(n) + 1)) + + +def domain(limit=68): + for p in range(2, limit + 1): + if prime(p): + a, r = 1, p + while r <= limit: + yield p, a, r + a, r = a + 1, r * p + + +def counting_valuations(p, a): + r = p ** a + values = [0] * r + for j in range(r - 2, -1, -1): + s, weight = j + 1, 1 + while s % p == 0: + weight *= p + s //= p + values[j] = values[j + 1] + weight + return values + + +def lower_hull(values): + hull = [] + for x, y in enumerate(values): + while len(hull) >= 2: + x0, y0 = hull[-2] + x1, y1 = hull[-1] + # Retain only genuine vertices: discard a collinear middle point. + if (x1 - x0) * (y - y1) > (y1 - y0) * (x - x1): + break + hull.pop() + hull.append((x, y)) + return hull + + +def predicted_vertices(p, a): + r = p ** a + return [(r - p ** k, k * (p - 1) * p ** (k - 1)) for k in range(a, 0, -1)] + [(r - 1, 0)] + + +def polygon_record(values, p, a): + r, e = p ** a, (p - 1) * p ** (a - 1) + require(len(values) == r, 'coefficient count') + require(values == counting_valuations(p, a), 'coefficient valuation mismatch') + hull = lower_hull(values) + require(hull == predicted_vertices(p, a), 'Newton vertices mismatch') + segments = [] + contacts = set() + for k, (left, right) in zip(range(a, 0, -1), zip(hull, hull[1:])): + x0, y0 = left + x1, y1 = right + lam = Fraction(y0 - y1, x1 - x0) + require(lam == 1 + Fraction((k - 1) * (p - 1), p), 'root valuation') + require(x1 - x0 == (p - 1) * p ** (k - 1), 'root multiplicity') + edge_contacts = [] + for j in range(x0, x1 + 1): + gap = Fraction(values[j] - y0) + lam * (j - x0) + require(gap >= 0, 'coefficient below claimed edge') + require((gap == 0) == ((r - j) % p ** (k - 1) == 0), 'edge-contact locus') + if gap == 0: + contacts.add(j) + edge_contacts.append(j) + segments.append({'valuation': str(lam), 'multiplicity': x1 - x0, + 'valuation_with_vp_p_1': str(lam / e), 'contacts': edge_contacts}) + require(sum(s['multiplicity'] for s in segments) == r - 1, 'total degree') + require(sum(Fraction(s['valuation']) * s['multiplicity'] for s in segments) == a * e, 'constant/product valuation') + require(all(Fraction(s['valuation']) > 0 for s in segments), 'nonunit root obligation') + return {'p': p, 'a': a, 'r': r, 'ramification_index': e, + 'coefficient_valuations': values, 'vertices': hull, 'segments': segments, + 'edge_contact_count': len(contacts)} + + +def reject(fn, name): + try: + fn() + except (ValueError, TypeError): + return name + raise ValueError('negative control accepted: ' + name) + + +def controls(): + out = [] + original = counting_valuations(2, 3) + mutant = original[:] + mutant[0] = 0 # f(z)+1: r+1 is a unit; all its roots have valuation zero. + require(lower_hull(mutant) == [(0, 0), (7, 0)], 'unit-constant control polygon') + out.append(reject(lambda: polygon_record(mutant, 2, 3), 'unit_constant_changes_root_polygon')) + omitted = original[:] + omitted[0] -= 4 # Omit the s=4 factor from the constant coefficient. + out.append(reject(lambda: polygon_record(omitted, 2, 3), 'omitted_ramified_factor')) + wrong_ramification = original[:] + wrong_ramification[0] = 3 # v_2(8), incorrectly used as v_pi(8). + out.append(reject(lambda: polygon_record(wrong_ramification, 2, 3), 'mixed_valuation_normalizations')) + reversed_order = list(reversed(original)) + out.append(reject(lambda: polygon_record(reversed_order, 2, 3), 'reversed_coefficient_order')) + nonmonic = original[:] + nonmonic[-1] = 1 + out.append(reject(lambda: polygon_record(nonmonic, 2, 3), 'nonunit_leading_coefficient')) + out.append(reject(lambda: cyclotomic.tail_valuations(2, 3, 2), 'nonprimitive_root')) + out.append(reject(lambda: cyclotomic.tail_valuations(4, 1, 1), 'composite_base')) + out.append(reject(lambda: cyclotomic.tail_valuations(2, 0, 1), 'zero_exponent')) + # Distinguish genuine vertices from extra collinear coefficient contacts. + odd = polygon_record(counting_valuations(3, 2), 3, 2) + require(odd['edge_contact_count'] == 5 and len(odd['vertices']) == 3, 'odd-prime contacts') + out.append(reject(lambda: require(odd['edge_contact_count'] == len(odd['vertices']), 'missing contacts'), 'vertices_are_not_all_contacts')) + return out + + +def check_sources(): + manifest = json.loads((HERE / 'SOURCE.json').read_text()) + root = HERE.parent.parent + for name, digest in manifest['sha256'].items(): + require(hashlib.sha256((root / name).read_bytes()).hexdigest() == digest, 'source drift: ' + name) + return manifest['base_commit'] + + +def run(): + base = check_sources() + records = [] + embeddings = coefficients = 0 + exact_digest = hashlib.sha256() + for p, a, r in domain(): + values = counting_valuations(p, a) + record = polygon_record(values, p, a) + primitive = [t for t in range(1, r) if gcd(t, r) == 1] + for t in primitive: + independent = cyclotomic.tail_valuations(p, a, t) + require(independent == values, 'independent cyclotomic coefficient mismatch at r=%d t=%d' % (r, t)) + exact_digest.update((canonical([r, t, independent]) + '\n').encode()) + embeddings += 1 + coefficients += r + record['primitive_powers'] = primitive + records.append(record) + negative = controls() + return {'schema': 1, 'base_commit': base, 'assignment_seed': 68, + 'scope': 'Finite coefficient/polygon audit; the separate written proof gives the uniform statement.', + 'domain': 'Every prime power 2 <= r <= 68 and every primitive exponent 1 <= t < r.', + 'radices': len(records), 'primitive_embeddings': embeddings, + 'coefficient_obligations': coefficients, 'independent_valuation_sha256': exact_digest.hexdigest(), + 'negative_controls': negative, 'cases': records} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--write-receipt', type=Path, help='Generate a receipt at the explicitly supplied path.') + args = parser.parse_args() + result = run() + if args.write_receipt: + args.write_receipt.write_text(json.dumps(result, indent=2) + '\n') + else: + expected = json.loads((HERE / 'EXPECTED.json').read_text()) + require(canonical(result) == canonical(expected), 'frozen receipt mismatch') + print('PASS_NEWTON_NONUNIT_AUDIT: %d radices; %d primitive embeddings; %d coefficient obligations; %d negative controls' % + (result['radices'], result['primitive_embeddings'], result['coefficient_obligations'], len(result['negative_controls']))) + + +if __name__ == '__main__': + main()