[comp.lang.prolog] Operator Tests for Prolog

cdsm@doc.ic.ac.uk (Chris Moss) (07/27/87)

You may have noticed there are subtle differences between the way
different Prolog handle operator definitions. The test file below
is designed to explore some of these on the lines of some of my 
earlier tests.
Post the results direct to me please and I'll post a summary to the net.


/* Test of Prolog operator implementations
Chris Moss. July 1987.    cdsm@doc.ic.ac.uk (or cdsm@icdoc.uucp)

Compile and execute the predicate optest, supplying full description of
system used (with version) as the second parameter. If necessary delete
any clauses which give syntax errors but do NOT change them in any way
(spaces may be crucial). Skip any run-time errors.  Send me the resultant
file if it is NOT one of the following or the results are different. If
you get a "parsed differently" message I'd welcome a modified test which
illustrates it as well; also let me know if you've had to make any
changes.  You may change the operator declarations if your system has
different conventions.  e.g.  If your operator precedence is in the
opposite direction then you may add some suitable constant to ALL the
operator priorities.

Thanks to Hamish Taylor for some of these tests. Note that some of the
answers are definitely WRONG. I leave you to decide which!

These are the results I already have (first letter of each message):

Version \ Test        1 2 3 4 5 6 7 8 91011121314151617181920
CProlog 1.5           M P - S - M S P A A A - N N P R D L N 
Quintus 2.0           M P - S C M S P A A A - N N P N D L N 
MACProlog 2.0         M P - S L L - P A A A - N N P R D L S
Poplog 9.3            D S P P R R S S P S P P N P - R - - - 
MuProlog 3.1db        M P P P R R P P P P P P P P P R - - - 

*/

optest(File,Version) :-
   	tell(File),
	write(['Operator test version 2 using',Version]), nl, nl,
	ptest(Summary), 
	write(Version), write('      '), summary(Summary), 
	told.

ptest(Summary) :- ptest(1,19,Summary), nl.
ptest(I,N,[]) :- I>N, !.
ptest(I,N,[S|Rest]) :- I=<N, 
	(otest(I,R), message(I,R,S)
     	 ; message(I,'- Failed (to parse) the test',S)),
	!,  J is I+1, ptest(J,N,Rest).

message(Num,Result,First) :- 
	write(Num), write(' '), write(Result), nl,
	name(Result,[F|_]), name(First,[F]).

summary([]) :- nl.
summary([A|B]) :- write(A), write(' '), summary(B).

:-op(4,fy,r).    :-op(6,xfy,r).   :-op(2,yf,r).
:-op(4,fy,l).    :-op(6,yfx,l).   :-op(2,yf,l).
:-op(6,fy,pre).  :-op(6,yf,post). :-op(7,yf,bigpost).
:-op(6,fy,both). :-op(6,yf,both).


/* prefix operators and functors */
otest(1,R) :- 'pre'(1,2) = pre (1,2), R ='Dyadic interpretation of pre (1,2)'
	; 'pre'(X) = pre (1,2), R = 'Monadic interpretation of pre (1,2)'
	; R = 'No, pre (1,2)  parsed differently'.
 
/* Prefix and Postfix ambiguities */
otest(2,R) :- pre(X) = (pre x post), 
	R = 'Prefix - (pre x post) = pre(post(X))'
	; post(X) = (pre x post), 
	R = 'Suffix - (pre x post) = post(pre(X))'
	; R = 'No,  (pre x post)  parsed differently'.
otest(3,R) :- both(both(a)) = (both both a), 
	  R= 'Prefix - (both both x) = both(both(a))'
	; R = 'No,  (both both a) parsed differently'.
otest(4,R) :- pre(bigpost) = (pre bigpost),
	  R = 'Prefix - (pre bigpost) = pre(bigpost)'
	; bigpost(pre) = (pre bigpost),
	  R = 'Suffix - (pre bigpost) = bigpost(pre)'
	; R = 'No, (pre bigpost) parsed differently'.

/* ambiguities with infix operators */
otest(5,R) :- 'l'('l'(a),'l'(b)) = (a l l l b), 
	  R = 'Balanced- (a l l l b) = (a l)l(l b)'
	; 'l'('l'('l'(a)),b) = (a l l l b), 
	R = 'Left hand - (a l l l b) = ((a l )l)l b'
	; 'l'(a,'l'('l'(b))) = (a l l l b),  
	R = 'Right hand -  (a l l l b) = a l ( l( l b))'
	; 'l'('l'(a,l),b)  = (a l l l b), 
	R = 'Constant - (a l l l b) = (a l (l)) l b'
	; 'l'(a,'l'(l,b)) = (a l l l b), 
	R = 'Middle - (a l l l b) = a l((l)l b)'
	; R = 'No,  (a l l l b) parsed differently'.
otest(6,R) :- 'r'('r'(a),'r'(b)) = (a r r r b), 
	R = 'Balanced - (a r r r b) = (a r)r(r b)'
	; 'r'('r'('r'(a)),b) = (a r r r b),  
	R = 'Left hand - (a r r r b) = ((a r)r)r b'
	; 'r'(a,'r'('r'(b))) = (a r r r b),  
	R = 'Right hand -  (a r r r b) = a r(r(r b))'
	; 'r'('r'(a,r),b)  = (a r r r b),  
	R = 'Constant - (a r r r b) = (a r(r))r b'
	; 'r'(a,'r'('r',b)) = (a r r r b),  
	R = 'Middle - (a r r r b) = a r((r)r b)'
	; R = 'No,  (a r r r b) parsed differently'.

/* Negative integers and the minus sign */
otest(7,R) :- /(X,Y)= -2/3, R = 'Sign, -2/3 parsed (-2)/3'
	; -(X) = -2/3, R = 'Prefix, -2/3 parsed -(2/3)'
	; R = 'No, -2/3 parsed differently'.
otest(8,R) :- /(X,Y)= -a/b, R = 'Sign, -a/b parsed (-a)/b'
	; -(X) = -a/b, R = 'Prefix, -a/b parsed -(a/b)'
	; R = 'No, -a/b parsed differently'.
otest(9,R) :- -(-,3) = - - 3, R = 'Atom, - - 3 parsed as (-)-(3)'
	; -(-(3)) = - - 3, R = 'Prefix, - - 3 parsed as -(-(3))'
	; -(-3) = - - 3, R = 'Sign, - - 3 parsed as -(-3)'
	; R = 'No, - - 3  parsed differently'.
otest(10,R) :- -(-,3) = - -3, R = 'Atom, - -3 parsed as (-)-(3)'
	; -(-(3)) = - -3, R = 'Prefix, - -3 parsed as -(-(3))'
	; -(-3) = - -3, R = 'Sign, - -3 parsed as -(-3)'
	; R = 'No, - -3  parsed differently'.

otest(11,R) :- -('-',a) = - - a,   R = 'Atom, - - a parsed as (-)-(a)'
	; -(-(a)) = - - a, R = 'Prefix, - - a parsed as -(-(a))'
	; R = 'No, - - a  parsed differently'.
otest(12,R) :- -(a,-b) = a - - b, 
	R = 'Prefix, a - - b parsed as a-(-b)'
	; R = 'No, a - - b parsed differently'. 
/* Evaluation of negative and positive integers */
otest(13,R) :- -X = -3, X=3, R = 'Prefix, - is functor of -3'
	; R = 'No, - is not functor of -3'.
otest(14,R) :- -X = - 3, X=3, R = 'Prefix, - is functor of - 3'
	; R = 'No, - is not functor of - 3'.
otest(15,R) :- +(3) = +3,  R = 'Prefix,   + is functor of +3'
	; R = 'No, + is not functor of +3'.

/* Evaluation of general arithmetic expressions */
otest(16,R) :- oteste(2+3,4,X),!,
	(X = 20, R='Remote expressions evaluated'
	; R='Different result for remote expressions').
otest(16,R) :- R='No evaluation of remote expressions'.

/* Treatment of | as disjunction */
otest(17,R) :- fail | R='Disjunction can be written as |'. 
otest(18,R) :- ';'(a,b) = (A | B), R='Lexical translation of | to ;'
	; R = 'No translation of | to ;'.
otest(19,R) :- '|'(a,b) = (A | B), R='Standard treatment of | as operator'
	; R = 'No equivalence of (A|B) to prefix form'.

oteste(A, B, C) :- C is A*B.
/* end of tests */