Abstract Refinements

5: module AbstractRefinements where
6: 
7: import Prelude hiding (max)
8: import Language.Haskell.Liquid.Prelude
9: {-@ LIQUID "--no-termination" @-}

Polymorphic Max Function

Consinder a polymorphic max function:
15: max     :: a -> a -> a
16: max x y = if x >= y then x else y


We can instantiate a with Odd
22: max     :: Odd -> Odd -> Odd
23: 
24: maxOdd :: Odd
25: maxOdd = max 3 7

Polymorphic Max in Haskell

In Haskell the type of max is
32: max     :: Ord a => a -> a -> a


We could ignore the class constraints, and procced as before:

Instantiate a with Odd
41: max     :: Odd -> Odd -> Odd
42: 
43: maxOdd :: Odd
44: maxOdd = max 3 7

Polymorphic Add in Haskell

But this can lead to unsoundness:
52: max     :: Ord a => a -> a -> a
53: (+)     :: Num a => a -> a -> a


So, ignoring class constraints allows us to: instantiate a with Odd
60: (+)     :: Odd -> Odd -> Odd
61: 
62: addOdd :: Odd
63: addOdd = 3 + 7

Polymorphism via Parametric Invariants

max returns one of its two inputs x and y.

This holds, regardless of what that property was!

Parametric Invariants

86: {-@ max :: forall <p :: a -> Prop>. Ord a => a<p> -> a<p> -> a<p> @-}
87: max     :: Ord a => a -> a -> a
88: forall a <p :: a-> Bool>.
(GHC.Classes.Ord a) =>
{VV : a<p> | true} -> {VV : a<p> | true} -> {VV : a<p> | true}max {VV : a | ((papp1 p VV))}x {VV : a | ((papp1 p VV))}y = if {VV : a | ((papp1 p VV)) && (VV == x)}x x1:{VV : a | ((papp1 p VV))}
-> x2:{VV : a | ((papp1 p VV))}
-> {VV : (GHC.Types.Bool) | (((Prop VV)) <=> (x1 <= x2))}<= {VV : a | ((papp1 p VV)) && (VV == y)}y then {VV : a | ((papp1 p VV)) && (VV == y)}y else {VV : a | ((papp1 p VV)) && (VV == x)}x 

Where

This type states explicitly:

Using Abstract Refinements

120: {-@ type Odd = {v:Int | (v mod 2) = 1} @-}
121: 
122: {-@ maxOdd :: Odd @-}
123: maxOdd     :: Int
124: {VV : (GHC.Types.Int) | ((VV mod 2) == 1)}maxOdd     = {VV : (GHC.Types.Int) | ((VV mod 2) == 1) && (VV > 0)}
-> {VV : (GHC.Types.Int) | ((VV mod 2) == 1) && (VV > 0)}
-> {VV : (GHC.Types.Int) | ((VV mod 2) == 1) && (VV > 0)}max {VV : (GHC.Types.Int) | (VV == (3  :  int))}3 {VV : (GHC.Types.Int) | (VV == (5  :  int))}5

Abstract Refinements in Type Constructors

Types cannot track information of monomorphic arguments:

134: data F = F {(AbstractRefinements.F) -> (GHC.Types.Int)w::Int}


The type F cannot give us information about the field x.

142: forall a. a -> afoo = let (AbstractRefinements.F)f = (GHC.Types.Int) -> (AbstractRefinements.F)F {VV : (GHC.Types.Int) | (VV == (0  :  int))}0 in -- :: f :: F
143:       case {VV : (AbstractRefinements.F) | (VV == f)}f of 
144:       F x -> {VV : (GHC.Types.Bool) | ((Prop VV))} -> a -> aliquidAssert ({VV : (GHC.Types.Int) | (VV == x)}x x1:(GHC.Types.Int)
-> x2:(GHC.Types.Int)
-> {VV : (GHC.Types.Bool) | (((Prop VV)) <=> (x1 >= x2))}>= {VV : (GHC.Types.Int) | (VV == (0  :  int))}0)

Demo: Lets solve this error using Abstract Refinements

Abstract Refinements in Type Constructors

155: data G = G {(AbstractRefinements.G) -> (GHC.Types.Int)y::Int{- <p> -}}
160: {-@ data G <p :: Int -> Prop> = G (y::Int<p>) @-}
166: forall a. a -> abar = let (AbstractRefinements.G <(VV == 0) && (VV /= AbstractRefinements.maxOdd)>)f = forall <p :: (GHC.Types.Int)-> Bool>.
{VV : (GHC.Types.Int)<p> | true} -> (AbstractRefinements.G <p>)G {VV : (GHC.Types.Int) | (VV == (0  :  int))}0 in -- :: f :: G <{v = 0}>
167:       case {VV : (AbstractRefinements.G <(VV == 0) && (VV /= AbstractRefinements.maxOdd)>) | (VV == f)}f of 
168:       G x -> {VV : (GHC.Types.Bool) | ((Prop VV))} -> a -> aliquidAssert ({VV : (GHC.Types.Int) | (VV == 0) && (VV == x) && (VV /= AbstractRefinements.maxOdd)}x x1:{VV : (GHC.Types.Int) | (VV == 0) && (VV == x) && (VV /= AbstractRefinements.maxOdd)}
-> x2:{VV : (GHC.Types.Int) | (VV == 0) && (VV == x) && (VV /= AbstractRefinements.maxOdd)}
-> {VV : (GHC.Types.Bool) | (((Prop VV)) <=> (x1 >= x2))}>= {VV : (GHC.Types.Int) | (VV == (0  :  int))}0)

Abstract Refinements in Lists

Remember increasing Lists?
175: data IL a = N | C (x :: a) (xs :: L {v:a | x <= v})
180: data L a = N | C {forall a. (AbstractRefinements.L a) -> ax :: a, forall a. (AbstractRefinements.L a) -> (AbstractRefinements.L a)xs :: L a {- v:a | p v x -}}
185: {-@ data L a <p :: a -> a -> Prop> = 
186:       N 
187:     | C (x :: a) (xs :: L <p> a<p x>)  @-}


We can get back increasing Lists:

194: {-@ type IncrL a = L <{\x v -> x <= v}> a @-}

Multiple Instantiations

Now increasing lists
202: type IncrL a = L <{\x v -> x <= v}> a


Co-exist with decreasing ones
208: type DecrL a = L <{\x v -> x >= v}> a

Ghc Sort

We can now verify algorithms that use both increasing and decreasing lists

217: {-@ type OList a = [a]<{\hd v -> hd <= v}> @-}
218: 
219: {-@ sort :: (Ord a) => [a] -> OList a  @-}
220: sort :: (Ord a) => [a] -> [a]
221: forall a. (GHC.Classes.Ord a) => [a] -> [a]<\hd9 VV -> (hd9 <= VV)>sort = {VV : [{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}
-> {VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}mergeAll forall <q :: [a]-> [[a]]-> Bool, p :: [[a]]-> [a]-> Bool>.
(x:{VV : [{VV : [a]<\x5 VV -> (x5 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}
 -> {VV : [a]<\x4 VV -> (x4 <= VV)><p x> | ((len VV) >= 0)})
-> (y:[a]
    -> {VV : [{VV : [a]<\x5 VV -> (x5 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)><q y> | ((len VV) > 0)})
-> x3:[a]
-> exists [z:{VV : [{VV : [a]<\x5 VV -> (x5 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)><q x3> | ((len VV) > 0)}].{VV : [a]<\x4 VV -> (x4 <= VV)><p z> | ((len VV) >= 0)}. [a]
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}sequences
222:   where
223:     [a]
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}sequences (a:b:xs)
224:       | {VV : a | (VV == a)}a x1:a
-> x2:a
-> {VV : (GHC.Types.Ordering) | ((VV == GHC.Types.EQ) <=> (x1 == x2)) && ((VV == GHC.Types.GT) <=> (x1 > x2)) && ((VV == GHC.Types.LT) <=> (x1 < x2))}`compare` {VV : a | (VV == b)}b x1:(GHC.Types.Ordering)
-> x2:(GHC.Types.Ordering)
-> {VV : (GHC.Types.Bool) | (((Prop VV)) <=> (x1 == x2))}== {VV : (GHC.Types.Ordering) | (VV == GHC.Types.GT) && ((cmp VV) == GHC.Types.GT)}GT = a:a
-> {VV : [{VV : a | (VV > a)}]<\x2 VV -> (VV > a) && (VV > x2)> | ((len VV) > 0)}
-> {VV : [a] | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}descending {VV : a | (VV == b)}b {VV : [{VV : a | (VV == a) && (VV > b)}]<\_ VV -> false> | (((null VV)) <=> false) && ((len VV) >= 0) && ((sumLens VV) >= 0)}[{VV : a | (VV == a)}a]  {VV : [a] | (VV == xs) && ((len VV) >= 0) && ((sumLens VV) >= 0)}xs
225:       | otherwise           = a:a
-> (x1:{VV : [{VV : a | (VV >= a)}]<\x3 VV -> (a <= VV) && (x3 <= VV)> | ((len VV) > 0)}
    -> {VV : [a]<\x2 VV -> (x2 <= VV)> | (VV /= x1) && ((len VV) > 0) && ((len VV) > (len x1))})
-> {VV : [a] | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}ascending  {VV : a | (VV == b)}b ({VV : a | (VV == a)}aforall <p :: a-> a-> Bool>.
x1:{VV : a | (VV >= a)}
-> x2:[{VV : a<p x1> | (VV >= a)}]<p>
-> {VV : [{VV : a | (VV >= a)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:) {VV : [a] | (VV == xs) && ((len VV) >= 0) && ((sumLens VV) >= 0)}xs
226:     sequences [x] = {VV : [{VV : [{VV : a | false}]<\_ VV -> false> | false}]<\_ VV -> false> | (((null VV)) <=> true) && ((len VV) == 0) && ((sumLens VV) == 0) && ((len VV) >= 0) && ((sumLens VV) >= 0)}[{VV : [{VV : a | (VV == a)}]<\_ VV -> false> | (((null VV)) <=> false) && ((len VV) >= 0) && ((sumLens VV) >= 0)}[{VV : a | (VV == a)}x]]
227:     sequences []  = {VV : [{VV : [{VV : a | false}]<\_ VV -> false> | false}]<\_ VV -> false> | (((null VV)) <=> true) && ((len VV) == 0) && ((sumLens VV) == 0) && ((len VV) >= 0) && ((sumLens VV) >= 0)}[{VV : [{VV : a | false}]<\_ VV -> false> | (((null VV)) <=> true) && ((len VV) == 0) && ((sumLens VV) == 0) && ((len VV) >= 0) && ((sumLens VV) >= 0)}[]]
228: 
229:     a:a
-> {VV : [{VV : a | (VV > a)}]<\x2 VV -> (VV > a) && (VV > x2)> | ((len VV) > 0)}
-> {VV : [a] | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}descending aa {VV : [{VV : a | (VV > a)}]<\x1 VV -> (VV > a) && (VV > x1)> | ((len VV) > 0)}as (b:bs)
230:       | {VV : a | (VV == a)}a x1:a
-> x2:a
-> {VV : (GHC.Types.Ordering) | ((VV == GHC.Types.EQ) <=> (x1 == x2)) && ((VV == GHC.Types.GT) <=> (x1 > x2)) && ((VV == GHC.Types.LT) <=> (x1 < x2))}`compare` {VV : a | (VV == b)}b x1:(GHC.Types.Ordering)
-> x2:(GHC.Types.Ordering)
-> {VV : (GHC.Types.Bool) | (((Prop VV)) <=> (x1 == x2))}== {VV : (GHC.Types.Ordering) | (VV == GHC.Types.GT) && ((cmp VV) == GHC.Types.GT)}GT = a:a
-> {VV : [{VV : a | (VV > a)}]<\x2 VV -> (VV > a) && (VV > x2)> | ((len VV) > 0)}
-> {VV : [a] | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}descending {VV : a | (VV == b)}b ({VV : a | (VV == a)}aforall <p :: a-> a-> Bool>.
x1:{VV : a | (VV > b)}
-> x2:[{VV : a<p x1> | (VV > b)}]<p>
-> {VV : [{VV : a | (VV > b)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:{VV : [{VV : a | (VV > a)}]<\x1 VV -> (VV > a) && (VV > x1)> | (VV == as) && ((len VV) > 0) && ((len VV) >= 0) && ((sumLens VV) >= 0)}as) {VV : [a] | (VV == bs) && ((len VV) >= 0) && ((sumLens VV) >= 0)}bs
231:     descending a as bs      = ({VV : a | (VV == a)}aforall <p :: a-> a-> Bool>.
x1:{VV : a | (a <= VV)}
-> x2:[{VV : a<p x1> | (a <= VV)}]<p>
-> {VV : [{VV : a | (a <= VV)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:{VV : [{VV : a | (VV > a)}]<\x1 VV -> (VV > a) && (VV > x1)> | (VV == as) && ((len VV) > 0) && ((len VV) >= 0) && ((sumLens VV) >= 0)}as)forall <p :: [a]-> [a]-> Bool>.
x1:{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}
-> x2:[{VV : [a]<\x3 VV -> (x3 <= VV)><p x1> | ((len VV) >= 0)}]<p>
-> {VV : [{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}: [a]
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}sequences {VV : [a] | ((len VV) >= 0) && ((sumLens VV) >= 0)}bs
232: 
233:     a:a
-> (x1:{VV : [{VV : a | (VV >= a)}]<\x3 VV -> (a <= VV) && (x3 <= VV)> | ((len VV) > 0)}
    -> {VV : [a]<\x2 VV -> (x2 <= VV)> | (VV /= x1) && ((len VV) > 0) && ((len VV) > (len x1))})
-> {VV : [a] | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}ascending aa x1:{VV : [{VV : a | (VV >= a)}]<\x2 VV -> (a <= VV) && (x2 <= VV)> | ((len VV) > 0)}
-> {VV : [a]<\x1 VV -> (x1 <= VV)> | (VV /= x1) && ((len VV) > 0) && ((len VV) > (len x1))}as (b:bs)
234:       | {VV : a | (VV == a)}a x1:a
-> x2:a
-> {VV : (GHC.Types.Ordering) | ((VV == GHC.Types.EQ) <=> (x1 == x2)) && ((VV == GHC.Types.GT) <=> (x1 > x2)) && ((VV == GHC.Types.LT) <=> (x1 < x2))}`compare` {VV : a | (VV == b)}b x1:(GHC.Types.Ordering)
-> x2:(GHC.Types.Ordering)
-> {VV : (GHC.Types.Bool) | (((Prop VV)) <=> (x1 /= x2))}/= {VV : (GHC.Types.Ordering) | (VV == GHC.Types.GT) && ((cmp VV) == GHC.Types.GT)}GT = a:a
-> (x1:{VV : [{VV : a | (VV >= a)}]<\x3 VV -> (a <= VV) && (x3 <= VV)> | ((len VV) > 0)}
    -> {VV : [a]<\x2 VV -> (x2 <= VV)> | (VV /= x1) && ((len VV) > 0) && ((len VV) > (len x1))})
-> {VV : [a] | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}ascending {VV : a | (VV == b)}b (ys:{VV : [{VV : a | (VV >= a) && (VV >= b)}]<\x2 VV -> (a <= VV) && (b <= VV) && (x2 <= VV)> | ((len VV) > 0)}
-> {VV : [a]<\x1 VV -> (VV >= x1)> | (VV /= ys) && ((len VV) > 0) && ((len VV) > (len ys))}\{VV : [{VV : a | (VV >= a) && (VV >= b)}]<\x1 VV -> (a <= VV) && (b <= VV) && (x1 <= VV)> | ((len VV) > 0)}ys -> x1:{VV : [{VV : a | (VV >= a)}]<\x2 VV -> (a <= VV) && (x2 <= VV)> | ((len VV) > 0)}
-> {VV : [a]<\x1 VV -> (x1 <= VV)> | (VV /= x1) && ((len VV) > 0) && ((len VV) > (len x1))}as ({VV : a | (VV == a)}aforall <p :: a-> a-> Bool>.
x1:{VV : a | (VV >= a)}
-> x2:[{VV : a<p x1> | (VV >= a)}]<p>
-> {VV : [{VV : a | (VV >= a)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:{VV : [{VV : a | (VV >= a) && (VV >= b)}]<\x1 VV -> (a <= VV) && (b <= VV) && (x1 <= VV)> | (VV == ys) && ((len VV) > 0) && ((len VV) >= 0) && ((sumLens VV) >= 0)}ys)) {VV : [a] | (VV == bs) && ((len VV) >= 0) && ((sumLens VV) >= 0)}bs
235:     ascending a as bs       = x1:{VV : [{VV : a | (VV >= a)}]<\x2 VV -> (a <= VV) && (x2 <= VV)> | ((len VV) > 0)}
-> {VV : [a]<\x1 VV -> (x1 <= VV)> | (VV /= x1) && ((len VV) > 0) && ((len VV) > (len x1))}as {VV : [{VV : a | (VV == a) && (VV > b)}]<\_ VV -> false> | (((null VV)) <=> false) && ((len VV) >= 0) && ((sumLens VV) >= 0)}[{VV : a | (VV == a)}a]forall <p :: [a]-> [a]-> Bool>.
x1:{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}
-> x2:[{VV : [a]<\x3 VV -> (x3 <= VV)><p x1> | ((len VV) >= 0)}]<p>
-> {VV : [{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}: [a]
-> {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) > 0)}sequences {VV : [a] | ((len VV) >= 0) && ((sumLens VV) >= 0)}bs

Ghc Sort : Helper Functions

242: forall a.
(GHC.Classes.Ord a) =>
{VV : [{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0)}
-> {VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}mergeAll [x] = {VV : [a]<\x1 VV -> (x1 <= VV)> | (VV == x) && ((len VV) >= 0) && ((sumLens VV) >= 0)}x
243: mergeAll xs  = forall a.
(GHC.Classes.Ord a) =>
{VV : [{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0)}
-> {VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}mergeAll (x1:{VV : [{VV : [a]<\x2 VV -> (VV >= x2)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (VV >= x1)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0) && ((len VV) <= (len x1))}mergePairs {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0) && ((sumLens VV) >= 0)}xs)
244: 
245: forall a.
(GHC.Classes.Ord a) =>
x1:{VV : [{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (VV >= x1)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0) && ((len VV) <= (len x1))}mergePairs (a:b:xs) = x1:{VV : [a]<\x3 VV -> (VV >= x3)> | ((len VV) >= 0)}
-> x2:{VV : [a]<\x2 VV -> (VV >= x2)> | ((len VV) >= 0)}
-> {VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0) && ((len VV) >= (len x1)) && ((len VV) >= (len x2))}merge1 {VV : [a]<\x1 VV -> (x1 <= VV)> | (VV == a) && ((len VV) >= 0) && ((sumLens VV) >= 0)}a {VV : [a]<\x1 VV -> (x1 <= VV)> | (VV == b) && ((len VV) >= 0) && ((sumLens VV) >= 0)}bforall <p :: [a]-> [a]-> Bool>.
x1:{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}
-> x2:[{VV : [a]<\x3 VV -> (x3 <= VV)><p x1> | ((len VV) >= 0)}]<p>
-> {VV : [{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}: forall a.
(GHC.Classes.Ord a) =>
x1:{VV : [{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0)}
-> {VV : [{VV : [a]<\x1 VV -> (VV >= x1)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | ((len VV) >= 0) && ((len VV) <= (len x1))}mergePairs {VV : [{VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0)}]<\_ VV -> ((len VV) >= 0)> | (VV == xs) && ((len VV) >= 0) && ((sumLens VV) >= 0)}xs
246: mergePairs [x]      = {VV : [{VV : [{VV : a | false}]<\_ VV -> false> | false}]<\_ VV -> false> | (((null VV)) <=> true) && ((len VV) == 0) && ((sumLens VV) == 0) && ((len VV) >= 0) && ((sumLens VV) >= 0)}[{VV : [a]<\x1 VV -> (x1 <= VV)> | (VV == a) && ((len VV) >= 0) && ((sumLens VV) >= 0)}x]
247: mergePairs []       = forall <p :: [a]-> [a]-> Bool>.
{VV : [{VV : [{VV : a | false}]<\_ VV -> false> | false}]<p> | (((null VV)) <=> true) && ((len VV) == 0) && ((sumLens VV) == 0)}[]
248: 
249: forall a.
(GHC.Classes.Ord a) =>
x1:{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}
-> x2:{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}
-> {VV : [a]<\x1 VV -> (VV >= x1)> | ((len VV) >= 0) && ((len VV) >= (len x1)) && ((len VV) >= (len x2))}merge1 (a:as') (b:bs')
250:   | {VV : a | (VV == a)}a x1:a
-> x2:a
-> {VV : (GHC.Types.Ordering) | ((VV == GHC.Types.EQ) <=> (x1 == x2)) && ((VV == GHC.Types.GT) <=> (x1 > x2)) && ((VV == GHC.Types.LT) <=> (x1 < x2))}`compare` {VV : a | (VV == b)}b x1:(GHC.Types.Ordering)
-> x2:(GHC.Types.Ordering)
-> {VV : (GHC.Types.Bool) | (((Prop VV)) <=> (x1 == x2))}== {VV : (GHC.Types.Ordering) | (VV == GHC.Types.GT) && ((cmp VV) == GHC.Types.GT)}GT = {VV : a | (VV == b)}bforall <p :: a-> a-> Bool>.
x1:{VV : a | (VV >= b)}
-> x2:[{VV : a<p x1> | (VV >= b)}]<p>
-> {VV : [{VV : a | (VV >= b)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:forall a.
(GHC.Classes.Ord a) =>
x1:{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}
-> x2:{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}
-> {VV : [a]<\x1 VV -> (VV >= x1)> | ((len VV) >= 0) && ((len VV) >= (len x1)) && ((len VV) >= (len x2))}merge1 ({VV : a | (VV == a)}aforall <p :: a-> a-> Bool>.
x1:{VV : a | (VV > b)}
-> x2:[{VV : a<p x1> | (VV > b)}]<p>
-> {VV : [{VV : a | (VV > b)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:{VV : [{VV : a | (a <= VV)}]<\x1 VV -> (x1 <= VV)> | (VV == as') && ((len VV) >= 0) && ((sumLens VV) >= 0)}as')  {VV : [{VV : a | (b <= VV)}]<\x1 VV -> (x1 <= VV)> | (VV == bs') && ((len VV) >= 0) && ((sumLens VV) >= 0)}bs'
251:   | otherwise           = {VV : a | (VV == a)}aforall <p :: a-> a-> Bool>.
x1:{VV : a | (VV >= a)}
-> x2:[{VV : a<p x1> | (VV >= a)}]<p>
-> {VV : [{VV : a | (VV >= a)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:forall a.
(GHC.Classes.Ord a) =>
x1:{VV : [a]<\x3 VV -> (x3 <= VV)> | ((len VV) >= 0)}
-> x2:{VV : [a]<\x2 VV -> (x2 <= VV)> | ((len VV) >= 0)}
-> {VV : [a]<\x1 VV -> (VV >= x1)> | ((len VV) >= 0) && ((len VV) >= (len x1)) && ((len VV) >= (len x2))}merge1 {VV : [{VV : a | (a <= VV)}]<\x1 VV -> (x1 <= VV)> | (VV == as') && ((len VV) >= 0) && ((sumLens VV) >= 0)}as' ({VV : a | (VV == b)}bforall <p :: a-> a-> Bool>.
x1:{VV : a | (VV >= a) && (VV >= b)}
-> x2:[{VV : a<p x1> | (VV >= a) && (VV >= b)}]<p>
-> {VV : [{VV : a | (VV >= a) && (VV >= b)}]<p> | (((null VV)) <=> false) && ((len VV) == (1 + (len x2))) && ((sumLens VV) == ((len x1) + (sumLens x2)))}:{VV : [{VV : a | (b <= VV)}]<\x1 VV -> (x1 <= VV)> | (VV == bs') && ((len VV) >= 0) && ((sumLens VV) >= 0)}bs')
252: merge1 [] bs            = {VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0) && ((sumLens VV) >= 0)}bs
253: merge1 as []            = {VV : [a]<\x1 VV -> (x1 <= VV)> | ((len VV) >= 0) && ((sumLens VV) >= 0)}as