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 */