:- pred constr(bool). :- mode constr(in). :- ignore constr/1. :- type tree(int) ---> leaf ; node( int, tree(int), tree(int) ). % ========================================================== % Program. % Binary Search Tree - duplicates not allowed %%%%%%% TREE VISIT %%%%%%% :- pred visit(tree(int),list(int)). % pre-order tree visitor :- mode visit(in,out). visit(leaf,[]). visit(node(A,L,R), Xs) :- visit(L,XL), visit(R,XR), concat(XL,A,XR,Xs). :- pred concat(list(int),int,list(int),list(int)). :- mode concat(in,in,in,out). concat([],X,Ys,[X|Ys]). concat([X|Xs],Y,Ys,[X|Zs]) :- concat(Xs,Y,Ys,Zs). % ========================================================== % catamorphisms :- pred bstree(tree(int),bool). :- mode bstree(in,out). :- cata bstree/2-1. bstree(leaf,B) :- constr(B). bstree(node(N,L,R),B) :- bstree(L,BL), bstree(R,BR), treemax(L,IsDefL,MaxL), treemin(R,IsDefR,MinR), constr( ( (GeqLeft=(IsDefL => N>MaxL)) & (LeqRight=(IsDefR => NMaxR, ite(MaxL>N,MaxL,N), ite(MaxR>N,MaxR,N) ), % max(MaxL,max(MaxR,N)) ite(IsDefL, ite(MaxL>N,MaxL,N), % max(MaxL,N) ite(IsDefR & MaxR>N,MaxR,N))))). % max(MaxR,N) :- pred treemin(tree(int),bool,int). :- mode treemin(in,out,out). :- cata treemin/3-1. treemin(leaf,IsDef,Min) :- constr(~IsDef & Min=0). treemin(node(N,L,R),IsDef,Min) :- treemin(L,IsDefL,MinL), treemin(R,IsDefR,MinR), constr(IsDef & (Min= ite(IsDefL & IsDefR, ite(MinL (HMaxT,H,MaxT), H)) )), listmax(T,IsDefT,MaxT). % ========================================================== % Verification :- pred ff1. ff1 :- constr( ~((B1 => B2) & (MinT=MinL & MaxT=MaxL)) ), bstree(T,B1), is_str_asorted(L,B2), treemin(T,IsDefT1,MinT), treemax(T,IsDefT2,MaxT), % Extra catas listmin(L,IsDefL1,MinL), listmax(L,IsDefL2,MaxL), % seem needed visit(T,L). :- pred ff2. ff2 :- constr(~( ((( (IsDefXs & (IsDefYs & (MaxXs ((B3 & B4) = B5) )), is_str_asorted(Xs,B3), is_str_asorted(Ys,B4), is_str_asorted(Zs,B5), listmax(Xs,IsDefXs,MaxXs), listmin(Ys,IsDefYs,MinYs), concat(Xs,Y,Ys,Zs). % ========================================================== :- query ff1/0. :- query ff2/0. % ==========================================================