opengalois 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. opengalois-0.2.0/LICENSE +21 -0
  2. opengalois-0.2.0/PKG-INFO +399 -0
  3. opengalois-0.2.0/README.md +369 -0
  4. opengalois-0.2.0/pyproject.toml +93 -0
  5. opengalois-0.2.0/setup.cfg +4 -0
  6. opengalois-0.2.0/src/opengalois/__init__.py +21 -0
  7. opengalois-0.2.0/src/opengalois/__main__.py +6 -0
  8. opengalois-0.2.0/src/opengalois/algorithms/__init__.py +0 -0
  9. opengalois-0.2.0/src/opengalois/algorithms/cuerpos_finitos.py +22 -0
  10. opengalois-0.2.0/src/opengalois/algorithms/dummit_quintic_tables.py +879 -0
  11. opengalois-0.2.0/src/opengalois/algorithms/factorization.py +580 -0
  12. opengalois-0.2.0/src/opengalois/algorithms/factorization_fpx.py +304 -0
  13. opengalois-0.2.0/src/opengalois/algorithms/factorization_leg.py +295 -0
  14. opengalois-0.2.0/src/opengalois/algorithms/intfactor.py +258 -0
  15. opengalois-0.2.0/src/opengalois/api.py +165 -0
  16. opengalois-0.2.0/src/opengalois/certificate.py +136 -0
  17. opengalois-0.2.0/src/opengalois/cli.py +652 -0
  18. opengalois-0.2.0/src/opengalois/codec/__init__.py +0 -0
  19. opengalois-0.2.0/src/opengalois/codec/rationals.py +62 -0
  20. opengalois-0.2.0/src/opengalois/engine/__init__.py +0 -0
  21. opengalois-0.2.0/src/opengalois/engine/context.py +130 -0
  22. opengalois-0.2.0/src/opengalois/engine/engine.py +134 -0
  23. opengalois-0.2.0/src/opengalois/engine/objects.py +317 -0
  24. opengalois-0.2.0/src/opengalois/engine/procedures/irreducible/_radical_utils.py +199 -0
  25. opengalois-0.2.0/src/opengalois/engine/procedures/irreducible/deg1.py +136 -0
  26. opengalois-0.2.0/src/opengalois/engine/procedures/irreducible/deg2.py +181 -0
  27. opengalois-0.2.0/src/opengalois/engine/procedures/irreducible/deg3.py +385 -0
  28. opengalois-0.2.0/src/opengalois/engine/procedures/irreducible/deg4.py +852 -0
  29. opengalois-0.2.0/src/opengalois/engine/procedures/irreducible/deg5.py +1466 -0
  30. opengalois-0.2.0/src/opengalois/engine/procedures/procedure.py +29 -0
  31. opengalois-0.2.0/src/opengalois/engine/procedures/reducible.py +978 -0
  32. opengalois-0.2.0/src/opengalois/engine/registry.py +61 -0
  33. opengalois-0.2.0/src/opengalois/explain/__init__.py +32 -0
  34. opengalois-0.2.0/src/opengalois/explain/api.py +286 -0
  35. opengalois-0.2.0/src/opengalois/explain/context.py +194 -0
  36. opengalois-0.2.0/src/opengalois/explain/errors.py +38 -0
  37. opengalois-0.2.0/src/opengalois/explain/graph.py +86 -0
  38. opengalois-0.2.0/src/opengalois/explain/math_render.py +562 -0
  39. opengalois-0.2.0/src/opengalois/explain/pdf.py +139 -0
  40. opengalois-0.2.0/src/opengalois/explain/proof_model.py +73 -0
  41. opengalois-0.2.0/src/opengalois/explain/renderers/__init__.py +9 -0
  42. opengalois-0.2.0/src/opengalois/explain/renderers/latex.py +82 -0
  43. opengalois-0.2.0/src/opengalois/explain/renderers/markdown.py +62 -0
  44. opengalois-0.2.0/src/opengalois/explain/templates/__init__.py +20 -0
  45. opengalois-0.2.0/src/opengalois/explain/templates/le5_core_1/__init__.py +12 -0
  46. opengalois-0.2.0/src/opengalois/explain/templates/le5_core_1/_helpers.py +58 -0
  47. opengalois-0.2.0/src/opengalois/explain/templates/le5_core_1/basic.py +369 -0
  48. opengalois-0.2.0/src/opengalois/explain/templates/le5_core_1/discriminant.py +181 -0
  49. opengalois-0.2.0/src/opengalois/explain/templates/le5_core_1/galois.py +1699 -0
  50. opengalois-0.2.0/src/opengalois/explain/templates/le5_core_1/radicals.py +676 -0
  51. opengalois-0.2.0/src/opengalois/explain/templates/le5_core_1/statements.py +304 -0
  52. opengalois-0.2.0/src/opengalois/explain/templates/registry.py +70 -0
  53. opengalois-0.2.0/src/opengalois/explain.py +348 -0
  54. opengalois-0.2.0/src/opengalois/models.py +53 -0
  55. opengalois-0.2.0/src/opengalois/nodes/__init__.py +0 -0
  56. opengalois-0.2.0/src/opengalois/nodes/discriminant.py +204 -0
  57. opengalois-0.2.0/src/opengalois/nodes/kappe_warren.py +295 -0
  58. opengalois-0.2.0/src/opengalois/nodes/normalize.py +97 -0
  59. opengalois-0.2.0/src/opengalois/nodes/reducibility.py +295 -0
  60. opengalois-0.2.0/src/opengalois/nodes/resolvent.py +399 -0
  61. opengalois-0.2.0/src/opengalois/nodes/square.py +211 -0
  62. opengalois-0.2.0/src/opengalois/polyops/__init__.py +0 -0
  63. opengalois-0.2.0/src/opengalois/polyops/asc_fpx.py +246 -0
  64. opengalois-0.2.0/src/opengalois/polyops/desc_qx.py +246 -0
  65. opengalois-0.2.0/src/opengalois/polyops/desc_zx.py +213 -0
  66. opengalois-0.2.0/src/opengalois/py.typed +0 -0
  67. opengalois-0.2.0/src/opengalois/radicals/__init__.py +70 -0
  68. opengalois-0.2.0/src/opengalois/radicals/ast.py +329 -0
  69. opengalois-0.2.0/src/opengalois/radicals/canon.py +271 -0
  70. opengalois-0.2.0/src/opengalois/radicals/cli_format.py +835 -0
  71. opengalois-0.2.0/src/opengalois/radicals/codec.py +301 -0
  72. opengalois-0.2.0/src/opengalois/radicals/parse.py +28 -0
  73. opengalois-0.2.0/src/opengalois/radicals/render.py +576 -0
  74. opengalois-0.2.0/src/opengalois/radicals/schemes/__init__.py +17 -0
  75. opengalois-0.2.0/src/opengalois/radicals/schemes/deg1_trivial.py +37 -0
  76. opengalois-0.2.0/src/opengalois/radicals/schemes/deg2_quadratic_formula.py +48 -0
  77. opengalois-0.2.0/src/opengalois/radicals/schemes/deg3_cardano_depressed_monic.py +84 -0
  78. opengalois-0.2.0/src/opengalois/radicals/schemes/deg4_ferrari_depressed_monic.py +61 -0
  79. opengalois-0.2.0/src/opengalois/radicals/schemes/deg5_mcclintock_depressed_monic.py +2719 -0
  80. opengalois-0.2.0/src/opengalois/radicals/schemes/lift_depressed_monic.py +24 -0
  81. opengalois-0.2.0/src/opengalois/rulesets/__init__.py +17 -0
  82. opengalois-0.2.0/src/opengalois/rulesets/le5_core_1.py +245 -0
  83. opengalois-0.2.0/src/opengalois/rulesets/registry.py +61 -0
  84. opengalois-0.2.0/src/opengalois/rulesets/types.py +72 -0
  85. opengalois-0.2.0/src/opengalois/schemas/certificate/3.0.0.json +266 -0
  86. opengalois-0.2.0/src/opengalois/schemas/certificate/3.1.0.json +225 -0
  87. opengalois-0.2.0/src/opengalois/verify.py +6720 -0
  88. opengalois-0.2.0/src/opengalois.egg-info/PKG-INFO +399 -0
  89. opengalois-0.2.0/src/opengalois.egg-info/SOURCES.txt +176 -0
  90. opengalois-0.2.0/src/opengalois.egg-info/dependency_links.txt +1 -0
  91. opengalois-0.2.0/src/opengalois.egg-info/entry_points.txt +2 -0
  92. opengalois-0.2.0/src/opengalois.egg-info/requires.txt +10 -0
  93. opengalois-0.2.0/src/opengalois.egg-info/top_level.txt +1 -0
  94. opengalois-0.2.0/tests/test_api_coeff_parsing.py +70 -0
  95. opengalois-0.2.0/tests/test_cardano_v2_fixtures.py +49 -0
  96. opengalois-0.2.0/tests/test_cli_analyze.py +106 -0
  97. opengalois-0.2.0/tests/test_cli_layout.py +31 -0
  98. opengalois-0.2.0/tests/test_cli_radical_roots_display.py +60 -0
  99. opengalois-0.2.0/tests/test_cli_verify.py +77 -0
  100. opengalois-0.2.0/tests/test_deg4_ferrari_v2_engine_smoke.py +47 -0
  101. opengalois-0.2.0/tests/test_deg4_ferrari_v2_fixtures.py +29 -0
  102. opengalois-0.2.0/tests/test_deg4_pair_sums_kappe_warren_formula.py +18 -0
  103. opengalois-0.2.0/tests/test_deg4_pair_sums_resolvent_equivalence.py +83 -0
  104. opengalois-0.2.0/tests/test_deg4_pair_sums_v2_pipeline.py +201 -0
  105. opengalois-0.2.0/tests/test_deg4_pair_sums_v2_regression_equivalence.py +58 -0
  106. opengalois-0.2.0/tests/test_deg5_dummit_two_quadratics.py +72 -0
  107. opengalois-0.2.0/tests/test_deg5_engine_normalization_and_regression.py +116 -0
  108. opengalois-0.2.0/tests/test_deg5_pipeline.py +179 -0
  109. opengalois-0.2.0/tests/test_desc_qx.py +329 -0
  110. opengalois-0.2.0/tests/test_dummit_paper_examples.py +316 -0
  111. opengalois-0.2.0/tests/test_dummit_quintic_tables.py +176 -0
  112. opengalois-0.2.0/tests/test_engine_deg1_radical_roots.py +33 -0
  113. opengalois-0.2.0/tests/test_engine_deg2_radical_roots.py +38 -0
  114. opengalois-0.2.0/tests/test_engine_deg3_cardano_v2_emission.py +31 -0
  115. opengalois-0.2.0/tests/test_engine_deg3_radical_roots.py +142 -0
  116. opengalois-0.2.0/tests/test_engine_irreducible_deg3_pipeline.py +29 -0
  117. opengalois-0.2.0/tests/test_engine_reducible_wiring.py +73 -0
  118. opengalois-0.2.0/tests/test_explain_deg4_pair_sums_v2.py +16 -0
  119. opengalois-0.2.0/tests/test_explain_irreducible_zassenhaus_trace.py +32 -0
  120. opengalois-0.2.0/tests/test_explain_nonsquare_v2.py +30 -0
  121. opengalois-0.2.0/tests/test_factorization_fpx_cantor_zassenhaus.py +64 -0
  122. opengalois-0.2.0/tests/test_fixtures.py +52 -0
  123. opengalois-0.2.0/tests/test_galois_group.py +27 -0
  124. opengalois-0.2.0/tests/test_hensel_factorization.py +76 -0
  125. opengalois-0.2.0/tests/test_hensel_factorization_refactor.py +73 -0
  126. opengalois-0.2.0/tests/test_irreducible_QQ_to_depressed_monic_rule.py +32 -0
  127. opengalois-0.2.0/tests/test_irreducible_deg4_pipeline_conrad.py +446 -0
  128. opengalois-0.2.0/tests/test_jcs_vector.py +65 -0
  129. opengalois-0.2.0/tests/test_kappe_warren_pair_sums_node.py +52 -0
  130. opengalois-0.2.0/tests/test_mpoly_integration.py +172 -0
  131. opengalois-0.2.0/tests/test_no_sympy_imports.py +126 -0
  132. opengalois-0.2.0/tests/test_radical_expr_verify.py +99 -0
  133. opengalois-0.2.0/tests/test_radical_roots_deg5_mcclintock_rule.py +26 -0
  134. opengalois-0.2.0/tests/test_radical_roots_rules.py +166 -0
  135. opengalois-0.2.0/tests/test_radicals_ast.py +54 -0
  136. opengalois-0.2.0/tests/test_radicals_cli_format.py +39 -0
  137. opengalois-0.2.0/tests/test_radicals_codec.py +47 -0
  138. opengalois-0.2.0/tests/test_radicals_deg1_trivial_scheme.py +10 -0
  139. opengalois-0.2.0/tests/test_radicals_deg2_quadratic_formula_scheme.py +16 -0
  140. opengalois-0.2.0/tests/test_radicals_deg3_cardano_scheme.py +125 -0
  141. opengalois-0.2.0/tests/test_radicals_render.py +26 -0
  142. opengalois-0.2.0/tests/test_radicals_validation_guards.py +73 -0
  143. opengalois-0.2.0/tests/test_reducibility_node_zassenhaus_trace.py +22 -0
  144. opengalois-0.2.0/tests/test_reducible_procedure.py +195 -0
  145. opengalois-0.2.0/tests/test_roundtrip_analyze_v3.py +37 -0
  146. opengalois-0.2.0/tests/test_smoke.py +7 -0
  147. opengalois-0.2.0/tests/test_solvable_by_radicals_rules.py +52 -0
  148. opengalois-0.2.0/tests/test_square_node_nonsquare_v2.py +45 -0
  149. opengalois-0.2.0/tests/test_v3_reducible_case_rules_22.py +48 -0
  150. opengalois-0.2.0/tests/test_v3_reducible_case_rules_23.py +46 -0
  151. opengalois-0.2.0/tests/test_v3_reducible_case_rules_batch1.py +45 -0
  152. opengalois-0.2.0/tests/test_v3_rule_degree_QQ.py +27 -0
  153. opengalois-0.2.0/tests/test_v3_rule_disc_QQ_compute_at_1.py +26 -0
  154. opengalois-0.2.0/tests/test_v3_rule_disc_nonsquare_lift_at_1.py +26 -0
  155. opengalois-0.2.0/tests/test_v3_rule_disc_square_lift_at_1.py +26 -0
  156. opengalois-0.2.0/tests/test_v3_rule_factorization_monic.py +29 -0
  157. opengalois-0.2.0/tests/test_v3_rule_galois_group_QQ_deg3_C3_at_1.py +24 -0
  158. opengalois-0.2.0/tests/test_v3_rule_galois_group_QQ_deg3_S3_at_1.py +24 -0
  159. opengalois-0.2.0/tests/test_v3_rule_galois_group_QQ_lift_depressed_monic.py +30 -0
  160. opengalois-0.2.0/tests/test_v3_rule_galois_group_deg2_C2.py +29 -0
  161. opengalois-0.2.0/tests/test_v3_rule_galois_group_deg4_c4.py +33 -0
  162. opengalois-0.2.0/tests/test_v3_rule_galois_group_deg4_d4.py +41 -0
  163. opengalois-0.2.0/tests/test_v3_rule_galois_group_deg4_pair_sums_v2.py +113 -0
  164. opengalois-0.2.0/tests/test_v3_rule_galois_group_deg4_s4_a4.py +45 -0
  165. opengalois-0.2.0/tests/test_v3_rule_galois_group_deg4_v4.py +32 -0
  166. opengalois-0.2.0/tests/test_v3_rule_irreducible_QQ_dummit_resolvent.py +27 -0
  167. opengalois-0.2.0/tests/test_v3_rule_irreducible_QQ_zassenhaus_trace.py +33 -0
  168. opengalois-0.2.0/tests/test_v3_rule_irreducible_deg1_trivial.py +27 -0
  169. opengalois-0.2.0/tests/test_v3_rule_irreducible_deg5_recompute.py +26 -0
  170. opengalois-0.2.0/tests/test_v3_rule_is_square_QQ_lift_at_1.py +26 -0
  171. opengalois-0.2.0/tests/test_v3_rule_nonsquare_QQ_isqrt_at_1.py +26 -0
  172. opengalois-0.2.0/tests/test_v3_rule_nonsquare_QQ_isqrt_v2.py +40 -0
  173. opengalois-0.2.0/tests/test_v3_rule_normalize_depressed_monic.py +26 -0
  174. opengalois-0.2.0/tests/test_v3_rule_resolvent_QQ_compute_deg4_cubic_x1x2_plus_x3x4_1.py +27 -0
  175. opengalois-0.2.0/tests/test_v3_rule_resolvent_deg5_sextic_dummit_F20.py +43 -0
  176. opengalois-0.2.0/tests/test_v3_rule_sqrt_QQ_check_at_1.py +26 -0
  177. opengalois-0.2.0/tests/test_verify_cardano_v2_helper.py +43 -0
  178. opengalois-0.2.0/tests/test_verify_radical_roots_reducible_compose_v2.py +26 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alejandro Parreño Minaya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,399 @@
1
+ Metadata-Version: 2.4
2
+ Name: opengalois
3
+ Version: 0.2.0
4
+ Summary: Glass-box Galois analysis for polynomials over Q up to degree 5 with proof-carrying output.
5
+ Author: Alejandro Parreño Minaya
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/aparreno14/OpenGalois
8
+ Project-URL: Repository, https://github.com/aparreno14/OpenGalois
9
+ Project-URL: Issues, https://github.com/aparreno14/OpenGalois/issues
10
+ Project-URL: Documentation, https://github.com/aparreno14/OpenGalois/tree/main/docs
11
+ Keywords: galois,quintic,number-theory,computer-algebra,proof-carrying
12
+ Classifier: Development Status :: 2 - Pre-Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: jsonschema>=4
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=8.0; extra == "dev"
23
+ Requires-Dist: ruff>=0.6; extra == "dev"
24
+ Requires-Dist: mypy>=1.8; extra == "dev"
25
+ Requires-Dist: types-setuptools; extra == "dev"
26
+ Requires-Dist: types-jsonschema; extra == "dev"
27
+ Requires-Dist: build>=1.2; extra == "dev"
28
+ Requires-Dist: twine>=5.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # OpenGalois
32
+
33
+ OpenGalois is a Python library for **glass-box Galois analysis** of polynomials over `Q[x]` of degree at most 5.
34
+
35
+ It computes Galois groups, determines solvability by radicals, and, when supported, produces radical expressions for the roots. Unlike a black-box computer algebra system, OpenGalois also emits a **proof-carrying JSON certificate**: a structured derivation that can be checked by an independent verifier using exact arithmetic and an explicit ruleset.
36
+
37
+ The guiding principle is simple:
38
+
39
+ > the result should not only be computed; it should be auditable.
40
+
41
+ OpenGalois is research software, currently in pre-alpha status.
42
+
43
+ ---
44
+
45
+ ## What OpenGalois is
46
+
47
+ OpenGalois is designed around three goals.
48
+
49
+ 1. **Exact algebraic computation**
50
+
51
+ Computations are performed over `Q`, using exact rational arithmetic. The mathematical core deliberately avoids floating-point approximations.
52
+
53
+ 2. **Proof-carrying output**
54
+
55
+ The output is not just a label such as `S5` or `D4`. OpenGalois emits a certificate containing the mathematical objects, facts, rules, premises and evidence used to justify the conclusion.
56
+
57
+ 3. **Human-readable explanations**
58
+
59
+ The same certificate can be rendered as a mathematical explanation. The explanation is non-normative: it is derived from the certificate, but the certificate and verifier remain the source of truth.
60
+
61
+ OpenGalois is not intended to compete with large general-purpose systems such as SageMath, PARI/GP, Magma, Mathematica, or Maple. Its purpose is narrower: to make the computation of Galois groups and radical expressions for low-degree polynomials transparent, reproducible and independently checkable.
62
+
63
+ ---
64
+
65
+ ## Mathematical scope
66
+
67
+ OpenGalois currently targets polynomials
68
+
69
+ ```text
70
+ f in Q[x], 1 <= deg(f) <= 5
71
+ ```
72
+
73
+ The current core ruleset is:
74
+
75
+ ```text
76
+ le5-core@1
77
+ ```
78
+
79
+ Supported analysis includes:
80
+
81
+ - factorization over `Q[x]`;
82
+ - irreducibility detection;
83
+ - discriminant computation;
84
+ - rational square and non-square checks;
85
+ - Galois group classification for degrees 1 through 5;
86
+ - reducible cases via the splitting fields of irreducible factors;
87
+ - solvability by radicals;
88
+ - radical expressions for supported solvable cases;
89
+ - certificate verification;
90
+ - explanation rendering in Markdown, LaTeX and PDF.
91
+
92
+ ### Irreducible cases
93
+
94
+ For irreducible polynomials, OpenGalois distinguishes the usual transitive possibilities:
95
+
96
+ - degree 1: trivial group;
97
+ - degree 2: `C2`;
98
+ - degree 3: `C3` or `S3`;
99
+ - degree 4: `C4`, `V4`, `D4`, `A4`, or `S4`;
100
+ - degree 5: `C5`, `D5`, `F20`, `A5`, or `S5`.
101
+
102
+ The degree-4 classification uses the pair-sums cubic resolvent attached to
103
+
104
+ ```text
105
+ (x1 + x2)(x3 + x4)
106
+ ```
107
+
108
+ and the `C4/D4` branch is resolved by the corresponding Kappe--Warren discriminant tests.
109
+
110
+ The degree-5 classification uses Dummit's sextic resolvent to detect the solvable branch and distinguish `S5`, `A5`, and `F20`. In the square-discriminant solvable branch, OpenGalois uses Dummit's auxiliary quadratic criterion to distinguish `D5` from `C5`.
111
+
112
+ ### Reducible cases
113
+
114
+ For reducible polynomials, OpenGalois factors the polynomial over `Q`, removes repeated factors and rational linear factors for the purpose of the splitting field, and then reasons from the irreducible factors.
115
+
116
+ The main nontrivial reducible patterns in degree at most 5 are:
117
+
118
+ - two irreducible quadratic factors, giving `C2` or `C2 x C2`;
119
+ - one irreducible quadratic and one irreducible cubic factor, giving `C6`, `S3`, or `D6`.
120
+
121
+ ---
122
+
123
+ ## Installation
124
+
125
+ Once published on PyPI:
126
+
127
+ ```bash
128
+ pip install opengalois
129
+ ```
130
+
131
+ For development from source:
132
+
133
+ ```bash
134
+ git clone https://github.com/aparreno14/OpenGalois.git
135
+ cd OpenGalois
136
+ python -m venv .venv
137
+ . .venv/bin/activate
138
+ pip install -U pip
139
+ pip install -e ".[dev]"
140
+ ```
141
+
142
+ On Windows PowerShell:
143
+
144
+ ```powershell
145
+ python -m venv .venv
146
+ .venv\Scripts\Activate.ps1
147
+ pip install -U pip
148
+ pip install -e ".[dev]"
149
+ ```
150
+
151
+ PDF explanation output requires a local LaTeX installation.
152
+
153
+ ---
154
+
155
+ ## Quickstart: Python API
156
+
157
+ ```python
158
+ from opengalois import analyze, verify, render_explanation
159
+
160
+ # f(x) = x^5 - x - 1
161
+ result = analyze([1, 0, 0, 0, -1, -1])
162
+
163
+ print(result.galois_group)
164
+ print(result.solvable_by_radicals)
165
+
166
+ certificate = result.certificate
167
+ verification = verify(certificate)
168
+
169
+ print(verification.verified)
170
+
171
+ explanation = render_explanation(result, format="md")
172
+ print(explanation)
173
+ ```
174
+
175
+ The coefficient list is given in descending degree order:
176
+
177
+ ```text
178
+ [a_n, ..., a_0]
179
+ ```
180
+
181
+ for
182
+
183
+ ```text
184
+ a_n*x^n + ... + a_0
185
+ ```
186
+
187
+ Exact rational coefficients may be given as strings:
188
+
189
+ ```python
190
+ result = analyze(["1", "0", "-13/5", "38/25", "667/125", "11672/3125"])
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Quickstart: CLI
196
+
197
+ Analyze a polynomial and write the certificate to disk:
198
+
199
+ ```bash
200
+ opengalois analyze 1 0 0 0 -1 -1 --output cert.json
201
+ ```
202
+
203
+ Verify a certificate:
204
+
205
+ ```bash
206
+ opengalois verify cert.json
207
+ ```
208
+
209
+ Render a human-readable explanation:
210
+
211
+ ```bash
212
+ opengalois explain cert.json --format markdown
213
+ ```
214
+
215
+ Write a LaTeX explanation:
216
+
217
+ ```bash
218
+ opengalois explain cert.json --format latex --out proof.tex
219
+ ```
220
+
221
+ Write a PDF explanation:
222
+
223
+ ```bash
224
+ opengalois explain cert.json --format pdf --out proof.pdf
225
+ ```
226
+
227
+ ---
228
+
229
+ ## Certificates
230
+
231
+ The central artifact produced by OpenGalois is a JSON certificate.
232
+
233
+ A certificate contains:
234
+
235
+ - the normalized input polynomial;
236
+ - a store of mathematical objects;
237
+ - a topologically ordered list of proved facts;
238
+ - the rule used for each fact;
239
+ - the premises required by each rule;
240
+ - optional rule-defined evidence;
241
+ - non-normative summary data for user interfaces.
242
+
243
+ The verifier accepts a certificate only if the normative proof payload is valid.
244
+
245
+ In particular, summaries, prose explanations, renderer output and UI metadata do not affect correctness.
246
+
247
+ ---
248
+
249
+ ## The Objects / Facts / Rules model
250
+
251
+ OpenGalois certificates are based on three concepts.
252
+
253
+ ### Objects
254
+
255
+ Objects are mathematical values appearing in the proof, such as:
256
+
257
+ - polynomials over `Q`;
258
+ - rational numbers;
259
+ - group identifiers;
260
+ - lists of factors;
261
+ - radical expressions.
262
+
263
+ Objects are stored canonically and referenced by stable identifiers.
264
+
265
+ ### Facts
266
+
267
+ Facts are mathematical claims about objects, for example:
268
+
269
+ ```text
270
+ IrreducibleQQ(f)
271
+ Discriminant(f, D)
272
+ IsSquareQQ(D)
273
+ NonSquareQQ(D)
274
+ ResolventQQ(R, f, p)
275
+ GaloisGroup(f, G)
276
+ RadicalRoots(f, R)
277
+ ```
278
+
279
+ A fact is a statement. It becomes accepted only when justified by a rule.
280
+
281
+ ### Rules
282
+
283
+ Rules are verifier-known inference steps. A rule specifies:
284
+
285
+ - what kind of fact it can prove;
286
+ - which premises are required;
287
+ - which object bindings must agree;
288
+ - what evidence, if any, is required;
289
+ - what deterministic checks the verifier must perform.
290
+
291
+ The engine proposes facts. The verifier distrusts the engine and checks every rule application independently.
292
+
293
+ ---
294
+
295
+ ## Radical expressions
296
+
297
+ Radical expressions in OpenGalois are represented as symbolic abstract syntax trees.
298
+
299
+ They are not floating-point approximations and they are not globally simplified algebraic numbers. Equality of radical expressions is structural, not equality modulo arbitrary algebraic identities.
300
+
301
+ This design is intentional. It keeps the verifier small and avoids hiding difficult symbolic simplification inside the trusted core.
302
+
303
+ For example, OpenGalois treats a symbol such as `sqrt(2)` as an algebraic radical object satisfying `u^2 = 2`, not as a numerical branch of the complex square-root function.
304
+
305
+ ---
306
+
307
+ ## Explanation layer
308
+
309
+ The explanation layer turns certificates into readable mathematical text.
310
+
311
+ It is designed to be:
312
+
313
+ - deterministic;
314
+ - derived from the proof graph;
315
+ - useful for auditing;
316
+ - independent from verification.
317
+
318
+ The explanation layer is not trusted by the verifier. If an explanation and a verified certificate ever disagree, the certificate and ruleset are authoritative.
319
+
320
+ ---
321
+
322
+ ## Documentation map
323
+
324
+ Start here:
325
+
326
+ - `docs/overview.md` — conceptual overview of the certificate model;
327
+ - `docs/certificate-format.md` — JSON certificate format;
328
+ - `docs/objects.md` — canonical object encodings;
329
+ - `docs/facts.md` — generic fact-language overview;
330
+ - `docs/rulesets/le5-core@1/facts.md` — fact catalog for the active ruleset;
331
+ - `docs/rulesets/le5-core@1/` — rule documentation;
332
+ - `docs/verification.md` — verifier model;
333
+ - `docs/explain.md` — explanation model;
334
+ - `docs/resolvents.md` — mathematical background on resolvents;
335
+ - `docs/adding-a-fact.md` — developer guide for adding predicates;
336
+ - `docs/adding-a-rule.md` — developer guide for adding rules.
337
+
338
+ ---
339
+
340
+ ## Development
341
+
342
+ Install development dependencies:
343
+
344
+ ```bash
345
+ pip install -e ".[dev]"
346
+ ```
347
+
348
+ Run tests:
349
+
350
+ ```bash
351
+ pytest -q
352
+ ```
353
+
354
+ Run Ruff:
355
+
356
+ ```bash
357
+ ruff check .
358
+ ```
359
+
360
+ Run mypy:
361
+
362
+ ```bash
363
+ mypy src
364
+ ```
365
+
366
+ Build and check the package metadata:
367
+
368
+ ```bash
369
+ python -m build
370
+ python -m twine check dist/*
371
+ ```
372
+
373
+ ---
374
+
375
+ ## Status
376
+
377
+ OpenGalois is currently pre-alpha research software.
378
+
379
+ The main public surface is:
380
+
381
+ ```python
382
+ analyze(polynomial, explain=False)
383
+ verify(certificate)
384
+ render_explanation(result_or_certificate, format="md")
385
+ ```
386
+
387
+ The certificate schema, ruleset and explanation templates may still evolve.
388
+
389
+ ---
390
+
391
+ ## License
392
+
393
+ OpenGalois is distributed under the MIT License.
394
+
395
+ ---
396
+
397
+ ## Academic context
398
+
399
+ OpenGalois was developed as part of the project *The Solvability Problem for Polynomials of Degree at Most 5*. The project studies the classification of Galois groups and solvability by radicals for low-degree polynomials, with an emphasis on exact computation, proof-carrying certificates and transparent mathematical explanations.