% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. % =========================================================== %Program :- pred revacc(list(int),list(int)). :- mode revacc(in,out). %revacc(L,R) :- reva(L,[],R). % correct clause revacc(L,R) :- reva(L,EL,R). % error: missing emptylist(EL). :- pred reva(list(int),list(int),list(int)). % reva([1,2], [7,9,8], F). F=[2,1, 7,9,8]. :- mode reva(in,in,out). % the accumulator remains "as is" at the right end % of the reversed list. reva([],A,A). reva([H|T],A,R) :- cons(H,A,HA), reva(T,HA,R). :- pred emptylist(list(int)). :- mode emptylist(in,in,out). emptylist([Y]). % error [Y] --> [] :- pred cons(int,list(int),list(int)). :- mode cons(in,in,out). cons(H,T,[H|T]). % =========================================================== % Catamorphisms :- pred count(int,list(int),int). :- mode count(in,in,out). :- cata count/3-2. count(X,[],N) :- constr( N=0). count(X,[H|T],N) :- constr( (N=ite(X=H,(NT+1),NT)) ), count(X,T,NT). % =========================================================== % Property to verify :- pred ff1. ff1 :- constr( ~( N1=N2) ), count(X,L,N1), count(X,R,N2), revacc(L,R). :- pred ff2. ff2 :- constr( ~( N3=(N1+N2)) ), count(X,Xs,N1), count(X,As,N2), count(X,Ys,N3), reva(Xs,As,Ys). :- pred ff3. ff3 :- constr(~(NHT=ite(H=X,(NT+1),NT) )), count(X,T,NT), count(X,HT,NHT), cons(H,T,HT). % ================================================================= :- query ff1/0. :- query ff2/0. :- query ff3/0. % =================================================================