% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. % ==================================================== % Program. :- pred perm(list(int),list(int)). :- mode perm(in,in). % in,in: perm is not functional perm([],[]). perm([],[158]). % error: this clause should be removed perm([X|Xs],[H|Perm]):- cons(X,Xs,XXs), delete(H,XXs,Rest), perm(Rest,Perm). :- pred delete(int,list(int),list(int)). :- mode delete(in,in,in). % delete is not total delete(X,[Y|T],T) :- constr(X=Y). % Taking X away from [Y|T]. Deleting exactly one copy of X. delete(X,[Y|T],[Y|TD]) :- % The list need not be ordered. The element X need not be the minimum. constr(~(X=Y)), % delete(X,L,LD) succeeds **IFF** X is a member of L. delete(Y,T,TD). % error: X should be Y :- pred cons(int,list(int),list(int)). :- mode cons(in,in,out). cons(H,T,[H|T]). % ==================================================== % catamorphisms :- pred listMin(list(int),bool,int). :- mode listMin(in,out,out). :- cata listMin/3-1. listMin([],IsDef,A) :- constr( ((~IsDef) & A=0) ). listMin([H|T],IsDef,Min) :- constr( (IsDef & ( Min = ite(IsDefT, ite(H (MinL=MinLP)) )), listMin(L,IsDefMinL,MinL), listMin(LP,IsDefMinLP,MinLP), perm(L,LP). :- pred ff2. % delete(X,L,LD) succeeds iff X is a member of L ff2 :- % delete constr( ~( IsDefMinL & (((X=MinL) & IsDefMinLD) => (MinLD >= MinL)) ) ), % cons(H,T,L), listMin(L,IsDefMinL,MinL), listMin(LD,IsDefMinLD,MinLD), delete(X,L,LD). :- pred ff3. ff3 :- % cons constr( ~( IsDefMinHT & (IsDefMinT => (MinHT=ite(H