%mathpiper,def="ExtendedEuclidean"

/* Extended Euclidean algorithm. Algorithm taken from
 * "Modern Computer Algebra". It does a Gcd calculation, but
 * returns the intermediate results also.
 *
 * Returns {l,r,s,t}
 * where
 * - l the number of steps required
 * - r[i] the i-th remainder
 * - s[i] and t[i] the i-th bezout coefficients of f and g:
     s[i]*f + t[i]*g = r[i] .
 * The gcd is r[l].
 *
 * This is a slightly modified version from the one described in
 * "Modern Computer Algebra", where the elements in list r are not
 * monic. If needed this can be done afterwards. As a consequence
 * this version works on integers as well as on polynomials.
 */

ExtendedEuclidean(_f,_g) <--
[
   Local(r,s,t,i);

   /* Initialize the loop */
   r:={f,g};
   s:={1,0};
   t:={0,1};
   i:=1;

   Local(q,newr,news,newt);
   newr:=1;
   While(newr != 0)
   [
     newr:=Rem(r[i],r[i+1]);
     q   :=Quotient(r[i],r[i+1]);
     news  :=(s[i]-q*s[i+1]);
     newt  :=(t[i]-q*t[i+1]);
     DestructiveAppend(r  ,newr);
     DestructiveAppend(s,news);
     DestructiveAppend(t,newt);
     i++;
   ];
   {r[i],s[i],t[i]};
];

%/mathpiper