% ================================================================= :- pred constr(bool). :- mode constr(in). :- ignore constr/1. :- type bintree_int ---> leaf ; node(int,bintree_int,bintree_int). % This is a binary tree supporting a heap. % leaf is the EMPTY bintree_int. Nodes may have DUPLICATE integer values. % ================================================================ % Program: ascending sorting. :- pred heapsort(list(int),list(int)). :- mode heapsort(in,out). heapsort([X,Y],[X,Y]). %error: erase this clause heapsort(L,SL) :- list_to_heap(L,H), heap_to_list(H,SL). % =============================================================== % making a heap out of a list. % Program predicate: not be a catamorphism. :- pred list_to_heap(list(int),bintree_int). :- mode list_to_heap(in,out). list_to_heap([],leaf). list_to_heap([X|Xs], Heap) :- list_to_heap(Xs, HeapXs), insert_heap(X, HeapXs, Heap). %% ------- % descending heap %:- pred insert_heap(int,bintree_int,bintree_int). %:- mode insert_heap(in,in,out). % %insert_heap(X, leaf, node(X,leaf,leaf)). %insert_heap(X, node(Top,L,R), node(Top,R,L1)) :- % Torsion! node(Top,R,L1), not node(Top,L1,R), and % constr(X=Top), insert_heap(Top,L,L1). % X on top. Insert Top in the left son-node. % ------- % ascending heap :- pred insert_heap(int,bintree_int,bintree_int). :- mode insert_heap(in,in,out). insert_heap(X, leaf, node(X,leaf,leaf)). insert_heap(X, node(Top,L,R), node(Top,R,L1)) :- % Torsion! node(Top,R,L1), not node(Top,L1,R), and constr(X>Top), insert_heap(X,L,L1). % Top unchanged. Insert X in the left son-node. insert_heap(X, node(Top,L,R), node(X,R,L1)) :- % Torsion! node(Top,R,L1), not node(Top,L1,R), and constr(X= RTop, heap_merge(RL,RR,MergedHeap). heap_merge(node(LTop,LL,LR),node(RTop,RL,RR), node(LTop,MergedHeap,node(RTop,RL,RR))) :- LTop =< RTop, heap_merge(LL,LR,MergedHeap). % =============================================================== % catamorphisms %----- checking a 'weakly ascending' ordered heap: % every father is smaller than or equal to each of its children. :- pred is_aheap(bintree_int,bool). :- mode is_aheap(in,out). :- cata is_aheap/2-1. is_aheap(leaf,Res) :- constr( Res ). is_aheap(node(Top,L,R),Res) :- top(L,IsTopL,TopL), top(R,IsTopR,TopR), is_aheap(L,ResL), is_aheap(R,ResR), constr(Res=ite((((IsTopL & IsTopR) & (Top= (H= % is_asorted(L,NL), is_aheap(H,B) => constr(true). % %:- spec heap_to_list(H,L) ==> % is_aheap(H,BH), is_asorted(L,BL) => constr(true). % %:- spec insert_heap(X,H,H1) ==> is_aheap(H,BH), is_aheap(H1,BH1) => constr(true). % %:- spec heap_merge(HL,HR,H1) ==> % is_aheap(HL,BHL), is_aheap(HR,BHR), is_aheap(H1,BH1) => constr(true). % %:- spec mkbtree(T,HL,HR,H1) ==> is_aheap(HL,BHL), is_aheap(HR,BHR), is_aheap(HT,BHT) % => constr(true). % =============================================================== :- query ff1/0. % ================================================================ % %% Catamorphic abstraction :- cata_abs list(int) ==> is_asorted(T,ResT). :- cata_abs bintree_int ==> is_aheap(HL,BHL). % %% ================================================================