% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. % ================================================================= % Program. ascending sorting (ascending because we take the minimum) :- pred selectionsort(list(int),list(int)). :- mode selectionsort(in,out). selectionsort([],[]). selectionsort([X],[Y]). % error: erase clause selectionsort([H|T],[Min|T1]) :- cons(H,T,HT), listMin(HT,IsDef,Min), % HT is not empty. IsDef is true. delete(Min,HT,L1), % Taking the minimum away from list HT. selectionsort(L1,T1). :- pred delete(int,list(int),list(int)). :- mode delete(in,in,in). %delete(X,[],[]). % delete is not total delete(X,[Y|T],T) :- constr(X=Y). % taking X away from [Y|T]. delete(X,[Y|T],[Y|TD]) :- % Deleting exactly one copy of X only. constr(~(X=Y)), % The list is not ordered. delete(X,T,TD). % The element X need not be the minimum. :- pred listMin(list(int),bool,int). :- mode listMin(in,out,out). %listMin([],IsDef,A) :- constr( ((~IsDef) & (A=0)) ). %error uncomment listMin([H|T],IsDef,Min) :- constr(IsDef & (Min = ite(IsDefT, ite(H (LMin=SMin)) )), listmin(L,IsDefLMin,LMin), listmin(S,IsDefSMin,SMin), selectionsort(L,S). % contracts (postcondition: true) :- spec listMin(HT,IsDef,Min) ==> listmin(HT,B1,SHT). :- spec delete(X,YT,T) ==> listmin(YT,B1,SYT) , listmin(T,B2,ST). :- spec cons(H,T,HT) ==> listmin(T,B1,ST), listmin(HT,B2,SHT). % ==================================================== :- query ff1/0. % ====================================================