% ================================================================= :- 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,L,false). bubblesort(L,SL) :- swap(L,L1,true), bubblesort(L1,SL). :- pred swap(list(int),list(int),bool). % bool is true if a swap has been done :- mode swap(in,out,out). swap([],[],false). swap([X],[X],false). swap([X,Y|Ys],[Y|Zs],true) :- constr(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 sum(list(int),int). :- mode sum(in,out). :- cata sum/2-1. sum([],S) :- constr((S=0)). sum([H|T],S) :- constr( S=(H+ST) ), sum(T,ST). % ================================================================= % Contract on bubblesort: :- spec bubblesort(L,S) ==> sum(L,SL), sum(S,SS) => constr(SL=SS). % Contract on swap: :- spec swap(LA,LB,ToF) ==> sum(LA,SLA), sum(LB,SLB) => constr( SLA = SLB ). % Contract on cons: :- spec cons(H,T,HT) ==> sum(T,ST), sum(HT,SHT) => constr( SHT = (H+ST) ). % ================================================================= % verification of contracts. :- pred ff1. ff1 :- constr(~(SL=SS)), sum(L,SL), sum(S,SS), bubblesort(L,S). :- pred ff2. ff2 :- constr( ~( SLA = SLB ) ), sum(LA,SLA), sum(LB,SLB), swap(LA,LB,ToF). :- pred ff3. ff3 :- constr( ~( SHT = (H+ST) ) ), sum(T,ST), sum(HT,SHT), cons(H,T,HT). % -------------------------------------------------- % NON-CATA predicates: bubblesort cons constr swap