gcdchk.red 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. MODULE GCDCHK; % Check for a unit gcd using modular arithmetic.
  2. % Author: Arthur C. Norman and Mary Ann Moore.
  3. % Modifications by: Anthony C. Hearn.
  4. FLUID '(!*BACKTRACE LIST!-OF!-LARGE!-PRIMES MODULAR!-VALUES);
  5. % LIST!-OF!-LARGE!-PRIMES is a list of the largest pair of adjacent
  6. % primes that can fit in the inum range of the implementation.
  7. % This should be set here in an implementation dependent manner.
  8. % For the time begin, a maximum inum value of 2^23 is assumed.
  9. LIST!-OF!-LARGE!-PRIMES := '(8388449 8388451);
  10. SYMBOLIC PROCEDURE MONIC!-MOD!-P A;
  11. IF NULL A THEN NIL
  12. ELSE IF DOMAINP A THEN 1
  13. ELSE IF LC A = 1 THEN A
  14. ELSE MULTIPLY!-BY!-CONSTANT!-MOD!-P(A,MODULAR!-RECIPROCAL LC A);
  15. SMACRO PROCEDURE BEFORE!-IN!-ORDER(A,B);
  16. %Predicate taking the value true if the polynomial
  17. %a has a leading term which comes strictly before that
  18. %of b in canonical order;
  19. NULL DOMAINP A AND (DOMAINP B OR LDEG A>LDEG B);
  20. SYMBOLIC PROCEDURE UNI!-PLUS!-MOD!-P(A,B);
  21. % Form the sum of the two univariate polynomials a and b
  22. % working over the ground domain defined by the routines
  23. % modular!-plus, modular!-times etc. The inputs to this
  24. % routine are assumed to have coefficients already
  25. % in the required domain;
  26. IF NULL A THEN B
  27. ELSE IF NULL B THEN A
  28. ELSE IF BEFORE!-IN!-ORDER(A,B)
  29. THEN (LT A) .+ UNI!-PLUS!-MOD!-P(RED A,B)
  30. ELSE IF BEFORE!-IN!-ORDER(B,A)
  31. THEN (LT B) .+ UNI!-PLUS!-MOD!-P(A,RED B)
  32. ELSE IF DOMAINP A
  33. THEN <<A:=MODULAR!-PLUS(A,B); IF A=0 THEN NIL ELSE A>>
  34. ELSE BEGIN SCALAR W;
  35. W:=UNI!-PLUS!-MOD!-P(RED A,RED B);
  36. B:=MODULAR!-PLUS(LC A,LC B);
  37. IF B=0 THEN RETURN W;
  38. RETURN (LPOW A .* B) .+ W
  39. END;
  40. %symbolic procedure uni!-times!-mod!-p(a,b);
  41. % if (null a) or (null b) then nil
  42. % else if domainp a then multiply!-by!-constant!-mod!-p(b,a)
  43. % else if domainp b then multiply!-by!-constant!-mod!-p(a,b)
  44. % else uni!-plus!-mod!-p(
  45. % uni!-plus!-mod!-p(uni!-times!-mod!-p(red a,red b),
  46. % uni!-times!-term!-mod!-p(lt a,b)),
  47. % uni!-times!-term!-mod!-p(lt b,red a));
  48. SYMBOLIC PROCEDURE UNI!-TIMES!-TERM!-MOD!-P(TERM,B);
  49. %Multiply the given polynomial by the given term;
  50. IF NULL B THEN NIL
  51. ELSE IF DOMAINP B THEN <<
  52. B:=MODULAR!-TIMES(TC TERM,B);
  53. IF B=0 THEN NIL
  54. ELSE (TPOW TERM .* B) .+ NIL >>
  55. ELSE BEGIN SCALAR W;
  56. W:=MODULAR!-TIMES(TC TERM,LC B);
  57. IF W=0 THEN RETURN UNI!-TIMES!-TERM!-MOD!-P(TERM,RED B);
  58. W:= (TVAR TERM TO (TDEG TERM+LDEG B)) .* W;
  59. RETURN W .+ UNI!-TIMES!-TERM!-MOD!-P(TERM,RED B)
  60. END;
  61. SYMBOLIC PROCEDURE UNI!-REMAINDER!-MOD!-P(A,B);
  62. % Remainder when a is divided by b;
  63. IF NULL B THEN REDERR "B=0 IN REMAINDER-MOD-P"
  64. ELSE IF DOMAINP B THEN NIL
  65. ELSE XUNI!-REMAINDER!-MOD!-P(A,B);
  66. SYMBOLIC PROCEDURE XUNI!-REMAINDER!-MOD!-P(A,B);
  67. % Remainder when the univariate modular polynomial a is
  68. % divided by b, given that b is non degenerate;
  69. IF DOMAINP A OR LDEG A < LDEG B THEN A
  70. ELSE BEGIN
  71. SCALAR Q,W;
  72. Q:=MODULAR!-QUOTIENT(MODULAR!-MINUS LC A,LC B);
  73. % compute -lc of quotient;
  74. W:= LDEG A - LDEG B; %ldeg of quotient;
  75. IF W=0 THEN A:=UNI!-PLUS!-MOD!-P(RED A,
  76. MULTIPLY!-BY!-CONSTANT!-MOD!-P(RED B,Q))
  77. ELSE
  78. A:=UNI!-PLUS!-MOD!-P(RED A,UNI!-TIMES!-TERM!-MOD!-P(
  79. (MVAR B TO W) .* Q,RED B));
  80. % the above lines of code use red a and red b because
  81. % by construction the leading terms of the required
  82. % answers will cancel out;
  83. RETURN XUNI!-REMAINDER!-MOD!-P(A,B)
  84. END;
  85. SYMBOLIC PROCEDURE MULTIPLY!-BY!-CONSTANT!-MOD!-P(A,N);
  86. % Multiply the polynomial a by the constant n
  87. % assumes that a is univariate, and that n is coprime with
  88. % the current modulus so that modular!-times(xxx,n) neq 0
  89. % for all xxx;
  90. IF NULL A THEN NIL
  91. ELSE IF N=1 THEN A
  92. ELSE IF DOMAINP A THEN MODULAR!-TIMES(A,N)
  93. ELSE (LPOW A .* MODULAR!-TIMES(LC A,N)) .+
  94. MULTIPLY!-BY!-CONSTANT!-MOD!-P(RED A,N);
  95. SYMBOLIC PROCEDURE UNI!-GCD!-MOD!-P(A,B);
  96. %Return the monic gcd of the two modular univariate
  97. %polynomials a and b;
  98. IF NULL A THEN MONIC!-MOD!-P B
  99. ELSE IF NULL B THEN MONIC!-MOD!-P A
  100. ELSE IF DOMAINP A THEN 1
  101. ELSE IF DOMAINP B THEN 1
  102. ELSE IF LDEG A > LDEG B THEN
  103. ORDERED!-UNI!-GCD!-MOD!-P(A,B)
  104. ELSE ORDERED!-UNI!-GCD!-MOD!-P(B,A);
  105. SYMBOLIC PROCEDURE ORDERED!-UNI!-GCD!-MOD!-P(A,B);
  106. % As above, but degr a > degr b;
  107. IF NULL B THEN MONIC!-MOD!-P A
  108. ELSE ORDERED!-UNI!-GCD!-MOD!-P(B,UNI!-REMAINDER!-MOD!-P(A,B));
  109. SYMBOLIC MACRO PROCEDURE MYERR U;
  110. LIST('ERRORSET,
  111. 'LIST .
  112. MKQUOTE CAADR U .
  113. FOR EACH J IN CDADR U COLLECT LIST('MKQUOTE,J),
  114. T,'!*BACKTRACE);
  115. SYMBOLIC PROCEDURE MODULAR!-MULTICHECK(U,V,VAR);
  116. IF ERRORP (U := MYERR MODULAR!-MULTICHECK1(U,V,VAR)) THEN NIL
  117. ELSE CAR U;
  118. SYMBOLIC PROCEDURE MODULAR!-MULTICHECK1(U,V,VAR);
  119. % TRUE if a modular check tells me that U and V are coprime;
  120. BEGIN
  121. SCALAR OLDP,P,MODULAR!-VALUES,UMODP,VMODP;
  122. P:=LIST!-OF!-LARGE!-PRIMES;
  123. OLDP:=SETMOD NIL;
  124. TRY!-NEXT!-PRIME:
  125. MODULAR!-VALUES:=NIL;
  126. IF NULL P THEN GOTO UNCERTAIN;
  127. SETMOD CAR P;
  128. P:=CDR P;
  129. IF NULL MODULAR!-IMAGE(LC U,VAR) OR NULL MODULAR!-IMAGE(LC V,VAR)
  130. THEN GO TO TRY!-NEXT!-PRIME;
  131. UMODP:=MODULAR!-IMAGE(U,VAR);
  132. VMODP:=MODULAR!-IMAGE(V,VAR);
  133. P := DOMAINP UNI!-GCD!-MOD!-P(UMODP,VMODP);
  134. UNCERTAIN:
  135. SETMOD OLDP;
  136. RETURN P
  137. END;
  138. SYMBOLIC PROCEDURE MODULAR!-IMAGE(P,VAR);
  139. IF DOMAINP P
  140. THEN IF NULL P THEN NIL
  141. ELSE IF NOT ATOM P THEN ERROR1()
  142. ELSE <<P := MODULAR!-NUMBER P; IF P=0 THEN NIL ELSE P>>
  143. ELSE BEGIN
  144. SCALAR V,X,W;
  145. V:=MVAR P;
  146. IF V=VAR THEN <<
  147. X:=MODULAR!-IMAGE(LC P,VAR);
  148. IF NULL X THEN RETURN MODULAR!-IMAGE(RED P,VAR)
  149. ELSE RETURN (LPOW P .* X) .+ MODULAR!-IMAGE(RED P,VAR) >>;
  150. X:=ATSOC(V,MODULAR!-VALUES);
  151. IF NULL X THEN <<
  152. X:=MODULAR!-NUMBER RANDOM CAR LIST!-OF!-LARGE!-PRIMES;
  153. MODULAR!-VALUES:=(V . X) . MODULAR!-VALUES >>
  154. ELSE X:=CDR X;
  155. X:=MODULAR!-EXPT(X,LDEG P);
  156. W:=MODULAR!-IMAGE(RED P,VAR);
  157. V:=MODULAR!-IMAGE(LC P,VAR);
  158. IF NULL V THEN X:=NIL
  159. ELSE X:=MODULAR!-TIMES(V,X);
  160. IF W THEN X:=MODULAR!-PLUS(X,W);
  161. RETURN IF X=0 THEN NIL ELSE X
  162. END;
  163. ENDMODULE;
  164. END;