% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. % ================================================================= % Program % rev(L,R): % list R is the reversal of list L :- pred rev(list(int),list(int)). :- mode rev(in,out). rev([],[]). rev([H|T],R) :- rev(T,S), snoc(S,H,R). % snoc(L,X,S): % list S is obtained by adding element X at the end of list L :- pred snoc(list(int),int,list(int)). :- mode snoc(in,in,out). snoc([],X,[X]). snoc([X|Xs],Y,[X|Zs]) :- snoc(Xs,Y,Zs). % ================================================================= % Contract on rev: % If list R is the reverse of list L then % L is weakly-ascending iff R is weakly-descending % weakly-ascending sequence: 1=<2=<3=<... % weakly-descending sequence: 9>=8>=7>=... :- spec rev(L,R) ==> isASorted(L,BL), isDSorted(R,BR) => constr( BL=BR ). % --- (AD1) % Contract on snoc: % for a weakly-descending list A :- spec snoc(A,X,C) ==> isDSorted(A,BA), listMin(A,IsDef,Min), isDSorted(C,BC) => constr( BC=(IsDef => (BA & X= (H= (H>=HdT & ResT))). % ------ listMin(L,IsDef,Min): IsDef=true iff L is a nonempty list and % if IsDef then Min is the minimum element on the list L :- pred listMin(list(int),bool,int). :- mode listMin(in,out,out). :- cata listMin/3-1. listMin([],IsDef,Min) :- constr( (~IsDef) & Min=0 ). % 0 can be any int. listMin([H|T],IsDef,Min) :- listMin(T,IsDefT,MinT), constr( (IsDef & (Min = ite(IsDefT, ite(H (BA & X=