11-- Based on DpsMergeSort4.hs and Insertion.hs with analysis
22{-# LANGUAGE CPP #-}
33
4+ {-# OPTIONS_GHC -Wno-name-shadowing #-}
5+
46module PiecewiseFallbackSort where
57
68import qualified Language.Haskell.Liquid.Bag as B
@@ -31,33 +33,45 @@ import Array.List as A
3133 left ts == left ys && right ts == right ys }>
3234 / [A.size xs ] @-}
3335msortInplace :: (Show a , HasPrimOrd a ) => Int -> A. Array a -. A. Array a -. (A. Array a , A. Array a )
34- msortInplace cutoff src tmp = -- cutoff > 0, though it may not be necessary to show sorting correctness
35- let ! (Ur len, src') = A. size2 src in
36- if len <= 1 then (src', tmp) -- MHB added
37- else if len <= cutoff then (isort_top' src', tmp)
38- else
39- let ! (srcA, srcB) = splitMid src'
40- ! (tmpA, tmpB) = splitMid tmp
41- ! (src1, src2) = splitMid srcA
42- ! (src3, src4) = splitMid srcB
43- ! (tmp1, tmp2) = splitMid tmpA
44- ! (tmp3, tmp4) = splitMid tmpB
45- ! (src1', tmp1') = msortInplace cutoff src1 tmp1
46- ! (src2', tmp2') = msortInplace cutoff src2 tmp2
47- ! (src3', tmp3') = msortInplace cutoff src3 tmp3
48- ! (src4', tmp4') = msortInplace cutoff src4 tmp4
49- tmpA' = A. append tmp1' tmp2'
50- tmpB' = A. append tmp3' tmp4'
51- ! (srcA'', tmpA'') = merge src1' src2' tmpA'
52- ! (srcB'', tmpB'') = merge src3' src4' tmpB'
53- src'' = A. append srcA'' srcB''
54- ! (tmp''', src''') = merge tmpA'' tmpB'' src''
55- in (src''', tmp''') ? lem_toBag_splitMid src
56- ? lem_toBag_splitMid tmp
57- ? lem_toBag_splitMid srcA
58- ? lem_toBag_splitMid srcB
59- ? lem_toBag_splitMid tmpA
60- ? lem_toBag_splitMid tmpB
36+ msortInplace cutoff src tmp = go cutoff src tmp where
37+ {-@ go :: n:Int -> xs:Array a
38+ -> { ys:(Array a ) | A. size ys == A. size xs && left xs == left ys &&
39+ right xs == right ys }
40+ -> (Array a , Array a )< {\ zs ts -> toBag xs == toBag zs && isSorted' zs &&
41+ token xs == token zs && token ys == token ts &&
42+ A. size xs == A. size zs && A. size ys == A. size ts &&
43+ left zs == left xs && right zs == right xs &&
44+ left ts == left ys && right ts == right ys }>
45+ / [A.size xs ] @-}
46+ go :: (Show a , HasPrimOrd a ) => Int -> A. Array a -. A. Array a -. (A. Array a , A. Array a )
47+ go cutoff src tmp =
48+ let ! (Ur len, src') = A. size2 src in
49+ if len <= 1 then (src', tmp) -- MHB added
50+ else if len <= cutoff then (isort_top' src', tmp)
51+ else
52+ let ! (srcA, srcB) = splitMid src'
53+ ! (tmpA, tmpB) = splitMid tmp
54+ ! (src1, src2) = splitMid srcA
55+ ! (src3, src4) = splitMid srcB
56+ ! (tmp1, tmp2) = splitMid tmpA
57+ ! (tmp3, tmp4) = splitMid tmpB
58+ ! (src1', tmp1') = msortInplace cutoff src1 tmp1
59+ ! (src2', tmp2') = msortInplace cutoff src2 tmp2
60+ ! (src3', tmp3') = msortInplace cutoff src3 tmp3
61+ ! (src4', tmp4') = msortInplace cutoff src4 tmp4
62+ tmpA' = A. append tmp1' tmp2'
63+ tmpB' = A. append tmp3' tmp4'
64+ ! (srcA'', tmpA'') = merge src1' src2' tmpA'
65+ ! (srcB'', tmpB'') = merge src3' src4' tmpB'
66+ src'' = A. append srcA'' srcB''
67+ ! (tmp''', src''') = merge tmpA'' tmpB'' src''
68+ in (src''', tmp''') ? lem_toBag_splitMid src
69+ ? lem_toBag_splitMid tmp
70+ ? lem_toBag_splitMid srcA
71+ ? lem_toBag_splitMid srcB
72+ ? lem_toBag_splitMid tmpA
73+ ? lem_toBag_splitMid tmpB
74+ {-# INLINE msortInplace #-}
6175
6276{-@ pfsort' :: y:a
6377 -> { xs:(Array a ) | A. size xs > 0 && left xs == 0 && right xs == size xs && y == A. get xs 0 }
@@ -72,6 +86,7 @@ pfsort' anyVal src =
7286 then truncate ((18820.2738 / (exp ((log (fromIntegral len)) * 0.5 ) )) :: Float )
7387 else 28 ) src' (A. makeArray len anyVal) in
7488 case A. free _tmp of ! () -> src''
89+ {-# INLINE pfsort' #-}
7590
7691{-@ pfsort :: { xs:(A. Array a ) | left xs == 0 && right xs == size xs }
7792 -> { ys:_ | toBag xs == toBag ys && isSorted' ys &&
@@ -81,3 +96,4 @@ pfsort src =
8196 let ! (Ur len, src') = A. size2 src in
8297 if len == 0 then src'
8398 else let ! (Ur x0, src'') = A. get2 0 src' in pfsort' x0 src''
99+ {-# INLINABLE pfsort #-}
0 commit comments