Exact Symbolic Demonstrations¶
Runnable SymPy & geometor.model Verification Suites
In strict accordance with GEOMETOR’s separation of archival treatise text and executable code, all symbolic constructions, polynomial verifications, and CLI tables live in src/geometor/fibonacci/ and demos/ rather than inside the historical codex pages.
Run any demonstration directly from the repository root:
uv run --no-sync python3 demos/mensuration_demo.py
uv run --no-sync python3 demos/divisions_demo.py
uv run --no-sync python3 demos/polyhedra_golden_demo.py
1. Mensuration, Heron’s Incenter Proof & Circle Bounds¶
demos/mensuration_demo.py exercises geometor.fibonacci.mensuration across Distinctio I and Distinctio III:
Exact rational conversion across the Pisan pertica, pes, uncia, denarius, panorum, and stariorum ($66$ square perticae).
Symbolic verification over $\mathbb{Z}[x, y, z]$ and geometric
Modelconstruction of Fibonacci’s incenter proof of Heron’s formula on $(13, 14, 15)$ ($T = (6, 4)$, $r = 4$, $s = 21$, $\Delta = 84$).Exact rational comparison of Fibonacci’s 96-gon bounds $\frac{6480}{2063} < \pi < \frac{7200}{2291}$ and $\pi_{\text{Fib}} = \frac{864}{275}$ against Archimedes’ $\frac{223}{71}$ and $\frac{22}{7}$.
1"""Runnable demonstration of *Practica Geometriae* Distinctio I & III: Pisan Metrology, Heron's Proof & Circle Bounds."""
2
3from __future__ import annotations
4
5import sys
6from pathlib import Path
7
8ROOT = Path(__file__).resolve().parents[1]
9SRC = ROOT / "src"
10if str(SRC) not in sys.path:
11 sys.path.insert(0, str(SRC))
12
13import sympy as sp # noqa: E402
14from rich.console import Console # noqa: E402
15from rich.table import Table # noqa: E402
16
17from geometor.fibonacci import ( # noqa: E402
18 PisanLinearMeasure,
19 construct_heron_incenter_proof,
20 decompose_pisan_area,
21 fibonacci_circle_bounds,
22 heron_area_exact,
23 multiply_pisan_lengths,
24 verify_heron_polynomial_identity,
25)
26
27
28def main() -> None:
29 console = Console()
30
31 # 1. Pisan Surveyor's Metrology (Introductoria & Distinctio I, Boncompagni pp. 3–5)
32 t_metro = Table(title="Distinctio I — Pisan Surveyor's Metrology (1 Stariorum = 66 Perticae)")
33 t_metro.add_column("Width", style="cyan")
34 t_metro.add_column("Length", style="cyan")
35 t_metro.add_column("Superficial Perticae", style="green")
36 t_metro.add_column("Stariora / Panora / Perticae / Pedes / Unciae", style="gold1")
37
38 examples = [
39 # Boncompagni p. 5: width = 7 perticae, length = 9 perticae, 2 pedes, 10 2/7 unciae -> 66 perticae = 1 stariorum
40 (
41 PisanLinearMeasure(perticae=7),
42 PisanLinearMeasure(perticae=9, pedes=2, unciae=sp.Rational(72, 7)),
43 ),
44 (
45 PisanLinearMeasure(perticae=12, pedes=3),
46 PisanLinearMeasure(perticae=8, pedes=4, unciae=9),
47 ),
48 (
49 PisanLinearMeasure(perticae=36),
50 PisanLinearMeasure(perticae=44),
51 ),
52 ]
53 for w, ln in examples:
54 res = multiply_pisan_lengths(w, ln)
55 t_metro.add_row(
56 f"{w.perticae}p {w.pedes}ft {w.unciae}in",
57 f"{ln.perticae}p {ln.pedes}ft {ln.unciae}in",
58 str(res.total_perticae),
59 f"{res.modiora} mod, {res.stariora} star, {res.panora} pan, "
60 f"{res.perticae} pert, {res.pedes_superficiales} ped, {res.unciae_superficiales} unc",
61 )
62 console.print(t_metro)
63 _ = decompose_pisan_area(66)
64
65 # 2. Heron's Formula & Incenter Proof (Distinctio III, Boncompagni pp. 40–41)
66 poly_res = verify_heron_polynomial_identity()
67 heron_proof = construct_heron_incenter_proof()
68 s22, exc22, sq22, area22 = heron_area_exact(13, 11, 20)
69
70 t_heron = Table(title="Distinctio III — Heron's Formula & Geometric Incenter Proof")
71 t_heron.add_column("Triangle / Check", style="cyan")
72 t_heron.add_column("Semiperimeter s", style="white")
73 t_heron.add_column("Excesses (s-a, s-b, s-c)", style="white")
74 t_heron.add_column("Exact Area", style="green")
75 t_heron.add_row(
76 "Boncompagni p. 40 Numerical (13, 11, 20)",
77 str(s22),
78 str(exc22),
79 f"sqrt({sq22}) = {area22}",
80 )
81 t_heron.add_row(
82 "Geometric Incenter Model (13, 14, 15)",
83 str(heron_proof.semiperimeter),
84 str(heron_proof.excesses),
85 f"r * s = {heron_proof.inradius} * {heron_proof.semiperimeter} = {heron_proof.area}",
86 )
87 t_heron.add_row(
88 "Polynomial Identity Z[x,y,z] Residual",
89 "-",
90 "a=y+z, b=z+x, c=x+y",
91 f"residual = {poly_res}",
92 )
93 console.print(t_heron)
94
95 # 3. Fibonacci's 96-gon Circle Measurement (Distinctio III, Boncompagni pp. 88–91)
96 cb = fibonacci_circle_bounds()
97 t_pi = Table(title="Distinctio III — Fibonacci's 96-gon Circle Bounds vs. Archimedes")
98 t_pi.add_column("Quantity", style="cyan")
99 t_pi.add_column("Exact Rational", style="green")
100 t_pi.add_column("Decimal (10 d.p.)", style="gold1")
101 t_pi.add_row("Archimedes Lower (3 + 10/71)", str(cb.archimedes_lower), f"{float(cb.archimedes_lower):.10f}")
102 t_pi.add_row("Fibonacci 96-gon Inscribed (1440 / 458 4/9)", str(cb.fibonacci_lower), f"{float(cb.fibonacci_lower):.10f}")
103 t_pi.add_row("True pi", "pi", f"{float(sp.pi.evalf()):.10f}")
104 t_pi.add_row("Fibonacci Mean Ratio (1440 / 458 1/3)", str(cb.fibonacci_pi), f"{float(cb.fibonacci_pi):.10f}")
105 t_pi.add_row("Fibonacci 96-gon Circumscribed (1440 / 458 1/5)", str(cb.fibonacci_upper), f"{float(cb.fibonacci_upper):.10f}")
106 t_pi.add_row("Archimedes Upper (864 / (275 - 1/11))", str(cb.archimedes_upper), f"{float(cb.archimedes_upper):.10f}")
107 console.print(t_pi)
108
109
110if __name__ == "__main__":
111 main()
2. Division of Planar Fields (De divisione camporum)¶
demos/divisions_demo.py exercises geometor.fibonacci.divisions on Distinctio IV (preserving Euclid’s On Divisions of Figures):
Straightedge-and-compass division of $\triangle ABG$ from an arbitrary point $D$ on side $[BG]$ in ratio $p : q$ via parallel transfer $[EZ] \parallel [AD]$ ($GZ = \frac{35}{3} = 11\frac{2}{3}$ when $BD = 5$, $p = q = 1$).
Semicircle mean-proportional construction ($AE^2 = \frac{p}{p+q} AB^2$) cutting $\triangle ABG$ parallel to base $[BG]$, reproducing Boncompagni p. 119 ($AE^2 = 50$, $AZ^2 = 72$, $EZ^2 = 98$ on sides $10, 14, 12$).
Concurrency of medians at centroid $D = X(2)$ in $2 : 1$ ratio, partitioning $\triangle ABG$ into three equal consort shares, plus root-mean-square trapezoid bisection on $(7, 17)$ yielding chord $13$ ($7^2, 13^2, 17^2$ in arithmetic progression).
1"""Runnable demonstration of *Practica Geometriae* Distinctio IV (*De divisione camporum*)."""
2
3from __future__ import annotations
4
5import sys
6from pathlib import Path
7
8ROOT = Path(__file__).resolve().parents[1]
9SRC = ROOT / "src"
10if str(SRC) not in sys.path:
11 sys.path.insert(0, str(SRC))
12
13from rich.console import Console # noqa: E402
14from rich.table import Table # noqa: E402
15
16from geometor.fibonacci import ( # noqa: E402
17 construct_triangle_medians_centroid,
18 construct_triangle_parallel_division,
19 construct_triangle_side_point_division,
20 trapezoid_parallel_division,
21)
22
23
24def main() -> None:
25 console = Console()
26
27 # 1. Dividing Triangle ABG from a Point D on Side BG (Boncompagni p. 112)
28 side_bisect = construct_triangle_side_point_division(p=1, q=1, d_offset_from_b=5)
29 side_third = construct_triangle_side_point_division(p=1, q=2, d_offset_from_b=5)
30
31 t_side = Table(title="Distinctio IV — Dividing Triangle (13, 14, 15) from Point D on Side BG (BD = 5)")
32 t_side.add_column("Target Ratio p : q", style="cyan")
33 t_side.add_column("Base Point E", style="white")
34 t_side.add_column("Cut Point Z on AG", style="white")
35 t_side.add_column("Exact GZ", style="gold1")
36 t_side.add_column("Share Areas (DZG : ABDZ)", style="green")
37 for res in (side_bisect, side_third):
38 t_side.add_row(
39 f"{res.ratio_p} : {res.ratio_q}",
40 str(res.pt_e),
41 str(res.pt_z),
42 str(res.gz_length),
43 f"{res.area_dzg} : {res.area_abdz} (sum = {res.area_total})",
44 )
45 console.print(t_side)
46
47 # 2. Dividing Triangle Parallel to Base via Euclid VI.13 Mean Proportional (Boncompagni p. 119)
48 par_101412 = construct_triangle_parallel_division(p=1, q=1, preset="10-14-12")
49 par_131415 = construct_triangle_parallel_division(p=1, q=2, preset="13-14-15")
50
51 t_par = Table(title="Distinctio IV — Dividing Triangle Parallel to Base BG via Semicircle Mean Proportional")
52 t_par.add_column("Triangle & Ratio", style="cyan")
53 t_par.add_column("AE^2", style="gold1")
54 t_par.add_column("AZ^2", style="gold1")
55 t_par.add_column("EZ^2", style="gold1")
56 t_par.add_column("Exact Areas (AEZ : EBGZ)", style="green")
57 t_par.add_row(
58 "(10, 14, 12), 1 : 1 (Boncompagni p. 119)",
59 str(par_101412.ae_quadrance),
60 str(par_101412.az_quadrance),
61 str(par_101412.ez_quadrance),
62 f"{par_101412.area_aez} : {par_101412.area_ebgz}",
63 )
64 t_par.add_row(
65 "(13, 14, 15), 1 : 2",
66 str(par_131415.ae_quadrance),
67 str(par_131415.az_quadrance),
68 str(par_131415.ez_quadrance),
69 f"{par_131415.area_aez} : {par_131415.area_ebgz}",
70 )
71 console.print(t_par)
72
73 # 3. Medians Concurrency & Three-Consort Centroid Partition (Boncompagni pp. 112–113, 120)
74 cent = construct_triangle_medians_centroid()
75 # 4. Trapezoid Parallel Bisection & Three Squares in Arithmetic Progression (7^2, 13^2, 17^2)
76 trap = trapezoid_parallel_division(top_base_a=7, bottom_base_b=17, height=10, p=1, q=1)
77
78 t_more = Table(title="Distinctio IV — Three-Consort Centroid & Trapezoid Root-Mean-Square Cut")
79 t_more.add_column("Construction", style="cyan")
80 t_more.add_column("Exact Invariants", style="green")
81 t_more.add_row(
82 "Three-Consort Centroid D = X(2) on (13, 14, 15)",
83 f"D = {cent.centroid_d}, Area(DAB) = Area(DBG) = Area(DGA) = {cent.consort_area} (Total = {cent.total_area})",
84 )
85 t_more.add_row(
86 "Trapezoid Parallel Bisection (a=7, b=17, h=10)",
87 f"Chord c = {trap.dividing_chord_c} (7^2 + 17^2 = 2 * 13^2 = 338), Areas = {trap.upper_area} : {trap.lower_area}",
88 )
89 console.print(t_more)
90
91
92if __name__ == "__main__":
93 main()
3. Regular Polyhedra, Extreme & Mean Ratio, Flos & Liber Abaci¶
demos/polyhedra_golden_demo.py exercises geometor.fibonacci.polyhedra_golden across Distinctio VI–VIII, Flos (1225), and Liber Abaci Ch. 12:
Simultaneous planar construction of all five Platonic solid edges in a sphere of diameter $6$ ($e_4^2 = 24$, $e_8^2 = 18$, $e_6^2 = 12$, $e_{12}^2 = 18 - 6\sqrt{5}$, $e_{20}^2 = 18 - \frac{18}{5}\sqrt{5}$) and Hypsicles’ Book XIV theorem $V_{12}/V_{20} = e_6/e_{20} = \sqrt{\frac{5 + \sqrt{5}}{6}}$.
Inscription of the regular pentagon and decagon in diameter $10$ via Euclid XIII.9–10 and Ptolemy’s census census quartic $x^4 + 3125 = 125x^2$.
Verification of John of Palermo’s congruum triple $(\frac{31}{12}, \frac{41}{12}, \frac{49}{12})$, the Flos sexagesimal cubic root $1;22,7,42,33,4,40 = \frac{39931699}{29160000}$, and the twelve-month rabbit ratio convergents $F_{n+1}/F_n \to \phi$.
1"""Runnable demonstration of *Practica Geometriae* Dist. VI–VIII, *Flos* (1225), and *Liber Abaci* Ch. 12."""
2
3from __future__ import annotations
4
5import sys
6from pathlib import Path
7
8ROOT = Path(__file__).resolve().parents[1]
9SRC = ROOT / "src"
10if str(SRC) not in sys.path:
11 sys.path.insert(0, str(SRC))
12
13import sympy as sp # noqa: E402
14from rich.console import Console # noqa: E402
15from rich.table import Table # noqa: E402
16
17from geometor.fibonacci import ( # noqa: E402
18 PHI,
19 construct_dodecahedron_golden_chord,
20 construct_pentagon_decagon_in_circle,
21 construct_sphere_polyhedra_section,
22 fibonacci_rabbit_convergents,
23 flos_congruum_squares,
24 flos_sexagesimal_cubic,
25 polyhedra_in_sphere,
26 solve_pentagon_ptolemy_quartic,
27 verify_cassini_identity,
28 verify_hypsicles_xiv_ratio,
29)
30
31
32def main() -> None:
33 console = Console()
34
35 # 1. Five Regular Polyhedra in a Sphere of Diameter d = 6 (Distinctio VI, pp. 190–202)
36 solids = polyhedra_in_sphere(6)
37 section = construct_sphere_polyhedra_section()
38 chord = construct_dodecahedron_golden_chord()
39 xiv_ratio = verify_hypsicles_xiv_ratio(6)
40
41 t_poly = Table(title="Distinctio VI — Five Regular Polyhedra in a Sphere of Diameter d = 6")
42 t_poly.add_column("Polyhedron", style="cyan")
43 t_poly.add_column("Exact Edge e", style="white")
44 t_poly.add_column("Embadum e^2", style="gold1")
45 t_poly.add_column("Face r_f^2", style="white")
46 t_poly.add_column("Insphere r_in^2", style="white")
47 t_poly.add_column("Volume", style="green")
48 for key, s in solids.items():
49 assert sp.simplify(section.quadrances[key] - s.edge_sq) == 0
50 t_poly.add_row(
51 s.name,
52 str(s.edge),
53 str(s.edge_sq),
54 str(s.face_circumradius_sq),
55 str(s.insphere_radius_sq),
56 str(sp.simplify(s.volume)),
57 )
58 console.print(t_poly)
59 console.print(
60 f"[bold green]Golden Chord BG[/bold green] = {chord.golden_major}, "
61 f"[bold green]Hypsicles Book XIV Ratio V_12 / V_20[/bold green] = {xiv_ratio}\n"
62 )
63
64 # 2. Pentagon & Decagon in Diameter 10 (Distinctio VIII, pp. 207–208) + Flos (1225)
65 pent = construct_pentagon_decagon_in_circle()
66 alg_side, alg_diag = solve_pentagon_ptolemy_quartic(10)
67 cubic = flos_sexagesimal_cubic()
68 cong_a, cong_x, cong_b = flos_congruum_squares()
69
70 t_sub = Table(title="Distinctio VIII & Flos (1225) — Algebraic & Geometric Subtleties")
71 t_sub.add_column("Problem", style="cyan")
72 t_sub.add_column("Exact Symbolic Result", style="green")
73 t_sub.add_row(
74 "Decagon & Pentagon in d = 10 (Euclid XIII.9–10)",
75 f"s_10 = {pent.decagon_side}, s_5 = {pent.pentagon_side} (Ptolemy quartic diag/side = {sp.simplify(alg_diag / alg_side)})",
76 )
77 t_sub.add_row(
78 "Flos Congruum Challenge x^2 +/- 5 = square",
79 f"(a, x, b) = ({cong_a}, {cong_x}, {cong_b}) => x^2 - 5 = {cong_a**2}, x^2 + 5 = {cong_b**2}",
80 )
81 t_sub.add_row(
82 "Flos Cubic x^3 + 2x^2 + 10x = 20",
83 f"1;22,7,42,33,4,40 = {cubic.rational_root}, |x_Fib - x_exact| = {float(cubic.abs_root_error.evalf()):.3e}",
84 )
85 console.print(t_sub)
86
87 # 3. Liber Abaci Ch. 12 Rabbit Recurrence -> Golden Ratio phi
88 verify_cassini_identity(15)
89 t_rab = Table(title=f"Liber Abaci Ch. 12 — Twelve-Month Rabbit Convergents to phi = {PHI}")
90 t_rab.add_column("Month", justify="right", style="cyan")
91 t_rab.add_column("Pairs F_{m+2}", justify="right", style="white")
92 t_rab.add_column("Ratio F_{m+2}/F_{m+1}", style="green")
93 t_rab.add_column("Cassini Det", justify="right", style="gold1")
94 t_rab.add_column("|Ratio - phi|", style="magenta")
95 for row in fibonacci_rabbit_convergents(12):
96 t_rab.add_row(
97 str(row.month),
98 str(row.pairs),
99 f"{row.ratio_to_prev} ({float(row.ratio_to_prev):.8f})",
100 f"{int(row.cassini_determinant):+d}",
101 f"{float(row.phi_error_abs.evalf()):.3e}",
102 )
103 console.print(t_rab)
104
105
106if __name__ == "__main__":
107 main()