% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. % ================================================================= % Program :- pred quicksort(list(int),list(int)). :- mode quicksort(in,out). quicksort([], []). quicksort([X | Xs], ResL) :- partition(X, Xs, Smalls, Bigs), % partition of the tail Xs quicksort(Smalls, Ls), % with respect to the pivot X. quicksort(Bigs, Bs), % X is NOT in Xs. cons(X,Bs,XBs), append(Ls, XBs, ResL). :- pred partition(int,list(int),list(int),list(int)). :- mode partition(in,in,out,out). partition(X, [], [], []). partition(X, [Y | Ys], [Y | Ls], Bs) :- constr( (X>Y) ), partition(X, Ys, Ls, Bs). partition(X, [Y | Xs], Ls, [Y | Bs]) :- constr( (X= (X, Xs, Ls, Bs). :- pred append(list(int),list(int),list(int)). :- mode append(in,in,out). append([],Ys,Ys). append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs). :- pred cons(int,list(int),list(int)). :- mode cons(in,in,out). cons(H,T,[H|T]). % ================================================================= % catamorphism :- pred length(list(int),int). :- mode length(in,out). :- cata length/2-1. length([],L) :- constr((L=0)). length([H|T],L) :- constr( (L=LT+1) ), length(T,LT). % ================================================================= % Verification. % Property: :- pred ff1. ff1 :- constr(~(LL=LS)), length(L,LL), length(S,LS), quicksort(L,S). % %:- pred ff2. %ff2 :- % constr( ~(LLs = (LSmalls+LBigs)) ), % length(Smalls,LSmalls), length(Bigs,LBigs), length(Ls,LLs), % partition(X,Ls,Smalls,Bigs). % %:- pred ff3. %ff3 :- % constr( ~(LZs = (LXs+LYs)) ), % length(Xs,LXs), length(Ys,LYs), length(Zs,LZs), % append(Xs,Ys,Zs). % ================================================================= :- query ff1/0. %:- query ff2/0. %:- query ff3/0. % ================================================================= % Catamorphic abstraction :- cata_abs list(int) ==> length(Ls,LLs). % =================================================================