% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. % ================================================================= % Program. descending sorting via selection sort :- pred selectionsort(list(int),list(int)). :- mode selectionsort(in,out). selectionsort([],[]). %error selectionsort([H|T],[Max|T1]) :- cons(H,T,HT), listMax(HT,IsDef,Max), % HT is not empty. IsDef is true. delete(Max,HT,L1), % Taking the maximum away from list HT. selectionsort(L1,T1). :- pred delete(int,list(int),list(int)). :- mode delete(in,in,in). %delete(X,[],[]). % delete in 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 maximum. :- pred cons(int,list(int),list(int)). :- mode cons(in,in,out). cons(H,T,[H]). %error: it should be cons(H,T,[H|T]). % ================================================================= % catamorphisms :- pred listMax(list(int),bool,int). :- mode listMax(in,out,out). :- cata listMax/3-1. listMax([],IsDef,A) :- constr( ((~IsDef) & (A=0)) ). % 0 can be any int listMax([H|T],IsDef,MaxHT) :- constr( IsDef & (MaxHT = ite(IsDefT, ite(H>MaxT,H,MaxT), H )) ), listMax(T,IsDefT,MaxT). % --- :- pred listMin(list(int),bool,int). :- mode listMin(in,out,out). :- cata listMin/3-1. listMin([],IsDef,A) :- constr( ((~IsDef) & (A=0)) ). % 0 can be any int. listMin([H|T],IsDef,Min) :- constr( IsDef & (Min = ite(IsDefT, ite(H ((MinL=LastS) & (MinL=MinS))) )), listMin(L,IsDefLMin,MinL), listMin(S,IsDefSMin,MinS), lastElem(S,IsDefSLast,LastS), selectionsort(L,S). % Contract on delete (for any A, not necessarily the minimum of L): :- pred ff2. ff2 :- constr(~( ((IsDefMaxL=IsDefLastL) & (IsDefMaxLD=IsDefLastLD)) & ((IsDefMaxL & A=MaxL) => (((~IsDefMaxLD) => (MaxL=LastL)) & (IsDefMaxLD => ((MaxLD=