% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. % ================================================================= % Program. ascending sorting :- pred bubblesort(list(int),list(int)). :- mode bubblesort(in,out). bubblesort(L,L) :- swap(L,L1,B), constr(~B), eqlist(L,L1). bubblesort(L,SL) :- swap(L,L1,B), constr(B), bubblesort(L1,SL). :- pred eqlist(list(int),list(int)). :- mode eqlist(in,in). eqlist(L,L). :- pred swap(list(int),list(int),bool). % bool is true if a swap has been done :- mode swap(in,out,out). swap([],[],B) :- constr(~B). swap([X],[X],B) :- constr(~B). swap([X,Y|Ys],[Y|Zs],B) :- constr(B & (X > Y)), cons(X,Ys,XYs), swap(XYs,Zs,B). swap([X,Y|Ys],[X|Zs],B) :- constr(X =< Y), cons(Y,Ys,YYs), swap(YYs,Zs,B). :- pred cons(int,list(int),list(int)). :- mode cons(in,in,out). cons(H,T,[H|T]). % ================================================================= % catamorphism :- pred listmember(int,list(int),bool). :- mode listmember(in,in,out). :- cata listmember/3-2. listmember(X,[],Res) :- constr(~Res). listmember(X,[Y|Ys],B) :- constr( B=ite(X=Y,true,B1) ) , listmember(X,Ys,B1). % ================================================================= % Verification. % Property: :- pred ff1. ff1 :- constr(~(SL=SS)), listmember(X,L,SL), listmember(X,S,SS), bubblesort(L,S). % contracts (postcondition: true) :- spec swap(L,L1,B) ==> listmember(X,L,LS), listmember(X,L1,L1S) => constr(true). :- spec eqlist(L,L1) ==> listmember(X,L,LS), listmember(X,L1,L1S) => constr(true). :- spec cons(H,T,HT) ==> listmember(X,T,TS), listmember(X,HT,HTS) => constr(true). % ================================================================= :- query ff1/0. % =================================================================