


















1 - R.A.O'Keefe.		Updated: 30 August 82

	Designed and written by Richard O'Keefe.
	Scenery by Lawrence Byrd.

	This package provides arithmetic for arbitrary precision rational
	numbers.  The normal domain of prolog 'integers' is extended to
	full rational 'numbers'.  This domain includes all Prolog integers.
	The predicate:

			number(N)

	will recognise any number in this extended domain.
	Rational numbers are produced by usi




























































































) are represented as Prolog integers;

	b) 1/0, 0/0, -1/0 are represented as infinity, undefined, neginfinity;

	c) All other numbers are reÿ
ÿ
ÿ







































































































































































































































































































































































































































































































































































































,000 after fixing addn to use
	unsigned numbers.

[21 April 81]

	Continued tidying things up.
	
 0^(1/N) = 0; this was an oversight.
	added new xwd(,) code in eva2, and beautified portray_
er.

[8 July 81]

	fixed mode er















	fixed negative number bugs in arccos and arcsin.  How long have
	these been
und without anyone (except Bernard) noticing?
	Also shunted some cuts aro
in the same general area.

[13 Sept 81]

	corrected typo {da=>Da} in 
/4.

[2 Dec 81]

	corrected a benign bug in number/5 (100000 had 
 written
	where R should have been), and some minor cosmetic 
ges.
	Unified error reporting into long_error[_message]. 
ed a
	few mode declaration






c 81]
h
































































































































































ugust 82]

	fixed bug in g
4 so that gcd(1/2,1/4)
/4, not 1/2!

[12 
 1983]

	arcta
l used to 
 addn/




































































000.
%				%  Lawrence's Low Level TIDY interface
	add/3,			%  add(A,B,C) => (C is A+B)/rational-eval
	multiply/3,		%  similar for *.  NB A,B must be numbers
	power/3.		%  similar for ^.  NOT general terms.


/* OPERATORS */

:- op(300, xfx, div).		%  integer quotient A div B = fix(A/B).


/* MODES and types */

%   The comments at the right give the argument types for each predicate.
%   The predicates can of course be called with any arguments, but these
%   






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































as thi
ke




























































bit quantities and so 100000
	be
s a suitable radix.

	The co
ctually unpacks the numb
erms into their sepa

	bits for all t
ow level ope
ons. At 
 sta





































































































































































9 to +99999 are ÿ
ÿ




















































































































































000, S), !, R=S.
eval(Term)     :- Term =.. [F,X,Y], relational_op(F, R, Flag),
		  !, eva2(X, A), eva2(Y, B), comq(A, B, 100000, S), !,
		  combine_ops(R, S, Flag, true).

	mod2(number(_,_,[]),    M) :- !, fail.
	mod2(number(_,[],_),    0).
	mod2(number(_,[L|_],_), M) :- M is L mod 2.


			% General evaluation of rational expressions

eval(Exp, Ans) :-	%    Hope for the best
	eva2(Exp, N),
	standardise(N, A), !,
	Ans = A.
eval(






























































000, C).
eva2(X-Y, C)     :- !, eva2(X, A), eva2(Y, B), subq(A, B, 100000, C).
eva2( -Y, C)     :- !,             eva2(Y, B), negq(   B, 100000, C).
eva2(X*Y, C)     :- !, eva2(X, A), eva2(Y, B), mulq(A, B, 100000, C).
eva2(X/Y, C)     :- !, eva2(X, A), eva2(Y




000, C).
eva2(X div Y, C) :- !, eva2(X, A), eva2(Y, B), divo(A, B, 100000, C, _).
eva2(X mod Y, C) :- !, eva2(X, A), eva2(Y, B), divo(A, B, 100000, _, C).
eva2(X++Y, C)	 :- !, eva2((X+Y) mod 360, C).
eva2(X--Y, C)	 :- !, eva2((X-Y) mod 360, C).
eva2(X^Y, C)     :- !, eva2(X, A), eva2(Y, B), powq(A, B, 100000, C).
eva2(sqrt(Y), C) :- !,		   eva2(Y, B), nthq(2, B, 100000, C).
eva2(pi,number(+,[355],[113])) :- !.
eva2(log(X,Y),C) :- !, eva2(X, A), eva2(Y, B), logq(A, B, 100000, C).
eva2(gcd




























100000, C).
eva2(sin(X), C)  :- !, eva2(X, A), sineval(A, C).
eva2(cos(X), C)  :- !, eva2(X, A), coseval(A, C).
eva2(tan(X), C)  :- !, eva2(X, A), taneval(A, C).
eva2(arcsin(X),C):- !, eva2(X, A), arcsineval(A, C).
eva2(arccos(X),C):- !, eva2(X, A), arccoseval(A, C).
eva2(arctan(X),C):- !, eva2(X, A), arctaneval(A, C).
eva2(abs(X),   number(+,N, D )) :- !, eva2(X, A), A = number(_,N,D).
eva2(n







































































		    e
(X*
U)*512+V, C).
eva2(X,       C) :- number(X, 100000, S, N, D), !, C = number(S, N, D).
eva2(Term,    C) :- Term =.. [F,X,Y], relational_op(F,R, Flag),
	            !, eva2(X, A), eva2(Y, B), comq(A, B, 10000




































































































































































= ")",
			%  45 = "-", 47 = "/", 48 =
 {ASCII codes}.

portray_number(A

	number(A, 100000, S, N, D),
	portray_number(S, N, D).
ortray_number(_,[],  
:- !,		%  0/0 = u
ined
		write(
fined).
	
ray_n
r
















































































































 put(45), putn(N), put(47), putn(D),
(41).

		putn([]   ) :- !, put(4
		pu

















0)	      +48, put(D4),	% D4*10^4 +
			D3 is (D/1


+48, p
3)










put(D2),	% D2*10^2 +
			D1 is (D/10) mod 10 
8, put(D1),	% D1*10^1 +
			D0 is (D) mod 10 
 +48, put(D0).	% D0*10^0 = D.


%% INTERFAC
NVERSIONS %%

			% Conversion of a numbe
f any form, to its
			%  essential b


number(infinity,        R, +,[








































































































































































































































/81),
			%  so only tho
ecessary are provid

add(A, B, C) :
 eval(C is 
.
	addq
B, 
00, X),
	standardise(X, C).

multiply(A, B, C) :-	% eval(C is A*B).
	mulq(A, B, 100000, X),
	standardise(X, C).

power(A, N, C) :-	% eval(C is A^B).
	powq(A, N, 100000, X),
	





















































































































































































































































































































































































































































































































































































and +99999 (ie
			%   within the current Radix).
			%  This may be defined for some rational powers
			%   but since there are results from this which are
			%   not representable as rationals it will fail
			%   in such cases.  The code for rational powers
			%   relies on numerator and denomin





















































































































































































































































































































































































































































































































































































































































































































































































= 3.

logq(B, X, R, L) 
absq(B, S, C),	%   
0 & |B| = C
	ab
, T, Y),	% 
T 0 & |
 Y





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































00 (current radix).
			%  This code should always be called with positive
			%  powers.

powz(-,A, N, R, -,C) :-
	N mod 2 =:= 1, !,
	pown(N, A, 























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































	!,
	eva2(180-X, Y),
	sineval(Y, S).
sineval(X, S) :-	% 0 <= X <= 90
	sineval1(X, S).

ineval1(number(+,[],[1]),   number(+,[],[1])).
	sineval1(number(+,[30],[1]), numbe
[1],[2])).
	sineval1(number(+,[45],[1]), number(+,[99],[140])).
	sineval1(numb
,[60],[1]), number(+,[45],[52]






[1]), number(+,[1],[1])).



coseval(X, C) :-
	eva2(90-X, Y), !,
	sineval(Y, C).


tan
(X, T) :-
	sineval(X, S),
	coseval(X, C), !,
	eva2(S/C, T).


arcsineval(S, X) :-

l(S >= 0), !,
	sineval1(X, S).
arcsineval(S, X) :-
	eval(S < 0),
	eva2(-S, T),
	sineval1(Y, T),
	eva2(-Y, X).


arccoseval(C, X) :-
	arcsineval(C, Y), !,
a2(90-Y, X).


arctaneval(number(S,N,D), number(S,M,C)) :-
	arctaneval
D, M, C).
	
arctaneval([],X, [], X) :- !.		%  arctan(0) = 0, arcta
def)







[







arctaneval(X,[], [90], [1]) :- !.	%  arc
inf) = 90`
arctaneval(N, D, M, C) :-

 100000,			%  the common radix
	m
N, N, R, Nsq),
	muln(D, D, R,
),
	addn(Nsq, Dsq, 0, R, 
 !,
	nthn(2, Sq, R, D
 !,
	arcsineval(n
r(+,N,Den), S
S = numbe
M,C).
%
































































































