% ================================================================= :- 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. DUPLICATE integer values ARE ALLOWED. % ================================================================ % Program: ascending sorting. :- pred heapsort(list(int),list(int)). :- mode heapsort(in,out). heapsort(L,SL) :- list_to_heap(L,H), heap_to_list(H,SL). % =============================================================== % making a heap out of a list. :- pred list_to_heap(list(int),bintree_int). :- mode list_to_heap(in,out). list_to_heap([], node(N,node(M,leaf,leaf),leaf)). %error: node(N,node(M,leaf,leaf),leaf) --> leaf list_to_heap([X|Xs], Heap) :- list_to_heap(Xs, HeapXs), insert_heap(X, HeapXs, 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). % in: node(...),node(...) out: node(...) for > heap_merge(node(LTop,LL,LR),node(RTop,RL,RR), node(LTop,MergedHeap,node(RTop,RL,RR))) :- LTop =< RTop, heap_merge(LL,LR,MergedHeap). % in: node(...),node(...) out: node(...) for =< % =============================================================== % 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= BH1)), is_aheap(H,BH), is_aheap(H1,BH1), insert_heap(A,H,H1). % ---------------------------------------------------------------- % Contract on heap_to_list: . :- pred ff4. ff4 :- constr( ~( (BH => BL) & (Top=HdL) )), top(H,IsDefTop,Top), hd(L,IsDef,HdL), % this is required for 4-sat. is_aheap(H,BH), is_asorted(L,BL), heap_to_list(H,L). % ---------------------------------------------------------------- % Contract on heap_merge: :- pred ff5. ff5 :- constr(~(((BHL & BHR) => BHT) % & ((IsDefTopL & IsDefTopR) => (TopL=TopHT v TopR=TopHT)) ) ), % top(HL,IsDefTopL,TopL), top(HR,IsDefTopR,TopR), top(HT,IsDefTopHT,TopHT), is_aheap(HL,BHL), is_aheap(HR,BHR), is_aheap(HT,BHT), heap_merge(HL,HR,HT). %---------------------------------------------------------------- :- pred ff6. ff6 :- constr(~( ((( ((( IsDefTopL & IsDefTopR) & (T= ((BHL & BHR) => BHT)) & (((( IsDefTopL & ~IsDefTopR) & T= BHT) ) & (((~IsDefTopL & IsDefTopR) & (T= BHT) ) & ((~IsDefTopL & ~IsDefTopR) => BHT) ) & (T=TopHT))), is_aheap(HL,BHL), is_aheap(HR,BHR), is_aheap(HT,BHT), top(HL,IsDefTopL,TopL), top(HR,IsDefTopR,TopR), top(HT,IsDefTopHT,TopHT), mkbtree(T,HL,HR,HT). % =============================================================== :- query ff1/0. :- query ff2/0. :- query ff3/0. :- query ff4/0. :- query ff5/0. :- query ff6/0. % ===============================================================