:- pred constr(bool). :- mode constr(in). :- ignore constr/1. :- type tree(int) ---> leaf ; node( int, tree(int), tree(int) ). % Note: duplicates are NOT allowed. % ========================================================== % Deletion from a binary search tree. treesum. % https://algs4.cs.princeton.edu/32bst/ % ========================================================== % Note: if X does not occur in tree(int), BSTdelete(X,tree(int)) = tree(int). :- pred bstdelete(int,tree(int),tree(int)). :- mode bstdelete(in,in,out). bstdelete(X,leaf,leaf). % Functionally, bstdelete(X,leaf)=leaf. bstdelete(X,node(A,leaf,R), R) :- constr(X=A). bstdelete(X,node(A,L,leaf), L) :- constr(X=A). bstdelete(X,node(A,L,R), node(Succ,L,Rd) ) :- constr(X=A & IsDef), bstdeletemin(R, Rd, Succ, IsDef). % (R w/o Succ) = Rd. Succ is the minimum of R. bstdelete(X,node(A,L,R), node(A,L1,R)) :- constr(X 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) % ---- % treemin for ANY binary tree (ok also for trees with duplicate values) :- pred treemin(tree(int),bool,int). :- mode treemin(in,out,out). :- cata treemin/3-1. treemin(leaf,IsDef,Min) :- constr(~IsDef & Min=0). % Min can be any int treemin(node(N,L,R),IsDef,Min) :- treemin(L,IsDefL,MinL), treemin(R,IsDefR,MinR), constr(IsDef & (Min= ite(IsDefL & IsDefR, ite(MinL (R2=R1 v (R2=R1-Y))) ), bstree(T1,B1), bstree(T2,B2), treesum(T1,R1), treesum(T2,R2), bstdelete(Y,T1,T2). % %% postcondition true % %:- spec bstdeletemin(T1,T2,X,B) ==> % bstree(T1,B1), bstree(T2,B2), treesum(T1,T1M), treesum(T2,T2M) % => constr(true). % ========================================================== :- query ff1/0. % ========================================================== % Catamorphic abstraction :- cata_abs tree(int) ==> bstree(T,B1), treesum(T,R2). % =================================================================