hex

18.9. Algebraic coefficients🔗

Import HexRCF.RealCoefficients to extend the same rcf command. The original HexRCF import and all its rational examples keep their existing behavior. The adapter is currently available in the development monorepo; it is not in the released hex-rcf package. The optional adapter accepts a selected algebraic coefficient in an otherwise rational polynomial sentence. Its direct notation support covers positive rational square roots and positive rational bases with a reciprocal natural exponent, including Mathlib's (2 : ℝ) ^ (1 / 3 : ℝ). It also accepts the checked Hex values CubeTwo.realAlgebraic and CubeTwo.shifted. For a different coordinate in a chosen number field, write a Selected.field expression with the field element and its checked chosen root, as shown below. In these examples, the power in (2 : ℝ) ^ (1 / 3 : ℝ) defines a closed coefficient; the quantified variable still occurs in an ordinary polynomial. Products with rational constants are supported. Closed division is also supported for the selected and reconstructed Hex inputs and these checked positive-root aliases. The adapter checks every original divisor before solving the target, including divisors erased by cancellation, zero multiplication or an empty domain. Named square/cube aliases keep their existing direct path when all original divisors are rational; algebraic division uses the common field.

Visible RealAlgebraicNumber.ofRat constructors also retain their proved rational value. They use the rational decision path after checked source lowering; mixed expressions may still use the algebraic path. Divisions inside the rational constructor's input remain original guard obligations. A known zero guard reports rcf: original closed divisor is zero, including when zero multiplication or an empty domain would otherwise hide it.

example : ∀ x : ℝ, x ^ 2 + (Hex.RealAlgebraicNumber.ofRat (3 / 2)).toReal > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + (Hex.RealAlgebraicNumber.ofRat (3 / 2)).toReal > 0 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 / (Hex.RealAlgebraicNumber.ofRat 2).toReal + Real.sqrt 2 + Real.sqrt 3 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 / (Hex.RealAlgebraicNumber.ofRat 2).toReal + √2 + √3 > 0 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + Real.sqrt (Hex.RealAlgebraicNumber.ofRat 2).toReal > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + √(Hex.RealAlgebraicNumber.ofRat 2).toReal > 0 All goals completed! 🐙

The last example proves the radicand's equality to 2 before identifying its square root with the positive selected root. Square roots of rational constructors with zero or negative values reduce through the rational path; they do not select a positive algebraic root.

Positive rational roots use the same selected-field certificate machinery. For a rational base a and positive natural degree n, the frontend records a.den * X^n - a.num and checks a real-axis isolating square with a strictly positive lower endpoint. The proved root equation and positivity identify that selected root with a ^ (1 / n : ℝ); approximation proposes the square but supplies no proof. The base and exponent may also use inverse notation, and visible rational constructors are lowered in both. Every original denominator in the base, exponent or surrounding expression remains a source guard.

section set_option maxRecDepth 8192 set_option maxHeartbeats 2400000 example : ∀ x : ℝ, x ^ 2 - 2 * Real.sqrt (1 / 2) * x + 1 / 2 ≥ 0 := ⊢ ∀ (x : ℝ), x ^ 2 - 2 * √(1 / 2) * x + 1 / 2 ≥ 0 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + (5 / 3 : ℝ) ^ (1 / 4 : ℝ) > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + (5 / 3) ^ (1 / 4) > 0 All goals completed! 🐙 example : ∃ x : ℝ, x ^ 2 = Real.sqrt (1 / 2) ∧ 0 < x ∧ x < 1 := ⊢ ∃ x, x ^ 2 = √(1 / 2) ∧ 0 < x ∧ x < 1 All goals completed! 🐙 example : ∀ x : ℝ, x / (2 : ℝ) ^ (1 / 3 : ℝ) = ((2 : ℝ) ^ (1 / 3 : ℝ)) ^ 2 * x / 2 := ⊢ ∀ (x : ℝ), x / 2 ^ (1 / 3) = (2 ^ (1 / 3)) ^ 2 * x / 2 All goals completed! 🐙 end

The first example uses the chosen positive square root in a polynomial whose minimum is zero. The third finds a further root over that coefficient field. The last checks the cube root's nonzero divisor before using its power equation. Division by a closed higher-root alias becomes multiplication by its closed inverse before abstraction, so the shared integer reifier receives no parameter denominator. Natural powers of the quantified variable keep their usual polynomial meaning. Nonreciprocal real exponents are outside this alias grammar. Roots with an algebraic base first authenticate that base in its selected field. Frozen polynomial, power and sign evidence then identifies the root with the original expression. For degrees greater than one, this checks the nonnegative branch; negative bases do not receive a signed-root interpretation. Degree one is ordinary identity and also accepts negative algebraic bases.

section set_option maxRecDepth 16384 set_option maxHeartbeats 2400000 example : ∀ x : ℝ, x ^ 2 - 2 * Real.sqrt (Real.sqrt 2) * x + Real.sqrt 2 ≥ 0 := ⊢ ∀ (x : ℝ), x ^ 2 - 2 * √√2 * x + √2 ≥ 0 All goals completed! 🐙 example : ∃ x : ℝ, x = Real.sqrt (3 + Real.sqrt 2) ∧ 2 < x ∧ x < 3 := ⊢ ∃ x, x = √(3 + √2) ∧ 2 < x ∧ x < 3 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + Real.sqrt (1 / (4 + Real.sqrt 2)) > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + √(1 / (4 + √2)) > 0 All goals completed! 🐙 end

These examples respectively use a nested root as a coefficient, locate a root of a shifted algebraic base, and retain the original divisor guard inside a root. Cancellation can yield a zero base, but never removes a zero-divisor obligation. The same authentication supports reciprocal natural root degrees such as (3 + Real.sqrt 2) ^ (1 / 3 : ℝ) and further nesting. The ordinary proof checks recorded certificates; it does not repeat the native root or sign searches.

Before common-field search, rcf.algebraic.commonDegree bounds the product of the canonical degrees of distinct selected generators (default 64), reporting exhaustion through the shared exponent dimension. This is a conservative admission bound: aliases for one selected generator count once, but algebraic relations between different generators can make the actual common degree smaller than the product. The admission also applies to a single generator. Algebraic-base roots require the root degree times the degree of the field authenticating their base to fit the same limit. This conservative bound applies before native root production, including when cancellation reduces the base's minimal degree. Repeated uses of exactly the same base share authentication throughout one recursive preparation. These roots require supported selected-field presentations and irreducibility certificates. It does not establish complete witness search or bound every later operation. Authentication follows source order; a terminal failure or exhaustion prevents authentication of later coefficients, even when a later negative base would decline.

The adapter's source preparation applies its coefficient-size limit to intermediate arithmetic in rational-root bases, reciprocal exponents and dyadic endpoints. Cancellation and zero powers do not erase those bounds.

The selected-field constructions below use the real root of X³ − 2. The adapter records an isolating square and verifies its root witness. It reconstructs Hex's Hex.AlgebraicNumber and Hex.RealAlgebraicNumber through the existing canonical constructor. The second coefficient is computed as 1 + a inside Hex.QAdjoin, then converted through Hex.RCF.RealCoefficients.Coefficients.ofField; its selected real value is proved to be 1 + a.toReal. This ofField tactic example uses the specific checked value CubeTwo.shifted. The definitions CubeTwo.realAlgebraic and CubeTwo.shifted contain these constructions, and the following aliases show their types and use. The second construction below takes a checked selected root directly, computes (a² + 1) / 2 with ordinary Hex.QAdjoin arithmetic, and uses Hex.RCF.RealCoefficients.Selected.field to retain the same root when converting back to a real algebraic number. These examples set maxRecDepth to 2048 and maxHeartbeats to 1000000 so Lean can elaborate their literal certificates; users may need the same options for similar goals.

The same checked construction works for a different cubic, X³ − X − 1. The square below selects its positive real root. The Hex.RCF.RealCoefficients.Selected.real_rootNear theorem identifies that root with the ordinary Hex.ZPoly.rootNear value at the real projection of the square's centre. The tactic can use the selected root when it is named by a def in the same file. It also accepts the existing checked Hex.AlgebraicNumber.ofNormalized constructor directly, followed by Hex.RealAlgebraicNumber.ofAlgebraic with a reality proof. The original isolation square authenticates the chosen root. Elaboration executes canonicalization. Before common-field search, the adapter checks a direct root witness on the original square. The kernel authenticates its literal square and polynomial identities rather than replaying canonicalization. Both identities must reduce in the kernel, including across imports. A transported certificate without a direct witness is currently rejected. The example below computes α² − 1 in the field of the selected root of X³ − X − 1 and uses its proved real conversion. The constructor data must be executable and visible to the frontend; an arbitrary opaque algebraic value has no implicit reconstruction rule.

Field signs first try exact rational Horner bounds on the authenticated generator interval. A strictly separated bound proves its sign; exactly [0,0] proves zero. Other zero-containing bounds retain a full rational Sturm query. Replay checks the recorded branch, and never rescues malformed query evidence with interval evaluation. The complete algebraic producer still succeeds on its proved input surface. Indexed sign retrieval below reduces fresh-module build time on the recorded examples.

A four-round matched comparison on the further-root, reciprocal-root and cubic examples used raw carriers and favored interval quotation in all twelve pairs, with median paired margins 4.513, 4.752 and 13.553 seconds. The reference reconstructs full queries after interval production, so this measures quotation-mode selection, not a speedup against older code or isolated kernel time. Shared-host variation and all completed samples are retained in reports/hexrcf-interval-proofs.md. Those probes now pin raw carriers explicitly; the pin was added after the measurement. The default is rcf.algebraic.intervalSigns=true; the false arm remains a comparison control. Direct coordinate quotation remains off by default: its two separate comparisons did not establish a gain. The comparison control changes evidence from the tactic producers. Quotation and replay of a supplied frozen table, including the explicit prepared replay API, preserve its entries regardless of this option.

rcf.algebraic.singleReplay is also false by default. It compares one Boolean certificate replay goal with separately checked conjuncts; source authentication and the final proof check remain separate. A four-round comparison of the same three examples used raw carriers and did not establish a speedup. The probes now explicitly pin that mode; the pin was added after the retained measurement. Combined replay produced smaller private proof files but used more peak memory. The report and retained samples record every completed arm and the exact source and import identities.

rcf.algebraic.monicCore is true by default. It normalizes the proposed carrier core while retaining the original polynomial product and checking both radical identities. Signed Sturm chains keep their existing positive scaling. All twelve pairs in a four-round comparison favored this mode on the same three examples, with lower peak memory. The report and retained samples describe these full-build observations. Successful proposals have checked soundness and a proved monic core. Radical proposal progress and interpreted squarefreeness are proved at the actual selected field embedding, using zero-reflecting coefficient semantics that preserve arithmetic and inversion. These are radical laws; bounded isolation can still exhaust. The complete library producer retains raw cores and its existing progress laws. Direct produceWithin calls also retain their raw default; the tactic passes its monic option explicitly. The false mode retains raw cores as a comparison control. This normalization does not remove the common-field authentication limitation.

rcf.algebraic.indexSigns is true by default. It retrieves field signs through a frozen tree of positions in the original checked evidence table. Every hit checks its array bounds and exact key. A missing route uses the original table lookup, so malformed routing cannot lose a recorded sign; an absent original entry still fails preflight. The kernel checks the same sign evidence and uses a proved checker equivalence before the existing soundness theorem. It does not sort keys during replay. Two separate four-round comparisons favored indexed lookup in every pair on the further-root, reciprocal and cubic examples. The preserved-hit mode's median paired reductions were 3.774, 3.493 and 3.527 seconds, with lower peak memory and larger private proof files. These are full fresh-module costs, not isolated lookup timing or an asymptotic claim. The report and retained samples include every completed arm and their source identities. The false mode keeps linear retrieval; older comparison probes explicitly pin that mode.

rcf.algebraic.signRefinements is zero by default. Setting it to a positive natural number bounds producer attempts to tighten the generator interval when Horner signs are inconclusive. The certificate retains the original generator and checks that the tighter count-one interval selects the same real root. Replay checks frozen data and never runs refinement. Inconclusive signs keep full query evidence; invalid proposed evidence is terminal. The retained comparison found no useful whole-module speedup at a four-step budget, even though the lower-precision fixed-field case removed full queries. This mode therefore remains optional. The entire bounded refinement loop is one native call: cancellation is checked before and after it, not between its steps. A large chosen budget can therefore delay interruption.

A separate initial-precision comparison proves the same fixed-field sentence at eight and sixty-four generator bits, using a checked selected-root equivalence for transport. The full sign queries fall from three to zero, and the private proof file shrinks by 6,456 bytes. Four retained rounds give median fresh-module times of 12.689 and 12.556 seconds; the paired median change is −0.169 seconds, with one slower candidate. Arm-specific constructor checks and the candidate transport are prebuilt, so their initial elaboration is excluded. This does not measure the total cost of changing precision or general field reconstruction, and does not justify a default precision change.

The four-width study with constructor and transport included checks eight, sixteen, thirty-two and sixty-four initial bits through the actual tactic proof-acceptance routine. All 36 fresh-module arms retain their output and standard-axiom audit. The variable paired observations justify no default change. Each timed module proves its own generator validity and selected-root equivalence; common imported laws and the original target are prebuilt. This fixed-field experiment does not implement arbitrary field reconstruction or nested transport.

The source repeated/shared-root comparison uses actual rcf goals with a squared zero polynomial and an additional polynomial sharing existing roots. All three checked carriers have four root sections and five sectors. Sixteen retained arms include the named-√2 frontend preparation, quotation and kernel acceptance; paired medians increase by 0.890 and 1.266 seconds for these changed inputs, retaining a −8.198-second repeated-input observation as well. Several input dimensions change together, so this is not a one-parameter complexity model or a general scaling claim.

For these reconstructed inputs, closed arithmetic is compiled into the common field after authenticating its source values. A quotient is recorded as a rational coordinate polynomial and checked by its multiplication identity; kernel replay does not repeat inverse search. When all source coordinates use one selected generator, the adapter retains that generator and its existing power basis; it does not run general common-field search. Polynomial and isolation-square checks still authenticate every proposed source coordinate. If the common defining polynomial exactly matches an authenticated source's polynomial, quotation reuses its supplied CheckedIrreducible proof. The kernel proves equality of the original and literal polynomials and transports the source instance along that equality; runtime equality alone is insufficient. This supports source proofs beyond the frontend's single-witness and quadratic-norm search languages, including a checked real quartic with a multi-prime certificate. The fresh goal proofs use ordinary imports, including certificate construction and replay through the owner's public API.

For a new common polynomial, the frontend first checks for an existing CheckedIrreducible instance for its exact quoted DensePoly.ofCoeffs literal. It binds that literal to the runtime polynomial and checks the supplied proof's type, axiom dependencies and ordinary-kernel validity. A rejected proof or an instance-search resource failure is terminal. If no certificate language succeeds, the diagnostic prints the exact instance target. An instance written using DensePoly.ofList need not match instance search's transparency.

The degree-eight regression uses one previously proved instance for the compositum of the selected quartic and √2, enabled with open scoped Hex.RCF.SuppliedIrreducible; its kernel irreducibility check reuses that theorem. Common-field construction still runs the normal native algorithm during search.

The matched construction-cost report compares rebuilding this proof with importing it for the same degree-eight goal and private executable imports; it records shared-host running times and memory, without a general scaling or automatic-certification claim.

Without such an instance, the frontend tries quadratic-norm and free witness certificates, then the owner's multi-prime certificate producer and ordinary-kernel quotation. These certificate languages do not cover every irreducible common defining polynomial. Increasing a search bound need not resolve a refusal, and their failure does not imply reducibility. The cubic example below verifies x / α = (α² − 1) * x at the selected positive root of X³ − X − 1. The same example also uses the ordinary QAdjoin.toAlgebraicNumber conversion followed by a reality proof, without the Coefficients.ofField wrapper. Both forms preserve the selected embedding.

The two-square-root examples below combine Real.sqrt 2 and Real.sqrt 3 in one common field and check that each field coordinate names the intended positive root. This path accepts positive rational radicands as well as natural literals, and also accepts the positive rational-root aliases above. A lone Real.sqrt 2 whose original divisors are all rational uses the earlier single-coefficient path; other positive natural square roots use the common-field frontend, including perfect-square radicands. Algebraic divisors contribute generators even when their quotients cancel, so they can increase the common-field degree. The two-root examples use a larger heartbeat limit for the quartic common field. The retained measurements below do not measure that degree increase. The next examples mix Mathlib's Real.sqrt 2 with a Hex root selected from X² − 3. They also use the ordinary QAdjoin element 1 + √3, converted back to a real algebraic number. rcf checks each proposed common-field coordinate against the original selected root before proving the sentence. For multiple sources, the tactic checks a defining polynomial and selected real root for the common field, then verifies that every original coefficient has the proposed value there. The higher-degree example below combines the selected real root of X³ − 2 with Real.sqrt 2. Some larger combinations still decline with an irreducibility-witness diagnostic: the current certificate search does not cover every polynomial that can define a common field.

open Hex.RCF.RealCoefficients set_option maxRecDepth 2048 set_option maxHeartbeats 1000000 private abbrev cubicGenerator : Hex.AlgebraicNumber := CubeTwo.realAlgebraic.toAlgebraic private abbrev fieldCoordinate : Hex.QAdjoin cubicGenerator := 1 + cubicGenerator.toQAdjoin private abbrev fieldCoefficient : Hex.RealAlgebraicNumber := Coefficients.ofField CubeTwo.realAlgebraic fieldCoordinate private abbrev selectedCubic : Hex.RealAlgebraicNumber := Selected.real CubeTwo.polynomial CubeTwo.square (⊢ Hex.atomWitness CubeTwo.polynomial CubeTwo.square All goals completed! 🐙) (⊢ ↑(Hex.mahlerPrec CubeTwo.polynomial) ≤ CubeTwo.square.prec All goals completed! 🐙) (⊢ CubeTwo.polynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff CubeTwo.polynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree CubeTwo.polynomial All goals completed! 🐙) CubeTwo.checked CubeTwo.squarefree (⊢ CubeTwo.square.meetsRealAxis = true All goals completed! 🐙) private abbrev selectedGenerator : Hex.AlgebraicNumber := selectedCubic.toAlgebraic private abbrev computedCoordinate : Hex.QAdjoin selectedGenerator := (selectedGenerator.toQAdjoin * selectedGenerator.toQAdjoin + 1) / 2 private abbrev computedCoefficient : Hex.RealAlgebraicNumber := Selected.field CubeTwo.polynomial CubeTwo.square (⊢ Hex.atomWitness CubeTwo.polynomial CubeTwo.square All goals completed! 🐙) (⊢ ↑(Hex.mahlerPrec CubeTwo.polynomial) ≤ CubeTwo.square.prec All goals completed! 🐙) (⊢ CubeTwo.polynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff CubeTwo.polynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree CubeTwo.polynomial All goals completed! 🐙) CubeTwo.checked CubeTwo.squarefree (⊢ CubeTwo.square.meetsRealAxis = true All goals completed! 🐙) computedCoordinate private abbrev plasticPolynomial : Hex.ZPoly := Hex.DensePoly.ofList [-1, -1, 0, 1] private abbrev plasticSquare : Hex.DyadicSquare := ⟨Dyadic.ofInt 5426 >>> (12 : Int), 0, 12⟩ private theorem plasticChecked : plasticPolynomial.CheckedIrreducible := ⟨⊢ plasticPolynomial.isIrreducible = true All goals completed! 🐙, ⊢ 0 < Hex.DensePoly.natDegree plasticPolynomial All goals completed! 🐙⟩ private theorem plasticSquarefree : Hex.HasOnlySimpleRoots plasticPolynomial := ⊢ Hex.HasOnlySimpleRoots plasticPolynomial hne:plasticPolynomial ≠ 0⊢ Hex.HasOnlySimpleRoots plasticPolynomial Try this: letI̵ The goal is a proposition, so `let` is preferred over `letI`. The difference between `let` and `letI` is that `letI` inlines the value. But this is not relevant for proofs because of proof irrelevance. Note: This linter can be disabled with `set_option linter.style.haveILetI false`hne:plasticPolynomial ≠ 0this:plasticPolynomial.CheckedIrreducible := ···⊢ Hex.HasOnlySimpleRoots plasticPolynomial All goals completed! 🐙 private def plasticRoot : Hex.RealAlgebraicNumber := Selected.real plasticPolynomial plasticSquare (⊢ Hex.atomWitness plasticPolynomial plasticSquare All goals completed! 🐙) (⊢ ↑(Hex.mahlerPrec plasticPolynomial) ≤ plasticSquare.prec All goals completed! 🐙) (⊢ plasticPolynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff plasticPolynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree plasticPolynomial All goals completed! 🐙) plasticChecked plasticSquarefree (⊢ plasticSquare.meetsRealAxis = true All goals completed! 🐙) example : plasticPolynomial.rootNear plasticSquare.re.toRat 0 = plasticRoot.toAlgebraic := ⊢ plasticPolynomial.rootNear plasticSquare.re.toRat = plasticRoot.toAlgebraic exact Selected.real_rootNear plasticPolynomial plasticSquare (⊢ Hex.atomWitness plasticPolynomial plasticSquare All goals completed! 🐙) (⊢ ↑(Hex.mahlerPrec plasticPolynomial) ≤ plasticSquare.prec All goals completed! 🐙) (⊢ plasticPolynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff plasticPolynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree plasticPolynomial All goals completed! 🐙) plasticChecked plasticSquarefree (⊢ plasticSquare.meetsRealAxis = true All goals completed! 🐙) example : ∀ x : ℝ, x + plasticRoot.toReal > x := ⊢ ∀ (x : ℝ), x + plasticRoot.toReal > x All goals completed! 🐙 private abbrev plasticRep : Hex.RefinedIsolation plasticPolynomial := Field.literalRep plasticPolynomial plasticSquare (⊢ Hex.atomWitness plasticPolynomial plasticSquare All goals completed! 🐙) (⊢ ↑(Hex.mahlerPrec plasticPolynomial) ≤ plasticSquare.prec All goals completed! 🐙) private abbrev plasticAlgebraic : Hex.AlgebraicNumber := Hex.AlgebraicNumber.ofNormalized plasticPolynomial (⊢ plasticPolynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff plasticPolynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree plasticPolynomial All goals completed! 🐙) plasticChecked plasticSquarefree plasticRep (Hex.AlgebraicNumber.ofNormalized?_isSome _ _ _ _ _ _ _) private def normalizedPlastic : Hex.RealAlgebraicNumber := Hex.RealAlgebraicNumber.ofAlgebraic plasticAlgebraic (⊢ plasticAlgebraic.isReal = true ⊢ plasticAlgebraic.toComplex.im = 0 exact (congrArg Complex.im (Selected.normalized_toComplex plasticPolynomial (⊢ plasticPolynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff plasticPolynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree plasticPolynomial All goals completed! 🐙) plasticChecked plasticSquarefree plasticRep _)).trans (Field.literalRep_real _ _ _ _ (⊢ plasticSquare.meetsRealAxis = true All goals completed! 🐙))) private abbrev plasticCoordinate : Hex.QAdjoin normalizedPlastic.toAlgebraic := normalizedPlastic.toAlgebraic.toQAdjoin ^ 2 - 1 private abbrev plasticCoefficient : Hex.RealAlgebraicNumber := Coefficients.ofField normalizedPlastic plasticCoordinate example : ∀ x : ℝ, x ^ 2 + plasticCoefficient.toReal > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + plasticCoefficient.toReal > 0 All goals completed! 🐙 example : ∀ x : ℝ, x / normalizedPlastic.toReal = plasticCoefficient.toReal * x := ⊢ ∀ (x : ℝ), x / normalizedPlastic.toReal = plasticCoefficient.toReal * x All goals completed! 🐙 private abbrev convertedPlastic : Hex.RealAlgebraicNumber := Hex.RealAlgebraicNumber.ofAlgebraic plasticCoordinate.toAlgebraicNumber (⊢ plasticCoordinate.toAlgebraicNumber.isReal = true ⊢ (Hex.PolyQuot.toComplex plasticCoordinate normalizedPlastic.toAlgebraic.rep ⋯).im = 0 All goals completed! 🐙) example : ∀ x : ℝ, x / normalizedPlastic.toReal = convertedPlastic.toReal * x := ⊢ ∀ (x : ℝ), x / normalizedPlastic.toReal = convertedPlastic.toReal * x All goals completed! 🐙 example : ∀ x : ℝ, x / Real.sqrt 2 = (Real.sqrt 2 / 2) * x := ⊢ ∀ (x : ℝ), x / √2 = √2 / 2 * x All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + Real.sqrt 4 - Real.sqrt 2 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + √4 - √2 > 0 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + 1 / (Real.sqrt 2 + 1) > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + 1 / (√2 + 1) > 0 All goals completed! 🐙 example : ∃ x : ℝ, x ^ 2 = 1 / (Real.sqrt 2 + 1) ∧ 0 < x ∧ x < 1 := ⊢ ∃ x, x ^ 2 = 1 / (√2 + 1) ∧ 0 < x ∧ x < 1 All goals completed! 🐙 /-- error: rcf: original closed divisor is zero -/ #guard_msgs in example : ∀ x : ℝ, x ^ 2 + 0 / (normalizedPlastic.toReal - normalizedPlastic.toReal) ≥ 0 := ⊢ ∀ (x : ℝ), x ^ 2 + 0 / (normalizedPlastic.toReal - normalizedPlastic.toReal) ≥ 0 ⊢ ∀ (x : ℝ), x ^ 2 + 0 / (normalizedPlastic.toReal - normalizedPlastic.toReal) ≥ 0 example : ∃ x : ℝ, x ^ 2 = normalizedPlastic.toReal ∧ 1 < x ∧ x < normalizedPlastic.toReal := ⊢ ∃ x, x ^ 2 = normalizedPlastic.toReal ∧ 1 < x ∧ x < normalizedPlastic.toReal All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + Real.sqrt 2 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + √2 > 0 All goals completed! 🐙 /- The tactic checks both roots in one common field. -/ set_option maxHeartbeats 5000000 in example : ∀ x : ℝ, x ^ 2 + Real.sqrt 3 - Real.sqrt 2 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + √3 - √2 > 0 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 set_option maxHeartbeats 5000000 in example : ∃ x : ℝ, Real.sqrt 2 < x ∧ x < Real.sqrt 3 := ⊢ ∃ x, √2 < x ∧ x < √3 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 private abbrev squareThreePolynomial : Hex.ZPoly := Hex.DensePoly.ofList [-3, 0, 1] private abbrev squareThreeSelection : Hex.DyadicSquare := ⟨Dyadic.ofInt 7094 >>> (12 : Int), 0, 10⟩ private theorem squareThreeChecked : squareThreePolynomial.CheckedIrreducible := Field.checkedIrreducible squareThreePolynomial (.eisenstein 3 0) (⊢ squareThreePolynomial.checkIrredWitness (Hex.ZPoly.IrredWitness.eisenstein 3 0) = true All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree squareThreePolynomial All goals completed! 🐙) private theorem squareThreeSquarefree : Hex.HasOnlySimpleRoots squareThreePolynomial := ⊢ Hex.HasOnlySimpleRoots squareThreePolynomial hne:squareThreePolynomial ≠ 0⊢ Hex.HasOnlySimpleRoots squareThreePolynomial Try this: letI̵ The goal is a proposition, so `let` is preferred over `letI`. The difference between `let` and `letI` is that `letI` inlines the value. But this is not relevant for proofs because of proof irrelevance. Note: This linter can be disabled with `set_option linter.style.haveILetI false`hne:squareThreePolynomial ≠ 0this:squareThreePolynomial.CheckedIrreducible := ···⊢ Hex.HasOnlySimpleRoots squareThreePolynomial All goals completed! 🐙 private def selectedThree : Hex.RealAlgebraicNumber := Selected.real squareThreePolynomial squareThreeSelection (⊢ Hex.atomWitness squareThreePolynomial squareThreeSelection All goals completed! 🐙) (⊢ ↑(Hex.mahlerPrec squareThreePolynomial) ≤ squareThreeSelection.prec All goals completed! 🐙) (⊢ squareThreePolynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff squareThreePolynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree squareThreePolynomial All goals completed! 🐙) squareThreeChecked squareThreeSquarefree (⊢ squareThreeSelection.meetsRealAxis = true All goals completed! 🐙) private abbrev squareThreeGenerator : Hex.AlgebraicNumber := selectedThree.toAlgebraic private abbrev squareThreeCoordinate : Hex.QAdjoin squareThreeGenerator := 1 + squareThreeGenerator.toQAdjoin private abbrev shiftedThree : Hex.RealAlgebraicNumber := Coefficients.ofField selectedThree squareThreeCoordinate set_option maxHeartbeats 5000000 in example : ∀ x : ℝ, x ^ 2 + selectedThree.toReal - Real.sqrt 2 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + selectedThree.toReal - √2 > 0 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 set_option maxHeartbeats 5000000 in example : ∀ x : ℝ, x ^ 2 + shiftedThree.toReal - Real.sqrt 2 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + shiftedThree.toReal - √2 > 0 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 set_option maxHeartbeats 5000000 in example : ∀ x : ℝ, x ^ 2 + selectedCubic.toReal - Real.sqrt 2 + 1 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + selectedCubic.toReal - √2 + 1 > 0 exponent 753 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 /-- error: rcf: the universal sentence is false on the prepared cells -/ #guard_msgs (whitespace := lax) in set_option maxHeartbeats 5000000 in example : ∀ x : ℝ, x ^ 2 + selectedThree.toReal - Real.sqrt 2 < 0 := ⊢ ∀ (x : ℝ), x ^ 2 + selectedThree.toReal - √2 < 0 ⊢ ∀ (x : ℝ), x ^ 2 + selectedThree.toReal - √2 < 0 example : ∃ x : ℝ, Real.sqrt 2 < x ∧ x < (3 : ℝ) / 2 := ⊢ ∃ x, √2 < x ∧ x < 3 / 2 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + (2 : ℝ) ^ (1 / 3 : ℝ) > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + 2 ^ (1 / 3) > 0 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + CubeTwo.realAlgebraic.toReal > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + CubeTwo.realAlgebraic.toReal > 0 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + fieldCoefficient.toReal > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + fieldCoefficient.toReal > 0 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + computedCoefficient.toReal > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + computedCoefficient.toReal > 0 All goals completed! 🐙 example : ∃ x : ℝ, x ^ 2 = selectedCubic.toReal := ⊢ ∃ x, x ^ 2 = selectedCubic.toReal All goals completed! 🐙 example : ∃ x : ℝ, x ^ 2 = selectedCubic.toReal ∧ 1 < x ∧ x < selectedCubic.toReal := ⊢ ∃ x, x ^ 2 = selectedCubic.toReal ∧ 1 < x ∧ x < selectedCubic.toReal All goals completed! 🐙 example : True := ⊢ True fail_if_success ⊢ ∀ (x : ℝ), x ^ 2 + √2 < 0 All goals completed! 🐙 example : True := ⊢ True fail_if_success ⊢ ∀ (x : ℝ), Real.sin x = 0 All goals completed! 🐙

The existential statements have no witness supplied by the user. For the selected cubic coefficient, rcf isolates a root of x² − selectedCubic over its fixed real number field and checks both inequalities at that same root in the interval example. The fail_if_success examples show that a false algebraic statement produces no proof, nonpolynomial syntax in the quantified variable is rejected, and a cancelled zero divisor remains an invalid input. CubeTwo.realAlgebraic exposes its checked selected-root construction, so its lone examples use the selected-root frontend. Earlier cubic measurements record their stated source revision and do not measure this routing change. The adapter's source reifier preserves explicit coefficient aliases and original divisor obligations before normalization. Closed values built with Selected.real may be named using def in the same file. Across modules, use abbrev or @[expose] def so the defining expression remains visible. For supported sentences, a divisor must be proved nonzero before certificate construction.

The next construction selects the positive root near 1.675 of X³ − 4X + 2. Combining it with √37 creates a degree-six common defining polynomial. The frontend's single-witness and quadratic-norm producers decline that new polynomial; the public multi-prime certificate route authenticates it before the goal's root and sign checks.

private abbrev certificatePolynomial : Hex.ZPoly := Hex.DensePoly.ofList [2, -4, 0, 1] private abbrev certificateSquare : Hex.DyadicSquare := ⟨Dyadic.ofIntWithPrec 112416129 26, 0, 24⟩ private theorem certificateChecked : certificatePolynomial.CheckedIrreducible := Field.checkedIrreducible certificatePolynomial (.eisenstein 2 0) (⊢ certificatePolynomial.checkIrredWitness (Hex.ZPoly.IrredWitness.eisenstein 2 0) = true All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree certificatePolynomial All goals completed! 🐙) private theorem certificateSquarefree : Hex.HasOnlySimpleRoots certificatePolynomial := ⊢ Hex.HasOnlySimpleRoots certificatePolynomial this:certificatePolynomial.CheckedIrreducible := ···⊢ Hex.HasOnlySimpleRoots certificatePolynomial exact (HexRootsTheory.hasOnlySimpleRoots_iff_separable certificatePolynomial (this:certificatePolynomial.CheckedIrreducible := ···⊢ certificatePolynomial ≠ 0 All goals completed! 🐙)).mpr (Hex.ZPoly.CheckedIrreducible.separable certificatePolynomial) private abbrev certificateRoot : Hex.RealAlgebraicNumber := Selected.real certificatePolynomial certificateSquare (⊢ Hex.atomWitness certificatePolynomial certificateSquare All goals completed! 🐙) (⊢ ↑(Hex.mahlerPrec certificatePolynomial) ≤ certificateSquare.prec All goals completed! 🐙) (⊢ certificatePolynomial.Primitive All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.leadingCoeff certificatePolynomial All goals completed! 🐙) (⊢ 0 < Hex.DensePoly.natDegree certificatePolynomial All goals completed! 🐙) certificateChecked certificateSquarefree (⊢ certificateSquare.meetsRealAxis = true All goals completed! 🐙) set_option maxRecDepth 8192 in set_option maxHeartbeats 5000000 in example : ∀ x : ℝ, x ^ 2 + certificateRoot.toReal + Real.sqrt 37 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + certificateRoot.toReal + √37 > 0 exponent 1403 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙

The algebraic examples use the proved generic accepted-query soundness theorem HexRealRootsTheory.Tarski.check_rootSum. Their fixed-field certificate checks and chosen-root identifications use only Lean's standard logical axioms. See HexNumberField and HexRealAlgebraic for the underlying number APIs.

Visible checked conversions preserve the actual option branch. RealAlgebraicNumber.ofAlgebraic? succeeds for a selected real or rational value, or an element of QAdjoin a.toAlgebraic for a real algebraic generator a. When applied to AlgebraicNumber.I, it returns none, so getD denotes its stated fallback. An explicit .re projection instead denotes the real part; the real part of I is zero.

example : ∃ x : ℝ, x = ((Hex.RealAlgebraicNumber.ofAlgebraic? Hex.AlgebraicNumber.I).getD (Hex.RealAlgebraicNumber.ofRat (3 / 2))).toReal ∧ 1 < x ∧ x < 2 := ⊢ ∃ x, x = ((Hex.RealAlgebraicNumber.ofAlgebraic? Hex.AlgebraicNumber.I).getD (Hex.RealAlgebraicNumber.ofRat (3 / 2))).toReal ∧ 1 < x ∧ x < 2 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + Hex.AlgebraicNumber.I.re.toReal ≥ 0 := ⊢ ∀ (x : ℝ), x ^ 2 + Hex.AlgebraicNumber.I.re.toReal ≥ 0 All goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + (4 : Hex.RealAlgebraicNumber).toReal + ((-3 : Int) : Hex.RealAlgebraicNumber).toReal > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + Hex.RealAlgebraicNumber.toReal 4 + (↑(-3)).toReal > 0 All goals completed! 🐙

The frontend also lowers visible real-algebraic arithmetic, inverses, natural powers and integer casts using the number library's interpretation theorems. Supported projections include selected real values, rational values, real QAdjoin coordinates and sums of supported projections. This recognition does not provide a general procedure for arbitrary complex expressions or opaque conversion code. Original rational, real-algebraic and supported real-field divisors remain obligations, including divisors inside an unused getD fallback, before any branch is simplified. Division over other carriers, raw PolyQuot.div/inv, integer powers and divisions depending on a binder inside conversions are rejected.

A fresh-module comparison of the cubic reciprocal uses identical imports and shared source setup for Coefficients.ofField and direct QAdjoin.toAlgebraicNumber conversion. At source b10ded789, Lean v4.35.0-rc3 on shared chungus2 CPU 18, four adjacent alternating AB/BA rounds give median build times 10.441 and 10.443 seconds respectively, with median peak RSS 3.29 GiB in both arms. The median paired direct-minus-wrapped margin is +0.013 seconds; margins range from −0.045 to +0.071 seconds and do not resolve a cost difference. Both private olean files contain 603,000 bytes. These are fresh-module lake build wall times, including Lake startup and replay, for one identity whose specialized equality atom is zero. There is no import-only arm or root-search scaling claim. The report and retained samples record all eight arms and host activity, and retain the separate b0c583792 snapshot. Each measurement is tied to its recorded source; later routing and environment cleanup are outside those measurements. They do not isolate the cost of checking separate source and target sign tables or establish general extension performance or total algebraic search.

A separate fixed-field input report retains 24 matched-import builds varying variable degree, atom count and integer coefficient width independently. These root-free carriers do not measure precision or nested depth. A representative two-field further-root proof, ∃ x : ℝ, x² = Real.sqrt 2 ∧ 1 < x ∧ x < Real.sqrt 3, takes 43.672 seconds at its recorded source on leased CPU 14, including build and profiler overhead. That source used full Sturm-query quotation and predates interval signs; this profile does not attribute the cost of the current default. Its exclusive kernel type-checking category totals 30.1 seconds; the smaller literal-replay category excludes those child checks. The report retains source identities, memory, serialized sizes, unique syntax and expanded-reference counts. It does not claim a complexity law or complete Phase-4 attestation.

18.9.1. Closed coefficient arithmetic🔗

The frontend keeps a whole closed arithmetic expression as one coefficient. For example, Real.sqrt 2 + Real.sqrt 3 is one coordinate, as are its square and its negative; repeated occurrences share that coordinate. The coefficient interpreter evaluates the expression in the selected common field. Bare named generators keep their direct handler; arithmetic around them uses the common-field handler, reusing that same field for a single generator.

Here √2 is Lean's notation for Real.sqrt 2.

example : ∀ x : ℝ, x ^ 2 + (√2 + √3) > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + (√2 + √3) > 0 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 example : ∀ x : ℝ, x ^ 2 + (√2 + √3) ^ 2 > 0 := ⊢ ∀ (x : ℝ), x ^ 2 + (√2 + √3) ^ 2 > 0 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙 example : ∃ x : ℝ, x = -(√2 + √3) ∧ x < -3 := ⊢ ∃ x, x = -(√2 + √3) ∧ x < -3 exponent 262 exceeds the threshold 256, exponentiation operation was not evaluated, use `set_option exponentiation.threshold <num>` to set a new thresholdAll goals completed! 🐙

These examples use the real-coefficient certificate checker. Fresh-module checks verify the corresponding named conformance proofs and their actual body dependencies. Extracting a whole coefficient never removes an original divisor condition: even 0 * (1 / (Real.sqrt 2 - Real.sqrt 2)) keeps its zero divisor through source preparation. The handler rejects it when preparing guards.