A candidate that divides both inputs is the gcd full
This proof shows: correctness, termination.
Let f,g∈Z[x] be nonzero and primitive, as after line L1. Let G=gcd(f,g), primitive with a positive leading coefficient. Fix an integer ξ≥2min(∣f∣∞,∣g∣∞)+2, and say a∈{f,g} is the input with ∣a∣∞=min(∣f∣∞,∣g∣∞). Every point used by the algorithm satisfies this bound: line L2 sets ξ to it, and line L8 never makes ξ smaller, because ⌊ξ⋅73794/27011⌋≥ξ for ξ≥1.
Fact 1 (Cauchy bound). If p∈Z[x] divides a and α∈C is a root of p, then ∣α∣<1+∣a∣∞≤ξ/2.
Proof. α is a root of a=∑i=0maixi with am=0. If ∣α∣≤1 the claim holds since ∣a∣∞≥1. Otherwise amαm=−∑i<maiαi gives
∣α∣m≤∣am∣∣α∣m≤∣a∣∞i<m∑∣α∣i=∣a∣∞∣α∣−1∣α∣m−1<∣a∣∞∣α∣−1∣α∣m, so ∣α∣−1<∣a∣∞. Finally 1+∣a∣∞≤ξ/2 is the bound on ξ. □
Fact 2. If p∈Z[x] divides a and degp=e≥1, then ∣p(ξ)∣>(ξ/2)e≥ξ/2. If p divides a and p=0, then p(ξ)=0.
Proof. Write p=lc(p)∏j=1e(x−αj). By Fact 1, ∣ξ−αj∣≥ξ−∣αj∣>ξ−ξ/2=ξ/2, and ∣lc(p)∣≥1. So ∣p(ξ)∣>(ξ/2)e, which is at least ξ/2 because ξ/2≥1. For e=0, p is a nonzero constant. □
Fact 3. For γ=0, h~=genpoly(γ,ξ) is nonzero, satisfies h~(ξ)=γ, and every coefficient lies in (−ξ/2,ξ/2]. Hence ∣cont(h~)∣≤ξ/2.
Proof. The expansion loop keeps γorig=∑j<ihjξj+γiξi, where γi is the value of γ after i steps, and it stops when γi=0. It does stop: if ∣γi∣≥1 then ∣γi+1∣≤(∣γi∣+ξ/2)/ξ<∣γi∣, because ξ≥2. Each digit is chosen in (−ξ/2,ξ/2]. The content divides each nonzero coefficient, so it is at most ξ/2 in absolute value, and there is a nonzero coefficient since γ=0. □
Theorem. At any try, let γ=gcd(f(ξ),g(ξ)), h~=genpoly(γ,ξ) and h=pp(h~). If h divides f and g in Z[x], then h=G.
Proof. By Fact 2 with p=a, a(ξ)=0, so γ=0 and Fact 3 applies. Write h~=ch with c=±cont(h~), so 0<∣c∣≤ξ/2.
Since h is primitive and divides f and g, it divides G (in Z[x], a common divisor divides the gcd). Write G=hk with k∈Z[x]. Since G divides f and g, the integer G(ξ) divides f(ξ) and g(ξ), hence divides γ: γ=mG(ξ) for a nonzero integer m. Now
ch(ξ)=h~(ξ)=γ=mG(ξ)=mh(ξ)k(ξ). The polynomial h divides a and is nonzero, so h(ξ)=0 by Fact 2, and therefore c=mk(ξ). So ∣k(ξ)∣≤∣c∣≤ξ/2.
The polynomial k divides G, which divides a. If degk≥1, Fact 2 gives ∣k(ξ)∣>ξ/2, a contradiction. So k is a nonzero integer constant. Both G and h are primitive, so k=±1, and both have positive leading coefficients, so k=1 and h=G. ■
Correctness of the output. If line L7 returns, the theorem gives h=gcd(ppf,ppg), and by Gauss's lemma c⋅h=gcd(f,g) for c=gcd(contf,contg). Otherwise the algorithm returns FAIL, which makes no claim.
Termination. Each try does finitely many integer operations: an evaluation, an integer gcd, a terminating expansion (Fact 3), and two trial divisions, each of which lowers the degree of the remainder at every step. The loop of line L3 runs at most T times. ■