From 889b5a214a6754ffd6f0f60b5bfe8bfe4a35cc22 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 19 Oct 2022 12:47:04 +0200 Subject: [PATCH 001/219] remove tests from todo --- tests/relational/todo/Ap.hs | 7 - tests/relational/todo/ApSum.hs | 8 - tests/relational/todo/ApSumAsync.hs | 29 -- tests/relational/todo/Assume.hs | 8 - tests/relational/todo/AssumeRelational.hs | 25 -- tests/relational/todo/Bsplit.hs | 48 --- tests/relational/todo/BuiltInFib.hs | 9 - tests/relational/todo/BuiltInNull.hs | 10 - tests/relational/todo/CaseAnalysis.hs | 27 -- tests/relational/todo/CaseOnRec.hs | 52 --- tests/relational/todo/DeltaSort.hs | 28 -- tests/relational/todo/Either.hs | 5 - tests/relational/todo/Example.hs | 70 ---- tests/relational/todo/Fib.hs | 18 -- tests/relational/todo/FibLet.hs | 23 -- tests/relational/todo/Filter.hs | 73 ----- tests/relational/todo/GD.hs | 53 --- tests/relational/todo/HornApp.hs | 9 - tests/relational/todo/IdInt.hs | 12 - tests/relational/todo/Incr.hs | 14 - tests/relational/todo/IncrF.hs | 18 -- tests/relational/todo/Incr_.hs | 14 - tests/relational/todo/IsZero.hs | 15 - tests/relational/todo/Isort.hs | 165 ---------- tests/relational/todo/ListSum.hs | 29 -- tests/relational/todo/Map.hs | 17 - tests/relational/todo/MapFusion.hs | 153 --------- tests/relational/todo/MapTest.hs | 48 --- tests/relational/todo/Max.hs | 10 - tests/relational/todo/Merge.hs | 9 - tests/relational/todo/Msort.hs | 45 --- tests/relational/todo/MultiRel.hs | 12 - tests/relational/todo/MultiRelNeg.hs | 2 - tests/relational/todo/MultiRel_.hs | 13 - tests/relational/todo/MutRecNeg.hs | 10 - tests/relational/todo/MutualRec.hs | 9 - tests/relational/todo/NullSize.hs | 25 -- tests/relational/todo/PredAbstr.hs | 4 - tests/relational/todo/Rec.hs | 10 - tests/relational/todo/RecAndNonRec.hs | 11 - tests/relational/todo/RecNonFunc.hs | 10 - tests/relational/todo/RecNonFunc_.hs | 18 -- tests/relational/todo/Repeat.hs | 21 -- tests/relational/todo/ReuseRel.hs | 12 - tests/relational/todo/SGD.hs | 373 ---------------------- tests/relational/todo/SGDSimple.hs | 56 ---- tests/relational/todo/SGDc.hs | 179 ----------- tests/relational/todo/SGDr.hs | 138 -------- tests/relational/todo/SGDr0.hs | 236 -------------- tests/relational/todo/SGDr00.hs | 177 ---------- tests/relational/todo/SGDu.hs | 229 ------------- tests/relational/todo/SndOrdPred.hs | 35 -- tests/relational/todo/SquareMult.hs | 21 -- tests/relational/todo/SquareMult_.hs | 24 -- tests/relational/todo/SumAlphaBeta.hs | 72 ----- tests/relational/todo/SynchCase.hs | 36 --- tests/relational/todo/SynchLists.hs | 32 -- tests/relational/todo/TakeMap.hs | 70 ---- tests/relational/todo/TakeMapPoly.hs | 70 ---- tests/relational/todo/TrdOrdPredNonRel.hs | 16 - tests/relational/todo/TyAbsAp.hs | 30 -- tests/relational/todo/TyAbsMax.hs | 16 - 62 files changed, 3018 deletions(-) delete mode 100644 tests/relational/todo/Ap.hs delete mode 100644 tests/relational/todo/ApSum.hs delete mode 100644 tests/relational/todo/ApSumAsync.hs delete mode 100644 tests/relational/todo/Assume.hs delete mode 100644 tests/relational/todo/AssumeRelational.hs delete mode 100644 tests/relational/todo/Bsplit.hs delete mode 100644 tests/relational/todo/BuiltInFib.hs delete mode 100644 tests/relational/todo/BuiltInNull.hs delete mode 100644 tests/relational/todo/CaseAnalysis.hs delete mode 100644 tests/relational/todo/CaseOnRec.hs delete mode 100644 tests/relational/todo/DeltaSort.hs delete mode 100644 tests/relational/todo/Either.hs delete mode 100644 tests/relational/todo/Example.hs delete mode 100644 tests/relational/todo/Fib.hs delete mode 100644 tests/relational/todo/FibLet.hs delete mode 100644 tests/relational/todo/Filter.hs delete mode 100644 tests/relational/todo/GD.hs delete mode 100644 tests/relational/todo/HornApp.hs delete mode 100644 tests/relational/todo/IdInt.hs delete mode 100644 tests/relational/todo/Incr.hs delete mode 100644 tests/relational/todo/IncrF.hs delete mode 100644 tests/relational/todo/Incr_.hs delete mode 100644 tests/relational/todo/IsZero.hs delete mode 100644 tests/relational/todo/Isort.hs delete mode 100644 tests/relational/todo/ListSum.hs delete mode 100644 tests/relational/todo/Map.hs delete mode 100644 tests/relational/todo/MapFusion.hs delete mode 100644 tests/relational/todo/MapTest.hs delete mode 100644 tests/relational/todo/Max.hs delete mode 100644 tests/relational/todo/Merge.hs delete mode 100644 tests/relational/todo/Msort.hs delete mode 100644 tests/relational/todo/MultiRel.hs delete mode 100644 tests/relational/todo/MultiRelNeg.hs delete mode 100644 tests/relational/todo/MultiRel_.hs delete mode 100644 tests/relational/todo/MutRecNeg.hs delete mode 100644 tests/relational/todo/MutualRec.hs delete mode 100644 tests/relational/todo/NullSize.hs delete mode 100644 tests/relational/todo/PredAbstr.hs delete mode 100644 tests/relational/todo/Rec.hs delete mode 100644 tests/relational/todo/RecAndNonRec.hs delete mode 100644 tests/relational/todo/RecNonFunc.hs delete mode 100644 tests/relational/todo/RecNonFunc_.hs delete mode 100644 tests/relational/todo/Repeat.hs delete mode 100644 tests/relational/todo/ReuseRel.hs delete mode 100644 tests/relational/todo/SGD.hs delete mode 100644 tests/relational/todo/SGDSimple.hs delete mode 100644 tests/relational/todo/SGDc.hs delete mode 100644 tests/relational/todo/SGDr.hs delete mode 100644 tests/relational/todo/SGDr0.hs delete mode 100644 tests/relational/todo/SGDr00.hs delete mode 100644 tests/relational/todo/SGDu.hs delete mode 100644 tests/relational/todo/SndOrdPred.hs delete mode 100644 tests/relational/todo/SquareMult.hs delete mode 100644 tests/relational/todo/SquareMult_.hs delete mode 100644 tests/relational/todo/SumAlphaBeta.hs delete mode 100644 tests/relational/todo/SynchCase.hs delete mode 100644 tests/relational/todo/SynchLists.hs delete mode 100644 tests/relational/todo/TakeMap.hs delete mode 100644 tests/relational/todo/TakeMapPoly.hs delete mode 100644 tests/relational/todo/TrdOrdPredNonRel.hs delete mode 100644 tests/relational/todo/TyAbsAp.hs delete mode 100644 tests/relational/todo/TyAbsMax.hs diff --git a/tests/relational/todo/Ap.hs b/tests/relational/todo/Ap.hs deleted file mode 100644 index 124762ded7..0000000000 --- a/tests/relational/todo/Ap.hs +++ /dev/null @@ -1,7 +0,0 @@ -module Fixme where - -ap :: (Int -> Int) -> Int -> Int -ap f x = f x - -{-@ relational ap ~ ap :: f1:_ -> xs1:_ -> _ ~ f2:_ -> xs2:_ -> _ - ~~ f1 == f2 => xs1 == xs2 => r1 f1 xs1 == r2 f2 xs2 @-} diff --git a/tests/relational/todo/ApSum.hs b/tests/relational/todo/ApSum.hs deleted file mode 100644 index 343ae34aef..0000000000 --- a/tests/relational/todo/ApSum.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Fixme where - -apsum :: Int -> Int -> Int -apsum n a = if n <= 0 then a else a + n + apsum (n - 1) a - -{-@ relational apsum ~ apsum - :: n1:Int -> a1:Int -> Int ~ n2:Int -> a2:Int -> Int - ~~ n1 == n2 => a1 < a2 => r1 n1 a1 < r2 n2 a2 @-} diff --git a/tests/relational/todo/ApSumAsync.hs b/tests/relational/todo/ApSumAsync.hs deleted file mode 100644 index 61f8d830e3..0000000000 --- a/tests/relational/todo/ApSumAsync.hs +++ /dev/null @@ -1,29 +0,0 @@ -module Fixme where - -{-@ reflect apsum @-} -apsum :: Int -> Int -> Int -apsum n a = if n <= 0 then a else a + n + apsum (n - 1) a - -{- - a1 <= a2 + n2 + apsum (n2 - 1) a2 --} - -{-@ relational apsum ~ apsum - :: n1:Int -> a1:Int -> Nat ~ n2:Int -> a2:Int -> Nat - ~~ n1 <= n2 => - 0 <= a1 && a1 <= a2 => - r1 n1 a1 <= r2 n2 a2 @-} - --- {-@ theorem :: n1:Int -> {a1:Int|0 <= a1} -> --- {n2:Int|n1 <= n2} -> {a2:Int|a1 <= a2} -> --- {apsum n1 a1 <= apsum n2 a2} @-} --- theorem :: Int -> Int -> Int -> Int -> () --- theorem _ _ _ _ = () - -{- T_unary <: T_relational -} - -foo :: Int -> Int -foo n = apsum n 1 - -{-@ relational foo ~ foo :: n1:_ -> _ ~ n2:_ -> _ - ~~ n1 < n2 => r1 n1 <= r2 n2 @-} diff --git a/tests/relational/todo/Assume.hs b/tests/relational/todo/Assume.hs deleted file mode 100644 index c20b114462..0000000000 --- a/tests/relational/todo/Assume.hs +++ /dev/null @@ -1,8 +0,0 @@ -{-@ assume foo :: x:{Int|x /= 0} -> {v:Int|v == 5} @-} -{-@ foo :: x:{Int|x /= 0} -> {v:Int|v = 5 / x} @-} -foo :: Int -> Int -foo = div 5 - -{-@ bar :: {v:Int|v == 5} @-} -bar :: Int -bar = foo 4 \ No newline at end of file diff --git a/tests/relational/todo/AssumeRelational.hs b/tests/relational/todo/AssumeRelational.hs deleted file mode 100644 index c8ec588377..0000000000 --- a/tests/relational/todo/AssumeRelational.hs +++ /dev/null @@ -1,25 +0,0 @@ -module AssumeRelational where - -update :: Int -> Int -> Int -update _ _ = 0 - -updates :: [Int] -> Int -> Int -updates [] w = w -updates (z : zs) w = updates zs (update z w) - -{-@ reflect diff @-} -{-@ diff :: xs:[Int] -> ys:{[Int]|len ys == len xs} -> Int @-} -diff :: [Int] -> [Int] -> Int -diff (x : xs) (y : ys) | x == y = diff xs ys -diff (x : xs) (y : ys) | x /= y = 1 + diff xs ys -diff _ _ = 0 - -{-@ assume relational update ~ update :: z1:Int -> w1:Int -> Int ~ z2:Int -> w2:Int -> Int - ~~ z1 = z2 => true => r1 z1 w1 - r2 z2 w2 = w1 - w2 @-} - -{-@ assume relational update ~ update :: z1:Int -> w1:Int -> Int ~ z2:Int -> w2:Int -> Int - ~~ true => true => r1 z1 w1 - r2 z2 w2 <= w1 - w2 + 5 @-} - -{-@ relational updates ~ updates :: zs1:[Int] -> w1:Int -> Int ~ zs2:[Int] -> w2:Int -> Int - ~~ len zs1 = len zs2 => true => - r1 zs1 w1 - r2 zs2 w2 <= w1 - w2 + 5 * AssumeRelational.diff zs1 zs2 @-} \ No newline at end of file diff --git a/tests/relational/todo/Bsplit.hs b/tests/relational/todo/Bsplit.hs deleted file mode 100644 index d3917230af..0000000000 --- a/tests/relational/todo/Bsplit.hs +++ /dev/null @@ -1,48 +0,0 @@ -module Fixme where - -{-@ data Tick a = T { res :: a, time :: Int} @-} -data Tick a = T { res :: a, time :: Int} - --- instance Monad Tick where --- (T r t) >>= f = let T r' t' = f r in T r' (t + t') --- instance Functor Tick --- instance Applicative Tick - --- {-@ reflect tick @-} --- tick :: Int -> a -> Tick a --- tick n a = T a n - -{-@ reflect diff @-} -{-@ diff :: xs:[Int] -> ys:{[Int]|len ys == len xs} -> Int @-} -diff :: [Int] -> [Int] -> Int -diff (x : xs) (y : ys) | x == y = diff xs ys -diff (x : xs) (y : ys) | x /= y = 1 + diff xs ys -diff _ _ = 0 - -{-@ data Split = S { l :: [Int], r :: [Int] } @-} -data Split = S { l :: [Int], r :: [Int] } - --- {-@ bsplit :: xs:[Int] -> {v:Tick Split|len xs / 2 <= len (l (res v)) && len (l (res v)) <= len xs / 2 + 1 --- && len (r (res v)) = len xs / 2} @-} --- bsplit :: [Int] -> Tick Split --- bsplit [] = T (S [] []) 0 --- bsplit [x] = T (S [x] []) 1 --- bsplit (x : y : xs) = --- let T (S ls rs) t = bsplit xs in T (S (x : ls) (y : rs)) (t + 2) - --- {-@ relational bsplit ~ bsplit :: xs1:_ -> _ ~ xs2:_ -> _ --- ~~ true => Fixme.diff xs1 xs2 == --- Fixme.diff (Fixme.l (Fixme.res (r1 xs1))) ((Fixme.l (Fixme.res (r2 xs2)))) --- + Fixme.diff (Fixme.r (Fixme.res (r1 xs1))) (Fixme.r (Fixme.res (r2 xs2))) @-} - -bsplit' :: [Int] -> Split -bsplit' [] = S [] [] -bsplit' [x] = S [x] [] -bsplit' (x : y : xs) = - let S ls rs = bsplit' xs in S (x : ls) (y : rs) - -{-@ relational bsplit' ~ bsplit' :: xs1:_ -> _ ~ xs2:_ -> _ - ~~ true => Fixme.diff xs1 xs2 == - Fixme.diff (Fixme.l ((r1 xs1))) ((Fixme.l ((r2 xs2)))) - + Fixme.diff (Fixme.r ((r1 xs1))) (Fixme.r ((r2 xs2))) @-} - diff --git a/tests/relational/todo/BuiltInFib.hs b/tests/relational/todo/BuiltInFib.hs deleted file mode 100644 index e90b65a7fe..0000000000 --- a/tests/relational/todo/BuiltInFib.hs +++ /dev/null @@ -1,9 +0,0 @@ -module Fixme where - -fib :: Int -> Int -fib x | x <= 1 = 1 -fib x = fib (x - 1) + fib (x - 2) - -{-@ relational fib ~ fib :: x1:_ -> {v:Int|v >= 1} ~ x2:_ -> {v:Int|v >= 1} - ~~ x1 <= x2 => r1 x1 <= r2 x2 @-} - diff --git a/tests/relational/todo/BuiltInNull.hs b/tests/relational/todo/BuiltInNull.hs deleted file mode 100644 index a609682430..0000000000 --- a/tests/relational/todo/BuiltInNull.hs +++ /dev/null @@ -1,10 +0,0 @@ -module Fixme where - -{-@ reflect null' @-} -null' :: [Int] -> Bool -null' [] = True -null' _ = False - -{-@ relational null' ~ null' :: l1:_ -> _ - ~ l2:_ -> _ - ~~ len l1 = len l2 => Fixme.null' l1 = Fixme.null' l2 @-} \ No newline at end of file diff --git a/tests/relational/todo/CaseAnalysis.hs b/tests/relational/todo/CaseAnalysis.hs deleted file mode 100644 index 00a068eb71..0000000000 --- a/tests/relational/todo/CaseAnalysis.hs +++ /dev/null @@ -1,27 +0,0 @@ -module CaseAnalysis where - -{-@ update :: Nat -> Int -> Int @-} -update :: Int -> Int -> Int -update z w = w + min z 5 - -{-@ updates :: [Nat] -> Int -> Int @-} -updates :: [Int] -> Int -> Int -updates [] w = w -updates (z : zs) w = updates zs (update z w) - -{-@ reflect diff @-} -{-@ diff :: xs:[Int] -> ys:{[Int]|len ys == len xs} -> Int @-} -diff :: [Int] -> [Int] -> Int -diff (x : xs) (y : ys) | x == y = diff xs ys -diff (x : xs) (y : ys) | x /= y = 1 + diff xs ys -diff _ _ = 0 - -{-@ relational update ~ update :: z1:Nat -> w1:Int -> Int ~ z2:Int -> w2:Int -> Int - ~~ z1 = z2 => true => r1 z1 w1 - r2 z2 w2 = w1 - w2 @-} - -{-@ relational update ~ update :: z1:Nat -> w1:Int -> Int ~ z2:Nat -> w2:Int -> Int - ~~ true => true => r1 z1 w1 - r2 z2 w2 <= w1 - w2 + 5 @-} - -{-@ relational updates ~ updates :: zs1:[Nat] -> w1:Int -> Int ~ zs2:[Nat] -> w2:Int -> Int - ~~ len zs1 = len zs2 => true => - r1 zs1 w1 - r2 zs2 w2 <= w1 - w2 + 5 * CaseAnalysis.diff zs1 zs2 @-} \ No newline at end of file diff --git a/tests/relational/todo/CaseOnRec.hs b/tests/relational/todo/CaseOnRec.hs deleted file mode 100644 index ff2857a283..0000000000 --- a/tests/relational/todo/CaseOnRec.hs +++ /dev/null @@ -1,52 +0,0 @@ -module Fixme where - -data Parity = Even | Odd - -{- - I. E ~ E - E == E <=> 0 == 0 [v] - - II. case f (if ...) of { E -> O; O -> E} ~ case f (if ...) of { E -> O; O -> E} - a) E ~ E - E == E - <=> f (n1 +/- 1) == f (n2 +/- 1) - <=> (n1 +/- 1 - n2 -/+ 1) mod 2 == 0 - <=> (n1 - n2) mod 2 == 0 [v] - b,c,d) same - - III. E ~ case f (if ...) of { E -> O; O -> E} - a) E ~ E - E == E <=> n2 mod 2 == 0 ??????????? - b) E ~ O - E == O <=> n2 mod 2 == 0 ???????? --} - -{-@ f :: n:Int -> {v:Parity| ((v == Fixme.Even) <=> (n mod 2 == 0)) - && ((v == Fixme.Odd) <=> (n mod 2 == 1)) } / [if n >= 0 then n else -n] @-} -f :: Int -> Parity -f 0 = Even -f n = case f (if n < 0 then n + 1 else n - 1) of - Even -> Odd - Odd -> Even - -{-@ relational isEven ~ isEven :: n1:_ -> _ ~ n2:_ -> _ - ~~ (n1 mod 2 = n2 mod 2) => (r1 n1 = r2 n2) @-} - -isEven :: Int -> Bool -isEven 0 = True -isEven n = if isEven n' then False else True - where n' = if n < 0 then n + 1 else n - 1 - --- if isEven n' then False else True ~ if isEven n' then False else True - --- Asynch: --- I. isEven n1' = True, isEven n2' = True |- False ~ False | (n1 mod 2 = n2 mod 2) => (r1 = r2) --- II. isEven n1' = True, isEven n2' = False |- False ~ True | (n1 mod 2 = n2 mod 2) => (r1 = r2) - --- isEven n1' ~ isEven n2' | (n1' mod 2 = n2' mod 2) => (r1 = r2) - --- isEven n1' ~ isEven n2' | r1 = r2 - - -{-@ relational isEven ~ isEven :: n1:_ -> _ ~ n2:_ -> _ - ~~ true => ((r1 n1 == r2 n2) <=> (n1 mod 2 = n2 mod 2)) @-} \ No newline at end of file diff --git a/tests/relational/todo/DeltaSort.hs b/tests/relational/todo/DeltaSort.hs deleted file mode 100644 index 11bdf3fadd..0000000000 --- a/tests/relational/todo/DeltaSort.hs +++ /dev/null @@ -1,28 +0,0 @@ -module DeltaSort where - -import Prelude hiding (abs, max) - -sort :: [Int] -> [Int] -sort [] = [] -sort (x:xs) = sort (filter (< x) xs) ++ [x] ++ sort (filter (>= x) xs) - -{-@ reflect delta @-} -{-@ delta :: xs:[Int] -> {ys:[Int]|len ys = len xs} -> Int @-} -delta :: [Int] -> [Int] -> Int -delta [] [] = 0 -delta (x:xs) (y:ys) = max (abs (x - y)) (delta xs ys) - -{-@ relational sort ~ sort :: xs:[Int] -> [Int] ~ ys:[Int] -> [Int] - ~~ true => DeltaSort.delta xs ys >= DeltaSort.delta (r1 xs) (r2 ys) @-} - ---------------------- -------- Utils ------- ---------------------- - -{-@ reflect max @-} -max :: Int -> Int -> Int -max a b = if a < b then b else a - -{-@ reflect abs @-} -abs :: Int -> Int -abs x = if x < 0 then -x else x \ No newline at end of file diff --git a/tests/relational/todo/Either.hs b/tests/relational/todo/Either.hs deleted file mode 100644 index 455f367811..0000000000 --- a/tests/relational/todo/Either.hs +++ /dev/null @@ -1,5 +0,0 @@ -module Fixme where - -{-@ foo :: {v:Either Bool Bool| isLeft v} @-} -foo :: Either Bool Bool -foo = Left True diff --git a/tests/relational/todo/Example.hs b/tests/relational/todo/Example.hs deleted file mode 100644 index 09011559e4..0000000000 --- a/tests/relational/todo/Example.hs +++ /dev/null @@ -1,70 +0,0 @@ -foo, bar :: Bool -> Int -foo a = if a then 0 else 2 -bar b = if b then 1 else 3 - -{-@ relational foo ~ bar :: x1:Bool -> Int ~ x2:Bool -> Int - ~~ x1 == x2 => r1 x1 < r2 x2 @-} - -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--ple" @-} - --- Refinemnet types (non-relational): -{-@ reflect isEven @-} -{-@ isEven :: n:Int -> {v:Bool|(v <=> n mod 2 = 0)} / [if n >= 0 then n else -n] @-} -isEven :: Int -> Bool -isEven 0 = True -isEven n = if (isEven (if n < 0 then n + 1 else n - 1)) then False else True - -{- -isEven ~ isEven | n mod 2 /= m mod 2 => r1 n /= r2 m - -I. True ~ True | 0 mod 2 /= 0 mod 2 => True /= True (v) - -II. True ~ not (isEven (if m < 0 then m + 1 else m - 1)) - | 0 mod 2 /= m mod 2 => True /= not (isEven (if m < 0 then m + 1 else m - 1)) (v) - -III. not (isEven (if n < 0 then n + 1 else n - 1)) ~ not (isEven (if m < 0 then m + 1 else m - 1)) - | n mod 2 /= m mod 2 => - not (isEven (if n < 0 then n + 1 else n - 1)) /= not (isEven (if m < 0 then m + 1 else m - 1)) (v) - - a) isEven (if n < 0 then n + 1 else n - 1) ~ isEven (if m < 0 then m + 1 else m - 1) - | n' mod 2 /= m' mod 2 => isEven n' /= isEven m' - b) isEven (if n < 0 then n + 1 else n - 1) ~ isEven (if m < 0 then m + 1 else m - 1) - | n' mod 2 /= m' mod 2 => isEven n' /= isEven m' - c) isEven (if n < 0 then n + 1 else n - 1) ~ isEven (if m < 0 then m + 1 else m - 1) - | n' mod 2 /= m' mod 2 => isEven n' /= isEven m' --} - -{-@ relational isEven ~ isEven :: n:Int -> Bool ~ m:Int -> Bool - ~~ n mod 2 /= m mod 2 => r1 n /= r2 m @-} -isEven_isEven :: Int -> Int -> () -isEven_isEven _ _ = () - - - -{-@ theorem :: n:Int -> m:Int -> {n mod 2 = m mod 2 => isEven n /= isEven m} / [if n >= 0 then n else -n] @-} -theorem :: Int -> Int -> () -theorem 0 0 = () -theorem n 0 = if isEven n then () else () -theorem 0 m = if isEven m then () else () -theorem n m = theorem n' m' - where - n' = if n < 0 then n + 1 else n - 1 - m' = if m < 0 then m + 1 else m - 1 - -{- isEven :: n:A -> B @-} -{- isEven :: n:A' -> B' ~ n:A' -> B' ~~ n mod 2 = m mod 2 => false @-} - -{- emp |- A <: A' - A |- B' <: B -} - --- abs :: Int -> {x:Int|0 <= x} --- abs x = if x < 0 then -x else x - --- safeDiv :: Int -> {d:Int|d /= 0} -> Int --- safeDiv = div - --- isEven :: n:Int -> {v:Bool|v <=> n mod 2 = 0} --- isEven 0 = True --- isEven n = not $ isEven (if n < 0 then n + 1 else n - 1) - diff --git a/tests/relational/todo/Fib.hs b/tests/relational/todo/Fib.hs deleted file mode 100644 index 80d7eabb85..0000000000 --- a/tests/relational/todo/Fib.hs +++ /dev/null @@ -1,18 +0,0 @@ -module Fixme where - -data N = Z | S N - -fib :: N -> Int -fib Z = 1 -fib (S Z ) = 1 -fib (S m@(S n)) = fib n + fib m - -{-@ reflect leq @-} -leq :: N -> N -> Bool -leq Z _ = True -leq _ Z = False -leq (S n) (S m) = leq n m - -{-@ relational fib ~ fib :: n1:_ -> { v:Int | v >= 1 } ~ n2:_ -> { v:Int | v >= 1 } - ~~ n1 == n2 => r1 n1 == r2 n2 @-} - diff --git a/tests/relational/todo/FibLet.hs b/tests/relational/todo/FibLet.hs deleted file mode 100644 index d77224d941..0000000000 --- a/tests/relational/todo/FibLet.hs +++ /dev/null @@ -1,23 +0,0 @@ -module Fixme where - -data N = Z | S N - -{-@ fib :: N -> { v:Int | v >= 1 } @-} -fib :: N -> Int -fib = let f = \l -> case l of - Z -> 1 - (S Z ) -> 1 - (S m@(S n)) -> fib n + fib m - in f - -{-@ reflect leq @-} -leq :: N -> N -> Bool -leq Z _ = True -leq _ Z = False -leq (S n) (S m) = leq n m - -{-@ relational fib ~ fib :: n:_ -> _ ~ m:_ -> _ - ~~ Fixme.leq n m => r1 n <= r2 m @-} - - - diff --git a/tests/relational/todo/Filter.hs b/tests/relational/todo/Filter.hs deleted file mode 100644 index 42776857db..0000000000 --- a/tests/relational/todo/Filter.hs +++ /dev/null @@ -1,73 +0,0 @@ -module Filter where - -{-@ measure d :: a -> a -> Double @-} -{-@ assume d :: x:a -> y:a -> {v:Double | v = d x y } @-} -d :: a -> a -> Double -d x y = undefined - --- Lam. fix filter(f). Lam. Lam. lam l. caseL l of --- nil => pack nil --- | h::tl => let r' = filter f [] [] tl in --- let b = (f h) in --- unpack r' as r in if b then pack (h::r) else pack r --- --- <= 0 : forall k. ((B ((U int) [diff, k] -> U bool)) => forall i; alpha. --- (list[i,alpha] U int) [diff, k * alpha] -> U (exists j ::size. (list[j] int))) --- --- From: https://github.com/ezgicicek/BiRelCost/blob/master/examples/binary/filter.br - -data List a = Nil | Cons a (List a) - -{-@ reflect lenList @-} -{-@ lenList :: List a -> Int @-} -lenList :: List a -> Int -lenList Nil = 0 -lenList (Cons _ xs) = 1 + lenList xs - --- {-@ reflect diff @-} {-@ diff :: xs:[Int] -> ys:{[Int]|len ys == --- len xs} -> Int @-} diff :: [Int] -> [Int] -> Int diff (x : xs) (y : --- ys) | x == y = diff xs ys diff (x : xs) (y : ys) | x /= y = 1 + --- diff xs ys diff _ _ = 0 - -{-@ reflect diff @-} -{-@ diff :: xs:List Int -> ys:{List Int|lenList ys == lenList xs} -> Int @-} -diff :: List Int -> List Int -> Int -diff (Cons x xs) (Cons y ys) - | x == y = diff xs ys -diff (Cons x xs) (Cons y ys) - | x /= y = 1 + diff xs ys -diff _ _ = 0 - -filter' :: Double -> (Int -> Bool) -> List Int -> List Int -filter' _ _ Nil = Nil -filter' k pred (Cons el els) - | pred el = Cons el (filter' k pred els) - | otherwise = filter' k pred els -{-@ relational filter' ~ filter' :: - k1:Double -> f1:(Int -> Bool) -> xs1:List Int -> List Int ~ - k2:Double -> f2:(Int -> Bool) -> xs2:List Int -> List Int - ~~ k1 = k2 => true => f1 = f2 && Filter.lenList xs1 = Filter.lenList xs2 => true @-} - -{- relational filter' ~ filter' :: - k1:Double -> f1:(x1:Int -> Bool) -> xs1:List Int -> List Int ~ - k2:Double -> f2:(x2:Int -> Bool) -> xs2:List Int -> List Int - ~~ k1 = k2 => (true => d x1 x2 <= k1) => lenList xs1 = lenList xs2 - => d (r1 f1 xs1) (r2 f2 xs2) - <= diff xs1 xs2 * k1 @-} - - - -add :: Int -> Int -> Int -add x y = x + y -{-@ relational add ~ add :: x1:Int -> y1:Int -> Int ~ - x2:Int -> y2:Int -> Int - ~~ x1 == x2 => y1 == y2 => - r1 x1 y1 == r2 x2 y2 @-} - -abs :: Int -> Int -abs x = if x < 0 then -x else x - -{-@ relational abs ~ abs :: x1:Int -> Int ~ - x2:Int -> Int - ~~ 0 <= x1 && x1 < x2 => - r1 x1 < r2 x2 @-} diff --git a/tests/relational/todo/GD.hs b/tests/relational/todo/GD.hs deleted file mode 100644 index 0cd1dd5a70..0000000000 --- a/tests/relational/todo/GD.hs +++ /dev/null @@ -1,53 +0,0 @@ -module GD where - -type Dbl = Double - -{-@ type StepSize = {v:Dbl|0 <= v} @-} -type StepSize = Dbl -type DataPoint = (Dbl, Dbl) -type Weight = Dbl -type LossFunction = DataPoint -> [Weight] -> Dbl - -{-@ gd :: [DataPoint] -> ws:[Weight] -> StepSize -> {v:[Weight]|len v == len ws} @-} -gd :: [DataPoint] -> [Weight] -> StepSize -> [Weight] -gd [] ws _ = ws -gd (z : zs) ws α = gd zs (update z ws α) α - -{-@ update :: DataPoint -> ws:[Weight] -> StepSize -> {v:[Weight]|len v = len ws} @-} -update :: DataPoint -> [Weight] -> StepSize -> [Weight] -update _ ws _ = ws - -{-@ reflect diff @-} -{-@ diff :: xs:[a] -> ys:{[a]|len ys == len xs} -> {v:Dbl|0 <= v} @-} -diff :: Eq a => [a] -> [a] -> Dbl -diff (x : xs) (y : ys) | x == y = diff xs ys -diff (x : xs) (y : ys) | x /= y = 1 + diff xs ys -diff _ _ = 0 - -{-@ measure dist :: [Weight] -> [Weight] -> Dbl @-} - -{-@ measure loss :: LossFunction @-} -loss :: LossFunction -loss _ _ = 0 - -{-@ measure lip :: {v:Dbl|0 <= v} @-} -lip :: Dbl -lip = 10 - -{-@ relational update ~ update :: z1:DataPoint -> ws1:[Weight] -> α1:StepSize -> {v:[Weight]|len v = len ws1} - ~ z2:DataPoint -> ws2:[Weight] -> α2:StepSize -> {v:[Weight]|len v = len ws2} - ~~ z1 = z2 => true => true => - dist (r1 z1 ws1 α1) (r2 z2 ws2 α2) <= - dist ws1 ws2 @-} - -{-@ relational update ~ update :: z1:DataPoint -> ws1:[Weight] -> α1:StepSize -> {v:[Weight]|len v = len ws1} - ~ z2:DataPoint -> ws2:[Weight] -> α2:StepSize -> {v:[Weight]|len v = len ws2} - ~~ true => true => true => - dist (r1 z1 ws1 α1) (r2 z2 ws2 α2) <= - dist ws1 ws2 + 2.0 @-} - -{-@ relational gd ~ gd :: zs1:[DataPoint] -> ws1:[Weight] -> α1:StepSize -> {v:[Weight]|len v == len ws1} - ~ zs2:[DataPoint] -> ws2:[Weight] -> α2:StepSize -> {v:[Weight]|len v == len ws2} - ~~ len zs1 = len zs2 => true => true => - dist (r1 zs1 ws1 α1) (r2 zs2 ws2 α2) <= - dist ws1 ws2 + 2.0 * GD.diff zs1 zs2 @-} diff --git a/tests/relational/todo/HornApp.hs b/tests/relational/todo/HornApp.hs deleted file mode 100644 index 99e0b04542..0000000000 --- a/tests/relational/todo/HornApp.hs +++ /dev/null @@ -1,9 +0,0 @@ -module HornApp where - -inc :: Int -> Int -inc x = x + 1 - -foo :: Int -> Int -foo x = inc x - -{-@ relational foo ~ foo :: x1:_ -> _ ~ x2:_ -> _ ~~ x1 < x2 => r1 x1 < r2 x2 @-} diff --git a/tests/relational/todo/IdInt.hs b/tests/relational/todo/IdInt.hs deleted file mode 100644 index f6e96467b2..0000000000 --- a/tests/relational/todo/IdInt.hs +++ /dev/null @@ -1,12 +0,0 @@ -i :: (Num a) => a -> a -i x = x - -j :: Int -> Int -j = i - -q :: Int -> Int -q x = j x - -{-@ relational q ~ q :: x1:Int -> _ ~ x2:Int -> _ - ~~ x1 < x2 => r1 x1 < r2 x2 @-} - diff --git a/tests/relational/todo/Incr.hs b/tests/relational/todo/Incr.hs deleted file mode 100644 index 4f5ab9d2d3..0000000000 --- a/tests/relational/todo/Incr.hs +++ /dev/null @@ -1,14 +0,0 @@ -module Fixme where - -{-@ plus :: a:Int -> b:Int -> {v:Int | v == a + b} @-} -plus :: Int -> Int -> Int -plus = (+) - -one :: Int -one = 1 - -incr :: Int -> Int -incr x = x `plus` one - -{-@ relational incr ~ incr :: x1:Int -> Int ~ x2:Int -> Int - ~~ x1 < x2 => r1 x1 > r2 x2 @-} diff --git a/tests/relational/todo/IncrF.hs b/tests/relational/todo/IncrF.hs deleted file mode 100644 index 39bd17ae83..0000000000 --- a/tests/relational/todo/IncrF.hs +++ /dev/null @@ -1,18 +0,0 @@ -module Fixme where - -{-@ add :: x:Int -> y:Int -> {v:Int|v = x + y} @-} -add :: Int -> Int -> Int -add = (+) - -{-@ incr :: x:Int -> {v:Int|v = x + 1} @-} -incr :: Int -> Int -incr x = let one = 1 in add x one - -incrf :: Int -> Int -incrf x = let tmp = \f -> add (f x) 1 in tmp incr - -{-@ type Pos = {v:Int|v > 0} @-} - -{-@ relational incrf ~ incrf - :: x1:Nat -> Pos ~ x2:Nat -> Pos - ~~ x1 == x2 => r1 x1 == r2 x2 @-} \ No newline at end of file diff --git a/tests/relational/todo/Incr_.hs b/tests/relational/todo/Incr_.hs deleted file mode 100644 index 8ec400f318..0000000000 --- a/tests/relational/todo/Incr_.hs +++ /dev/null @@ -1,14 +0,0 @@ -module Fixme where - -{-@ plus :: a:Int -> b:Int -> {v:Int | v == a + b} @-} -plus :: Int -> Int -> Int -plus = (+) - -one :: Int -one = 1 - -incr :: Int -> Int -incr x = x `plus` one - -{-@ relational incr ~ incr :: x1:Int -> Int ~ x2:Int -> Int -~~ x1 < x2 => r1 x1 < r2 x2 @-} diff --git a/tests/relational/todo/IsZero.hs b/tests/relational/todo/IsZero.hs deleted file mode 100644 index 0d7af25bb8..0000000000 --- a/tests/relational/todo/IsZero.hs +++ /dev/null @@ -1,15 +0,0 @@ -module Fixme where - -isZero :: Int -> Bool -isZero 0 = True -isZero _ = False - -{-@ reflect leq @-} -leq :: Bool -> Bool -> Bool -leq True False = False -leq _ _ = True - -{-@ relational isZero ~ isZero :: x1:Nat -> Bool ~ x2:Nat -> Bool - ~~ x1 <= x2 => Fixme.leq (r2 x2) (r1 x1) @-} --- ~~ x1 < x2 => Fixme.leq (r2 x2) (r1 x1) @-} -- works --- ~~ x1 == x2 => Fixme.leq (r2 x2) (r1 x1) @-} -- doesn't \ No newline at end of file diff --git a/tests/relational/todo/Isort.hs b/tests/relational/todo/Isort.hs deleted file mode 100644 index 37b0e92c8d..0000000000 --- a/tests/relational/todo/Isort.hs +++ /dev/null @@ -1,165 +0,0 @@ -module Isort where - -import Prelude hiding ( Applicative(..) - , Monad(..) - , fmap - , length - ) -{-@ infix >>= @-} -{-@ infix >=> @-} -{-@ infix : @-} - --- {-@ reflect insert @-} --- {-@ insert :: y:Int -> xs:[Int] -> {v:Tick [Int]| leq y xs => Isort.tcost v <= 1} @-} -insert :: Int -> [Int] -> Tick [Int] -insert y [] = pure [y] -insert y xs@(x : _) | y <= x = step 1 $ pure (y : xs) -insert y (x : xs) = step 1 $ fmap (cons x) (insert y xs) - --- {-@ reflect isort @-} -isort :: [Int] -> Tick [Int] -isort [] = pure [] -isort (x : xs) = step t $ insert x xs' - where Tick t xs' = isort xs - --- Unary - --- {-@ isortThm :: {xs:[Int]|sorted xs} -> {ys:[Int]|len ys = len xs} -> --- {tcost (isort xs) <= tcost (isort ys)} @-} --- isortThm :: [Int] -> [Int] -> () --- isortThm [] [] = () --- isortThm (x:xs) (y:ys) = undefined - --- Relational - -{-@ relational isort ~ isort :: xs1:[Int] -> Tick [Int] - ~ xs2:[Int] -> Tick [Int] - ~~ Isort.sorted xs1 && len xs1 = len xs2 => - Isort.tcost (r1 xs1) <= Isort.tcost (r2 xs2) @-} - --- Axiomatization - -{-@ reflect leq @-} -leq :: Int -> [Int] -> Bool -leq _ [] = True -leq y (x : xs) = y <= x && leq y xs - -{-@ reflect sorted @-} -sorted :: [Int] -> Bool -sorted [] = True -sorted (x : xs) = sorted xs && leq x xs - --- Data.Lists - -{-@ measure length @-} -{-@ length :: [a] -> Nat @-} -length :: [a] -> Int -length [] = 0 -length (x : xs) = 1 + length xs - -{-@ reflect cons @-} -{-@ cons :: x:a -> xs:[a] -> {z:[a] | z == x:xs && length z == length xs + 1} @-} -cons :: a -> [a] -> [a] -cons x xs = x : xs - --- Data.RTrick - -data Tick a = Tick { tcost :: Int, tval :: a } -{-@ data Tick a = Tick { tcost :: Int, tval :: a } @-} - -{-@ reflect pure @-} -pure :: a -> Tick a -pure x = Tick 0 x - -{-@ reflect fmap @-} -fmap :: (a -> b) -> Tick a -> Tick b -fmap f (Tick i x) = Tick i (f x) - -{-@ reflect liftA2 @-} -liftA2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c -liftA2 f (Tick i x) (Tick j y) = Tick (i + j) (f x y) - -{-@ reflect >=> @-} -(>=>) :: (a -> Tick b) -> (b -> Tick c) -> a -> Tick c -(>=>) f g x = let Tick i y = f x in let Tick j z = g y in Tick (i + j) z - -{-@ reflect >>= @-} -{-@ (>>=) :: mx:Tick a -> m:(a -> Tick b) -> {t:Tick b | tcost t == tcost mx + tcost (m (tval mx)) } @-} -(>>=) :: Tick a -> (a -> Tick b) -> Tick b -Tick i x >>= m = let Tick j w = m x in Tick (i + j) w - -{-@ reflect bbind @-} -{-@ bbind :: n:Int -> mx:Tick a -> m:(a -> {t:Tick b | tcost t <= n }) - -> {t:Tick b | tcost t <= tcost mx + n } @-} -bbind :: Int -> Tick a -> (a -> Tick b) -> Tick b -bbind _ (Tick i x) m = let Tick j w = m x in Tick (i + j) w - -{-@ reflect ebind @-} -{-@ ebind :: n:Int -> mx:Tick a -> m:(a -> {t:Tick b | tcost t == n }) - -> {t:Tick b | tcost t == tcost mx + n } @-} -ebind :: Int -> Tick a -> (a -> Tick b) -> Tick b -ebind _ (Tick i x) m = let Tick j w = m x in Tick (i + j) w - -{-@ reflect step @-} -step :: Int -> Tick a -> Tick a -step i (Tick j x) = Tick (i + j) x - --- Proof.Combinators - -type Proof = () -data QED = QED - -{-@ assert :: b:{Bool | b } -> {b} @-} -assert :: Bool -> () -assert _ = () - -{-@ (==.) :: x:a -> { y:a | x == y } -> { v:a | x == v && y == v } @-} -infixl 3 ==. -(==.) :: a -> a -> a -_ ==. x = x -{-# INLINE (==.) #-} - -{-@ (***) :: a -> QED -> Proof @-} -infixl 1 *** -(***) :: a -> QED -> Proof -_ *** _ = () -{-# INLINE (***) #-} - -{-@ (?) :: x:a -> Proof -> { v:a | x == v } @-} -infixl 3 ? -(?) :: a -> Proof -> a -x ? _ = x -{-# INLINE (?) #-} - --- Proof.Quantified - -infixl 3 <=> -{-@ (<=>) :: t1:Tick a - -> t2:{Tick a | tval t1 == tval t2 && tcost t2 == tcost t1} - -> {t:Tick a | t == t2 && tval t1 == tval t && tval t2 == tval t && tcost t == tcost t2 && tcost t2 == tcost t } @-} -(<=>) :: Tick a -> Tick a -> Tick a -(<=>) _ x = x - -infixl 3 >== -{-@ (>==) :: t1:Tick a -> i:Int - -> t2:{Tick a | tval t1 == tval t2 && tcost t1 == i + tcost t2} - -> {t:Tick a | t == t2 && tval t1 == tval t && tval t2 == tval t && - tcost t1 == i + tcost t && tcost t == tcost t2 } @-} -(>==) :: Tick a -> Int -> Tick a -> Tick a -(>==) _ _ x = x - -infixl 3 ==> -(==>) :: (a -> b) -> a -> b -f ==> x = f x - -infixl 3 <== -{-@ (<==) :: t1:Tick a -> i:Int - -> t2:{Tick a | tval t1 == tval t2 && i + tcost t1 == tcost t2} - -> {t:Tick a | t == t2 && tval t1 == tval t && tval t2 == tval t && - i + tcost t1 == tcost t && tcost t == tcost t2 } @-} -(<==) :: Tick a -> Int -> Tick a -> Tick a -(<==) _ _ x = x - -infixl 3 ==< -(==<) :: (a -> b) -> a -> b -f ==< x = f x diff --git a/tests/relational/todo/ListSum.hs b/tests/relational/todo/ListSum.hs deleted file mode 100644 index 216f8343af..0000000000 --- a/tests/relational/todo/ListSum.hs +++ /dev/null @@ -1,29 +0,0 @@ -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--ple" @-} - -module Twice where -import Prelude hiding ( sum - , length - ) - - -thm :: [Int] -> [Int] -> () -{-@ thm :: xs:[Int] -> ys:{[Int] | prop xs ys && length ys == length xs } -> {sum xs == 2 * sum ys } @-} -thm [] [] = () -thm (x : xs) (y : ys) = thm xs ys - -{-@ measure sum @-} -sum :: [Int] -> Int -sum [] = 0 -sum (x : xs) = x + sum xs - -{-@ measure length @-} -length :: [a] -> Int -length [] = 0 -length (x : xs) = 1 + length xs - -{-@ reflect prop @-} -prop :: [Int] -> [Int] -> Bool -prop [] [] = True -prop (x : xs) (y : ys) = x == 2 * y && prop xs ys -prop _ _ = False diff --git a/tests/relational/todo/Map.hs b/tests/relational/todo/Map.hs deleted file mode 100644 index 184760904c..0000000000 --- a/tests/relational/todo/Map.hs +++ /dev/null @@ -1,17 +0,0 @@ -module Fixme where - -import Prelude hiding (map) - -{-@ reflect diff @-} -{-@ diff :: xs:[Int] -> ys:{[Int]|len ys == len xs} -> Int @-} -diff :: [Int] -> [Int] -> Int -diff (x : xs) (y : ys) | x == y = diff xs ys -diff (x : xs) (y : ys) | x /= y = 1 + diff xs ys -diff _ _ = 0 - -map :: (Int -> Int) -> [Int] -> [Int] -map _ [] = [] -map f (x:xs) = f x : map f xs - -{-@ relational map ~ map :: f1:(x1:_ -> _) -> xs1:_ -> _ ~ f2:(x2:_ -> _) -> xs2:_ -> _ - ~~ true => len xs1 = len xs2 && f1 = f2 => Fixme.diff xs1 xs2 >= Fixme.diff (r1 f1 xs1) (r2 f2 xs2) @-} diff --git a/tests/relational/todo/MapFusion.hs b/tests/relational/todo/MapFusion.hs deleted file mode 100644 index f6e8568275..0000000000 --- a/tests/relational/todo/MapFusion.hs +++ /dev/null @@ -1,153 +0,0 @@ -module MapFusion where - -import Prelude hiding ( mapM - , Applicative(..) - , Monad(..) - , length - ) - -{-@ infix >>= @-} -{-@ infix >=> @-} -{-@ infix : @-} - -{-@ reflect mapM @-} -{-@ mapM :: (Int -> Tick Int) -> xs:[Int] -> Tick {os:[Int] | length os == length xs} @-} -mapM :: (Int -> Tick Int) -> [Int] -> Tick [Int] -mapM f [] = pure [] -mapM f (x : xs) = step 1 (liftA2 cons (f x) (mapM f xs)) - -seqMap :: (Int -> Tick Int) -> (Int -> Tick Int) -> [Int] -> Tick [Int] -seqMap _ _ [] = pure [] -seqMap f g (x : xs) = step 2 $ liftA2 cons (g fx) (seqMap f g xs) - where Tick _ fx = f x - -compMap :: (Int -> Tick Int) -> (Int -> Tick Int) -> [Int] -> Tick [Int] -compMap _ _ [] = pure [] -compMap f g (x : xs) = step 1 $ liftA2 cons (g fx) (compMap f g xs) - where Tick _ fx = f x - -{-@ relational seqMap ~ compMap :: f1:(Int -> Tick Int) -> g1:(Int -> Tick Int) -> xs1:[Int] -> {v:Tick [Int]|v = mapM f1 xs1 >>= mapM g1} - ~ f2:(Int -> Tick Int) -> g2:(Int -> Tick Int) -> xs2:[Int] -> {v:Tick [Int]|v = mapM (f2 >=> g2) xs2} - ~~ f1 = f2 => g1 = g2 => xs1 = xs2 => - MapFusion.tcost (r1 f1 g1 xs1) = len xs1 + MapFusion.tcost (r2 f2 g2 xs2) && - MapFusion.tval (r1 f1 g1 xs1) = MapFusion.tval (r2 f2 g2 xs2) @-} - -mapFusion :: (Int -> Tick Int) -> (Int -> Tick Int) -> [Int] -> () -{-@ mapFusion :: f:(Int -> Tick Int) -> g:(Int -> Tick Int) -> xs:[Int] - -> { (tval (mapM f xs >>= mapM g) == tval (mapM (f >=> g) xs)) && - (tcost (mapM f xs >>= mapM g) == length xs + tcost (mapM (f >=> g) xs)) - } - @-} -mapFusion f g [] = () -mapFusion f g (_ : xs) = mapFusion f g xs - --- Data.Lists - -{-@ measure length @-} -{-@ length :: [a] -> Nat @-} -length :: [a] -> Int -length [] = 0 -length (x : xs) = 1 + length xs - -{-@ reflect cons @-} -{-@ cons :: x:a -> xs:[a] -> {z:[a] | z == x:xs && length z == length xs + 1} @-} -cons :: a -> [a] -> [a] -cons x xs = x : xs - --- Data.RTrick - -data Tick a = Tick { tcost :: Int, tval :: a } -{-@ data Tick a = Tick { tcost :: Int, tval :: a } @-} - -{-@ reflect pure @-} -pure :: a -> Tick a -pure x = Tick 0 x - -{-@ reflect liftA2 @-} -liftA2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c -liftA2 f (Tick i x) (Tick j y) = Tick (i + j) (f x y) - -{-@ reflect >=> @-} -(>=>) :: (a -> Tick b) -> (b -> Tick c) -> a -> Tick c -(>=>) f g x = let Tick i y = f x in let Tick j z = g y in Tick (i + j) z - -{-@ reflect >>= @-} -{-@ (>>=) :: mx:Tick a -> m:(a -> Tick b) -> {t:Tick b | tcost t == tcost mx + tcost (m (tval mx)) } @-} -(>>=) :: Tick a -> (a -> Tick b) -> Tick b -Tick i x >>= m = let Tick j w = m x in Tick (i + j) w - -{-@ reflect bbind @-} -{-@ bbind :: n:Int -> mx:Tick a -> m:(a -> {t:Tick b | tcost t <= n }) - -> {t:Tick b | tcost t <= tcost mx + n } @-} -bbind :: Int -> Tick a -> (a -> Tick b) -> Tick b -bbind _ (Tick i x) m = let Tick j w = m x in Tick (i + j) w - -{-@ reflect ebind @-} -{-@ ebind :: n:Int -> mx:Tick a -> m:(a -> {t:Tick b | tcost t == n }) - -> {t:Tick b | tcost t == tcost mx + n } @-} -ebind :: Int -> Tick a -> (a -> Tick b) -> Tick b -ebind _ (Tick i x) m = let Tick j w = m x in Tick (i + j) w - -{-@ reflect step @-} -step :: Int -> Tick a -> Tick a -step i (Tick j x) = Tick (i + j) x - --- Proof.Combinators - -type Proof = () -data QED = QED - -{-@ assert :: b:{Bool | b } -> {b} @-} -assert :: Bool -> () -assert _ = () - -{-@ (==.) :: x:a -> { y:a | x == y } -> { v:a | x == v && y == v } @-} -infixl 3 ==. -(==.) :: a -> a -> a -_ ==. x = x -{-# INLINE (==.) #-} - -{-@ (***) :: a -> QED -> Proof @-} -infixl 1 *** -(***) :: a -> QED -> Proof -_ *** _ = () -{-# INLINE (***) #-} - -{-@ (?) :: x:a -> Proof -> { v:a | x == v } @-} -infixl 3 ? -(?) :: a -> Proof -> a -x ? _ = x -{-# INLINE (?) #-} - --- Proof.Quantified - -infixl 3 <=> -{-@ (<=>) :: t1:Tick a - -> t2:{Tick a | tval t1 == tval t2 && tcost t2 == tcost t1} - -> {t:Tick a | t == t2 && tval t1 == tval t && tval t2 == tval t && tcost t == tcost t2 && tcost t2 == tcost t } @-} -(<=>) :: Tick a -> Tick a -> Tick a -(<=>) _ x = x - -infixl 3 >== -{-@ (>==) :: t1:Tick a -> i:Int - -> t2:{Tick a | tval t1 == tval t2 && tcost t1 == i + tcost t2} - -> {t:Tick a | t == t2 && tval t1 == tval t && tval t2 == tval t && - tcost t1 == i + tcost t && tcost t == tcost t2 } @-} -(>==) :: Tick a -> Int -> Tick a -> Tick a -(>==) _ _ x = x - -infixl 3 ==> -(==>) :: (a -> b) -> a -> b -f ==> x = f x - -infixl 3 <== -{-@ (<==) :: t1:Tick a -> i:Int - -> t2:{Tick a | tval t1 == tval t2 && i + tcost t1 == tcost t2} - -> {t:Tick a | t == t2 && tval t1 == tval t && tval t2 == tval t && - i + tcost t1 == tcost t && tcost t == tcost t2 } @-} -(<==) :: Tick a -> Int -> Tick a -> Tick a -(<==) _ _ x = x - -infixl 3 ==< -(==<) :: (a -> b) -> a -> b -f ==< x = f x diff --git a/tests/relational/todo/MapTest.hs b/tests/relational/todo/MapTest.hs deleted file mode 100644 index cd6a35e0d5..0000000000 --- a/tests/relational/todo/MapTest.hs +++ /dev/null @@ -1,48 +0,0 @@ -module MapTest where - -import Prelude hiding (map) - -data List a = Nil | Cons a (List a) deriving Eq - -{-@ reflect lenList @-} -{-@ lenList :: List a -> Int @-} -lenList :: List a -> Int -lenList Nil = 0 -lenList (Cons _ xs) = 1 + (lenList xs) - -{-@ reflect diff @-} -{-@ diff :: xs:List Int -> ys:{List Int|lenList ys == lenList xs} -> Int @-} -diff :: List Int -> List Int -> Int -diff (Cons x xs) (Cons y ys) - | x == y = diff xs ys -diff (Cons x xs) (Cons y ys) - | x /= y = 1 + diff xs ys -diff _ _ = 0 - --- map :: (Int -> Int) -> List Int -> List Int --- map _ Nil = Nil --- map f (Cons x xs) = Cons (f x) (map f xs) --- {-@ relational map ~ map :: --- f1:(x1:Int -> Int) -> xs1:List Int -> List Int ~ --- f2:(x2:Int -> Int) -> xs2:List Int -> List Int --- ~~ xs1 = xs2 => true => true @-} - -{-@ reflect diff' @-} -{-@ diff' :: xs:List Int -> ys:{List Int|lenList ys == lenList xs} -> Bool @-} -diff' :: List Int -> List Int -> Bool -diff' (Cons x xs) (Cons y ys) - | x == y = True && diff' xs ys -diff' (Cons x xs) (Cons y ys) - | x /= y = False && diff' xs ys -diff' _ _ = True - -map :: (Int -> Int) -> List Int -> List Int -map _ Nil = Nil -map f (Cons x xs) = Cons (f x) (map f xs) -{-@ relational map ~ map :: - f1:(x1:Int -> Int) -> xs1:List Int -> List Int ~ - f2:(x2:Int -> Int) -> xs2:List Int -> List Int - ~~ f1 = f2 => MapTest.lenList xs1 = MapTest.lenList xs2 => MapTest.diff' xs1 xs2 @-} --- {-@ relational map ~ map :: f1:(x1:_ -> _) -> xs1:_ -> _ ~ f2:(x2:_ -> _) -> xs2:_ -> _ --- ~~ f1 == f2 => true => Fixme.diff xs1 xs2 >= Fixme.diff (r1 f1 xs1) (r2 f2 xs2) @-} - diff --git a/tests/relational/todo/Max.hs b/tests/relational/todo/Max.hs deleted file mode 100644 index dd43710275..0000000000 --- a/tests/relational/todo/Max.hs +++ /dev/null @@ -1,10 +0,0 @@ -module Fixme where - -max :: Int -> Int -> Int -max a b = if a < b then b else a - -{-@ relational max ~ max :: a1:_ -> b1: _ -> _ ~ a2:_ -> b2: _ -> _ - ~~ true => a1 < b1 && a2 < b2 && b1 < b2 => r1 a1 b1 < r2 a2 b2 @-} - - - diff --git a/tests/relational/todo/Merge.hs b/tests/relational/todo/Merge.hs deleted file mode 100644 index 5da6c8ee99..0000000000 --- a/tests/relational/todo/Merge.hs +++ /dev/null @@ -1,9 +0,0 @@ -module Fixme where - -{-@ merge :: xs:[Int] -> ys:[Int] -> {v:[Int]|len v == len xs + len ys} @-} -merge :: [Int] -> [Int] -> [Int] -merge [] ys = ys -merge xs [] = xs -merge (x : xs) ys@(y : _) | x <= y = x : merge xs ys -merge xs (y : ys) = y : merge xs ys - diff --git a/tests/relational/todo/Msort.hs b/tests/relational/todo/Msort.hs deleted file mode 100644 index fbc5a3b276..0000000000 --- a/tests/relational/todo/Msort.hs +++ /dev/null @@ -1,45 +0,0 @@ -module Fixme where - -{-@ data Tick a = T { res :: a, time :: Int} @-} -data Tick a = T { res :: a, time :: Int} - -{-@ data Split = S { l :: [Int], r :: [Int] } @-} -data Split = S { l :: [Int], r :: [Int] } - -{-@ assume bsplit :: xs:[Int] -> {v:Tick Split|len xs / 2 <= len (l (res v)) && len (l (res v)) <= len xs / 2 + 1 - && len (r (res v)) = len xs / 2} @-} -{-@ ignore bsplit @-} -bsplit :: [Int] -> Tick Split -bsplit = undefined - -{-@ ignore merge @-} -merge :: [Int] -> [Int] -> Tick [Int] -merge = undefined - -{-@ relational msort ~ msort :: xs1:_ -> _ ~ xs2:_ -> _ ~~ diff xs1 xs2 @-} -msort :: [Int] -> Tick [Int] -msort [] = T [] 0 -msort [x] = T [x] 1 -msort xs@(_:_:_) = T xs' (tsplit + tmerge) - where - T (S ls rs) tsplit = bsplit xs - T xs' tmerge = merge (msort ls) (msort rs)) 0 - -{- -fix msort(z). lam f. Lam. Lam. lam l. caseL l of - nil => nil - | h::tl => caseL tl of - nil => h::nil - | h'::tl' => let r = bsplit () [] [] l in - unpack r as y in - clet y as x in - let r1 = (msort () f [] [] (fst x)) in - let r2 = (msort () f [] [] (snd x)) in - merge () f [] [] r1 r2 - -<= 0 : -B (unitR => (B (U ((int X int) [max,0]-> bool, (int X int) [min,0]-> bool))) => -forall i; alpha. -(list [i, alpha] U int) [diff, sum(minpowlin (alpha, i), {0, cl(log (i))})] -> U (list [i] int) -) --} \ No newline at end of file diff --git a/tests/relational/todo/MultiRel.hs b/tests/relational/todo/MultiRel.hs deleted file mode 100644 index ea3b12af25..0000000000 --- a/tests/relational/todo/MultiRel.hs +++ /dev/null @@ -1,12 +0,0 @@ -module MultiRel where - -foo :: Int -> Int -foo x = x - -{-@ relational foo ~ foo :: x:Int -> Int ~ y:Int -> Int ~~ x < y => r1 x < r2 y @-} -{-@ relational foo ~ foo :: x:Int -> Int ~ y:Int -> Int ~~ x = y => r1 x = r2 y @-} - -bar :: Int -> Int -bar x = foo x - -{-@ relational bar ~ bar :: x:Int -> Int ~ y:Int -> Int ~~ true => (x <= y <=> r1 x <= r2 y) @-} \ No newline at end of file diff --git a/tests/relational/todo/MultiRelNeg.hs b/tests/relational/todo/MultiRelNeg.hs deleted file mode 100644 index 3cccc12bfb..0000000000 --- a/tests/relational/todo/MultiRelNeg.hs +++ /dev/null @@ -1,2 +0,0 @@ -module MultiRel where - diff --git a/tests/relational/todo/MultiRel_.hs b/tests/relational/todo/MultiRel_.hs deleted file mode 100644 index 132d47da04..0000000000 --- a/tests/relational/todo/MultiRel_.hs +++ /dev/null @@ -1,13 +0,0 @@ -module MultiRel where - -foo :: Int -> Int -foo x = x - -{-@ relational foo ~ foo :: x:Int -> Int ~ y:Int -> Int ~~ x < y => r1 x < r2 y @-} -{-@ relational foo ~ foo :: x:Int -> Int ~ y:Int -> Int ~~ x > y => r1 x > r2 y @-} -{-@ relational foo ~ foo :: x:Int -> Int ~ y:Int -> Int ~~ x = y => r1 x = r2 y @-} - -bar :: Int -> Int -bar x = foo x - -{-@ relational bar ~ bar :: x:Int -> Int ~ y:Int -> Int ~~ true => (x <= y <=> r1 x <= r2 y) @-} \ No newline at end of file diff --git a/tests/relational/todo/MutRecNeg.hs b/tests/relational/todo/MutRecNeg.hs deleted file mode 100644 index 0f8b292b14..0000000000 --- a/tests/relational/todo/MutRecNeg.hs +++ /dev/null @@ -1,10 +0,0 @@ -module MutRec where - -{-@ relational foo ~ foo :: n1:_ -> _ ~ n2:_ -> _ ~~ true => bar @-} -foo :: Bool -foo = True - - -{-@ relational bar ~ bar :: n1:_ -> _ ~ n2:_ -> _ ~~ true => r1 n1 = 0 && r2 n2 = 0 @-} -bar :: Bool -bar = True \ No newline at end of file diff --git a/tests/relational/todo/MutualRec.hs b/tests/relational/todo/MutualRec.hs deleted file mode 100644 index a8025e5767..0000000000 --- a/tests/relational/todo/MutualRec.hs +++ /dev/null @@ -1,9 +0,0 @@ -module This where - -{-@ f, g :: x:Nat -> Nat @-} -f, g :: Int -> Int -f x = if x <= 0 then 0 else 1 + g (x - 1) -g x = if x <= 0 then 0 else 1 + f (x - 1) - -{-@ relational f ~ g :: x:_ -> _ ~ y:_ -> _ - ~~ x == y => r1 x == r2 y @-} \ No newline at end of file diff --git a/tests/relational/todo/NullSize.hs b/tests/relational/todo/NullSize.hs deleted file mode 100644 index 819bd1c095..0000000000 --- a/tests/relational/todo/NullSize.hs +++ /dev/null @@ -1,25 +0,0 @@ -module Fixme where - -import Prelude hiding ( null ) - -data List a = Nil | Cons a (List a) - -{-@ measure size @-} -{-@ size :: l:List Int -> {v:Nat | ((v == 0) <=> (is$Fixme.Nil l))} @-} -size :: List Int -> Int -size Nil = 0 -size (Cons _ xs) = 1 + size xs - -{-@ measure null @-} -null :: List Int -> Bool -null Nil = True -null _ = False - --- {-@ thm :: l1:List Int -> l2:List Int -> --- { v:() | Fixme.size l1 == Fixme.size l2 } -> {Fixme.null l1 <=> Fixme.null l2} @-} --- thm :: List Int -> List Int -> () -> () --- thm l1 l2 () = () - -{-@ relational null ~ null :: l1:List Int -> Bool - ~ l2:List Int -> Bool - ~~ (Fixme.size l1 == Fixme.size l2) => ((r1 l1) <=> (r2 l2)) @-} \ No newline at end of file diff --git a/tests/relational/todo/PredAbstr.hs b/tests/relational/todo/PredAbstr.hs deleted file mode 100644 index 183ce138a8..0000000000 --- a/tests/relational/todo/PredAbstr.hs +++ /dev/null @@ -1,4 +0,0 @@ -nil :: a -> b -> (a, b) -nil a b = (a, b) - -{-@ relational nil ~ nil :: a:_ -> b:_ -> _ ~ a':_ -> b':_ -> _ ~~ true @-} \ No newline at end of file diff --git a/tests/relational/todo/Rec.hs b/tests/relational/todo/Rec.hs deleted file mode 100644 index 7d7fb0fcb5..0000000000 --- a/tests/relational/todo/Rec.hs +++ /dev/null @@ -1,10 +0,0 @@ -module Fixme where - -f :: Int -> Int -f x = if x <= 0 then 0 else 1 + f (x - 1) - -f' :: Int -> Int -f' x = if x <= 0 then 0 else 1 + f' (x - 1) - -{-@ relational f ~ f' :: x1:_ -> _ ~ x2:_ -> _ - ~~ x1 == x2 => r1 x1 >= 0 && r2 x2 >= 0 @-} diff --git a/tests/relational/todo/RecAndNonRec.hs b/tests/relational/todo/RecAndNonRec.hs deleted file mode 100644 index b4db752e2e..0000000000 --- a/tests/relational/todo/RecAndNonRec.hs +++ /dev/null @@ -1,11 +0,0 @@ -module Fixme where - -f :: Int -> Int -f x = if x <= 0 then 0 else 1 + f (x - 1) - -g :: Int -> Int -g x = if x <= 0 then 0 else x - -{-@ relational f ~ g :: x1:_ -> _ ~ x2:_ -> { v:Int | ((x2 <= 0) <=> (v == 0)) - && ((x2 > 0) <=> (v == x2)) } - ~~ x1 == x2 => r1 x1 == r2 x2 @-} diff --git a/tests/relational/todo/RecNonFunc.hs b/tests/relational/todo/RecNonFunc.hs deleted file mode 100644 index 62d418c99d..0000000000 --- a/tests/relational/todo/RecNonFunc.hs +++ /dev/null @@ -1,10 +0,0 @@ -{-@ LIQUID "--no-termination" @-} - -module Fixme where - -{-@ r :: Nat @-} -r :: Int -r = 1 + r - -{-@ relational r ~ r :: _ ~ _ - ~~ r1 == r2 @-} \ No newline at end of file diff --git a/tests/relational/todo/RecNonFunc_.hs b/tests/relational/todo/RecNonFunc_.hs deleted file mode 100644 index bbcdfd2f3f..0000000000 --- a/tests/relational/todo/RecNonFunc_.hs +++ /dev/null @@ -1,18 +0,0 @@ -{-@ LIQUID "--no-termination" @-} - -module RecNonFunc where - -{-@ reflect eq @-} -{-@ eq :: xs:[Int] -> {ys:[Int]|len xs = len ys} -> Bool @-} -eq :: [Int] -> [Int] -> Bool -eq [] [] = True -eq (x:xs) (y:ys) = if x == y then eq xs ys else False - -r :: [Int] -r = let cons = (:) in 0 `cons` r - -{-@ relational r ~ r :: [Int] ~ [Int] - ~~ RecNonFunc.eq r1 r2 @-} - -r' :: Bool -r' = if True then False else r' diff --git a/tests/relational/todo/Repeat.hs b/tests/relational/todo/Repeat.hs deleted file mode 100644 index b5b2b07538..0000000000 --- a/tests/relational/todo/Repeat.hs +++ /dev/null @@ -1,21 +0,0 @@ -module Fixme where - -import Prelude hiding ( sum ) - -data List a = Nil | Cons a (List a) - -{-@ type Repeat a X = List {v:a | v == X} @-} - -{-@ aps :: x:Int -> Repeat Int x -> Int @-} -aps :: Int -> List Int -> Int -aps _ Nil = 0 -aps a (Cons x xs) = x + aps a xs - -{-@ measure size @-} -{-@ size :: List a -> Nat @-} -size :: List a -> Int -size Nil = 0 -size (Cons _ xs) = 1 + size xs - -{-@ relational aps ~ aps :: x1:Int -> l1:Repeat Int x1 -> Int ~ x2:Int -> l2:Repeat Int x2 -> Int - ~~ x1 < x2 => true => len l1 == len l2 && r1 x1 l1 < r2 x2 l2 @-} diff --git a/tests/relational/todo/ReuseRel.hs b/tests/relational/todo/ReuseRel.hs deleted file mode 100644 index ef9aa0806b..0000000000 --- a/tests/relational/todo/ReuseRel.hs +++ /dev/null @@ -1,12 +0,0 @@ -l :: [Int] -> Int -l [] = 0 -l (_:xs) = 1 + l xs - -{-@ relational l ~ l :: xs:_ -> _ ~ ys:_ -> _ - ~~ len xs == len ys => (r1 xs) == (r2 ys) @-} - -foo :: [Int] -> Int -foo [] = l [] -foo (_:xs) = foo xs - -{-@ relational foo ~ foo :: xs:_ -> _ ~ ys:_ -> _ ~~ true => (r1 xs) == (r2 ys) @-} \ No newline at end of file diff --git a/tests/relational/todo/SGD.hs b/tests/relational/todo/SGD.hs deleted file mode 100644 index d35e70b05d..0000000000 --- a/tests/relational/todo/SGD.hs +++ /dev/null @@ -1,373 +0,0 @@ -module SGD where - -import Prelude hiding ( elem - , sum - ) -import Data.Functor.Identity - -{-@ type Prob = {v:Double|0 <= v && v <= 1} @-} -type Prob = Double --- {-@ type StepSize = {v:Double|0 <= v} @-} -type StepSize = Double -type DataPoint = (Double, Double) -type Weight = Double -type LossFunction = DataPoint -> [Weight] -> Double - -type Set a = [a] -type DataSet = Set DataPoint - -{- Cu(e,x.φ) ≜ ∃n,y. (e 􏰁 {cstepn(cret(y))}) ∧ φ[y/x] -} - -{- Cid :: {v:Distr a | φ (runIdentity v) } -} - --- {-@ relational Distr a ~ Distr b ~~ x1 = x2 => r1 @-} -type Distr a = Identity a -type DataDistr = Distr DataPoint - -{-@ reflect one @-} -{-@ one :: {v:Double|v = 1} @-} -one :: Double -one = 1 - -{-@ reflect diff @-} -{-@ diff :: xs:[a] -> ys:{[a]|lend ys == lend xs} -> {v:Double|0 <= v} @-} -diff :: Eq a => [a] -> [a] -> Double -diff (x : xs) (y : ys) | x == y = diff xs ys -diff (x : xs) (y : ys) | x /= y = 1 + diff xs ys -diff _ _ = 0 - -{-@ measure dist :: a -> a -> Double @-} -dist :: a -> a -> Double -dist _ _ = 0 - -{-@ measure SGD.unif :: zs:DataSet -> DataDistr @-} -{-@ reflect unif @-} -{-@ unif :: DataSet -> DataDistr @-} -unif :: DataSet -> DataDistr -unif zs = ppure (if null zs then (0, 0) else head zs) - - -data Foo = Foo -type Arg a = Foo -> a - -{-@ measure SGD.choice :: Prob -> Distr a -> Distr a -> Distr a @-} -{-@ choice :: (Prob) -> Distr a -> Distr a -> Distr a @-} -choice :: (Double) -> Distr a -> Distr a -> Distr a -choice p a b = a - -{-@ measure SGD.l :: Double @-} -{-@ measure SGD.l' :: Double @-} - -update :: DataPoint -> [Weight] -> StepSize -> LossFunction -> [Weight] -update z w α f = w - -{-@ sgd :: DataSet -> [Weight] -> [StepSize] -> LossFunction -> Distr [Weight] @-} -sgd :: DataSet -> [Weight] -> [StepSize] -> LossFunction -> Distr [Weight] -sgd zs w0 [] f = pure w0 -sgd zs w0 (α : a) f = do - z' <- unif zs - sgd zs (update z' w0 α f) a f -{- - === let z' = choice (1 / length zs) (unif [z]) (unif zs0) in - let w'= update z' w0 α f in - sgd zs w' a f - ? Unif (zs0 ++ [z]) = Choice |S|/|S++S'| Unif(S) Unif(S') - === choice (1 / length zs) - (let z' = unif [z] in sgd zs (update z' w0 α f) a f) - (let z' = unif zs0 in sgd zs (update z' w0 α f) a f) - ? let z = choice p mu mu' in e === choice p (let z = mu in e) (let z = mu' in e) --} - --- {-@ unif ~ unif :: zs1:DataSet -> DataDistr --- ~ zs2:DataSet -> DataDistr --- ~~ zs1 = zs2 && @-} - - -{-@ measure SGD.ppure :: a -> Distr a @-} - -ppure :: a -> Distr a -ppure = undefined - -{-@ assume relational ppure ~ ppure :: x1:a -> Distr a - ~ x2:a -> Distr a - ~~ true => dist (r1 x1) (r2 x2) <= dist x1 x2 @-} - -{- - x1 ~ x2 => s1 ~ s2 | Phi - --------------------------------------- unit - pure x1 ~ pure x2 => m s1 ~ m s2 | - --} - -pbind :: Distr a -> (a -> Distr b) -> Distr b -pbind = undefined - -qbind :: Distr a -> (a -> Distr b) -> Distr b -qbind = undefined - -{- - - --} - --- TODO: add ws1 ws2 -{-@ assume relational pbind ~ pbind :: μ1:Distr a -> f1:(y1:a -> Distr b) -> Distr b - ~ μ2:Distr a -> f2:(y2:a -> Distr b) -> Distr b - ~~ true => - true => - dist (r1 μ1 f1) (r2 μ2 f2) <= SGD.l @-} - -{- {()|true => true => (forall x1 x2. x1 /= x2 => dist (f1 x1) (f2 x2) <= SGD.l) => dist (r1 μ1 f1) (r2 μ2 f2) <= SGD.l} -} - -{- f :: (x1 = x2 => dist (f1 x1) (f2 x2) <= SGD.l) -} - -{- f ~ g | -} -{- pbind ~ pbind | p[μ1 := a][f1 := f][μ2 := b][f2 := g] -} -{- pbind a f ~ pbind b g | theorem -} - -{-@ assume relational qbind ~ qbind :: μ1:Distr a -> f1:(y1:a -> Distr b) -> Distr b - ~ μ2:Distr a -> f2:(y2:a -> Distr b) -> Distr b - ~~ μ1 = μ2 => true => dist (r1 μ1 f1) (r2 μ2 f2) <= SGD.l' @-} - -{- -forall μ1 μ2 f1 f2. μ1 = μ2 => (forall x1 x2. x1 = x2 => dist (f1 x1) (f2 x2) <= SGD.l') => dist (r1 μ1 f1) (r2 μ2 f2) <= SGD.l' -forall μ1 μ2 x1 x1 f1 f2. μ1 = μ2 => true => (x1 = x2 => dist (f1 x1) (f2 x2) <= SGD.l') => dist (r1 μ1 f1) (r2 μ2 f2) <= SGD.l' --} - --- {-@ unif zs0 >>= \z' -> sgd zs1 (update z' w1 α f) a f ~ unif zs0 >>= \z' -> sgd zs2 (update z' w2 α f) a f --- :: Distr [Weight] ~ Distr [Weight] ~~ @-} - - - -{- - a1 ~ a2 | g - g <: <> Phi r1 r2 - a1 ~ a2 | <> Phi r1 r2 -f1 ~ f2 | forall x1 x2. Phi x1 x2 => <> Psi (r1 x1) (r2 x2) -f1 ~ f2 | p => q -p => q <: forall x1 x2. Phi x1 x2 => <> Psi (r1 x1) (r2 x2) ----------------------------------------------------------------bind - bind a1 f1 ~ bind a2 f2 | <> Psi --} - -{- {<> Phi} forall a1 a2, <> Phi a1 a2 -> <> Psi (f1 a1) (f2 a2) -> <> Psi (bind a1 f1) (bind a2 f2) - - a1 ~ a2 => m s1 ~ m s2 | Phi (runId r1) (runId r2) - f1 ~ f2 => x1:s1 -> m t1 ~ x2:s2 -> m t2 | Phi x1 x2 => Psi - ----------------------------------------------------------------------------------------- bind - bind a1 f1 ~ bind a2 f2 => m t1 ~ m t2 | Psi --} --- ||w_i - w'_i|| + 2Lα_i = ||w_i-1 - w'_i-1|| + 2Lα_i + 2Lα_i_1 = ... --- ||w_i - w'_i|| = ||w_i-1 - w'_i-1|| + 2Lα_i-1 = ... -{-@ assume relational choice ~ choice - :: p:Prob -> e1:Distr a -> e1':Distr a -> Distr a - ~ q:Prob -> e2:Distr a -> e2':Distr a -> Distr a - ~~ p = q => true => - true => - dist (r1 p e1 e1') (r2 q e2 e2') <= p * dist e1 e2 + (1 - p) * dist e1' e2' @-} -- ||w_0 - w'_0|| + 2pLα * len a_i - -- p * (p * dist e1_(i-1) e2_(i-1) + (1 - p) * dist e1' e2') + (1 - p) * (p * dist e1 e2 + (1 - p) * dist e1' e2') - -{-@ relational sgd' ~ sgd' :: zs1:DataSet -> ws1:[Weight] -> α1:[StepSize] -> f1:LossFunction -> Distr [Weight] - ~ zs2:DataSet -> ws2:[Weight] -> α2:[StepSize] -> f2:LossFunction -> Distr [Weight] - ~~ 1 = SGD.lend zs1 && SGD.lend zs1 = SGD.lend zs2 => - true => - SGD.lend α1 = SGD.lend α2 => f1 = f2 => - dist (r1 zs1 ws1 α1 f1) (r2 zs2 ws2 α2 f2) - <= (SGD.one / SGD.lend zs1) * dist ws1 ws2 + (1 - (SGD.one / SGD.lend zs1)) * dist ws1 ws2 @-} - - -{- dist r1 r2 <= (one / lend zs1) * SGD.l + (1 - one / lend zs1) * SGD.l' -} -{-@ sgd' :: {v:DataSet|len v > 0} -> [Weight] -> [StepSize] -> LossFunction -> Distr [Weight] @-} -sgd' :: DataSet -> [Weight] -> [StepSize] -> LossFunction -> Distr [Weight] -sgd' _ w0 [] _ = ppure w0 -sgd' zs w0 (α : a) f = choice (one / lend zs) - (pbind uhead upd) - (qbind utail upd) - where - uhead = unif [head zs] - utail = unif (tail zs) - upd z' = sgd' zs (update z' w0 α f) a f - -{-@ assume (/) :: x:_ -> y:_ -> {v:_|v = x / y} @-} - -{- -{-@ foo :: {v:[Prob]|SGD.lend v >= 1} -> DataSet -> DataSet -> Distr DataPoint @-} -foo :: [Double] -> DataSet -> DataSet -> Distr DataPoint -foo zs x y = choice (one / lend zs) (unif x) (unif y) - -{-@ relational foo ~ foo :: z1:_ -> x1:_ -> y1:_ -> _ ~ z2:_ -> x2:_ -> y2:_ -> _ - ~~ SGD.lend z1 >= 1 && SGD.lend z1 = SGD.lend z2 => - dist (SGD.unif x1) (SGD.unif x2) <= SGD.l => dist (SGD.unif y1) (SGD.unif y2) <= SGD.l' => - dist (r1 x1 y1) (r2 x2 y2) <= (SGD.one / SGD.lend z1) * SGD.l + (1 - SGD.one / SGD.lend z1) * SGD.l' -@-} --} - -{- -z1 := head zs1 -z2 := head zs2 -zs0 := tail zs2 = tail zs2 - -choice (1 / length zs1) - (unif [z1] >>= \z' -> sgd zs1 (update z' w1 α f) a f) - (unif zs0 >>= \z' -> sgd zs1 (update z' w1 α f) a f) - ~ choice (1 / length zs2) - (unif [z2] >>= \z' -> sgd zs2 (update z' w2 α f) a f) - (unif zs0 >>= \z' -> sgd zs2 (update z' w2 α f) a f) - | dist (r1 zs1 w1 α f) (r2 zs2 w2 α f) <= dist w1 w2 + (1 / length zs1) * 2 * L * (sum α) - -I. choice ~ choice :: p1:Prob -> e1:Distr a -> e1':Distr a -> Distr a - ~ p2:Prob -> e2:Distr a -> e2':Distr a -> Distr a - | p1 = p2 => - dist e1 e2 <= k => - dist e1' e2' <= k' => - dist r1 r2 <= p * k + (1 - p) * k' -1 - p := 1 / length zs1 -k := dist w1 w2 + 2 * L * sum (α:a) -k' := dist w1 w2 - -II. z' = unif [z] - -z1' ~ z2' | true - -sgd zs1 (update z1' w1 α f) a f - ~ sgd zs2 (update z2' w2 α f) a f - | dist r1 r2 <= dist (update z1' w1 α f) (update z2' w2 α f) + (1 / length zs1) * 2 * L * sum a - -sgd zs1 (update z1' w1 α f) a f - ~ sgd zs2 (update z2' w2 α f) a f - | dist r1 r2 <= dist w1 w2 + 2 * L * α + (1 / length zs1) * 2 * L * sum a - -sgd zs1 (update z1' w1 α f) a f - ~ sgd zs2 (update z2' w2 α f) a f - | dist r1 r2 <= dist w1 w2 + 2 * L * sum (α:a) - -QED. - -III. z' = unif zs0 - -sgd zs1 (update z1' w1 α f) a f - ~ sgd zs2 (update z2' w2 α f) a f - | dist r1 r2 <= dist (update z1' w1 α f) (update z2' w2 α f) + (1 / length zs1) * 2 * L * sum a - -sgd zs1 (update z1' w1 α f) a f - ~ sgd zs2 (update z2' w2 α f) a f - | dist r1 r2 <= k - -QED. --} - -{-@ measure lend @-} -{-@ lend :: xs:[a] -> {v:Double|v >= 0 && (1 <= v <=> 1 <= len xs)} @-} -lend :: [a] -> Double -lend [] = 0 -lend (_ : xs) = 1 + lend xs - -{-@ reflect disjunion @-} -disjunion :: [DataPoint] -> [DataPoint] -> [DataPoint] -disjunion [] ys = ys -disjunion (x : xs) ys | elem x ys = disjunion xs ys -disjunion (x : xs) ys = x : disjunion xs ys - --- {-@ inline axiom @-} --- axiom :: [DataPoint] -> [DataPoint] -> Bool --- axiom zs zs' = unif (disjunion zs zs') == choice (lend zs / lend (disjunion zs zs')) (unif zs) (unif zs') - --- axiom' zs1 zs2 = unif zs1 == choice (lend (intersect zs1 zs2) / lend zs1) (intersect zs1 zs2) (minus zs1 zs2) --- axiom'' = let z = choice p mu mu' in e ~> choice p (let z = mu in e) (let z = mu' in e) - -{-@ reflect elem @-} -elem :: DataPoint -> DataSet -> Bool -elem _ [] = False -elem y (x : xs) = y == x || elem y xs - -{-@ reflect intersect @-} -{-@ intersect :: zs1:DataSet -> zs2:DataSet -> {v:DataSet|lend v <= lend zs1} @-} -intersect :: DataSet -> DataSet -> DataSet -intersect [] _ = [] -intersect (x : xs) ys | elem x ys = x : intersect xs ys -intersect (_ : xs) ys = intersect xs ys - -{-@ reflect minus @-} -minus :: DataSet -> DataSet -> DataSet -minus [] ys = [] -minus (x : xs) ys | elem x ys = minus xs ys -minus (x : xs) ys = x : minus xs ys - -{-@ reflect sum @-} -sum :: [StepSize] -> StepSize -sum [] = 0 -sum (α : αs) = α + sum αs - -{-@ reflect div @-} -{-@ div :: Double -> {v:Double|v /= 0} -> Double @-} -div :: Double -> Double -> Double -div a b = a / b - -type Sgd - = DataSet -> Distr [Weight] -> [StepSize] -> LossFunction -> Distr [Weight] - --- {-@ pred :: {zs1:DataSet|lend zs1 /= 0} -> {zs2:DataSet|lend zs1 = lend zs2} -> Sgd -> Sgd -> Distr [Weight] -> Distr [Weight] -> --- [StepSize] -> [StepSize] -> LossFunction -> LossFunction -> Bool @-} --- pred :: DataSet -> DataSet -> Sgd -> Sgd -> Distr [Weight] -> Distr [Weight] -> [StepSize] -> [StepSize] -> LossFunction -> LossFunction -> Bool --- pred zs1 zs2 r1 r2 ws1 ws2 α1 α2 f1 f2 = --- SGD.unif zs1 == SGD.choice (SGD.lend (SGD.intersect zs1 zs2) / SGD.lend zs1) --- (SGD.unif (SGD.intersect zs1 zs2)) (SGD.unif (SGD.minus zs1 zs2)) && --- SGD.unif zs2 == SGD.choice (SGD.lend (SGD.intersect zs2 zs1) / SGD.lend zs2) --- (SGD.unif (SGD.intersect zs2 zs1)) (SGD.unif (SGD.minus zs2 zs1)) && --- length zs1 == length zs2 && --- dist (r1 zs1 ws1 α1 f1) (r2 zs2 ws2 α2 f2) <= dist ws1 ws2 + 2.0 * SGD.diff zs1 zs2 - --- {-@ pred' :: {zs1:DataSet|lend zs1 /= 0} -> {zs2:DataSet|lend zs1 = lend zs2} -> Sgd -> Sgd -> Distr [Weight] -> Distr [Weight] -> --- [StepSize] -> [StepSize] -> LossFunction -> LossFunction -> Bool @-} --- pred' :: DataSet -> DataSet -> Sgd -> Sgd -> Distr [Weight] -> Distr [Weight] -> [StepSize] -> [StepSize] -> LossFunction -> LossFunction -> Bool --- pred' zs1 zs2 r1 r2 ws1 ws2 α1 α2 f1 f2 = --- SGD.unif zs1 == SGD.choice (SGD.lend (SGD.intersect zs1 zs2) / SGD.lend zs1) --- (SGD.unif (SGD.intersect zs1 zs2)) (SGD.unif (SGD.minus zs1 zs2)) && --- SGD.unif zs2 == SGD.choice (SGD.lend (SGD.intersect zs2 zs1) / SGD.lend zs2) --- (SGD.unif (SGD.intersect zs2 zs1)) (SGD.unif (SGD.minus zs2 zs1)) && --- length zs1 == length zs2 && --- dist (r1 zs1 ws1 α1 f1) (r2 zs2 ws2 α2 f2) <= dist ws1 ws2 + 2.0 * SGD.diff zs1 zs2 - --- {-@ relational sgd ~ sgd :: zs1:DataSet -> ws1:Distr [Weight] -> α1:[StepSize] -> f1:LossFunction -> v:Distr [Weight] --- ~ zs2:DataSet -> ws2:Distr [Weight] -> α2:[StepSize] -> f2:LossFunction -> v:Distr [Weight] --- ~~ SGD.unif zs1 = SGD.choice (SGD.lend (SGD.intersect zs1 zs2) / SGD.lend zs1) --- (SGD.unif (SGD.intersect zs1 zs2)) (SGD.unif (SGD.minus zs1 zs2)) && --- SGD.unif zs2 = SGD.choice (SGD.lend (SGD.intersect zs2 zs1) / SGD.lend zs2) --- (SGD.unif (SGD.intersect zs2 zs1)) (SGD.unif (SGD.minus zs2 zs1)) |- --- SGD.lend zs1 /= 0 && SGD.lend zs1 = SGD.lend zs2 => true => α1 = α2 => f1 = f2 => --- dist (r1 zs1 ws1 α1 f1) (r2 zs2 ws2 α2 f2) <= --- dist ws1 ws2 + 2.0 * (1 - (SGD.lend (SGD.intersect zs1 zs2) / SGD.lend zs1)) * SGD.sum α1 @-} - --- {-@ relational sgd' ~ sgd' :: zs1:DataSet -> ws1:[Weight] -> α1:[StepSize] -> f1:LossFunction -> Distr [Weight] --- ~ zs2:DataSet -> ws2:[Weight] -> α2:[StepSize] -> f2:LossFunction -> Distr [Weight] --- ~~ SGD.intersect zs1 zs2 = tail zs1 && SGD.intersect zs1 zs2 = tail zs2 && --- SGD.minus zs1 zs2 = [head zs1] && SGD.minus zs2 zs1 = [head zs2] => --- dist ws1 ws2 <= (SGD.one / SGD.lend zs1) * SGD.l + --- (1 - SGD.one / SGD.lend zs1) * SGD.l' => --- α1 = α2 => f1 = f2 => --- dist (r1 zs1 ws1 α1 f1) (r2 zs2 ws2 α2 f2) --- <= (SGD.one / SGD.lend zs1) * SGD.l + --- (1 - SGD.one / SGD.lend zs1) * SGD.l' @-} - -{-@ relational sgd' ~ sgd' :: zs1:DataSet -> ws1:[Weight] -> α1:[StepSize] -> f1:LossFunction -> Distr [Weight] - ~ zs2:DataSet -> ws2:[Weight] -> α2:[StepSize] -> f2:LossFunction -> Distr [Weight] - ~~ 1 = SGD.lend zs1 && SGD.lend zs1 = SGD.lend zs2 => - dist ws1 ws2 <= SGD.l + SGD.l' => - true => true => - dist (r1 zs1 ws1 α1 f1) (r2 zs2 ws2 α2 f2) - <= (SGD.one / SGD.lend zs1) * SGD.l + (1 - SGD.one / SGD.lend zs1) * SGD.l' @-} - --- {-@ (>>=) w1 update ~ (>>=) w2 update | p @-} --- {-@ update ~ update | k @-} - --- {-@ update ~ update | k @-} - -{-@ assume relational update ~ update :: z1:DataPoint -> ws1:[Weight] -> α1:StepSize -> f1:LossFunction -> [Weight] - ~ z2:DataPoint -> ws2:[Weight] -> α2:StepSize -> f2:LossFunction -> [Weight] - ~~ z1 = z2 => true => α1 = α2 => f1 = f2 => - dist (r1 z1 ws1 α1 f1) (r2 z2 ws2 α2 f2) <= SGD.l' @-} - -{-@ assume relational update ~ update :: z1:DataPoint -> ws1:[Weight] -> α1:StepSize -> f1:LossFunction -> [Weight] - ~ z2:DataPoint -> ws2:[Weight] -> α2:StepSize -> f2:LossFunction -> [Weight] - ~~ true => true => α1 = α2 => f1 = f2 => - dist (r1 z1 ws1 α1 f1) (r2 z2 ws2 α2 f2) <= SGD.l @-} diff --git a/tests/relational/todo/SGDSimple.hs b/tests/relational/todo/SGDSimple.hs deleted file mode 100644 index 5cc272636e..0000000000 --- a/tests/relational/todo/SGDSimple.hs +++ /dev/null @@ -1,56 +0,0 @@ -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--ple" @-} -{-@ LIQUID "--no-termination" @-} - -module SGDSimple where - -{- reflect update @-} -{-@ relational update ~ update :: x1:_ -> _ ~ x2:_ -> _ ~~ x1 < x2 => r1 x1 < r2 x2 @-} -update :: Int -> Int -update x = x + 1 - -{- reflect update' @-} -{-@ relational update' ~ update' :: y1:_ -> x1:_ -> _ ~ y2:_ -> x2:_ -> _ ~~ true => x1 < x2 => r1 y1 x1 < r2 y2 x2 @-} -update' :: Int -> Int -> Int -update' _ x = x + 1 - --- TODO: add x1 x2 to the env --- TODO: support fo precs for functions -{-@ relational bind ~ bind :: x1:_ -> f1:(z1:_ -> _) -> _ - ~ x2:_ -> f2:(z2:_ -> _) -> _ - ~~ x1 < x2 => (z1 < z2 => r1 z1 < r2 z2) => - r1 x1 f1 < r2 x2 f2 @-} -bind :: Int -> (Int -> Int) -> Int -bind x f = f x - -{-@ relational sgd ~ sgd :: x1:_ -> _ ~ x2:_ -> _ - ~~ x1 < x2 => r1 x1 < r2 x2 @-} -sgd :: Int -> Int -sgd x = bind x update - --- TODO: support eta expansion -{-@ relational sgd' ~ sgd' :: x1:_ -> _ ~ x2:_ -> _ - ~~ x1 < x2 => r1 x1 < r2 x2 @-} -sgd' :: Int -> Int -sgd' x = bind x (\z -> update z) - - --- {-@ update' 0 ~ update' 0 :: true => x1 < x2 => r1 y1 x1 < r2 y2 x2 @-} - --- {-@ u' ~ u' :: x1 < x2 => r1 y1 x1 < r2 y2 x2 @-} - --- {-@ u' ~ u' :: x1 < x2 => (0 < 0 => r1 y1 x1 < r2 y2 x2) @-} - --- TODO: support multiple arguments -{-@ relational sgd'' ~ sgd'' :: x1:_ -> _ ~ x2:_ -> _ - ~~ x1 < x2 => r1 x1 < r2 x2 @-} -sgd'' :: Int -> Int -sgd'' x = bind x (update' 0) - - -- let b1 = bind x - -- u = update' 0 - -- in b1 u - -- = let u' = update' 0 - -- in bind x u' - - diff --git a/tests/relational/todo/SGDc.hs b/tests/relational/todo/SGDc.hs deleted file mode 100644 index 59c39b7a41..0000000000 --- a/tests/relational/todo/SGDc.hs +++ /dev/null @@ -1,179 +0,0 @@ -module SGDu where - -import Prelude hiding ( head - , tail - ) -import Data.Functor.Identity - - -import Language.Haskell.Liquid.ProofCombinators - -{-@ type Prob = {v:Double|0 <= v && v <= 1} @-} -type Prob = Double - -type StepSize = Double -type DataPoint = (Double, Double) -type Weight = Double -type LossFunction = DataPoint -> Weight -> Double - -type Set a = [a] -{-@ type DataSet = {v:Set DataPoint|0 < len v && 0 < lend v } @-} -type DataSet = Set DataPoint -type Distr a = a -type DataDistr = Distr DataPoint - - -{-@ measure dist :: a -> a -> Double @-} -{-@ dist :: x1:a -> x2:a -> {v:Double | v == dist x1 x2 } @-} -dist :: a -> a -> Double -dist _ _ = undefined - - -{-@ relationalchoice - :: p:Prob -> e1:Distr a -> e1':Distr a - -> q:{Prob | p = q } -> e2:Distr a -> e2':Distr a - -> {p = q => true => - true => - (dist (choice p e1 e1') (choice q e2 e2') <= p * (dist e1 e2) + (1 - p) * (dist e1' e2'))} @-} -relationalchoice :: Prob -> Distr a -> Distr a -> Prob -> Distr a -> Distr a -> () -relationalchoice _ _ _ _ _ _ = undefined - - -{-@ measure SGDu.choice :: Prob -> Distr a -> Distr a -> Distr a @-} -{-@ assume choice :: x1:Prob -> x2:Distr a -> x3:Distr a -> {v:Distr a | v == choice x1 x2 x3 } @-} -choice :: Prob -> Distr a -> Distr a -> Distr a -choice _ x _ = x - -{-@ measure SGDu.unif :: zs:DataSet -> DataDistr @-} -{-@ assume unif :: x:DataSet -> {v:DataDistr | v == unif x } @-} -unif :: DataSet -> DataDistr -unif = undefined - -{- relationalupdatep :: z1:DataPoint -> ws1:[Weight] -> α1:StepSize -> f1:LossFunction -> - z2:DataPoint -> ws2:[Weight] -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2} @-} - -{- relationalupdateq :: z1:DataPoint -> ws1:[Weight] -> α1:StepSize -> f1:LossFunction -> - {z2:DataPoint|z1 = z2} -> ws2:[Weight] -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2} @-} - -{-@ measure SGDu.update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight @-} -update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight -update = undefined - -{-@ reflect one @-} -{-@ one :: {v:Double|v = 1} @-} -one :: Double -one = 1 - -{-@ measure lend @-} -{-@ lend :: xs:[a] -> {v:Double|v >= 0} @-} -lend :: [a] -> Double -lend [] = 0 -lend (_ : xs) = 1 + lend xs - -{-@ relationalpbind :: e1:Distr a -> f1:(a -> Distr b) -> e2:Distr a -> f2:(a -> Distr b) -> - { dist (pbind e1 f1) (pbind e2 f2) = dist e1 e2} @-} -relationalpbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalpbind _ _ _ _ = undefined - -{-@ relationalqbind :: e1:Distr a -> f1:(a -> Distr b) -> {e2:Distr a | e1 = e2} -> f2:(a -> Distr b) -> - { dist (qbind e1 f1) (qbind e2 f2) = dist e1 e2} @-} -relationalqbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalqbind _ _ _ _ = undefined - -{-@ measure SGDu.pbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ assume pbind :: x1:Distr a -> x2:(a -> Distr b) -> {v:Distr b | v = pbind x1 x2 } @-} -pbind :: Distr a -> (a -> Distr b) -> Distr b -pbind = undefined - -{-@ measure SGDu.qbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ assume qbind :: x1:Distr a -> x2:(a -> Distr b) -> {v:Distr b | v = qbind x1 x2 } @-} -qbind :: Distr a -> (a -> Distr b) -> Distr b -qbind = undefined - -{-@ measure SGDu.ppure :: a -> Distr a @-} -ppure :: a -> Distr a -ppure x = x - -{-@ reflect upd @-} -upd :: DataSet -> Weight -> StepSize -> [StepSize] -> LossFunction -> DataPoint -> Distr Weight -{-@ upd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> StepSize -> [StepSize] -> LossFunction -> DataPoint -> Distr Weight @-} -upd zs w0 α a f z' = sgd zs (update z' w0 α f) a f - -{-@ reflect head @-} -{-@ head :: {xs:[a] | len xs > 0 } -> a @-} -head :: [a] -> a -head (z : _) = z - -{-@ reflect tail @-} -{-@ tail :: {xs:[a] | len xs > 0 } -> {v:[a] | len v == len xs - 1 && lend v == lend xs - 1 } @-} -tail :: [a] -> [a] -tail (_ : zs) = zs - -{-@ reflect sgd @-} -{-@ sgd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> [StepSize] -> LossFunction -> Distr Weight @-} -sgd :: DataSet -> Weight -> [StepSize] -> LossFunction -> Distr Weight -sgd _ w0 [] _ = ppure w0 -sgd zs w0 (α : a) f = choice (one / lend zs) - (pbind uhead (upd zs w0 α a f)) - (qbind utail (upd zs w0 α a f)) - where - uhead = unif [head zs] - utail = unif (tail zs) - -{-@ thm :: zs1:{DataSet | 1 < lend zs1 && 1 < len zs1 } -> ws1:Weight -> α1:[StepSize] -> f1:LossFunction -> - zs2:{DataSet | 1 < lend zs2 && 1 < len zs2 && lend zs1 == lend zs2 } -> ws2:Weight -> {α2:[StepSize]|len α2 = len α1} -> f2:LossFunction -> - {SGDu.lend zs1 = SGDu.lend zs2 && (SGDu.lend zs1) > 1 => - f1 = f2 => (SGDu.lend α2 = SGDu.lend α1) => - dist (sgd zs1 ws1 α1 f1) (sgd zs2 ws2 α2 f2) <= - (SGDu.one / (SGDu.lend zs1)) * (dist ws1 ws2) + (1 - (SGDu.one / (SGDu.lend zs1))) * (dist ws1 ws2)} @-} -thm :: DataSet -> Weight -> [StepSize] -> LossFunction -> DataSet -> Weight -> [StepSize] -> LossFunction -> () -thm zs1 ws1 α1@[] f1 zs2 ws2 α2@[] f2 = - dist (sgd zs1 ws1 α1 f1) (sgd zs2 ws2 α2 f2) - === dist (ppure ws1) (ppure ws2) - === dist ws1 ws2 - =<= (SGDu.one / (SGDu.lend zs1)) - * (dist ws1 ws2) - + (1 - (SGDu.one / (SGDu.lend zs1))) - * (dist ws1 ws2) - *** QED -thm zs1 ws1 as1@(α1 : a1) f1 zs2 ws2 as2@(α2 : a2) f2 = - dist (sgd zs1 ws1 as1 f1) (sgd zs2 ws2 as2 f2) - === dist - (choice (one / lend zs1) - (pbind uhead1 (upd zs1 ws1 α1 a1 f1)) - (qbind utail1 (upd zs1 ws1 α1 a1 f1)) - ) - (choice (one / lend zs2) - (pbind uhead2 (upd zs2 ws2 α2 a2 f2)) - (qbind utail2 (upd zs2 ws2 α2 a2 f2)) - ) - ? relationalchoice (one / lend zs1) - (pbind uhead1 (upd zs1 ws1 α1 a1 f1)) - (qbind utail1 (upd zs1 ws1 α1 a1 f1)) - (one / lend zs2) - (pbind uhead2 (upd zs2 ws2 α2 a2 f2)) - (qbind utail2 (upd zs2 ws2 α2 a2 f2)) - =<= ( (one / lend zs1) - * (dist (pbind uhead1 (upd zs1 ws1 α1 a1 f1)) - (pbind uhead2 (upd zs2 ws2 α2 a2 f2)) - ) - + ( (1 - (one / lend zs1)) - * (dist (qbind utail1 (upd zs1 ws1 α1 a1 f1)) - (qbind utail2 (upd zs2 ws2 α2 a2 f2)) - ) - ) - ) - ? thm zs1 ws1 a1 f1 zs2 ws2 a2 f2 - ? relationalpbind uhead1 (upd zs1 ws1 α1 a1 f1) uhead2 (upd zs2 ws2 α2 a2 f2) - ? relationalqbind utail1 (upd zs1 ws1 α1 a1 f1) utail2 (upd zs2 ws2 α2 a2 f2) - *** QED - where - uhead1 = unif [head zs1] - utail1 = unif (tail zs1) - uhead2 = unif [head zs2] - utail2 = unif (tail zs2) - -thm zs1 ws1 _ f1 zs2 ws2 _ f2 = () - diff --git a/tests/relational/todo/SGDr.hs b/tests/relational/todo/SGDr.hs deleted file mode 100644 index 4a83d36477..0000000000 --- a/tests/relational/todo/SGDr.hs +++ /dev/null @@ -1,138 +0,0 @@ -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--ple" @-} -{-@ LIQUID "--no-termination" @-} - - -module SGDr where - -import Prelude hiding ( head - , tail - ) -import Data.Functor.Identity -import Language.Haskell.Liquid.ProofCombinators - -{-@ infix : @-} -{-@ type Prob = {v:Double| 0 <= v && v <= 1} @-} -type Prob = Double - -{-@ type StepSize = {v:Double | 0.0 <= v } @-} -type StepSize = Double -{-@ data StepSizes = SSEmp | SS StepSize StepSizes @-} -data StepSizes = SSEmp | SS StepSize StepSizes -type DataPoint = (Double, Double) -type Weight = Double -type LossFunction = DataPoint -> Weight -> Double - -type Set a = [a] -{-@ type DataSet = {v:Set DataPoint| 1 < len v && 1.0 < lend v } @-} -type DataSet = Set DataPoint -type Distr a = a -type DataDistr = Distr DataPoint - -{-@ measure dist :: a -> a -> Double @-} -{-@ assume dist :: x1:_ -> x2:_ -> {v:Double | v == dist x1 x2 } @-} -dist :: a -> a -> Double -dist _ _ = 0 - -{-@ assume relational choice ~ choice - :: p:_ -> e1:_ -> e1':_ -> _ - ~ q:_ -> e2:_ -> e2':_ -> _ - ~~ p = q !=> true !=> true !=> - dist (r1 p e1 e1') (r2 q e2 e2') <= p * (dist e1 e2) + (1 - p) * (dist e1' e2') @-} - -{-@ choice :: Prob -> Distr a -> Distr a -> Distr a @-} -choice :: Prob -> Distr a -> Distr a -> Distr a -choice _ x _ = x - -unif :: DataSet -> DataDistr -unif = undefined - -{-@ assume relational update ~ update - :: z1:_ -> ws1:_ -> α1:_ -> f1:_ -> _ - ~ z2:_ -> ws2:_ -> α2:_ -> f2:_ -> _ - ~~ true !=> true !=> α1 = α2 !=> (true => r1 = r2) !=> - dist (r1 z1 ws1 α1 f1) (r2 z2 ws2 α2 f2) = dist ws1 ws2 @-} - -{-@ assume relational update ~ update - :: z1:_ -> ws1:_ -> α1:_ -> f1:_ -> _ - ~ z2:_ -> ws2:_ -> α2:_ -> f2:_ -> _ - ~~ z1 = z2 !=> true !=> α1 = α2 !=> (true => r1 = r2) !=> - dist (r1 z1 ws1 α1 f1) (r2 z2 ws2 α2 f2) = dist ws1 ws2 @-} - -update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight -update = undefined - -{-@ reflect one @-} -{-@ one :: {v:Double|v = 1} @-} -one :: Double -one = 1 - -{-@ measure lend @-} -{-@ lend :: xs:[a] -> {v:Double|v >= 0} @-} -lend :: [a] -> Double -lend [] = 0 -lend (_ : xs) = 1 + lend xs - -{-@ assume relational pbind ~ pbind :: e1:_ -> f1:_ -> _ - ~ e2:_ -> f2:_ -> _ - ~~ true !=> (true => true) !=> - dist (r1 e1 f1) (r2 e2 f2) = dist (f1 e1) (f2 e2) @-} - -{-@ assume relational qbind ~ qbind :: e1:_ -> f1:_ -> _ - ~ e2:_ -> f2:_ -> _ - ~~ e1 = e2 !=> (true => true) !=> - dist (r1 e1 f1) (r2 e2 f2) = dist (f1 e1) (f2 e2) @-} - -pbind :: Distr a -> (a -> Distr b) -> Distr b -pbind = undefined - -qbind :: Distr a -> (a -> Distr b) -> Distr b -qbind = undefined - -{-@ reflect ppure @-} -ppure :: a -> Distr a -ppure x = x - -{-@ reflect head @-} -{-@ head :: {xs:[a] | len xs > 0 } -> a @-} -head :: [a] -> a -head (z : _) = z - -{-@ reflect tail @-} -{-@ tail :: {xs:[a] | len xs > 0 } -> {v:[a] | len v == len xs - 1 && lend v == lend xs - 1 } @-} -tail :: [a] -> [a] -tail (_ : zs) = zs - - -{- - -uhead ~ uhead => -upd ~ upd --------------------------------------- -pbind uhead upd ~ pbind uhead upd => -qbind utail upd ~ qbind utail upd --------------------------------------- -choice ~ choice => dist () --} -{-@ sgd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> StepSizes -> LossFunction -> Distr Weight @-} -sgd :: DataSet -> Weight -> StepSizes -> LossFunction -> Distr Weight -sgd _ w0 SSEmp _ = let lemma = undefined in ppure w0 -sgd zs w0 (SS α a) f = ((1 / SGDr.lend dsl_d1Q2) * dist ?c ?g + (1 - 1 / SGDr.lend dsl_d1Q2) * dist ?b ?i - =<= dist ws1 ws2) - - `cast` - choice (one / lend zs) - (pbind uhead upd) - (qbind utail upd) - where - upd z' = sgd zs (update z' w0 α f) a f - uhead = unif [head zs] - utail = unif (tail zs) - -{-@ relational sgd ~ sgd :: zs1:_ -> ws1:_ -> α1:_ -> f1:_ -> _ - ~ zs2:_ -> ws2:_ -> α2:_ -> f2:_ -> _ - ~~ 1 < SGDr.lend zs1 && 1 < len zs1 && 1 < SGDr.lend zs2 && 1 < len zs2 - && SGDr.tail zs1 = SGDr.tail zs2 !=> - true !=> α2 = α1 !=> (true => r1 = r2) !=> - SGDr.dist (r1 zs1 ws1 α1 f1) (r2 zs2 ws2 α2 f2) <= SGDr.dist ws1 ws2 -@-} \ No newline at end of file diff --git a/tests/relational/todo/SGDr0.hs b/tests/relational/todo/SGDr0.hs deleted file mode 100644 index 4991e28316..0000000000 --- a/tests/relational/todo/SGDr0.hs +++ /dev/null @@ -1,236 +0,0 @@ -{-@ LIQUID "--no-termination" @-} -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--fast" @-} -{-@ LIQUID "--ple" @-} - - -module SGDu where - -import Prelude hiding ( head - , tail - , sum - ) -import Data.Functor.Identity -import Language.Haskell.Liquid.ProofCombinators - -{-@ infix : @-} -type Prob = Double - -type StepSize = Double -data StepSizes = SSEmp | SS StepSize StepSizes -type DataPoint = (Double, Double) -type Weight = Double -type LossFunction = DataPoint -> Weight -> Double - -type Set a = [a] -type DataSet = Set DataPoint -type Distr a = a -type DataDistr = Distr DataPoint - -{-@ measure dist :: a -> a -> Double @-} -{-@ assume dist :: x1:_ -> x2:_ -> {v:Double | v == dist x1 x2 } @-} -dist :: a -> a -> Double -dist _ _ = 0 - -{-@ assume relationalchoice :: p:Prob -> e1:Distr a -> e1':Distr a - -> q:{Prob | p = q } -> e2:Distr a -> e2':Distr a - -> {dist (choice p e1 e1') (choice q e2 e2') <= p * (dist e1 e2) + (1.0 - p) * (dist e1' e2')} @-} -relationalchoice :: Prob -> Distr a -> Distr a -> Prob -> Distr a -> Distr a -> () -relationalchoice _ _ _ _ _ _ = () - -{-@ assume relational choice ~ choice - :: p:_ -> e1:_ -> e1':_ -> _ - ~ q:_ -> e2:_ -> e2':_ -> _ - ~~ p = q => true => true => - dist (r1 p e1 e1') (r2 q e2 e2') <= p * (dist e1 e2) + (1.0 - p) * (dist e1' e2') @-} - - - -{-@ measure SGDu.choice :: Prob -> Distr a -> Distr a -> Distr a @-} -{-@ choice :: x1:Prob -> x2:Distr a -> x3:Distr a -> {v:Distr a | v == choice x1 x2 x3 } @-} -choice :: Prob -> Distr a -> Distr a -> Distr a -choice _ x _ = x - -{-@ measure SGDu.unif :: zs:DataSet -> DataDistr @-} -{-@ assume unif :: x:DataSet -> {v:DataDistr | v == unif x } @-} -unif :: DataSet -> DataDistr -unif _ = (0,0) - -{-@ assume relationalupdatep :: z1:DataPoint -> ws1:Weight -> α1:StepSize -> f1:LossFunction -> - z2:DataPoint -> ws2:Weight -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2} @-} -relationalupdatep :: DataPoint -> Weight -> StepSize -> LossFunction -> DataPoint -> Weight -> StepSize -> LossFunction -> () -relationalupdatep _ _ _ _ _ _ _ _ = () - -{-@ measure lend @-} -{-@ lend :: xs:[a] -> {v:Double| 0.0 <= v } @-} -lend :: [a] -> Double -lend [] = 0 -lend (_ : xs) = 1 + lend xs - -{-@ measure SGDu.update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight @-} -update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight -update _ w _ _ = w - -{-@ reflect one @-} -{-@ one :: {v:Double| v = 1.0 } @-} -one :: Double -one = 1 - -{-@ assume relationalupdateq :: z1:DataPoint -> ws1:Weight -> α1:StepSize -> f1:LossFunction -> - {z2:DataPoint| true} -> ws2:Weight -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2} @-} -relationalupdateq :: DataPoint -> Weight -> StepSize -> LossFunction -> DataPoint -> Weight -> StepSize -> LossFunction -> () -relationalupdateq = undefined - -{-@ assume relational update ~ update - :: z1:_ -> ws1:_ -> α1:_ -> f1:_ -> _ - ~ z2:_ -> ws2:_ -> α2:_ -> f2:_ -> _ - ~~ true => true => α1 = α2 => f1 = f2 => - dist (r1 z1 ws1 α1 f1) (r2 z2 ws2 α2 f2) = dist ws1 ws2 @-} - -{-@ assume relational pbind ~ pbind :: e1:_ -> f1:_ -> _ - ~ e2:_ -> f2:_ -> _ - ~~ true => true => - dist (r1 e1 f1) (r2 e2 f2) = dist (f1 e1) (f2 e2) @-} - - -{-@ assume relational qbind ~ qbind :: e1:_ -> f1:_ -> _ - ~ e2:_ -> f2:_ -> _ - ~~ true => true => - dist (r1 e1 f1) (r2 e2 f2) = dist (f1 e1) (f2 e2) @-} - -{-@ assume relationalpbind :: e1:Distr a -> f1:(a -> Distr b) -> e2:Distr a -> f2:(a -> Distr b) -> - { dist (pbind e1 f1) (pbind e2 f2) = dist (f1 e1) (f2 e2)} @-} -relationalpbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalpbind = undefined - - -{-@ assume relationalqbind :: e1:Distr a -> f1:(a -> Distr b) -> {e2:Distr a | e1 = e2} -> f2:(a -> Distr b) -> - { dist (qbind e1 f1) (qbind e2 f2) = dist (f1 e1) (f2 e2)} @-} -relationalqbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalqbind = undefined - -{-@ measure SGDu.pbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ pbind :: x1:Distr a -> x2:(a -> Distr b) - -> {v:Distr b | v = SGDu.pbind x1 x2 } @-} -pbind :: Distr a -> (a -> Distr b) -> Distr b -pbind a f = const (f a) () -- f a -{-# NOINLINE pbind #-} - -{-@ measure SGDu.qbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ qbind :: x1:Distr a -> x2:(a -> Distr b) - -> {v:Distr b | v = SGDu.qbind x1 x2 } @-} -qbind :: Distr a -> (a -> Distr b) -> Distr b -qbind x f = f x - -{-@ reflect ppure @-} -ppure :: a -> Distr a -ppure x = x - -{-@ reflect head @-} -{-@ head :: {xs:[a] | len xs > 0 } -> a @-} -head :: [a] -> a -head (z : _) = z - -{-@ reflect tail @-} -{-@ tail :: {xs:[a] | len xs > 0 } -> {v:[a] | len v == len xs - 1 && lend v == lend xs - 1 } @-} -tail :: [a] -> [a] -tail (_ : zs) = zs - -{-@ measure sslen @-} -sslen :: StepSizes -> Int -{-@ sslen :: StepSizes -> Nat @-} -sslen SSEmp = 0 -sslen (SS _ ss) = 1 + sslen ss - -{-@ reflect upd @-} -{-@ upd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> StepSize -> ss:StepSizes -> LossFunction -> DataPoint - -> Distr Weight / [ sslen ss, 1 ] @-} -upd :: DataSet -> Weight -> StepSize -> StepSizes -> LossFunction -> DataPoint -> Distr Weight -upd zs w0 α a f z' = sgd zs (update z' w0 α f) a f - -{-@ reflect sgd @-} -{-@ sgd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> ss:StepSizes -> _ - -> Distr Weight / [ sslen ss, 0 ] @-} -sgd :: DataSet -> Weight -> StepSizes -> LossFunction -> Distr Weight -sgd _ w0 SSEmp _ = ppure w0 -sgd zs w0 (SS α a) f = thm zs w0 a f zs w0 a f `cast` - choice (one / lend zs) - (pbind uhead (upd zs w0 α a f)) - (qbind utail (upd zs w0 α a f)) - - where - uhead = unif [head zs] - utail = unif (tail zs) - - -{-@ reflect rconst @-} -rconst :: a -> b -> a -rconst x _ = x - -{-@ relational sgd ~ sgd :: zs1:{_ | 1 < len zs1 && 1 < lend zs1 } -> ws1:_ -> α1:_ -> f1:_ -> _ - ~ zs2:{_ | 1 < len zs2 && 1 < lend zs2 } -> ws2:_ -> α2:_ -> f2:_ -> _ - ~~ (1 < SGDu.lend zs1 && 1 < len zs1 && 1 < SGDu.lend zs2 && 1 < len zs2 && SGDu.lend zs1 == SGDu.lend zs2 && tail zs1 = tail zs2) - => true => α2 = α1 => f1 = f2 => true - @-} - - -{-@ ple thm @-} -{-@ thm :: zs1:{DataSet | 1 < lend zs1 && 1 < len zs1 } -> ws1:Weight -> α1:StepSizes -> f1:LossFunction -> - zs2:{DataSet | 1 < lend zs2 && 1 < len zs2 && lend zs1 == lend zs2 && tail zs1 = tail zs2} -> - ws2:Weight -> {α2:StepSizes| α2 = α1} -> {f2:LossFunction|f1 = f2} -> - {dist (sgd zs1 ws1 α1 f1) (sgd zs2 ws2 α2 f2) <= dist ws1 ws2} @-} -thm :: DataSet -> Weight -> StepSizes -> LossFunction -> DataSet -> Weight -> StepSizes -> LossFunction -> () -thm zs1 ws1 α1@SSEmp f1 zs2 ws2 α2@SSEmp f2 - = dist (sgd zs1 ws1 α1 f1) (sgd zs2 ws2 α2 f2) - =<= dist (ppure ws1) (ppure ws2) - *** QED - -thm zs1 ws1 as1@(SS α1 a1) f1 zs2 ws2 as2@(SS α2 a2) f2 = - dist (sgd zs1 ws1 as1 f1) (sgd zs2 ws2 as2 f2) - ==. dist (thm zs1 ws1 a1 f1 zs1 ws1 a1 f1 `cast` sgd zs1 ws1 as1 f1) - (thm zs2 ws2 a2 f2 zs2 ws2 a2 f2 `cast` sgd zs2 ws2 as2 f2) - ==. dist - (choice (one / lend zs1) (pbind uhead1 updWs1) (qbind utail1 updWs1)) - (choice (one / lend zs2) (pbind uhead2 updWs2) (qbind utail2 updWs2)) - ? relationalchoice (one / lend zs1) (pbind uhead1 updWs1) (qbind utail1 updWs1) - (one / lend zs2) (pbind uhead2 updWs2) (qbind utail2 updWs2) - - ==. (one / lend zs1) * (dist (pbind uhead1 updWs1) (pbind uhead2 updWs2)) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? relationalpbind uhead1 updWs1 uhead2 updWs2 - - ==. (one / lend zs1) * (dist (updWs1 uhead1) (updWs2 uhead2)) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? thm zs1 (update uhead1 ws1 α1 f1) a1 f1 zs2 (update uhead2 ws2 α2 f2) a2 f2 - - ==. (one / lend zs1) * (dist (update uhead1 ws1 α1 f1) (update uhead2 ws2 α2 f2)) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? (dist (update uhead1 ws1 α1 f1) (update uhead2 ws2 α2 f2) - ? relationalupdatep uhead1 ws1 α1 f1 uhead2 ws2 α2 f2 - === dist ws1 ws2 - *** QED) - - ==. (one / lend zs1) * (dist ws1 ws2) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? relationalqbind utail1 updWs1 utail2 updWs2 - - ==. (one / lend zs1) * (dist ws1 ws2) - + (1 - (one / lend zs1)) * (dist (updWs1 utail1) (updWs2 utail2)) - ? thm zs1 (update utail1 ws1 α1 f1) a1 f1 zs2 (update utail2 ws2 α2 f2) a2 f2 - ? relationalupdateq utail1 ws1 α1 f1 utail2 ws2 α2 f2 - - ==. (one / lend zs1) * (dist ws1 ws2) - + (1 - (one / lend zs1)) * (dist ws1 ws2) - - ==. dist ws1 ws2 - *** QED - where - updWs1 = upd zs1 ws1 α1 a1 f1 - updWs2 = upd zs2 ws2 α2 a2 f2 - uhead1 = unif [head zs1] - utail1 = unif (tail zs1) - uhead2 = unif [head zs2] - utail2 = unif (tail zs2) -thm zs1 ws1 _ f1 zs2 ws2 _ f2 = () \ No newline at end of file diff --git a/tests/relational/todo/SGDr00.hs b/tests/relational/todo/SGDr00.hs deleted file mode 100644 index 294262de5f..0000000000 --- a/tests/relational/todo/SGDr00.hs +++ /dev/null @@ -1,177 +0,0 @@ -{-@ LIQUID "--no-termination" @-} -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--fast" @-} -{-@ LIQUID "--ple" @-} - - -module SGDu where - -import Prelude hiding ( head - , tail - , sum - ) -import Data.Functor.Identity -import Language.Haskell.Liquid.ProofCombinators - -{-@ infix : @-} -type Prob = Double - -type StepSize = Double -data StepSizes = SSEmp | SS StepSize StepSizes -type DataPoint = (Double, Double) -type Weight = Double -type LossFunction = DataPoint -> Weight -> Double - -type Set a = [a] -type DataSet = Set DataPoint -type Distr a = a -type DataDistr = Distr DataPoint - -{-@ measure dist :: a -> a -> Double @-} -{-@ assume dist :: x1:_ -> x2:_ -> {v:Double | v == dist x1 x2 } @-} -dist :: a -> a -> Double -dist _ _ = 0 - -{-@ assume relationalchoice :: p:Prob -> e1:Distr a -> e1':Distr a - -> q:{Prob | p = q } -> e2:Distr a -> e2':Distr a - -> {dist (choice p e1 e1') (choice q e2 e2') <= p * (dist e1 e2) + (1.0 - p) * (dist e1' e2')} @-} -relationalchoice :: Prob -> Distr a -> Distr a -> Prob -> Distr a -> Distr a -> () -relationalchoice _ _ _ _ _ _ = () - -{-@ assume relational choice ~ choice - :: p:_ -> e1:_ -> e1':_ -> _ - ~ q:_ -> e2:_ -> e2':_ -> _ - ~~ p = q => true => true => - dist (r1 p e1 e1') (r2 q e2 e2') <= p * (dist e1 e2) + (1.0 - p) * (dist e1' e2') @-} - - - -{-@ measure SGDu.choice :: Prob -> Distr a -> Distr a -> Distr a @-} -{-@ choice :: x1:Prob -> x2:Distr a -> x3:Distr a -> {v:Distr a | v == choice x1 x2 x3 } @-} -choice :: Prob -> Distr a -> Distr a -> Distr a -choice _ x _ = x - -{-@ measure SGDu.unif :: zs:DataSet -> DataDistr @-} -{-@ assume unif :: x:DataSet -> {v:DataDistr | v == unif x } @-} -unif :: DataSet -> DataDistr -unif _ = (0,0) - -{-@ assume relationalupdatep :: z1:DataPoint -> ws1:Weight -> α1:StepSize -> f1:LossFunction -> - z2:DataPoint -> ws2:Weight -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2} @-} -relationalupdatep :: DataPoint -> Weight -> StepSize -> LossFunction -> DataPoint -> Weight -> StepSize -> LossFunction -> () -relationalupdatep _ _ _ _ _ _ _ _ = () - -{-@ measure lend @-} -{-@ lend :: xs:[a] -> {v:Double| 0.0 <= v } @-} -lend :: [a] -> Double -lend [] = 0 -lend (_ : xs) = 1 + lend xs - -{-@ measure SGDu.update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight @-} -update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight -update _ w _ _ = w - -{-@ reflect one @-} -{-@ one :: {v:Double| v = 1.0 } @-} -one :: Double -one = 1 - -{-@ assume relationalupdateq :: z1:DataPoint -> ws1:Weight -> α1:StepSize -> f1:LossFunction -> - {z2:DataPoint| true} -> ws2:Weight -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2} @-} -relationalupdateq :: DataPoint -> Weight -> StepSize -> LossFunction -> DataPoint -> Weight -> StepSize -> LossFunction -> () -relationalupdateq = undefined - -{-@ assume relational update ~ update - :: z1:_ -> ws1:_ -> α1:_ -> f1:_ -> _ - ~ z2:_ -> ws2:_ -> α2:_ -> f2:_ -> _ - ~~ true => true => α1 = α2 => f1 = f2 => - dist (r1 z1 ws1 α1 f1) (r2 z2 ws2 α2 f2) = dist ws1 ws2 @-} - -{-@ assume relational pbind ~ pbind :: e1:_ -> f1:_ -> _ - ~ e2:_ -> f2:_ -> _ - ~~ true => true => - dist (r1 e1 f1) (r2 e2 f2) = dist (f1 e1) (f2 e2) @-} - - -{-@ assume relational qbind ~ qbind :: e1:_ -> f1:_ -> _ - ~ e2:_ -> f2:_ -> _ - ~~ true => true => - dist (r1 e1 f1) (r2 e2 f2) = dist (f1 e1) (f2 e2) @-} - -{-@ assume relationalpbind :: e1:Distr a -> f1:(a -> Distr b) -> e2:Distr a -> f2:(a -> Distr b) -> - { dist (pbind e1 f1) (pbind e2 f2) = dist (f1 e1) (f2 e2)} @-} -relationalpbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalpbind = undefined - - -{-@ assume relationalqbind :: e1:Distr a -> f1:(a -> Distr b) -> {e2:Distr a | e1 = e2} -> f2:(a -> Distr b) -> - { dist (qbind e1 f1) (qbind e2 f2) = dist (f1 e1) (f2 e2)} @-} -relationalqbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalqbind = undefined - -{-@ measure SGDu.pbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ pbind :: x1:Distr a -> x2:(a -> Distr b) - -> {v:Distr b | v = SGDu.pbind x1 x2 } @-} -pbind :: Distr a -> (a -> Distr b) -> Distr b -pbind a f = const (f a) () -- f a -{-# NOINLINE pbind #-} - -{-@ measure SGDu.qbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ qbind :: x1:Distr a -> x2:(a -> Distr b) - -> {v:Distr b | v = SGDu.qbind x1 x2 } @-} -qbind :: Distr a -> (a -> Distr b) -> Distr b -qbind x f = f x - -{-@ reflect ppure @-} -ppure :: a -> Distr a -ppure x = x - -{-@ reflect head @-} -{-@ head :: {xs:[a] | len xs > 0 } -> a @-} -head :: [a] -> a -head (z : _) = z - -{-@ reflect tail @-} -{-@ tail :: {xs:[a] | len xs > 0 } -> {v:[a] | len v == len xs - 1 && lend v == lend xs - 1 } @-} -tail :: [a] -> [a] -tail (_ : zs) = zs - -{-@ measure sslen @-} -sslen :: StepSizes -> Int -{-@ sslen :: StepSizes -> Nat @-} -sslen SSEmp = 0 -sslen (SS _ ss) = 1 + sslen ss - -{-@ reflect upd @-} -{-@ upd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> StepSize -> ss:StepSizes -> LossFunction -> DataPoint - -> Distr Weight / [ sslen ss, 1 ] @-} -upd :: DataSet -> Weight -> StepSize -> StepSizes -> LossFunction -> DataPoint -> Distr Weight -upd zs w0 α a f z' = sgd zs (update z' w0 α f) a f - -{-@ reflect sgd @-} -{-@ sgd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> ss:StepSizes -> LossFunction - -> Distr Weight / [ sslen ss, 0 ] @-} -sgd :: DataSet -> Weight -> StepSizes -> LossFunction -> Distr Weight -sgd _ w0 SSEmp _ = ppure w0 -sgd zs w0 (SS α a) f = choice (one / lend zs) - (pbind uhead (upd zs w0 α a f)) - (qbind utail (upd zs w0 α a f)) - - where - uhead = unif [head zs] - utail = unif (tail zs) - - -{-@ reflect rconst @-} -rconst :: a -> b -> a -rconst x _ = x - -{-@ relational sgd ~ sgd :: zs1:{_ | 1 < len zs1 && 1 < lend zs1 } -> ws1:_ -> α1:_ -> f1:_ -> _ - ~ zs2:{_ | 1 < len zs2 && 1 < lend zs2 } -> ws2:_ -> α2:_ -> f2:_ -> _ - ~~ (1 < SGDu.lend zs1 && 1 < len zs1 && 1 < SGDu.lend zs2 && 1 < len zs2 && SGDu.lend zs1 == SGDu.lend zs2 && tail zs1 = tail zs2) - => true => α2 = α1 => f1 = f2 => true - @-} - - diff --git a/tests/relational/todo/SGDu.hs b/tests/relational/todo/SGDu.hs deleted file mode 100644 index 5c5b360679..0000000000 --- a/tests/relational/todo/SGDu.hs +++ /dev/null @@ -1,229 +0,0 @@ -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--fast" @-} - -module SGDu where - -import Prelude hiding ( head - , tail - , sum - ) -import Data.Functor.Identity -import Language.Haskell.Liquid.ProofCombinators - -{-@ infix : @-} -{-@ type Prob = {v:Double| 0 <= v && v <= 1} @-} -type Prob = Double - -{-@ type StepSize = {v:Double | 0.0 <= v } @-} -type StepSize = Double -{-@ data StepSizes = SSEmp | SS StepSize StepSizes @-} -data StepSizes = SSEmp | SS StepSize StepSizes -type DataPoint = (Double, Double) -type Weight = Double -type LossFunction = DataPoint -> Weight -> Double - -type Set a = [a] -{-@ type DataSet = {v:Set DataPoint| 0 < len v && 0.0 < lend v } @-} -type DataSet = Set DataPoint -type Distr a = a -type DataDistr = Distr DataPoint - -{-@ measure dist :: a -> a -> Double @-} -{-@ assume dist :: x1:_ -> x2:_ -> {v:Double | v == dist x1 x2 } @-} -dist :: a -> a -> Double -dist _ _ = 0 - -{-@ assume relationalchoice :: p:Prob -> e1:Distr a -> e1':Distr a - -> q:{Prob | p = q } -> e2:Distr a -> e2':Distr a - -> {dist (choice p e1 e1') (choice q e2 e2') <= p * (dist e1 e2) + (1.0 - p) * (dist e1' e2')} @-} -relationalchoice :: Prob -> Distr a -> Distr a -> Prob -> Distr a -> Distr a -> () -relationalchoice _ _ _ _ _ _ = () - -{-@ measure SGDu.choice :: Prob -> Distr a -> Distr a -> Distr a @-} -{-@ assume choice :: x1:Prob -> x2:Distr a -> x3:Distr a -> {v:Distr a | v == choice x1 x2 x3 } @-} -choice :: Prob -> Distr a -> Distr a -> Distr a -choice _ x _ = x - -{-@ measure SGDu.unif :: zs:DataSet -> DataDistr @-} -{-@ assume unif :: x:DataSet -> {v:DataDistr | v == unif x } @-} -unif :: DataSet -> DataDistr -unif _ = (0,0) - -{-@ assume relationalupdatep :: z1:DataPoint -> ws1:Weight -> α1:StepSize -> f1:LossFunction -> - z2:DataPoint -> ws2:Weight -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2 + 2.0 * α1} @-} -relationalupdatep :: DataPoint -> Weight -> StepSize -> LossFunction -> DataPoint -> Weight -> StepSize -> LossFunction -> () -relationalupdatep _ _ _ _ _ _ _ _ = () - -{-@ measure lend @-} -{-@ lend :: xs:[a] -> {v:Double| 0.0 <= v } @-} -lend :: [a] -> Double -lend [] = 0 -lend (_ : xs) = 1 + lend xs - -{-@ measure SGDu.update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight @-} -update :: DataPoint -> Weight -> StepSize -> LossFunction -> Weight -update _ w _ _ = w - -{-@ reflect one @-} -{-@ one :: {v:Double| v = 1.0 } @-} -one :: Double -one = 1 - -{-@ assume relationalupdateq :: z1:DataPoint -> ws1:Weight -> α1:StepSize -> f1:LossFunction -> - {z2:DataPoint|z1 = z2} -> ws2:Weight -> {α2:StepSize|α1 = α2} -> {f2:LossFunction|f1 = f2} -> - {dist (update z1 ws1 α1 f1) (update z2 ws2 α2 f2) = dist ws1 ws2} @-} -relationalupdateq :: DataPoint -> Weight -> StepSize -> LossFunction -> DataPoint -> Weight -> StepSize -> LossFunction -> () -relationalupdateq = undefined - - -{-@ assume relationalpbind :: e1:Distr a -> f1:(a -> Distr b) -> e2:Distr a -> f2:(a -> Distr b) -> - { dist (pbind e1 f1) (pbind e2 f2) = dist e1 e2} @-} -relationalpbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalpbind = undefined - -{-@ assume relationalqbind :: e1:Distr a -> f1:(a -> Distr b) -> {e2:Distr a | e1 = e2} -> f2:(a -> Distr b) -> - { dist (qbind e1 f1) (qbind e2 f2) = dist e1 e2} @-} -relationalqbind :: Distr a -> (a -> Distr b) -> Distr a -> (a -> Distr b) -> () -relationalqbind = undefined - -{-@ measure SGDu.pbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ assume pbind :: x1:Distr a -> x2:(a -> Distr b) -> {v:Distr b | v = pbind x1 x2 } @-} -pbind :: Distr a -> (a -> Distr b) -> Distr b -pbind = undefined - -{-@ measure SGDu.qbind :: Distr a -> (a -> Distr b) -> Distr b @-} -{-@ assume qbind :: x1:Distr a -> x2:(a -> Distr b) -> {v:Distr b | v = qbind x1 x2 } @-} -qbind :: Distr a -> (a -> Distr b) -> Distr b -qbind = undefined - -{-@ reflect ppure @-} -ppure :: a -> Distr a -ppure x = x - -{-@ reduce :: p:Double -> ws1:Weight -> ws2:Weight -> {p * dist ws1 ws2 + (1 - p) * dist ws1 ws2 = dist ws1 ws2} @-} -reduce :: Double -> Weight -> Weight -> () -reduce _ _ _ = () - -{-@ reflect sum @-} -{-@ sum :: StepSizes -> {v:StepSize | 0.0 <= v } @-} -sum :: StepSizes -> Double -sum SSEmp = 0 -sum (SS a as) = a + sum as - -{-@ reflect estab @-} -{-@ estab :: DataSet -> StepSizes -> {v:Double | 0.0 <= v} @-} -estab :: DataSet -> StepSizes -> Double -estab zs as = 2.0 / (lend zs) * sum as - -{-@ ple estabconsR @-} -{-@ measure SGDu.estabconsR :: DataSet -> StepSize -> StepSizes -> () @-} -{-@ estabconsR :: zs:{DataSet | lend zs /= 0} -> x:StepSize -> xs:StepSizes - -> { estab zs (SS x xs) == 2.0 * x * (one / lend zs) + estab zs xs } @-} -estabconsR :: DataSet -> StepSize -> StepSizes -> () -estabconsR zs x xs - = estab zs (SS x xs) - ==. 2.0 / (lend zs) * sum (SS x xs) - ==. 2.0 * x * (one / lend zs) + estab zs xs - *** QED - - -{-@ reflect head @-} -{-@ head :: {xs:[a] | len xs > 0 } -> a @-} -head :: [a] -> a -head (z : _) = z - -{-@ reflect tail @-} -{-@ tail :: {xs:[a] | len xs > 0 } -> {v:[a] | len v == len xs - 1 && lend v == lend xs - 1 } @-} -tail :: [a] -> [a] -tail (_ : zs) = zs - -{-@ measure sslen @-} -sslen :: StepSizes -> Int -{-@ sslen :: StepSizes -> Nat @-} -sslen SSEmp = 0 -sslen (SS _ ss) = 1 + sslen ss - -{-@ reflect upd @-} -{-@ upd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> StepSize -> ss:StepSizes -> LossFunction -> DataPoint - -> Distr Weight / [ sslen ss, 1 ] @-} -upd :: DataSet -> Weight -> StepSize -> StepSizes -> LossFunction -> DataPoint -> Distr Weight -upd zs w0 α a f z' = sgd zs (update z' w0 α f) a f - -{-@ reflect sgd @-} -{-@ sgd :: zs:{DataSet | 1 < len zs && 1 < lend zs } -> Weight -> ss:StepSizes -> LossFunction - -> Distr Weight / [ sslen ss, 0 ] @-} -sgd :: DataSet -> Weight -> StepSizes -> LossFunction -> Distr Weight -sgd _ w0 SSEmp _ = ppure w0 -sgd zs w0 (SS α a) f = choice (one / lend zs) - (pbind uhead (upd zs w0 α a f)) - (qbind utail (upd zs w0 α a f)) `rconst` estabconsR zs α a - where - uhead = unif [head zs] - utail = unif (tail zs) - - -{-@ reflect rconst @-} -rconst :: a -> b -> a -rconst x _ = x - -{-@ ple thm @-} -{-@ thm :: zs1:{DataSet | 1 < lend zs1 && 1 < len zs1 } -> ws1:Weight -> α1:StepSizes -> f1:LossFunction -> - zs2:{DataSet | 1 < lend zs2 && 1 < len zs2 && lend zs1 == lend zs2 && tail zs1 = tail zs2} -> - ws2:Weight -> {α2:StepSizes| α2 = α1} -> {f2:LossFunction|f1 = f2} -> - {dist (sgd zs1 ws1 α1 f1) (sgd zs2 ws2 α2 f2) <= dist ws1 ws2 + estab zs1 α1} @-} -thm :: DataSet -> Weight -> StepSizes -> LossFunction -> DataSet -> Weight -> StepSizes -> LossFunction -> () -thm zs1 ws1 α1@SSEmp f1 zs2 ws2 α2@SSEmp f2 = - dist (sgd zs1 ws1 α1 f1) (sgd zs2 ws2 α2 f2) - =<= dist (ppure ws1) (ppure ws2) + estab zs1 α1 - *** QED - -thm zs1 ws1 as1@(SS α1 a1) f1 zs2 ws2 as2@(SS α2 a2) f2 = - dist (sgd zs1 ws1 as1 f1) (sgd zs2 ws2 as2 f2) - === dist - (choice (one / lend zs1) (pbind uhead1 updWs1) (qbind utail1 updWs1) `rconst` estabconsR zs1 α1 a1) - (choice (one / lend zs2) (pbind uhead2 updWs2) (qbind utail2 updWs2) `rconst` estabconsR zs2 α2 a2) - === dist - (choice (one / lend zs1) (pbind uhead1 updWs1) (qbind utail1 updWs1)) - (choice (one / lend zs2) (pbind uhead2 updWs2) (qbind utail2 updWs2)) - ? relationalchoice (one / lend zs1) (pbind uhead1 updWs1) (qbind utail1 updWs1) - (one / lend zs2) (pbind uhead2 updWs2) (qbind utail2 updWs2) - - === (one / lend zs1) * (dist (pbind uhead1 updWs1) (pbind uhead2 updWs2)) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? relationalpbind uhead1 updWs1 uhead2 updWs2 - - === (one / lend zs1) * (dist (updWs1 uhead1) (updWs2 uhead2)) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? thm zs1 (update uhead1 ws1 α1 f1) a1 f1 zs2 (update uhead2 ws2 α2 f2) a2 f2 - - === (one / lend zs1) * (dist (update uhead1 ws1 α1 f1) (update uhead2 ws2 α2 f2) + estab zs1 a1) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? relationalupdatep uhead1 ws1 α1 f1 uhead2 ws2 α2 f2 - - === (one / lend zs1) * (dist ws1 ws2 + 2 * α1 + estab zs1 a1) - + (1 - (one / lend zs1)) * (dist (qbind utail1 updWs1) (qbind utail2 updWs2)) - ? relationalqbind utail1 updWs1 utail2 updWs2 - - === (one / lend zs1) * (dist ws1 ws2 + 2 * α1 + estab zs1 a1) - + (1 - (one / lend zs1)) * (dist (updWs1 utail1) (updWs2 utail2)) - ? thm zs1 (update utail1 ws1 α1 f1) a1 f1 zs2 (update utail2 ws2 α2 f2) a2 f2 - ? relationalupdateq utail1 ws1 α1 f1 utail2 ws2 α2 f2 - - === (one / lend zs1) * (dist ws1 ws2 + 2 * α1 + estab zs1 a1) - + (1 - (one / lend zs1)) * (dist ws1 ws2 + estab zs1 a1) - - === dist ws1 ws2 + 2.0 * α1 * (one / lend zs1) + estab zs1 a1 - ? estabconsR zs1 α1 a1 - - === dist ws1 ws2 + estab zs1 (SS α1 a1) - === dist ws1 ws2 + estab zs1 as1 - *** QED - where - updWs1 = upd zs1 ws1 α1 a1 f1 - updWs2 = upd zs2 ws2 α2 a2 f2 - uhead1 = unif [head zs1] - utail1 = unif (tail zs1) - uhead2 = unif [head zs2] - utail2 = unif (tail zs2) -thm zs1 ws1 _ f1 zs2 ws2 _ f2 = () \ No newline at end of file diff --git a/tests/relational/todo/SndOrdPred.hs b/tests/relational/todo/SndOrdPred.hs deleted file mode 100644 index f7449b6718..0000000000 --- a/tests/relational/todo/SndOrdPred.hs +++ /dev/null @@ -1,35 +0,0 @@ -module SndOrdPred where - -{-@ relational foo ~ foo :: x1:_ -> _ ~ x2:_ -> _ - ~~ x1 < x2 => r1 x1 < r2 x2 @-} -foo :: Int -> Int -foo x = x + 1 - -{-@ relational bar ~ bar :: f1:(x1':_ -> _) -> x1:_ -> _ - ~ f2:(x2':_ -> _) -> x2:_ -> _ - ~~ (x1' < x2' => r1 <= r2) => x1 < x2 => r1 f1 x1 <= r2 f2 x2 && (f1 1 <= f2 1) @-} -bar :: (Int -> Int) -> Int -> Int -bar f x = f (x + 1) - -{- - u1 => v1 v2 => u2 - (-1) ~ (-1) | v1 => v2 (syn) - -------------------------------- - (-1) ~ (-1) | u1 => u2 (chk) x ~ x | x1 < x2 - - bar ~ bar | (x1' < x2' => r1 x1' < r2 x2') => x1 < x2 => r1 x1 <= r2 x2 - ------------------------------------------------------------------------ - bar (-1) x ~ bar (-1) x | (x1' < x2' => true && true => f1 x1' < f2 x2') => r1 < r2 (syn) - - - |- (h1 && h2 => p) || h1 => p || h2 => p || true => p - - - (x1' < x2' => x1' < x2' && f1 x1' < f2 x2' => f1 x1' < f2 x2') => r1 < r2 |- p - ------------------------------------------------------------------------------ - bar (-1) x ~ bar (-1) x | true (chk) -} - -{-@ relational baz ~ baz :: x1:Int -> Int ~ x2:Int -> Int ~~ x1 < x2 => r1 x1 <= r2 x2 @-} -baz :: Int -> Int -baz x = bar foo x - diff --git a/tests/relational/todo/SquareMult.hs b/tests/relational/todo/SquareMult.hs deleted file mode 100644 index 63fe68fc6f..0000000000 --- a/tests/relational/todo/SquareMult.hs +++ /dev/null @@ -1,21 +0,0 @@ -module Fixme where - -data Bit = O | I - -{-@ data SqMul = SqMul { sq :: Int, mul :: Int, r :: Int } @-} -data SqMul = SqMul { sq :: Int, mul :: Int, r :: Int } - -{-@ reflect weight @-} -weight :: [Bit] -> Int -weight [] = 0 -weight (O : bs) = weight bs -weight (I : bs) = 1 + weight bs - -sam :: Int -> [Bit] -> SqMul -sam _ [] = SqMul 0 0 1 -sam x (O : bs) = let (SqMul s m r) = sam x bs in SqMul (1 + s) m (r * r) -sam x (I : bs) = - let (SqMul s m r) = sam x bs in SqMul (1 + s) (1 + m) (x * r * r) - -{-@ relational sam ~ sam :: x1:_ -> p1:_ -> _ ~ x2:_ -> p2:_ -> _ - ~~ true => true => (len p1 == 0) @-} \ No newline at end of file diff --git a/tests/relational/todo/SquareMult_.hs b/tests/relational/todo/SquareMult_.hs deleted file mode 100644 index 3a2e1f378d..0000000000 --- a/tests/relational/todo/SquareMult_.hs +++ /dev/null @@ -1,24 +0,0 @@ -module Fixme where - -data Bit = O | I - -{-@ data SqMul = SqMul { sq :: Int, mul :: Int, r :: Int } @-} -data SqMul = SqMul { sq :: Int, mul :: Int, r :: Int } - -{-@ reflect weight @-} -weight :: [Bit] -> Int -weight [] = 0 -weight (O : bs) = weight bs -weight (I : bs) = 1 + weight bs - -sam :: Int -> [Bit] -> SqMul -sam _ [] = SqMul 0 0 1 -sam x (O : bs) = let (SqMul s m r) = sam x bs in SqMul (1 + s) m (r * r) -sam x (I : bs) = - let (SqMul s m r) = sam x bs in SqMul (1 + s) (1 + m) (x * r * r) - -{-@ relational sam ~ sam :: x1:_ -> p1:_ -> _ ~ x2:_ -> p2:_ -> _ - ~~ true => len p1 == len p2 => - Fixme.weight p1 - Fixme.weight p2 == - Fixme.mul (r1 x1 p1) - Fixme.mul (r2 x2 p2) - && Fixme.sq (r1 x1 p1) == Fixme.sq (r2 x2 p2) @-} \ No newline at end of file diff --git a/tests/relational/todo/SumAlphaBeta.hs b/tests/relational/todo/SumAlphaBeta.hs deleted file mode 100644 index bdaed3bc69..0000000000 --- a/tests/relational/todo/SumAlphaBeta.hs +++ /dev/null @@ -1,72 +0,0 @@ -module SumAlphaBeta where - -{-@ LIQUID "--reflection" @-} -{-@ LIQUID "--ple" @-} - --- {-@ reflect foo @-} --- {-@ foo :: xs:[Bool] -> α:N -> β:N -> n:N -> {v:N| v = n + α * countT xs + β * (len xs - countT xs)} @-} --- foo :: [Bool] -> N -> N -> N -> N --- foo [] _ _ n = n --- foo (x : xs) α β n = if x then foo xs α β (n + α) else foo xs α β (n + β) - --- {-@ reflect countT @-} --- countT :: [Bool] -> N --- countT [] = 0 --- countT (True : xs) = 1 + countT xs --- countT (False : xs) = countT xs - --- -- Sum Negers, express countFalse through countTrue --- {-@ thm :: xs:[Bool] -> α:N -> β:N -> n:N -> {foo xs α β n = n + α * countT xs + β * (len xs - countT xs)} @-} --- thm :: [Bool] -> N -> N -> N -> () --- thm [] _ _ _ = () --- thm (True : xs) α β n = thm xs α β (α + n) --- thm (False : xs) α β n = thm xs α β (β + n) - --- {-@ reflect foo' @-} --- {-@ foo' :: xs:[Bool] -> α:N -> β:N -> n:N -> {v:N| v = n + α * countT xs + β * (len xs - countT xs)} @-} --- foo' :: [Bool] -> Double -> Double -> Double -> Double --- foo' [] _ _ n = n --- foo' (x : xs) α β n = if x then foo' xs α β (n + α) else foo' xs α β (n + β) - --- {-@ reflect countT @-} --- countT' :: [Bool] -> Double --- countT' [] = 0 --- countT' (True : xs) = 1 + countT' xs --- countT' (False : xs) = countT' xs - --- {-@ reflect lend @-} --- lend :: [a] -> Double --- lend [] = 0 --- lend (_:xs) = 1 + lend xs - --- -- Sum Negers, express countFalse through countTrue --- {-@ thm''' :: xs:[Bool] -> α:_ -> β:_ -> n:_ -> {foo xs α β n = n + α * countT xs + β * (lend xs - countT xs)} @-} --- thm''' :: [Bool] -> Double -> Double -> Double -> () --- thm''' [] _ _ _ = () --- thm''' (True : xs) α β n = thm''' xs α β (α + n) --- thm''' (False : xs) α β n = thm''' xs α β (β + n) - -type N = Double - -{-@ reflect α @-} -α :: N -{-@ reflect β @-} -β :: N - -α = 1 -β = 2 - -{-@ reflect foo @-} -{-@ foo :: xs:[Bool] -> n:N -> {v:N| v = n + α * countT xs + β * (len xs - countT xs)} @-} -foo :: [Bool] -> N -> N -foo [] n = n -foo (x : xs) n = if x then foo xs (n + α) else foo xs (n + β) - -{-@ reflect countT @-} -countT :: [Bool] -> N -countT [] = 0 -countT (True : xs) = 1 + countT xs -countT (False : xs) = countT xs - -{-@ relational foo ~ foo :: xs1:_ -> n1:_ -> _ ~ xs2:_ -> n2:_ -> _ ~~ - xs1 = xs2 => true => r1 xs1 n1 - r2 xs2 n2 = n1 - n2 @-} \ No newline at end of file diff --git a/tests/relational/todo/SynchCase.hs b/tests/relational/todo/SynchCase.hs deleted file mode 100644 index a69c02d039..0000000000 --- a/tests/relational/todo/SynchCase.hs +++ /dev/null @@ -1,36 +0,0 @@ -module SynchCase where - -x, y :: Int -x = 0 -y = 0 - -{-@ relational x ~ y :: _ ~ _ ~~ r1 = r2 @-} - -foo :: Int -> Bool -foo x = if x == 0 then True else False - -{-@ relational foo ~ foo :: x:_ -> _ ~ y:_ -> _ ~~ x = y => r1 x = r2 y @-} - -foox, fooy :: Bool -foox = foo x -fooy = foo y - -{-@ relational foox ~ fooy :: _ ~ _ ~~ r1 = r2 @-} - -foox', fooy' :: Bool -foox' = if x == 0 then True else False -fooy' = if y == 0 then True else False - -{-@ relational foox' ~ fooy' :: _ ~ _ ~~ r1 = r2 @-} - -a, b :: Bool -a = True -b = True - -{-@ relational a ~ b :: _ ~ _ ~~ r1 = r2 @-} - -fooa, foob :: Int -fooa = if a then 1 else 0 -foob = if b then 1 else 0 - -{-@ relational fooa ~ foob :: _ ~ _ ~~ r1 = r2 @-} diff --git a/tests/relational/todo/SynchLists.hs b/tests/relational/todo/SynchLists.hs deleted file mode 100644 index 68dcf71168..0000000000 --- a/tests/relational/todo/SynchLists.hs +++ /dev/null @@ -1,32 +0,0 @@ -module SynchLisis where - --- {-@ prefSum :: Int -> [Nat] -> Nat @-} --- prefSum :: Int -> [Int] -> Int --- prefSum n _ | n <= 0 = 0 --- prefSum _ [] = 0 --- prefSum n (x : xs) = 1 + prefSum (n - 1) xs - --- {-@ relational prefSum ~ prefSum :: n:Int -> xs:_ -> _ ~ m:Int -> ys:_ -> _ --- ~~ n = m => xs = ys => r1 n xs <= r2 m ys @-} - - -{-@ hasEvenLen :: [Int] -> {v:Bool|v} @-} -hasEvenLen :: [Int] -> Bool -hasEvenLen [] = True -hasEvenLen (x : xs) = let b = hasEvenLen xs in if b then False else True - -{- -I. l1 = [], l2 = [] |- True ~ True | true => r1 = r2 - -II. l1 = [], l2 = (x2 : xs2), hasEvenLen xs |- True ~ False | true => r1 = r2 - -III. l1 = [], l2 = (x2 : xs2), !hasEvenLen xs |- True ~ True | true => r1 = r2 - -III. l1 = [], l2 = (x : xs), hasEvenLen xs |- True ~ False | true => r1 = r2 - -IV. l1 = (x1 : xs1), l2 = (x : xs), hasEvenLen xs |- True ~ False | true => r1 = r2 - --} - --- {-@ relational hasEvenLen ~ hasEvenLen :: xs:[Int] -> Bool ~ ys:[Int] -> Bool --- ~~ true => r1 xs == r2 ys @-} diff --git a/tests/relational/todo/TakeMap.hs b/tests/relational/todo/TakeMap.hs deleted file mode 100644 index 226bbec4b1..0000000000 --- a/tests/relational/todo/TakeMap.hs +++ /dev/null @@ -1,70 +0,0 @@ -module TakeMap where - -import Prelude hiding ( map - , take - ) -import Language.Haskell.Liquid.ProofCombinators - -{-@ reflect map @-} -map :: (Int -> Int) -> [Int] -> [Int] -map _ [] = [] -map f (x : xs) = f x : map f xs - -{-@ reflect take @-} -take :: Int -> [Int] -> [Int] -take n _ | n <= 0 = [] -take _ [] = [] -take n (x : xs) = x : take (n - 1) xs - ---- Unary - -{-@ commMapTake :: n:Int -> g:(Int -> Int) -> l:[Int] -> {map g (take n l) = take n (map g l)} @-} -commMapTake :: Int -> (Int -> Int) -> [Int] -> () -commMapTake _ _ [] = () -commMapTake n _ _ | n <= 0 = () -commMapTake n g (x : xs) = commMapTake (n - 1) g xs - ---- Relational - -mapTake :: Int -> (Int -> Int) -> [Int] -> [Int] -mapTake n g l = map g (take n l) - -takeMap :: Int -> (Int -> Int) -> [Int] -> [Int] -takeMap n g l = take n (map g l) - -{-@ reflect prefix @-} -prefix :: [Int] -> [Int] -> Bool -prefix [] _ = True -prefix (x : xs) (y : ys) | x == y = prefix xs ys -prefix _ _ = False - -{-@ reflect gPrefix @-} -gPrefix :: (Int -> Int) -> [Int] -> [Int] -> Bool -gPrefix g xs ys = prefix (map g xs) ys - -{-@ relational take ~ map :: n:Int -> xs:[Int] -> [Int] - ~ g:(Int -> Int) -> ys:[Int] -> [Int] - ~~ true => xs = ys => - TakeMap.gPrefix g (r1 n xs) (r2 g ys) && - len (r1 n xs) = TakeMap.min n (len xs) && - len (r2 g ys) = len ys @-} - -{-@ relational map ~ take :: g:(Int -> Int) -> xs:[Int] -> [Int] - ~ n:Int -> ys:[Int] -> [Int] - ~~ true => TakeMap.gPrefix g xs ys && n >= len xs => - TakeMap.prefix (r1 g xs) (r2 n ys) && - len (r1 g xs) = len xs && - len (r2 n ys) = TakeMap.min n (len ys) @-} - -{-@ relational mapTake ~ takeMap - :: n1:Int -> g1:(Int -> Int) -> l1:[Int] -> [Int] ~ n2:Int -> g2:(Int -> Int) -> l2:[Int] -> [Int] - ~~ n1 = n2 => g1 = g2 => l1 = l2 => - TakeMap.prefix (r1 n1 g1 l1) (r2 n2 g2 l2) && - len (r1 n1 g1 l1) = TakeMap.min n1 (len l1) && - len (r2 n2 g2 l2) = TakeMap.min n2 (len l2) @-} - ---- Utils - -{-@ reflect min @-} -min :: Int -> Int -> Int -min a b = if a <= b then a else b diff --git a/tests/relational/todo/TakeMapPoly.hs b/tests/relational/todo/TakeMapPoly.hs deleted file mode 100644 index f0255c59fc..0000000000 --- a/tests/relational/todo/TakeMapPoly.hs +++ /dev/null @@ -1,70 +0,0 @@ -module TakeMap where - -import Prelude hiding ( map - , take - ) -import Language.Haskell.Liquid.ProofCombinators - -{-@ reflect map @-} -map :: (a -> b) -> [a] -> [b] -map _ [] = [] -map f (x : xs) = f x : map f xs - -{-@ reflect take @-} -take :: Int -> [a] -> [a] -take n _ | n <= 0 = [] -take _ [] = [] -take n (x : xs) = x : take (n - 1) xs - ---- Unary - -{-@ commMapTake :: n:Int -> g:(a -> b) -> l:[a] -> {map g (take n l) = take n (map g l)} @-} -commMapTake :: Int -> (a -> b) -> [a] -> () -commMapTake _ _ [] = () -commMapTake n _ _ | n <= 0 = () -commMapTake n g (x : xs) = commMapTake (n - 1) g xs - ---- Relational - -mapTake :: Int -> (a -> b) -> [a] -> [b] -mapTake n g l = map g (take n l) - -takeMap :: Int -> (a -> b) -> [a] -> [b] -takeMap n g l = take n (map g l) - -{-@ reflect prefix @-} -prefix :: Eq a => [a] -> [a] -> Bool -prefix [] _ = True -prefix (x : xs) (y : ys) | x == y = prefix xs ys -prefix _ _ = False - -{-@ reflect gPrefix @-} -gPrefix :: Eq b => (a -> b) -> [a] -> [b] -> Bool -gPrefix g xs ys = prefix (map g xs) ys - -{-@ relational take ~ map :: n:Int -> xs:[a] -> [a] - ~ g:(a -> b) -> ys:[a] -> [b] - ~~ true => xs = ys => - TakeMap.gPrefix g (r1 n xs) (r2 g ys) && - len (r1 n xs) = TakeMap.min n (len xs) && - len (r2 g ys) = len ys @-} - -{-@ relational map ~ take :: g:(a -> b) -> xs:[a] -> [b] - ~ n:Int -> ys:[a] -> [a] - ~~ true => TakeMap.gPrefix g xs ys && n >= len xs => - TakeMap.prefix (r1 g xs) (r2 n ys) && - len (r1 g xs) = len xs && - len (r2 n ys) = TakeMap.min n (len ys) @-} - -{-@ relational mapTake ~ takeMap - :: n1:Int -> g1:(a -> b) -> l1:[a] -> [b] ~ n2:Int -> g2:(a -> b) -> l2:[a] -> [b] - ~~ n1 = n2 => g1 = g2 => l1 = l2 => - TakeMap.prefix (r1 n1 g1 l1) (r2 n2 g2 l2) && - len (r1 n1 g1 l1) = TakeMap.min n1 (len l1) && - len (r2 n2 g2 l2) = TakeMap.min n2 (len l2) @-} - ---- Utils - -{-@ reflect min @-} -min :: Ord a => a -> a -> a -min a b = if a <= b then a else b diff --git a/tests/relational/todo/TrdOrdPredNonRel.hs b/tests/relational/todo/TrdOrdPredNonRel.hs deleted file mode 100644 index 3aff57ad6e..0000000000 --- a/tests/relational/todo/TrdOrdPredNonRel.hs +++ /dev/null @@ -1,16 +0,0 @@ -module TrdOrdPredNonRel where - --- {-@ reflect h @-} -h :: Int -> Int -h x = x + 1 - --- {-@ reflect g @-} -g :: (Int -> Int) -> Int -g h = h 0 - -f :: ((Int -> Int) -> Int) -> Int -f g = g h - -{-@ relational f ~ f :: g1:(h1:(x1:Int -> Int) -> Int) -> Int - ~ g2:(h2:(x2:Int -> Int) -> Int) -> Int - ~~ ((x1 < x2 => true) => r1 h1 < r2 h2) => r1 g1 < r2 g2 @-} \ No newline at end of file diff --git a/tests/relational/todo/TyAbsAp.hs b/tests/relational/todo/TyAbsAp.hs deleted file mode 100644 index c703220210..0000000000 --- a/tests/relational/todo/TyAbsAp.hs +++ /dev/null @@ -1,30 +0,0 @@ -module TyAbsAp where - -ap :: (a -> b) -> a -> b -ap f a = f a - -ap''' :: (a -> b) -> a -> b -ap''' f a = f a - -ap' :: (a -> b) -> a -> () -> b -ap' f a _ = f a - -ap'' :: (a -> b) -> a -> c -> b -ap'' f a _ = f a - -{-@ relational ap ~ ap''' :: f:(a -> b) -> x:a -> b ~ g:(a -> b) -> y:a -> b - ~~ f = g => x = y => r1 f x = r2 g y @-} - --- {-@ relational ap' ~ ap'' :: f:(a -> b) -> x:a -> u:() -> b ~ g:(a -> b) -> y:a -> z:c -> b --- ~~ f = g => x = y => true => r1 f x u = r2 g y z @-} - --- {-@ relational ap ~ ap :: f:(a -> b) -> x:a -> b ~ g:(b -> b) -> y:b -> b --- ~~ f = g => x = y => r1 f x = r2 g y @-} - -{- ap id () -} - -apZero :: (b -> b) -> b -> b -apZero = ap - --- {-@ relational ap ~ ap :: f:(a -> b) -> x:a -> b ~ g:(c -> d) -> y:c -> d --- ~~ true => true => r1 f x = r2 g y @-} diff --git a/tests/relational/todo/TyAbsMax.hs b/tests/relational/todo/TyAbsMax.hs deleted file mode 100644 index 82017e6060..0000000000 --- a/tests/relational/todo/TyAbsMax.hs +++ /dev/null @@ -1,16 +0,0 @@ -module TyAbsMax where - -import Prelude hiding ( max ) - -{-@ max :: (Ord a, Eq a) => a -> a -> a @-} -max :: Ord a => a -> a -> a -max a b = if a < b then b else a - -{-@ relational max ~ max :: x1:a -> y1:a -> a ~ x2:a -> y2:a -> a - ~~ true => x1 = x2 => y1 = y2 => r1 x1 y1 = r2 x2 y2 @-} - -{-@ relational max ~ max :: Ord a => x1:a -> y1:a -> a ~ Ord a => x2:a -> y2:a -> a - ~~ true => x1 <= x2 => y1 <= y2 => r1 x1 y1 <= r2 x2 y2 @-} - -{-@ relational max ~ max :: Ord a => x1:a -> y1:a -> a ~ Ord b => x2:b -> y2:b -> b - ~~ true => true => x1 <= y1 && x2 <= y2 => r1 x1 y1 = y1 && r2 x2 y2 = y2 @-} \ No newline at end of file From 0a7460be7152f9c41ca535f040195cbd3df9db33 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 20 Oct 2022 08:45:16 +0200 Subject: [PATCH 002/219] rm haskell.yml --- .github/workflows/haskell.yml | 61 ----------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 .github/workflows/haskell.yml diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml deleted file mode 100644 index ec348d008d..0000000000 --- a/.github/workflows/haskell.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: stack install & run examples - -on: - push: - branches: '**' - pull_request: - branches: '**' - -permissions: - contents: read - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - uses: actions/setup-haskell@v1 - with: - ghc-version: '8.10.3' - enable-stack: true - stack-version: 'latest' - - - name: Cache - uses: actions/cache@v3 - env: - cache-name: cache - with: - path: ~/.stack-work - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('~/stack.yaml') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Install Z3 - run: | - wget https://github.com/Z3Prover/z3/releases/download/z3-4.9.1/z3-4.9.1-x64-glibc-2.31.zip - unzip z3-4.9.1-x64-glibc-2.31.zip - rm -f z3-4.9.1-x64-glibc-2.31.zip - sudo cp z3-4.9.1-x64-glibc-2.31/bin/libz3.a /usr/local/lib - sudo cp z3-4.9.1-x64-glibc-2.31/bin/z3 /usr/local/bin - sudo cp z3-4.9.1-x64-glibc-2.31/include/* /usr/local/include - rm -rf z3-4.9.1-x64-glibc-2.31 - z3 --version - - name: Build - run: stack setup && stack install - - name: Test Relational - run: | - chmod +x ./tests/relational/rtest - ./tests/relational/rtest - shell: bash - - name: Test Non-Relational - run: | - stack --no-terminal --stack-yaml stack.yaml run test-driver - stack --no-terminal --stack-yaml stack.yaml test tests:tasty - stack --no-terminal --stack-yaml stack.yaml test -j1 liquidhaskell:liquidhaskell-parser --flag liquidhaskell:devel - From 943fa07219df5d83920ce3b5048b551aa6be7aef Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Thu, 20 Oct 2022 11:14:16 +0200 Subject: [PATCH 003/219] Update Generate.hs --- src/Language/Haskell/Liquid/Constraint/Generate.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Generate.hs b/src/Language/Haskell/Liquid/Constraint/Generate.hs index e6ca408040..3c55a83633 100644 --- a/src/Language/Haskell/Liquid/Constraint/Generate.hs +++ b/src/Language/Haskell/Liquid/Constraint/Generate.hs @@ -90,8 +90,10 @@ consAct γ cfg info = do let gSrc = giSrc info when (gradual cfg) (mapM_ (addW . WfC γ . val . snd) (gsTySigs sSpc ++ gsAsmSigs sSpc)) γ' <- foldM (consCBTop cfg info) γ (giCbs gSrc) + -- Relational Checking: the following only runs when the list of relational specs is not empty (ψ, γ'') <- foldM (consAssmRel cfg info) ([], γ') (gsAsmRel sSpc ++ gsRelation sSpc) mapM_ (consRelTop cfg info γ'' ψ) (gsRelation sSpc) + -- End: Relational Checking mapM_ (consClass γ) (gsMethods $ gsSig $ giSpec info) hcs <- gets hsCs hws <- gets hsWfs @@ -1486,4 +1488,4 @@ isGenericVar α t = all (\(c, α') -> (α'/=α) || isGenericClass c ) (classCon -- fail msg = panic Nothing msg instance MonadFail Data.Functor.Identity.Identity where - fail msg = panic Nothing msg \ No newline at end of file + fail msg = panic Nothing msg From 738966897fc10108e09fb535b21d0639a96390c7 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 20 Oct 2022 14:37:46 +0200 Subject: [PATCH 004/219] remove comments --- .../Haskell/Liquid/Constraint/Relational.hs | 261 +----------------- 1 file changed, 5 insertions(+), 256 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index 9c43076259..383ddf1a88 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -23,7 +23,6 @@ import Data.Bifunctor ( Bifunctor(bima import qualified Data.HashMap.Strict as M import qualified Data.List as L import Data.String ( IsString(..) ) --- import qualified Debug.Trace as D import qualified Language.Fixpoint.Types as F import qualified Language.Fixpoint.Types.Visitor as F import Language.Haskell.Liquid.Constraint.Env @@ -179,10 +178,7 @@ consRelCheckBind γ ψ b1@(Rec [(f1, e1)]) b2@(Rec [(f2, e2)]) t1 t2 ra rp γ''' <- γ'' `addPreds` traceWhenLoud ("PRECONDITION " ++ F.showpp (vs2xs (F.PAnd fo)) ++ "\n" ++ "ASSUMPTION " ++ F.showpp (vs2xs a)) map vs2xs [F.PAnd fo, a] - -- TODO: replace ho prems with true let p' = unapp rp (zip vs1 vs2) - -- let bs1 = zip vs1 (fst . vargs <$> ts1) - -- let bs2 = zip vs2 (fst . vargs <$> ts2) let ψ' = ho ++ ψ consRelCheck γ''' ψ' (xbody e1'') (xbody e2'') (vs2xs $ ret t1) (vs2xs $ ret t2) (vs2xs $ concl (fromRelExpr p')) where @@ -203,14 +199,13 @@ consRelCheckBind _ _ (Rec [(_, e1)]) (Rec [(_, e2)]) t1 t2 _ rp consRelCheckBind _ _ b1@(Rec _) b2@(Rec _) _ _ _ _ = F.panic $ "consRelCheckBind Rec: multiple binders are not supported " ++ F.showpp (b1, b2) --- Definition of CoreExpr: https://hackage.haskell.org/package/ghc-8.10.1/docs/CoreSyn.html consRelCheck :: CGEnv -> PrEnv -> CoreExpr -> CoreExpr -> SpecType -> SpecType -> F.Expr -> CG () consRelCheck γ ψ (Tick tt e) d t s p = - {- traceChk "Left Tick" e d t s p $ -} consRelCheck (γ `setLocation` Sp.Tick tt) ψ e d t s p + consRelCheck (γ `setLocation` Sp.Tick tt) ψ e d t s p consRelCheck γ ψ e (Tick tt d) t s p = - {- traceChk "Right Tick" e d t s p $ -} consRelCheck (γ `setLocation` Sp.Tick tt) ψ e d t s p + consRelCheck (γ `setLocation` Sp.Tick tt) ψ e d t s p consRelCheck γ ψ l1@(Lam α1 e1) e2 rt1@(RAllT s1 t1 r1) t2 p | Ghc.isTyVar α1 @@ -259,25 +254,7 @@ consRelCheck γ ψ l1@(Let (NonRec x1 d1) e1) l2@(Let (NonRec x2 d2) e2) t1 t2 p let (e1', e2') = subRelCopies e1 x1 e2 x2 γ' <- γ += ("consRelCheck Let L", F.symbol evar1, s1) γ'' <- γ' += ("consRelCheck Let R", F.symbol evar2, s2) - -- let rs2xs = F.mkSubst [(resL, F.EVar $ F.symbol evar1), (resR, F.EVar $ F.symbol evar2)] - -- let (vs1, ts1) = vargs s1 - -- let (vs2, ts2) = vargs s2 - -- let binders = vs1 ++ vs2 ++ concatMap (fst . vargs) ts1 ++ concatMap (fst . vargs) ts2 - -- let qs' = traceWhenLoud ("Let qs: " ++ F.showpp qs) qs - -- let (ho, fo) = L.partition (F.containsVars binders) qs' - -- γ''' <- γ'' `addPreds` map (F.subst rs2xs) fo - -- let ψ' = ψ ++ map (\q -> toRel (evar1, evar2, s1, s2, q)) ho consRelCheck γ'' ψ e1' e2' t1 t2 p - -- where - -- -- unapp = L.foldl' (\p (v1, v2) -> unapplyRelArgs v1 v2 p) - -- toRel (f1, f2, t1', t2', q) = - -- let (vs1, ts1) = vargs t1' - -- in let (vs2, ts2) = vargs t2' - -- in let bs1 = zip vs1 (fst . vargs <$> ts1) - -- in let bs2 = zip vs2 (fst . vargs <$> ts2) - -- -- TODO: add symmetric RelPred - -- in let rp = RelPred f1 f2 bs1 bs2 $ ERBasic q - -- in traceWhenLoud ("consRelCheck toRel: " ++ F.showpp (f1, f2, bs1, bs2, q)) rp consRelCheck γ ψ l1@(Let (Rec []) e1) l2@(Let (Rec []) e2) t1 t2 p @@ -291,28 +268,8 @@ consRelCheck γ ψ l1@(Let (Rec ((x1, d1):bs1)) e1) l2@(Let (Rec ((x2, d2):bs2)) let (e1', e2') = subRelCopies e1 x1 e2 x2 γ' <- γ += ("consRelCheck Let L", F.symbol evar1, s1) γ'' <- γ' += ("consRelCheck Let R", F.symbol evar2, s2) - -- let rs2xs = F.mkSubst [(resL, F.EVar $ F.symbol evar1), (resR, F.EVar $ F.symbol evar2)] - -- let (vs1, ts1) = vargs s1 - -- let (vs2, ts2) = vargs s2 - -- let binders = vs1 ++ vs2 ++ concatMap (fst . vargs) ts1 ++ concatMap (fst . vargs) ts2 - -- γ''' <- γ'' `addPreds` map (F.subst rs2xs) (filter (not . F.containsVars binders) qs) consRelCheck γ'' ψ (Let (Rec bs1) e1') (Let (Rec bs2) e2') t1 t2 p -{- consRelCheck γ ψ c1@(Case e1 x1 _ alts1) c2@(Case e2 x2 _ alts2) t1 t2 p - | Just alts <- unifyAlts x1 x2 alts1 alts2 = - traceChk "Case Sync " c1 c2 t1 t2 p $ do - (s1, s2, _) <- consRelSynth γ ψ e1 e2 - γ' <- γ += ("consRelCheck Case Sync L", x1', s1) - γ'' <- γ' += ("consRelCheck Case Sync R", x2', s2) - forM_ (ctors alts) $ consSameCtors γ'' ψ x1' x2' s1 s2 (nonDefaults alts) - forM_ alts $ consRelCheckAltSync γ'' ψ t1 t2 p x1' x2' s1 s2 - where - nonDefaults = filter (/= DEFAULT) . ctors - ctors = map (\(c, _, _, _, _) -> c) - (evar1, evar2) = mkRelCopies x1 x2 - x1' = F.symbol evar1 - x2' = F.symbol evar2 -} - consRelCheck γ ψ c1@(Case e1 x1 _ alts1) e2 t1 t2 p = traceChk "Case Async L" c1 e2 t1 t2 p $ do s1 <- consUnarySynth γ e1 @@ -337,16 +294,6 @@ consRelCheck γ ψ e d t1 t2 p = addC (SubC γ s1 t1) ("consRelCheck (Synth): s1 = " ++ F.showpp s1 ++ " t1 = " ++ F.showpp t1) addC (SubC γ s2 t2) ("consRelCheck (Synth): s2 = " ++ F.showpp s2 ++ " t2 = " ++ F.showpp t2) --- consSameCtors :: CGEnv -> PrEnv -> F.Symbol -> F.Symbol -> SpecType -> SpecType -> [AltCon] -> AltCon -> CG () --- consSameCtors γ _ x1 x2 _ _ _ (DataAlt c) | isBoolDataCon c --- = entl γ (F.PIff (F.EVar x1) (F.EVar x2)) "consSameCtors DataAlt Bool" --- consSameCtors γ _ x1 x2 _ _ _ (DataAlt c) --- = entl γ (F.PIff (isCtor c $ F.EVar x1) (isCtor c $ F.EVar x2)) "consSameCtors DataAlt" --- consSameCtors _ _ _ _ _ _ _ (LitAlt _) --- = F.panic "consSameCtors undefined for literals" --- consSameCtors _ _ _ _ _ _ _ DEFAULT --- = F.panic "consSameCtors undefined for default" - consExtAltEnv :: CGEnv -> F.Symbol -> SpecType -> AltCon -> [Var] -> CoreExpr -> String -> CG (CGEnv, CoreExpr) consExtAltEnv γ x s c bs e suf = do ct <- ctorTy γ c s @@ -364,13 +311,6 @@ consRelCheckAltAsyncR γ ψ t1 t2 p e1 x2 s2 (c, bs2, e2) = do (γ', e2') <- consExtAltEnv γ x2 s2 c bs2 e2 relSuffixR consRelCheck γ' ψ e1 e2' t1 t2 p --- consRelCheckAltSync :: CGEnv -> PrEnv -> SpecType -> SpecType -> F.Expr -> --- F.Symbol -> F.Symbol -> SpecType -> SpecType -> RelAlt -> CG () --- consRelCheckAltSync γ ψ t1 t2 p x1 x2 s1 s2 (c, bs1, bs2, e1, e2) = do --- (γ', e1') <- consExtAltEnv γ x1 s1 c bs1 e1 relSuffixL --- (γ'', e2') <- consExtAltEnv γ' x2 s2 c bs2 e2 relSuffixR --- consRelCheck γ'' ψ e1' e2' t1 t2 p - ctorTy :: CGEnv -> AltCon -> SpecType -> CG SpecType ctorTy γ (DataAlt c) (RApp _ ts _ _) | Just ct <- mbct = refreshTy $ ct `instantiateTys` ts @@ -389,7 +329,6 @@ unapply γ y yt (z : zs) (RFun x _ s t _) e suffix = do z' = mkCopyWithSuffix suffix z evar = F.symbol z' e' = subVarAndTy z z' e --- unapply γ y yt l@(_ : _) (RAllP p ty) e suffix = unapply γ y yt l (forgetRAllP p ty) e suffix unapply _ _ _ (_ : _) t _ _ = F.panic $ "can't unapply type " ++ F.showpp t unapply γ y yt [] t e _ = do let yt' = t `F.meet` yt @@ -409,10 +348,10 @@ instantiateTys = L.foldl' go consRelSynth :: CGEnv -> PrEnv -> CoreExpr -> CoreExpr -> CG (SpecType, SpecType, [F.Expr]) consRelSynth γ ψ (Tick tt e) d = - {- traceSyn "Left Tick" e d -} consRelSynth (γ `setLocation` Sp.Tick tt) ψ e d + consRelSynth (γ `setLocation` Sp.Tick tt) ψ e d consRelSynth γ ψ e (Tick tt d) = - {- traceSyn "Right Tick" e d -} consRelSynth (γ `setLocation` Sp.Tick tt) ψ e d + consRelSynth (γ `setLocation` Sp.Tick tt) ψ e d consRelSynth γ ψ a1@(App e1 d1) e2 | Type t1 <- GM.unTickExpr d1 = traceSyn "App Ty L" a1 e2 $ do @@ -431,7 +370,6 @@ consRelSynth γ ψ e1 a2@(App e2 d2) | Type t2 <- GM.unTickExpr d2 = consRelSynth γ ψ a1@(App e1 d1) a2@(App e2 d2) = traceSyn "App Exp Exp" a1 a2 $ do (ft1, ft2, fps) <- consRelSynth γ ψ e1 e2 (t1, t2, ps) <- consRelSynthApp γ ψ ft1 ft2 fps d1 d2 - -- qs <- instantiateApp a1 a2 γ ψ return (t1, t2, ps) consRelSynth γ ψ e d = traceSyn "Unary" e d $ do @@ -461,10 +399,9 @@ consRelSynthApp :: CGEnv -> PrEnv -> SpecType -> SpecType -> consRelSynthApp γ ψ ft1 ft2 ps e1 (Tick _ e2) = consRelSynthApp γ ψ ft1 ft2 ps e1 e2 consRelSynthApp γ ψ ft1 ft2 ps (Tick t1 e1) e2 = - -- TODO: create span consRelSynthApp (γ `setLocation` Sp.Tick t1) ψ ft1 ft2 ps e1 e2 -consRelSynthApp γ ψ ft1@(RFun v1 _ s1{- @RFun{} -} t1 r1) ft2@(RFun v2 _ s2{- @RFun{} -} t2 r2) ps@[F.PImp q p] d1@(Var x1) d2@(Var x2) +consRelSynthApp γ ψ ft1@(RFun v1 _ s1 t1 r1) ft2@(RFun v2 _ s2 t2 r2) ps@[F.PImp q p] d1@(Var x1) d2@(Var x2) = traceSynApp ft1 ft2 ps d1 d2 $ do entlFunRefts γ r1 r2 "consRelSynthApp HO" let qsubst = F.subst $ F.mkSubst [(v1, F.EVar resL), (v2, F.EVar resR)] @@ -483,16 +420,6 @@ consRelSynthApp γ ψ ft1@(RFun v1 _ s1 t1 r1) ft2@(RFun v2 _ s2 t2 r2) ps@[] d1 return (subst t1, subst t2, map subst qs) consRelSynthApp _ _ RFun{} RFun{} ps d1@(Var _) d2@(Var _) = F.panic $ "consRelSynthApp: multiple rel sigs not supported " ++ F.showpp (ps, d1, d2) --- do --- entlFunRefts γ r1 r2 "consRelSynthApp FO" --- consUnaryCheck γ d1 s1 --- consUnaryCheck γ d2 s2 --- let qsubst = F.subst $ F.mkSubst [(v1, F.EVar resL), (v2, F.EVar resR)] --- (_, _, qs) <- consRelSynth γ ψ d1 d2 --- let subst = --- F.subst $ F.mkSubst --- [(v1, F.EVar $ F.symbol x1), (v2, F.EVar $ F.symbol x2)] --- return (subst t1, subst t2, map (subst . unapplyRelArgs v1 v2) (qsubst qs ++ ps)) consRelSynthApp _ _ RFun{} RFun{} _ d1 d2 = F.panic $ "consRelSynthApp: expected application to variables, got" ++ F.showpp (d1, d2) consRelSynthApp _ _ t1 t2 p d1 d2 = @@ -541,7 +468,6 @@ consUnarySynth γ e@(Case _ _ _ alts) = traceUSyn "Case" e $ do t <- freshTyType (typeclass (getConfig γ)) (caseKVKind alts) e $ Ghc.exprType e addW $ WfC γ t - -- consUnaryCheck γ e t return $ removeAbsRef t consUnarySynth _ e@(Cast _ _) = F.panic $ "consUnarySynth is undefined for Cast " ++ F.showpp e consUnarySynth _ e@(Type _) = F.panic $ "consUnarySynth is undefined for Type " ++ F.showpp e @@ -562,8 +488,6 @@ base _ = False selfifyExpr :: SpecType -> F.Expr -> Maybe SpecType selfifyExpr (RFun v i s t r) f = (\t' -> RFun v i s t' r) <$> selfifyExpr t (F.EApp f (F.EVar v)) --- selfifyExpr (RAllT α t r) f = (\t -> RAllT α t r) <$> selfifyExpr t f --- selfifyExpr (RAllT α t r) f = (\t -> RAllT α t r) <$> selfifyExpr t (F.ETApp f (F.FVar 0)) selfifyExpr t e | base t = Just $ t `strengthen` eq e where eq = uTop . F.exprReft selfifyExpr _ _ = Nothing @@ -650,17 +574,6 @@ consRelSub _ t1@RAllT {} t2@RAllT {} _ _ = F.panic $ "consRelSub is undefined fo consRelSub _ t1@RImpF {} t2@RImpF {} _ _ = F.panic $ "consRelSub is undefined for RImpF " ++ show (t1, t2) consRelSub _ t1 t2 _ _ = F.panic $ "consRelSub is undefined for different types " ++ show (t1, t2) --------------------------------------------------------------- --- Predicate Well-Formedness --------------------------------- --------------------------------------------------------------- - --- wfTruth :: SpecType -> SpecType -> F.Expr --- wfTruth (RAllT _ t1 _) t2 = wfTruth t1 t2 --- wfTruth t1 (RAllT _ t2 _) = wfTruth t1 t2 --- wfTruth (RFun _ _ _ t1 _) (RFun _ _ _ t2 _) = --- F.PImp F.PTrue $ wfTruth t1 t2 --- wfTruth _ _ = F.PTrue - -------------------------------------------------------------- -- Helper Definitions ---------------------------------------- -------------------------------------------------------------- @@ -676,13 +589,11 @@ partitionArgs :: [Var] -> [Var] -> [SpecType] -> [SpecType] -> [F.Expr] -> (PrEn partitionArgs xs1 xs2 ts1 ts2 qs = (map toRel ho, map toUnary fo) where (ho, fo) = L.partition (isFuncPred . toUnary) (zip5 xs1 xs2 ts1 ts2 qs) - -- unapp = L.foldl' (\p (v1, v2) -> unapplyRelArgs v1 v2 p) toRel (f1, f2, t1, t2, q) = let (vs1, ts1') = vargs t1 in let (vs2, ts2') = vargs t2 in let bs1 = zip vs1 (fst . vargs <$> ts1') in let bs2 = zip vs2 (fst . vargs <$> ts2') - -- TODO: add symmetric RelPred in let rp = RelPred f1 f2 bs1 bs2 $ ERBasic q in traceWhenLoud ("partitionArgs toRel: " ++ F.showpp (f1, f2, bs1, bs2, q)) rp toUnary (_, _, _, _, q) = q @@ -694,18 +605,6 @@ unRAllT t msg = F.panic $ msg ++ ": expected RAllT, got: " ++ F.showpp t forgetRAllP :: PVU RTyCon RTyVar -> SpecType -> SpecType forgetRAllP _ t = t --- isCtor :: Ghc.DataCon -> F.Expr -> F.Expr --- isCtor d = F.EApp (F.EVar $ makeDataConChecker d) - --- isAltCon :: AltCon -> F.Symbol -> F.Expr --- isAltCon (DataAlt c) x | c == Ghc.trueDataCon = F.EVar x --- isAltCon (DataAlt c) x | c == Ghc.falseDataCon = F.PNot $ F.EVar x --- isAltCon (DataAlt c) x = isCtor c (F.EVar x) --- isAltCon _ _ = F.PTrue - --- isBoolDataCon :: DataCon -> Bool --- isBoolDataCon c = c == Ghc.trueDataCon || c == Ghc.falseDataCon - args :: CoreExpr -> CoreExpr -> SpecType -> SpecType -> F.Expr -> Maybe ([Var], [Var], [F.Symbol], [F.Symbol], [SpecType], [SpecType], [F.Expr]) args e1 e2 t1 t2 ps @@ -746,102 +645,10 @@ prems :: F.Expr -> [F.Expr] prems (F.PImp q p) = q : prems p prems _ = [] --- conclRel :: RelExpr -> F.Expr --- conclRel (ERBasic e ) = e --- conclRel (ERChecked _ b) = conclRel b --- conclRel (ERUnChecked _ b) = conclRel b - concl :: F.Expr -> F.Expr concl (F.PImp _ p) = concl p concl p = p --- unpackApp :: CoreExpr -> Maybe [Var] --- unpackApp = fmap reverse . unpack' . GM.unTickExpr --- where --- unpack' :: CoreExpr -> Maybe [Var] --- unpack' (Tick _ e) = unpack' e --- unpack' (Var f ) = Just [f] --- unpack' (App e (Var α)) | Ghc.isTyVar α = unpack' e --- unpack' (App e (Type _)) = unpack' e --- unpack' (App e (Var x)) = (x :) <$> unpack' e --- unpack' e = traceWhenLoud ("can't unpackApp APP " ++ show e) Nothing - --- instantiateApp :: CoreExpr -> CoreExpr -> CGEnv -> PrEnv -> CG [F.Expr] --- instantiateApp e1 e2 γ ψ = traceWhenLoud --- ("instantiateApp " ++ F.showpp e1 ++ " " ++ F.showpp e2 ++ " " ++ (concatMap ((++ "\n"). show) ψ)) --- concatMapM (inst (unpackApp e1) (unpackApp e2)) ψ --- where --- inst :: Maybe [Var] -> Maybe [Var] -> RelPred -> CG [F.Expr] --- inst (Just (f1:xs1)) (Just (f2:xs2)) qpr --- | fun1 qpr == f1 --- , fun2 qpr == f2 --- , length (args1 qpr) == length xs1 --- , length (args2 qpr) == length xs2 --- = do --- p <- traceWhenLoud ("instantiateApp qpr pred: " ++ F.showpp (fromRelExpr (prop qpr))) --- consTotalHOPred xs1 xs2 (args1 qpr) (args2 qpr) (prop qpr) [] --- return $ --- traceWhenLoud ("instantiateApp: " ++ F.showpp p) --- [p] --- inst _ _ _ = return [] --- consTotalHOPred :: [Var] -> [Var] -> [(F.Symbol, [F.Symbol])] -> [(F.Symbol, [F.Symbol])] -> RelExpr -> [F.Expr] -> CG F.Expr --- consTotalHOPred [] [] [] [] rps qs = return $ if null p then F.PTrue else L.foldr1 F.PImp p --- where --- ps = fromRelExpr rps --- p = reverse qs ++ (prems ps ++ [concl ps]) --- consTotalHOPred (x1:xs1) (x2:xs2) ((b1, bs1@(_:_)):vs1) ((b2, bs2@(_:_)):vs2) ps' qs --- | Just (q, ps) <- traceWhenLoud ("consTotalHOPred ps' (chk) " ++ F.showpp (fromRelExpr ps')) unImp ps' = do --- (tf1, tf2, _) <- consRelSynth γ ψ (Var x1) (Var x2) --- case (tf1, tf2) of --- (RFun x1' _ _ _ _, RFun x2' _ _ _ _) -> do --- fqs <- instantiateApp (App (Var x1) (Var evar1)) (App (Var x2) (Var evar2)) γ ψ --- let fqsub = F.mkSubst [(F.symbol evar1, F.EVar x1'), (F.symbol evar2, F.EVar x2')] --- let bs2args = zip (bs1 ++ bs2) (F.EVar <$> fst (vargs tf1) ++ fst (vargs tf2)) --- let qsub = F.mkSubst (traceWhenLoud ("subst qpr prem " ++ show bs2args) bs2args) --- let p = F.subst fqsub $ F.PAnd (unapplyRelArgs (F.symbol x1) (F.symbol x2) <$> fqs) --- let q' = F.subst qsub q --- consRelSub γ tf1 tf2 (traceWhenLoud ("consTotalHOPred fqs for (" ++ F.showpp evar1 ++ " " ++ F.showpp evar2 ++ "): " --- ++ F.showpp fqs ++ " consTotalHOPred p: " ++ F.showpp p) p) --- (traceWhenLoud ("consTotalHOPred q: " ++ F.showpp q') q') --- let bs2fs = F.mkSubst [(b1, F.EVar (F.symbol x1)), (b2, F.EVar (F.symbol x2))] --- consTotalHOPred xs1 xs2 vs1 vs2 --- (substR bs2fs $ unapplyRelArgsR (F.symbol x1) (F.symbol x2) ps) qs --- _ -> F.panic "consTotalHOPred: bs " --- where --- (evar1, evar2) = mkRelCopies x1 x2 --- -- f1 = symbolType γ x1 "consTotalHOPred funArg L" --- -- f2 = symbolType γ x2 "consTotalHOPred funArg R" --- consTotalHOPred (x1:xs1) (x2:xs2) ((b1, _):vs1) ((b2, _):vs2) (ERChecked q ps) qs --- = do --- (tf1, tf2, _) <- consRelSynth γ ψ (Var x1) (Var x2) --- fqs <- instantiateApp (Var x1) (Var x2) γ ψ --- let bs2rs = [(b1, F.EVar resL), (b2, F.EVar resR)] --- let qsub = F.mkSubst bs2rs --- let p = F.PAnd (unapplyRelArgs (F.symbol x1) (F.symbol x2) <$> fqs) --- let q' = F.subst qsub q --- consRelSub γ tf1 tf2 (traceWhenLoud ("consTotalHOPred fqs: " ++ F.showpp fqs ++ " consTotalHOPred p: " ++ F.showpp p) p) --- (traceWhenLoud ("consTotalHOPred q: " ++ F.showpp q') q') --- let bs2args = F.mkSubst [(b1, F.EVar (F.symbol x1)), (b2, F.EVar (F.symbol x2))] --- consTotalHOPred xs1 xs2 vs1 vs2 --- (substR bs2args $ unapplyRelArgsR (F.symbol x1) (F.symbol x2) ps) qs --- consTotalHOPred (x1:xs1) (x2:xs2) ((v1, _):vs1) ((v2, _):vs2) (ERUnChecked q ps) qs --- = consTotalHOPred xs1 xs2 vs1 vs2 (substR sb $ unapplyRelArgsR (F.symbol x1) (F.symbol x2) ps) (F.subst sb <$> q : qs) --- where --- sb = F.mkSubst [(v1, F.EVar $ F.symbol x1), (v2, F.EVar $ F.symbol x2)] --- -- TODO: change the parser to prioritise ERUnChecked q ps --- consTotalHOPred (x1:xs1) (x2:xs2) ((v1, _):vs1) ((v2, _):vs2) (ERBasic (F.PImp q ps)) qs --- = consTotalHOPred xs1 xs2 vs1 vs2 (substR sb $ unapplyRelArgsR (F.symbol x1) (F.symbol x2) (ERBasic ps)) (F.subst sb <$> q : qs) --- where --- sb = F.mkSubst [(v1, F.EVar $ F.symbol x1), (v2, F.EVar $ F.symbol x2)] --- consTotalHOPred xs1 xs2 vs1 vs2 ps qs = F.panic $ "consTotalHOPred: number of premises should be >= length of arg list" ++ --- F.showpp xs1 ++ " " ++ F.showpp xs2 ++ " " ++ F.showpp vs1 ++ " " ++ F.showpp vs2 ++ --- " " ++ F.showpp (fromRelExpr ps) ++ " " ++ F.showpp qs - --- substR :: F.Subst -> RelExpr -> RelExpr --- substR sb (ERChecked p rp) = ERChecked (F.subst sb p) (substR sb rp) --- substR sb (ERUnChecked p rp) = ERUnChecked (F.subst sb p) (substR sb rp) --- substR sb (ERBasic p) = ERBasic (F.subst sb p) - extendWithTyVar :: CGEnv -> TyVar -> CG CGEnv extendWithTyVar γ a | isValKind (Ghc.tyVarKind a) @@ -849,15 +656,6 @@ extendWithTyVar γ a | otherwise = return γ --- unifyAlts :: CoreBndr -> CoreBndr -> [Alt CoreBndr] -> [Alt CoreBndr] -> Maybe [RelAlt] --- unifyAlts x1 x2 alts1 alts2 = mapM subRelCopiesAlts (zip alts1 alts2) --- where --- subRelCopiesAlts ((a1, bs1, e1), (a2, bs2, e2)) --- | a1 /= a2 = Nothing --- | otherwise = let (e1', e2') = L.foldl' sb (subRelCopies e1 x1 e2 x2) (zip bs1 bs2) --- in Just (a1, mkLCopies bs1, mkRCopies bs2, e1', e2') --- sb (e1, e2) (x1', x2') = subRelCopies e1 x1' e2 x2' - matchFunArgs :: SpecType -> SpecType -> F.Symbol -> F.Expr matchFunArgs (RAllT _ t1 _) t2 x = matchFunArgs t1 t2 x matchFunArgs t1 (RAllT _ t2 _) x = matchFunArgs t1 t2 x @@ -888,12 +686,6 @@ subVarAndTy x v = subTy (M.singleton x $ TyVarTy v) . sub (M.singleton x $ Var v mkRelCopies :: Var -> Var -> (Var, Var) mkRelCopies x1 x2 = (mkCopyWithSuffix relSuffixL x1, mkCopyWithSuffix relSuffixR x2) --- mkLCopies :: [Var] -> [Var] --- mkLCopies = (mkCopyWithSuffix relSuffixL <$>) - --- mkRCopies :: [Var] -> [Var] --- mkRCopies = (mkCopyWithSuffix relSuffixR <$>) - mkCopyWithName :: String -> Var -> Var mkCopyWithName s v = Ghc.setVarName v $ Ghc.mkSystemName (Ghc.getUnique v) (Ghc.mkVarOcc s) @@ -953,53 +745,10 @@ fromRelExpr (ERBasic e) = e fromRelExpr (ERChecked a b) = F.PImp a (fromRelExpr b) fromRelExpr (ERUnChecked a b) = F.PImp a (fromRelExpr b) --- unImp :: RelExpr -> Maybe (F.Expr, RelExpr) --- unImp (ERBasic (F.PImp a b)) = Just (a, ERBasic b) --- unImp (ERChecked a b) = Just (a, b) --- unImp (ERUnChecked a b) = Just (a, b) --- unImp _ = Nothing - --- toBasic :: RelExpr -> Maybe F.Expr --- toBasic (ERBasic e) = Just e --- toBasic (ERChecked _ _) = Nothing --- toBasic (ERUnChecked a b) = F.PImp a <$> toBasic b - --- toBasicOr :: F.Expr -> RelExpr -> F.Expr --- toBasicOr t = MB.fromMaybe t . toBasic - - -------------------------------------------------------------- -- Debug ----------------------------------------------------- -------------------------------------------------------------- --- showType :: SpecType -> String --- showType (RAllP _ t ) = "RAllP " ++ showType t --- showType (RAllT _ t _) = "RAllT " ++ showType t --- showType (RImpF _ _ t t' _) = --- "RImpF(" ++ showType t ++ ", " ++ showType t' ++ ") " --- showType (RFun _ _ t t' _) = "RFun(" ++ showType t ++ ", " ++ showType t' ++ ") " --- showType (RAllE _ t t' ) = "RAllE(" ++ showType t ++ ", " ++ showType t' ++ ") " --- showType (REx _ t t' ) = "REx(" ++ showType t ++ ", " ++ showType t' ++ ") " --- showType (RAppTy t t' _) = --- "RAppTy(" ++ showType t ++ ", " ++ showType t' ++ ") " --- showType (RApp _ ts _ _) = "RApp" ++ show (showType <$> ts) --- showType (RRTy xts _ _ t) = --- "RRTy(" --- ++ show (map (\(_, s) -> showType s) xts) --- ++ ", " --- ++ showType t --- ++ ") " --- showType v@(RVar _ _ ) = "RVar " ++ F.showpp v --- showType v@(RExprArg _) = "RExprArg " ++ F.showpp v --- showType v@(RHole _) = "RHole" ++ F.showpp v - --- traceUnapply :: (PPrint x1, PPrint x2, PPrint e1, PPrint e2) => x1 -> x2 -> e1 -> e2 -> e2 --- traceUnapply x1 x2 e1 e2 = traceWhenLoud ("Unapply\n" --- ++ "x1: " ++ F.showpp x1 ++ "\n\n" --- ++ "x2: " ++ F.showpp x2 ++ "\n\n" --- ++ "e1: " ++ F.showpp e1 ++ "\n\n" --- ++ "e2: " ++ F.showpp e2) e2 - traceSub :: (PPrint t, PPrint s, PPrint p, PPrint q) => String -> t -> s -> p -> q -> a -> a traceSub msg t s p q = traceWhenLoud (msg ++ " RelSub\n" From 5b9e8e2f4f71489bfc16f222dbbc5dad929d3801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Thu, 20 Oct 2022 17:18:16 -0300 Subject: [PATCH 005/219] Remove mention of obsolete option --smtsolver=z3mem --- docs/mkDocs/docs/options.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/mkDocs/docs/options.md b/docs/mkDocs/docs/options.md index 6b725260f9..663796ce02 100644 --- a/docs/mkDocs/docs/options.md +++ b/docs/mkDocs/docs/options.md @@ -192,11 +192,6 @@ Currently, LiquidHaskell supports To use these solvers, you must install the corresponding binaries from the above web-pages into your `PATH`. -You can also build and link against the Z3 API (faster but requires more -dependencies). If you do so, you can use that interface with: - - $ liquid --smtsolver=z3mem foo.hs - ## Short Error Messages **Options:** `short-errors` From 3a60248ce437b7d4ce9d3399db04421240a8add8 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Mon, 24 Oct 2022 16:24:17 +0200 Subject: [PATCH 006/219] update FP --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index f6af0464c0..e378d2ee86 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit f6af0464c0b2ccd908075d5254864dbcf73f8e7a +Subproject commit e378d2ee8656da929e41c2d593a88a81e9620391 From cd7d9c71876804516d8bc4f2792dd1dd56e0537d Mon Sep 17 00:00:00 2001 From: PLR <51248199+plredmond@users.noreply.github.com> Date: Fri, 11 Nov 2022 10:16:52 -0800 Subject: [PATCH 007/219] remove nix flake --- flake.lock | 68 --------------------------- flake.nix | 131 ----------------------------------------------------- 2 files changed, 199 deletions(-) delete mode 100644 flake.lock delete mode 100644 flake.nix diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 8ead923564..0000000000 --- a/flake.lock +++ /dev/null @@ -1,68 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "locked": { - "lastModified": 1652776076, - "narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "liquid-fixpoint": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1653693908, - "narHash": "sha256-IYrQB9M/XdDaDzQ1576iUNvbehJ4fUlKvPtg5l/Z5xU=", - "owner": "plredmond", - "repo": "liquid-fixpoint", - "rev": "8ce7686045c49b25b46ea3024e9c0dd2979d8488", - "type": "github" - }, - "original": { - "owner": "plredmond", - "ref": "nix-flake", - "repo": "liquid-fixpoint", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1653504306, - "narHash": "sha256-bqjEskV+/tqOQqSEaCu4e6uWZ0F7ekBiMR16xpn4V0k=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "6efc186e6079ff3f328a2497ff3d36741ac60f6e", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-22.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "liquid-fixpoint": "liquid-fixpoint", - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 0d5bffe08b..0000000000 --- a/flake.nix +++ /dev/null @@ -1,131 +0,0 @@ -{ - - description = "LiquidHaskell packages"; - - inputs = { - nixpkgs.url = github:NixOS/nixpkgs/nixos-22.05; - flake-utils.url = github:numtide/flake-utils; - - liquid-fixpoint.url = github:plredmond/liquid-fixpoint/nix-flake; # TODO change to official repo after merge - liquid-fixpoint.inputs.nixpkgs.follows = "nixpkgs"; - liquid-fixpoint.inputs.flake-utils.follows = "flake-utils"; - }; - - outputs = { self, nixpkgs, flake-utils, liquid-fixpoint }: - let - composeOverlays = funs: builtins.foldl' nixpkgs.lib.composeExtensions (self: super: { }) funs; - haskellOverlay = compiler: final: prev: new: - let new-overrides = new.overrides or (a: b: { }); in - { - haskell = prev.haskell // { - packages = prev.haskell.packages // { - ${compiler} = prev.haskell.packages.${compiler}.override - (old: old // new // { - overrides = self: super: old.overrides self super // new-overrides self super; - }); - }; - }; - }; - haskellPackagesOverlay = compiler: final: prev: cur-packages-overlay: - haskellOverlay compiler final prev { overrides = cur-packages-overlay; }; - ghc = "ghc8107"; # Based on https://github.com/ucsd-progsys/liquid-fixpoint/blob/develop/stack.yaml#L3 - beComponent = pkgs: pkg: pkgs.haskell.lib.overrideCabal pkg (old: { - enableLibraryProfiling = false; - buildTools = (old.buildTools or [ ]) ++ [ pkgs.z3 ]; - }); - mkOutputs = system: - let - # do not use when defining the overlays - pkgs = import nixpkgs { - inherit system; - overlays = [ self.overlay.${system} ]; - }; - in - { - - packages = { - # Group 1: LH without tests - liquidhaskell = pkgs.haskell.packages.${ghc}.liquidhaskell; - # Group 2: Depends on LH - liquid-ghc-prim = pkgs.haskell.packages.${ghc}.liquid-ghc-prim; - # Group 3: Depends on liquid-ghc-prim - liquid-base = pkgs.haskell.packages.${ghc}.liquid-base; - # Group 4: Depends on liquid-base - liquid-bytestring = pkgs.haskell.packages.${ghc}.liquid-bytestring; - liquid-containers = pkgs.haskell.packages.${ghc}.liquid-containers; - liquid-parallel = pkgs.haskell.packages.${ghc}.liquid-parallel; - liquid-platform = pkgs.haskell.packages.${ghc}.liquid-platform; - liquid-prelude = pkgs.haskell.packages.${ghc}.liquid-prelude; - liquid-vector = pkgs.haskell.packages.${ghc}.liquid-vector; - # Group 5: Depends on all of the above - liquidhaskell_with_tests = pkgs.haskell.packages.${ghc}.liquidhaskell_with_tests; - }; - - defaultPackage = pkgs.haskell.packages.${ghc}.liquidhaskell_with_tests; - - devShell = self.defaultPackage.${system}.env; - - overlay = composeOverlays [ - liquid-fixpoint.overlay.${system} - self.overlays.${system}.updateAllCabalHashes - self.overlays.${system}.addLiquidHaskellWithoutTests - self.overlays.${system}.addLiquidGHCPrim - self.overlays.${system}.addLiquidBase - self.overlays.${system}.addLiquidHaskellPackages - self.overlays.${system}.addLiquidHaskellWithTests - ]; - - overlays = { - updateAllCabalHashes = final: prev: - { - all-cabal-hashes = final.fetchurl { - # fetch latest cabal hashes https://github.com/commercialhaskell/all-cabal-hashes/commits/hackage as of Fri May 27 06:40:19 PM UTC 2022 - url = "https://github.com/commercialhaskell/all-cabal-hashes/archive/91cbef8524376834839ea2814010a0258a06e37e.tar.gz"; - sha256 = "01h8cd2b1w4060dyyh4zz604gpjyzhvvc0mb1aj18b1z2bcgfakj"; - }; - }; - addLiquidHaskellWithoutTests = final: prev: haskellPackagesOverlay ghc final prev (selfH: superH: - let callCabal2nix = final.haskell.packages.${ghc}.callCabal2nix; in - with final.haskell.lib; { - liquidhaskell = - let src = final.nix-gitignore.gitignoreSource [ ".swp" "*.nix" "result" "liquid-*" ] ./.; - in - dontHaddock # src/Language/Haskell/Liquid/Types/RefType.hs:651:3: error: parse error on input ‘-- | _meetable t1 t2’ - (doJailbreak # LH requires slightly old versions of recursion-schemes and optparse-applicative - (dontCheck (beComponent final (callCabal2nix "liquidhaskell" src { })))); - }); - addLiquidGHCPrim = final: prev: haskellPackagesOverlay ghc final prev (selfH: superH: - let callCabal2nix = final.haskell.packages.${ghc}.callCabal2nix; in - with final.haskell.lib; { - liquid-ghc-prim = dontHaddock (beComponent final (callCabal2nix "liquid-ghc-prim" ./liquid-ghc-prim { })); - }); - addLiquidBase = final: prev: haskellPackagesOverlay ghc final prev (selfH: superH: - let callCabal2nix = final.haskell.packages.${ghc}.callCabal2nix; in - with final.haskell.lib; { - liquid-base = dontHaddock (beComponent final (callCabal2nix "liquid-base" ./liquid-base { })); - }); - addLiquidHaskellPackages = final: prev: haskellPackagesOverlay ghc final prev (selfH: superH: - let callCabal2nix = final.haskell.packages.${ghc}.callCabal2nix; in - with final.haskell.lib; { - liquid-bytestring = (beComponent final (callCabal2nix "liquid-bytestring" ./liquid-bytestring { })); - liquid-containers = (beComponent final (callCabal2nix "liquid-containers" ./liquid-containers { })); - liquid-parallel = (beComponent final (callCabal2nix "liquid-parallel" ./liquid-parallel { })); - liquid-platform = (beComponent final (callCabal2nix "liquid-platform" ./liquid-platform { })); - liquid-prelude = (beComponent final (callCabal2nix "liquid-prelude" ./liquid-prelude { })); - liquid-vector = (beComponent final (callCabal2nix "liquid-vector" ./liquid-vector { })); - }); - addLiquidHaskellWithTests = final: prev: haskellPackagesOverlay ghc final prev (selfH: superH: - with final.haskell.lib; { - liquidhaskell_with_tests = overrideCabal selfH.liquidhaskell (old: { - doCheck = true; # change the value set above - testDepends = old.testDepends or [ ] ++ [ final.hostname ]; - testHaskellDepends = old.testHaskellDepends ++ builtins.attrValues (builtins.removeAttrs self.packages.${system} [ "liquidhaskell_with_tests" ]); - preCheck = ''export TASTY_LIQUID_RUNNER="liquidhaskell -v0"''; - }); - }); - }; - - }; - in - flake-utils.lib.eachDefaultSystem mkOutputs; -} From df76b5eb7b3ce099b8ae14d7e634306de1f79acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Tue, 15 Nov 2022 18:22:02 -0300 Subject: [PATCH 008/219] Remove unused module Language.Stitch.LH.Data.Map --- .../src/Language/Stitch/LH/Data/Map.hs | 92 ------------------- tests/benchmarks/stitch-lh/stitch-lh.cabal | 1 - tests/tests.cabal | 1 - 3 files changed, 94 deletions(-) delete mode 100644 tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Map.hs diff --git a/tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Map.hs b/tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Map.hs deleted file mode 100644 index 45c2eac945..0000000000 --- a/tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Map.hs +++ /dev/null @@ -1,92 +0,0 @@ -{-# LANGUAGE LambdaCase #-} -{-# OPTIONS_GHC -fenable-rewrite-rules -Wno-inline-rule-shadowing #-} - ------------------------------------------------------------------------------ --- | --- Module : Language.Stitch.LH.Data.Map --- Copyright : (C) 2021 Facundo Domínguez --- License : BSD-style (see LICENSE) --- Stability : experimental --- --- An interface of maps that can be used in reflected definitions --- with LH. It is not currently used in the rest of stitch-lh, but --- I'm keeping it for now, just for the record. --- --- The ability to reflect operations on Maps comes into play when --- trying to reflect the typechecker. ----------------------------------------------------------------------------- - -module Language.Stitch.LH.Data.Map - ( module Language.Stitch.LH.Data.Map - , Map - ) - where - -import Data.Map (Map) -import qualified Data.Map as Map -import Data.Set (Set) -import qualified Data.Set as Set -import Prelude hiding (lookup) - --- XXX: put lookup in the logic and use rewrite rules to give it --- an implementation --- XXX: GHC only seems to fire rules if the definitions are eta expanded. -{-@ -reflect lookup -lazy lookup -lookup - :: forall

Bool>. - Ord a - => k : a - -> m : Map a b

- -> { r : Maybe b

- | not (Set.member k (mapKeys m)) <=> r = Nothing - } -@-} -lookup :: Ord a => a -> Map a b -> Maybe b -lookup a m = lookup a m - where - _ = Set.empty :: Set () -- quiet warning about unused imports - -{-# RULES "lookupImpl" lookup = Map.lookup #-} - -{-@ -reflect insert -lazy insert -insert - :: forall

Bool>. - Ord a - => a - -> b

- - -> Map a b

- -> Map a b

-@-} -insert :: Ord a => a -> b -> Map a b -> Map a b -insert a b m = insert a b m - -{-# RULES "insertImpl" insert = Map.insert #-} - -{-@ -reflect empty -lazy empty -empty :: forall

Bool>. Map a b

-@-} -empty :: Map a b -empty = goEmpty () - --- XXX: Making goEmpty local to empty, causes LH to crash when --- building Check.hs. -{-@ reflect goEmpty @-} -{-@ lazy goEmpty @-} -- With PR 2069 a termination error appears --- XXX: For some reason, GHC aggrees to fire emptyImpl only if --- empty appears in an auxiliar definition like this one. -goEmpty :: () -> Map a b -goEmpty () = goEmpty () - -{-# RULES "emptyImpl" goEmpty () = Map.empty #-} - - -{-@ -measure mapKeys :: Map a b -> Set a -@-} diff --git a/tests/benchmarks/stitch-lh/stitch-lh.cabal b/tests/benchmarks/stitch-lh/stitch-lh.cabal index 2291983876..0a37c98d97 100644 --- a/tests/benchmarks/stitch-lh/stitch-lh.cabal +++ b/tests/benchmarks/stitch-lh/stitch-lh.cabal @@ -42,7 +42,6 @@ library Language.Stitch.LH.Check -- Language.Stitch.LH.CSE Language.Stitch.LH.Data.List - Language.Stitch.LH.Data.Map Language.Stitch.LH.Eval Language.Stitch.LH.Lex Language.Stitch.LH.Monad diff --git a/tests/tests.cabal b/tests/tests.cabal index b24d09d6d2..7d2fc30f1b 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -69,7 +69,6 @@ executable benchmark-stitch-lh Language.Stitch.LH.Check -- , Language.Stitch.LH.CSE , Language.Stitch.LH.Data.List - , Language.Stitch.LH.Data.Map , Language.Stitch.LH.Eval , Language.Stitch.LH.Lex , Language.Stitch.LH.Monad From dc8fdf64c4f3292e8fbca09317d310d76db91c47 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 16 Nov 2022 15:31:29 +1300 Subject: [PATCH 009/219] Remove name shadowing from Language.Haskell.Liquid.Bare.Expand --- src/Language/Haskell/Liquid/Bare/Expand.hs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/Expand.hs b/src/Language/Haskell/Liquid/Bare/Expand.hs index 22f0e67a38..79352c53a4 100644 --- a/src/Language/Haskell/Liquid/Bare/Expand.hs +++ b/src/Language/Haskell/Liquid/Bare/Expand.hs @@ -6,8 +6,6 @@ {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE OverloadedStrings #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Bare.Expand ( -- * Create alias expansion environment makeRTEnv @@ -58,7 +56,7 @@ import qualified Language.Haskell.Liquid.Bare.Plugged as Bare makeRTEnv :: Bare.Env -> ModName -> Ms.BareSpec -> Bare.ModSpecs -> LogicMap -> BareRTEnv -------------------------------------------------------------------------------- -makeRTEnv env m mySpec iSpecs lmap +makeRTEnv env modName mySpec iSpecs lmap = renameRTArgs $ makeRTAliases tAs $ makeREAliases eAs where tAs = [ t | (_, s) <- specs, t <- Ms.aliases s ] @@ -68,9 +66,9 @@ makeRTEnv env m mySpec iSpecs lmap -- this clearly breaks things if a signature -- contains lmap functions but never gets -- elaborated - else [ specREAlias env m e | (_, xl) <- M.toList (lmSymDefs lmap) + else [ specREAlias env modName e | (_, xl) <- M.toList (lmSymDefs lmap) , let e = lmapEAlias xl ] - specs = (m, mySpec) : M.toList iSpecs + specs = (modName, mySpec) : M.toList iSpecs -- | We apply @renameRTArgs@ *after* expanding each alias-definition, to -- ensure that the substitutions work properly (i.e. don't miss expressions @@ -90,11 +88,11 @@ makeREAliases = graphExpand buildExprEdges f mempty -- | @renameTys@ ensures that @RTAlias@ type parameters have distinct names -- to avoid variable capture e.g. as in T1556.hs renameTys :: RTAlias F.Symbol BareType -> RTAlias F.Symbol BareType -renameTys rt = rt { rtTArgs = ys, rtBody = subts (rtBody rt) (zip xs ys) } +renameTys rt = rt { rtTArgs = ys, rtBody = sbts (rtBody rt) (zip xs ys) } where xs = rtTArgs rt ys = (`F.suffixSymbol` rtName rt) <$> xs - subts = foldl (flip subt) + sbts = foldl (flip subt) renameVV :: RTAlias F.Symbol BareType -> RTAlias F.Symbol BareType @@ -187,8 +185,8 @@ checkCyclicAliases table graph cycleAliasErr :: AliasTable x t -> [F.Symbol] -> Error cycleAliasErr _ [] = panic Nothing "checkCyclicAliases: No type aliases in reported cycle" -cycleAliasErr t scc@(rta:_) = ErrAliasCycle { pos = fst (locate rta) - , acycle = map locate scc } +cycleAliasErr t symList@(rta:_) = ErrAliasCycle { pos = fst (locate rta) + , acycle = map locate symList } where locate sym = ( GM.fSrcSpan $ fromAliasSymbol t sym , pprint sym ) From b93c5861ac26904be95815164c903cb66bdd0421 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 16 Nov 2022 15:31:47 +1300 Subject: [PATCH 010/219] Remove name shadowing from Language.Haskell.Liquid.Bare.Measure --- src/Language/Haskell/Liquid/Bare/Measure.hs | 54 ++++++++++----------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/Measure.hs b/src/Language/Haskell/Liquid/Bare/Measure.hs index d64195de37..a53d8c1eba 100644 --- a/src/Language/Haskell/Liquid/Bare/Measure.hs +++ b/src/Language/Haskell/Liquid/Bare/Measure.hs @@ -2,8 +2,6 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -- | This module contains (most of) the code needed to lift Haskell entitites, -- . code- (CoreBind), and data- (Tycon) definitions into the spec level. @@ -65,21 +63,21 @@ makeMeasureDefinition :: Bool -> Bare.TycEnv -> LogicMap -> [Ghc.CoreBind] -> Lo -> Measure LocSpecType Ghc.DataCon makeMeasureDefinition allowTC tycEnv lmap cbs x = case GM.findVarDef (val x) cbs of - Nothing -> Ex.throw $ errHMeas x "Cannot extract measure from haskell function" - Just (v, def) -> Ms.mkM vx vinfo mdef MsLifted (makeUnSorted allowTC (Ghc.varType v) mdef) + Nothing -> Ex.throw $ errHMeas x "Cannot extract measure from haskell function" + Just (v, cexp) -> Ms.mkM vx vinfo mdef MsLifted (makeUnSorted allowTC (Ghc.varType v) mdef) where vx = F.atLoc x (F.symbol v) - mdef = coreToDef' allowTC tycEnv lmap vx v def + mdef = coreToDef' allowTC tycEnv lmap vx v cexp vinfo = GM.varLocInfo (logicType allowTC) v makeUnSorted :: Bool -> Ghc.Type -> [Def LocSpecType Ghc.DataCon] -> UnSortedExprs -makeUnSorted allowTC t defs +makeUnSorted allowTC ty defs | isMeasureType ta = mempty | otherwise = map defToUnSortedExpr defs where - ta = go $ Ghc.expandTypeSynonyms t + ta = go $ Ghc.expandTypeSynonyms ty go (Ghc.ForAllTy _ t) = go t go Ghc.FunTy{ Ghc.ft_arg = p, Ghc.ft_res = t} | isErasable p = go t @@ -89,16 +87,16 @@ makeUnSorted allowTC t defs isMeasureType (Ghc.TyConApp _ ts) = all Ghc.isTyVarTy ts isMeasureType _ = False - defToUnSortedExpr def = (xx:(fst <$> binds def), - Ms.bodyPred (F.mkEApp (measure def) [F.expr xx]) (body def)) + defToUnSortedExpr defn = (xx:(fst <$> binds defn), + Ms.bodyPred (F.mkEApp (measure defn) [F.expr xx]) (body defn)) xx = F.vv $ Just 10000 isErasable = if allowTC then GM.isEmbeddedDictType else Ghc.isClassPred coreToDef' :: Bool -> Bare.TycEnv -> LogicMap -> LocSymbol -> Ghc.Var -> Ghc.CoreExpr -> [Def LocSpecType Ghc.DataCon] -coreToDef' allowTC tycEnv lmap vx v def = - case runToLogic embs lmap dm (errHMeas vx) (coreToDef allowTC vx v def) of +coreToDef' allowTC tycEnv lmap vx v defn = + case runToLogic embs lmap dm (errHMeas vx) (coreToDef allowTC vx v defn) of Right l -> l Left e -> Ex.throw e where @@ -122,8 +120,8 @@ makeMeasureInline :: Bool -> F.TCEmb Ghc.TyCon -> LogicMap -> [Ghc.CoreBind] -> -> (LocSymbol, LMap) makeMeasureInline allowTC embs lmap cbs x = case GM.findVarDef (val x) cbs of - Nothing -> Ex.throw $ errHMeas x "Cannot inline haskell function" - Just (v, def) -> (vx, coreToFun' allowTC embs Nothing lmap vx v def ok) + Nothing -> Ex.throw $ errHMeas x "Cannot inline haskell function" + Just (v, defn) -> (vx, coreToFun' allowTC embs Nothing lmap vx v defn ok) where vx = F.atLoc x (F.symbol v) ok (xs, e) = LMap vx (F.symbol <$> xs) (either id id e) @@ -135,10 +133,10 @@ makeMeasureInline allowTC embs lmap cbs x = coreToFun' :: Bool -> F.TCEmb Ghc.TyCon -> Maybe Bare.DataConMap -> LogicMap -> LocSymbol -> Ghc.Var -> Ghc.CoreExpr -> (([Ghc.Var], Either F.Expr F.Expr) -> a) -> a -coreToFun' allowTC embs dmMb lmap x v def ok = either Ex.throw ok act +coreToFun' allowTC embs dmMb lmap x v defn ok = either Ex.throw ok act where act = runToLogic embs lmap dm err xFun - xFun = coreToFun allowTC x v def + xFun = coreToFun allowTC x v defn err = errHMeas x dm = Mb.fromMaybe mempty dmMb @@ -186,20 +184,20 @@ zipMapMaybe :: (a -> Maybe b) -> [a] -> [(a, b)] zipMapMaybe f = Mb.mapMaybe (\x -> (x, ) <$> f x) hasDataDecl :: ModName -> Ms.BareSpec -> Ghc.TyCon -> HasDataDecl -hasDataDecl mod spec - = \tc -> F.notracepp (msg tc) $ M.lookupDefault def (tcName tc) decls +hasDataDecl modName spec + = \tc -> F.notracepp (msg tc) $ M.lookupDefault defn (tcName tc) decls where msg tc = "hasDataDecl " ++ show (tcName tc) - def = NoDecl Nothing - tcName = fmap (qualifiedDataName mod) . tyConDataName True - dcName = qualifiedDataName mod . tycName + defn = NoDecl Nothing + tcName = fmap (qualifiedDataName modName) . tyConDataName True + dcName = qualifiedDataName modName . tycName decls = M.fromList [ (Just dn, hasDecl d) | d <- Ms.dataDecls spec , let dn = dcName d] qualifiedDataName :: ModName -> DataName -> DataName -qualifiedDataName mod (DnName lx) = DnName (qualifyModName mod <$> lx) -qualifiedDataName mod (DnCon lx) = DnCon (qualifyModName mod <$> lx) +qualifiedDataName modName (DnName lx) = DnName (qualifyModName modName <$> lx) +qualifiedDataName modName (DnCon lx) = DnCon (qualifyModName modName <$> lx) {-tyConDataDecl :: {tc:TyCon | isAlgTyCon tc} -> Maybe DataDecl @-} tyConDataDecl :: ((Ghc.TyCon, DataName), HasDataDecl) -> Maybe DataDecl @@ -236,11 +234,11 @@ dataConDecl d = {- F.notracepp msg $ -} DataCtor dx (F.symbol <$> as) [] xts xts = [(Bare.makeDataConSelector Nothing d i, RT.bareOfType t) | (i, t) <- its ] dx = F.symbol <$> GM.locNamedThing d its = zip [1..] ts - (as,_ps,ts,t) = Ghc.dataConSig d - outT = Just (RT.bareOfType t :: BareType) + (as,_ps,ts,ty) = Ghc.dataConSig d + outT = Just (RT.bareOfType ty :: BareType) _outT :: Maybe BareType _outT - | isGadt = Just (RT.bareOfType t) + | isGadt = Just (RT.bareOfType ty) | otherwise = Nothing @@ -295,18 +293,18 @@ dataConSel permitTC dc n (Proj i) = mkArrow (zip as (repeat mempty)) [] [] [xt] -- bkDataCon :: DataCon -> Int -> ([RTVar RTyVar RSort], [SpecType], (Symbol, SpecType, RReft)) bkDataCon :: (F.Reftable (RTProp RTyCon RTyVar r), PPrint r, F.Reftable r) => Bool -> Ghc.DataCon -> Int -> ([RTVar RTyVar RSort], [RRType r], (F.Symbol, RFInfo, RRType r, r)) -bkDataCon permitTC dc nFlds = (as, ts, (F.dummySymbol, classRFInfo permitTC, t, mempty)) +bkDataCon permitTC dcn nFlds = (as, ts, (F.dummySymbol, classRFInfo permitTC, t, mempty)) where ts = RT.ofType <$> Misc.takeLast nFlds (map Ghc.irrelevantMult _ts) t = -- Misc.traceShow ("bkDataConResult" ++ GM.showPpr (dc, _t, _t0)) $ RT.ofType $ Ghc.mkTyConApp tc tArgs' as = makeRTVar . RT.rTyVar <$> (αs ++ αs') - ((αs,αs',_,_,_ts,_t), _t0) = hammer dc + ((αs,αs',_,_,_ts,_t), _t0) = hammer dcn tArgs' = take (nArgs - nVars) tArgs ++ (Ghc.mkTyVarTy <$> αs) nVars = length αs nArgs = length tArgs (tc, tArgs) = Mb.fromMaybe err (Ghc.splitTyConApp_maybe _t) - err = GM.namedPanic dc ("Cannot split result type of DataCon " ++ show dc) + err = GM.namedPanic dcn ("Cannot split result type of DataCon " ++ show dcn) hammer dc = (Ghc.dataConFullSig dc, Ghc.varType . Ghc.dataConWorkId $ dc) data DataConSel = Check | Proj Int From d69d022191bb55c934a7da5c5dec7bd719dad5b3 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 16 Nov 2022 15:32:02 +1300 Subject: [PATCH 011/219] Remove name shadowing from Language.Haskell.Liquid.Bare.Misc --- src/Language/Haskell/Liquid/Bare/Misc.hs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/Misc.hs b/src/Language/Haskell/Liquid/Bare/Misc.hs index b44e4f17a3..a07c144408 100644 --- a/src/Language/Haskell/Liquid/Bare/Misc.hs +++ b/src/Language/Haskell/Liquid/Bare/Misc.hs @@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleContexts #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} module Language.Haskell.Liquid.Bare.Misc ( joinVar @@ -167,7 +166,7 @@ mapTyRVar α a s@(MTVST αas err) Nothing -> return $ MTVST ((α,a):αas) err matchKindArgs' :: [Type] -> [SpecType] -> [SpecType] -matchKindArgs' ts1 ts2 = reverse $ go (reverse ts1) (reverse ts2) +matchKindArgs' ts1' = reverse . go (reverse ts1') . reverse where go (_:ts1) (t2:ts2) = t2:go ts1 ts2 go ts [] | all isKind ts @@ -176,7 +175,7 @@ matchKindArgs' ts1 ts2 = reverse $ go (reverse ts1) (reverse ts2) matchKindArgs :: [SpecType] -> [SpecType] -> [SpecType] -matchKindArgs ts1 ts2 = reverse $ go (reverse ts1) (reverse ts2) +matchKindArgs ts1' = reverse . go (reverse ts1') . reverse where go (_:ts1) (t2:ts2) = t2:go ts1 ts2 go ts [] = ts From 0f9c3f640904f813bd7441578ed15902c0380f45 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 16 Nov 2022 15:32:58 +1300 Subject: [PATCH 012/219] Remove name shadowing from Language.Haskell.Liquid.Bare.Plugged --- src/Language/Haskell/Liquid/Bare/Plugged.hs | 32 ++++++++++----------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/Plugged.hs b/src/Language/Haskell/Liquid/Bare/Plugged.hs index 8a1f0ad56f..274f41bc47 100644 --- a/src/Language/Haskell/Liquid/Bare/Plugged.hs +++ b/src/Language/Haskell/Liquid/Bare/Plugged.hs @@ -1,8 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PartialTypeSignatures #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Bare.Plugged ( makePluggedSig , makePluggedDataCon @@ -159,7 +157,7 @@ plugHolesOld, plugHolesNew -> LocSpecType -- NOTE: this use of toType is safe as rt' is derived from t. -plugHolesOld allowTC tce tyi x f t0 zz@(Loc l l' st0) +plugHolesOld allowTC tce tyi xx f t0 zz@(Loc l l' st0) = Loc l l' . mkArrow (zip (updateRTVar <$> αs') rs) ps' [] [] . makeCls cs' @@ -175,22 +173,22 @@ plugHolesOld allowTC tce tyi x f t0 zz@(Loc l l' st0) su' = [(y, RVar (rTyVar x) ()) | (x, y) <- tyvsmap] :: [(RTyVar, RSort)] coSub = M.fromList [(F.symbol y, F.FObj (F.symbol x)) | (y, x) <- su] ps' = fmap (subts su') <$> ps - cs' = [(F.dummySymbol, RApp c ts [] mempty) | (c, ts) <- cs ] + cs' = [(F.dummySymbol, RApp c ts [] mempty) | (c, ts) <- cs2 ] (αs', rs) = unzip αs - (αs,_,cs,rt) = bkUnivClass (F.notracepp "hs-spec" $ ofType (Ghc.expandTypeSynonyms t0) :: SpecType) + (αs,_,cs2,rt) = bkUnivClass (F.notracepp "hs-spec" $ ofType (Ghc.expandTypeSynonyms t0) :: SpecType) (_,ps,_ ,st) = bkUnivClass (F.notracepp "lq-spec" st0) makeCls cs t = foldr (uncurry (rFun' (classRFInfo allowTC))) t cs - err hsT lqT = ErrMismatch (GM.fSrcSpan zz) (pprint x) + err hsT lqT = ErrMismatch (GM.fSrcSpan zz) (pprint xx) (text "Plugged Init types old") (pprint $ Ghc.expandTypeSynonyms t0) (pprint $ toRSort st0) (Just (hsT, lqT)) - (Ghc.getSrcSpan x) + (Ghc.getSrcSpan xx) -plugHolesNew allowTC@False tce tyi x f t0 zz@(Loc l l' st0) +plugHolesNew allowTC@False tce tyi xx f t0 zz@(Loc l l' st0) = Loc l l' . mkArrow (zip (updateRTVar <$> as'') rs) ps [] [] . makeCls cs' @@ -200,24 +198,24 @@ plugHolesNew allowTC@False tce tyi x f t0 zz@(Loc l l' st0) rt' = tx rt as'' = subRTVar su <$> as' (as',rs) = unzip as - cs' = [ (F.dummySymbol, ct) | (c, t) <- cs, let ct = tx (RApp c t [] mempty) ] + cs' = [ (F.dummySymbol, ct) | (c, t) <- tyCons, let ct = tx (RApp c t [] mempty) ] tx = subts su su = case Bare.runMapTyVars allowTC (toType False rt) st err of Left e -> Ex.throw e Right s -> [ (rTyVar x, y) | (x, y) <- Bare.vmap s] - (as,_,cs,rt) = bkUnivClass (ofType (Ghc.expandTypeSynonyms t0) :: SpecType) + (as,_,tyCons,rt) = bkUnivClass (ofType (Ghc.expandTypeSynonyms t0) :: SpecType) (_,ps,_ ,st) = bkUnivClass st0 makeCls cs t = foldr (uncurry (rFun' (classRFInfo allowTC))) t cs - err hsT lqT = ErrMismatch (GM.fSrcSpan zz) (pprint x) + err hsT lqT = ErrMismatch (GM.fSrcSpan zz) (pprint xx) (text "Plugged Init types new") (pprint $ Ghc.expandTypeSynonyms t0) (pprint $ toRSort st0) (Just (hsT, lqT)) - (Ghc.getSrcSpan x) + (Ghc.getSrcSpan xx) -plugHolesNew allowTC@True tce tyi x f t0 zz@(Loc l l' st0) +plugHolesNew allowTC@True tce tyi a f t0 zz@(Loc l l' st0) = Loc l l' . mkArrow (zip (updateRTVar <$> as'') rs) ps [] (if length cs > length cs' then cs else cs') -- . makeCls cs' @@ -237,12 +235,12 @@ plugHolesNew allowTC@True tce tyi x f t0 zz@(Loc l l' st0) cs = [ (x, classRFInfo allowTC, t, r) | (x,t,r)<-cs0] cs' = [ (x, classRFInfo allowTC, t, r) | (x,t,r)<-cs0'] - err hsT lqT = ErrMismatch (GM.fSrcSpan zz) (pprint x) + err hsT lqT = ErrMismatch (GM.fSrcSpan zz) (pprint a) (text "Plugged Init types new") (pprint $ Ghc.expandTypeSynonyms t0) (pprint $ toRSort st0) (Just (hsT, lqT)) - (Ghc.getSrcSpan x) + (Ghc.getSrcSpan a) subRTVar :: [(RTyVar, RTyVar)] -> SpecRTVar -> SpecRTVar subRTVar su a@(RTVar v i) = Mb.maybe a (`RTVar` i) (lookup v su) @@ -251,9 +249,9 @@ goPlug :: F.TCEmb Ghc.TyCon -> Bare.TyConMap -> (Doc -> Doc -> Error) -> (SpecTy -> SpecType goPlug tce tyi err f = go where - go t (RHole r) = (addHoles t') { rt_reft = f t r } + go st (RHole r) = (addHoles t') { rt_reft = f st r } where - t' = everywhere (mkT $ addRefs tce tyi) t + t' = everywhere (mkT $ addRefs tce tyi) st addHoles = everywhere (mkT addHole) -- NOTE: make sure we only add holes to RVar and RApp (NOT RFun) addHole :: SpecType -> SpecType From 6442f4bee7fd2db6732adb26013dba114b9afa69 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 16 Nov 2022 15:33:10 +1300 Subject: [PATCH 013/219] Remove name shadowing from Language.Haskell.Liquid.Bare.Resolve --- src/Language/Haskell/Liquid/Bare/Resolve.hs | 30 ++++++++++----------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/Resolve.hs b/src/Language/Haskell/Liquid/Bare/Resolve.hs index 35f9892b18..ef611bc97b 100644 --- a/src/Language/Haskell/Liquid/Bare/Resolve.hs +++ b/src/Language/Haskell/Liquid/Bare/Resolve.hs @@ -11,8 +11,6 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TupleSections #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Bare.Resolve ( -- * Creating the Environment makeEnv @@ -125,8 +123,8 @@ localBinds = concatMap (bgo S.empty) where add x g = maybe g (`S.insert` g) (localKey x) adds b g = foldr add g (Ghc.bindersOf b) - take x g = maybe [] (\k -> [x | not (S.member k g)]) (localKey x) - pgo g (x, e) = take x g ++ go (add x g) e + take' x g = maybe [] (\k -> [x | not (S.member k g)]) (localKey x) + pgo g (x, e) = take' x g ++ go (add x g) e bgo g (Ghc.NonRec x e) = pgo g (x, e) bgo g (Ghc.Rec xes) = concatMap (pgo g) xes go g (Ghc.App e a) = concatMap (go g) [e, a] @@ -640,16 +638,16 @@ rankedThings f ias = case Misc.sortOn fst (Misc.groupList ibs) of ------------------------------------------------------------------------------- lookupTyThing :: Env -> ModName -> LocSymbol -> [((Int, F.Symbol), Ghc.TyThing)] ------------------------------------------------------------------------------- -lookupTyThing env name lsym = [ (k, t) | (k, ts) <- ordMatches, t <- ts] +lookupTyThing env mdname lsym = [ (k, t) | (k, ts) <- ordMatches, t <- ts] where ordMatches = Misc.sortOn fst (Misc.groupList matches) matches = myTracepp ("matches-" ++ msg) [ ((k, m), t) | (m, t) <- lookupThings env x - , k <- myTracepp msg $ mm nameSym m mods ] - msg = "lookupTyThing: " ++ F.showpp (lsym, x, mods) - (x, mods) = symbolModules env (F.val lsym) - nameSym = F.symbol name + , k <- myTracepp msg $ mm nameSym m mds ] + msg = "lookupTyThing: " ++ F.showpp (lsym, x, mds) + (x, mds) = symbolModules env (F.val lsym) + nameSym = F.symbol mdname allowExt = allowExtResolution env lsym mm name m mods = myTracepp ("matchMod: " ++ F.showpp (lsym, name, m, mods, allowExt)) $ matchMod env name m allowExt mods @@ -776,9 +774,9 @@ maybeResolveSym env name kind x = case resolveLocSym env name kind x of -- | @ofBareType@ and @ofBareTypeE@ should be the _only_ @SpecType@ constructors ------------------------------------------------------------------------------- ofBareType :: Env -> ModName -> F.SourcePos -> Maybe [PVar BSort] -> BareType -> SpecType -ofBareType env name l ps t = either fail id (ofBareTypeE env name l ps t) +ofBareType env name l ps t = either fail' id (ofBareTypeE env name l ps t) where - fail = Ex.throw + fail' = Ex.throw -- fail = Misc.errorP "error-ofBareType" . F.showpp ofBareTypeE :: Env -> ModName -> F.SourcePos -> Maybe [PVar BSort] -> BareType -> Lookup SpecType @@ -845,7 +843,7 @@ type Expandable r = ( PPrint r ofBRType :: (Expandable r) => Env -> ModName -> ([F.Symbol] -> r -> r) -> F.SourcePos -> BRType r -> Lookup (RRType r) -ofBRType env name f l t = go [] t +ofBRType env name f l = go [] where goReft bs r = return (f bs r) goRImpF bs x i t1 t2 r = RImpF x i <$> (rebind x <$> go bs t1) <*> go (x:bs) t2 <*> goReft bs r @@ -967,13 +965,13 @@ txRefSort :: TyConMap -> F.TCEmb Ghc.TyCon -> LocSpecType -> LocSpecType txRefSort tyi tce t = F.atLoc t $ mapBot (addSymSort (GM.fSrcSpan t) tce tyi) (val t) addSymSort :: Ghc.SrcSpan -> F.TCEmb Ghc.TyCon -> TyConMap -> SpecType -> SpecType -addSymSort sp tce tyi (RApp rc@RTyCon{} ts rs r) - = RApp rc ts (zipWith3 (addSymSortRef sp rc) pvs rargs [1..]) r' +addSymSort sp tce tyi (RApp rc@RTyCon{} ts rs rr) + = RApp rc ts (zipWith3 (addSymSortRef sp rc) pvs rargs [1..]) r2 where (_, pvs) = RT.appRTyCon tce tyi rc ts -- pvs = rTyConPVs rc' (rargs, rrest) = splitAt (length pvs) rs - r' = L.foldl' go r rrest + r2 = L.foldl' go rr rrest go r (RProp _ (RHole r')) = r' `F.meet` r go r (RProp _ t' ) = let r' = Mb.fromMaybe mempty (stripRTypeBase t') in r `F.meet` r' @@ -1014,7 +1012,7 @@ addSymSortRef' _ _ _ p (RProp s t) xs = spliceArgs "addSymSortRef 2" s p spliceArgs :: String -> [(F.Symbol, b)] -> PVar t -> [(F.Symbol, t)] -spliceArgs msg s p = go (fst <$> s) (pargs p) +spliceArgs msg syms p = go (fst <$> syms) (pargs p) where go [] [] = [] go [] ((s,x,_):as) = (x, s):go [] as From 08bcff85db0022eee575c05ed4feccc79de0ef24 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 16 Nov 2022 15:38:21 +1300 Subject: [PATCH 014/219] Remove name shadowing from Language.Haskell.Liquid.Bare.ToBare --- src/Language/Haskell/Liquid/Bare/ToBare.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/ToBare.hs b/src/Language/Haskell/Liquid/Bare/ToBare.hs index 5e1f846f08..a34b1f0eba 100644 --- a/src/Language/Haskell/Liquid/Bare/ToBare.hs +++ b/src/Language/Haskell/Liquid/Bare/ToBare.hs @@ -1,8 +1,6 @@ -- | This module contains functions that convert things -- to their `Bare` versions, e.g. SpecType -> BareType etc. -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Bare.ToBare ( -- * Types specToBare @@ -85,7 +83,7 @@ txRTV :: (c1 -> c2) -> (tv1 -> tv2) -> RTVU c1 tv1 -> RTVU c2 tv2 txRTV cF vF (RTVar α z) = RTVar (vF α) (txRType cF vF <$> z) txPV :: (c1 -> c2) -> (tv1 -> tv2) -> PVU c1 tv1 -> PVU c2 tv2 -txPV cF vF (PV x k y txes) = PV x k' y txes' +txPV cF vF (PV sym k y txes) = PV sym k' y txes' where txes' = [ (tx t, x, e) | (t, x, e) <- txes] k' = tx <$> k From d3809144d5f178e03d5adfe80dda1f10c4af7da2 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 16 Nov 2022 15:42:27 +1300 Subject: [PATCH 015/219] Remove name shadowing from Language.Haskell.Liquid.Bare.Typeclass --- src/Language/Haskell/Liquid/Bare/Typeclass.hs | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/Typeclass.hs b/src/Language/Haskell/Liquid/Bare/Typeclass.hs index 7d485d2213..4fa4b95c4f 100644 --- a/src/Language/Haskell/Liquid/Bare/Typeclass.hs +++ b/src/Language/Haskell/Liquid/Bare/Typeclass.hs @@ -1,8 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Bare.Typeclass ( compileClasses , elaborateClassDcp @@ -48,7 +46,7 @@ compileClasses -> [(ModName, Ms.BareSpec)] -> (Ms.BareSpec, [(Ghc.ClsInst, [Ghc.Var])]) compileClasses src env (name, spec) rest = - (spec { sigs = sigs' } <> clsSpec, instmethods) + (spec { sigs = sigsNew } <> clsSpec, instmethods) where clsSpec = mempty { dataDecls = clsDecls @@ -65,13 +63,13 @@ compileClasses src env (name, spec) rest = } clsDecls = makeClassDataDecl (M.toList refinedMethods) -- class methods - (refinedMethods, sigs') = foldr grabClassSig (mempty, mempty) (sigs spec) + (refinedMethods, sigsNew) = foldr grabClassSig (mempty, mempty) (sigs spec) grabClassSig :: (F.LocSymbol, ty) -> (M.HashMap Ghc.Class [(Ghc.Id, ty)], [(F.LocSymbol, ty)]) -> (M.HashMap Ghc.Class [(Ghc.Id, ty)], [(F.LocSymbol, ty)]) - grabClassSig sig@(lsym, ref) (refs, sigs') = case clsOp of - Nothing -> (refs, sig : sigs') + grabClassSig sigPair@(lsym, ref) (refs, sigs') = case clsOp of + Nothing -> (refs, sigPair : sigs') Just (cls, sig) -> (M.alter (merge sig) cls refs, sigs') where clsOp = do @@ -234,19 +232,19 @@ elaborateClassDcp coreToLg simplifier dcp = do t -- YL: is this redundant if we already have strengthenClassSel? strengthenTy :: F.Symbol -> SpecType -> SpecType - strengthenTy x t = mkUnivs tvs pvs (RFun z i cls (t' `RT.strengthen` mt) r) + strengthenTy x t = mkUnivs tvs pvs (RFun z i clas (t' `RT.strengthen` mt) r) where - (tvs, pvs, RFun z i cls t' r) = bkUniv t + (tvs, pvs, RFun z i clas t' r) = bkUniv t vv = rTypeValueVar t' mt = RT.uReft (vv, F.PAtom F.Eq (F.EVar vv) (F.EApp (F.EVar x) (F.EVar z))) elaborateMethod :: F.Symbol -> S.HashSet F.Symbol -> SpecType -> SpecType -elaborateMethod dc methods t = mapExprReft - (\_ -> substClassOpBinding tcbind dc methods) - t +elaborateMethod dc methods st = mapExprReft + (\_ -> substClassOpBinding tcbindSym dc methods) + st where - tcbind = grabtcbind t + tcbindSym = grabtcbind st grabtcbind :: SpecType -> F.Symbol grabtcbind t = F.notracepp "grabtcbind" @@ -263,7 +261,7 @@ elaborateMethod dc methods t = mapExprReft -- After: Funcctor.fmap ($p1Applicative##GHC.Base.Applicative) substClassOpBinding :: F.Symbol -> F.Symbol -> S.HashSet F.Symbol -> F.Expr -> F.Expr -substClassOpBinding tcbind dc methods e = go e +substClassOpBinding tcbind dc methods = go where go :: F.Expr -> F.Expr go (F.EApp e0 e1) @@ -404,7 +402,7 @@ makeClassAuxTypesOne elab (ldcp, inst, methods) = subst ((a, ta):su) t = subsTyVarMeet' (a, ta) (subst su t) substAuxMethod :: F.Symbol -> M.HashMap F.Symbol F.Symbol -> F.Expr -> F.Expr -substAuxMethod dfun methods e = F.notracepp "substAuxMethod" $ go e +substAuxMethod dfun methods = F.notracepp "substAuxMethod" . go where go :: F.Expr -> F.Expr go (F.EApp e0 e1) | F.EVar x <- F.notracepp "e0" e0 From 49f57057298ce04e383033f17b5cc002eb1b6ca0 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 16 Nov 2022 09:02:28 +0100 Subject: [PATCH 016/219] fix for #2091 --- .../Haskell/Liquid/Constraint/Generate.hs | 24 ++++++++++++++++--- tests/pos/T2091.hs | 21 ++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 tests/pos/T2091.hs diff --git a/src/Language/Haskell/Liquid/Constraint/Generate.hs b/src/Language/Haskell/Liquid/Constraint/Generate.hs index 3c55a83633..72ea564dcc 100644 --- a/src/Language/Haskell/Liquid/Constraint/Generate.hs +++ b/src/Language/Haskell/Liquid/Constraint/Generate.hs @@ -1059,9 +1059,9 @@ castTy γ t e _ castTy' γ τ (Var x) - = do t <- trueTy (typeclass (getConfig γ)) τ - -- tx <- varRefType γ x -- NV HERE: the refinements of the var x do not get into the - -- -- environment. Check + = do t0 <- trueTy (typeclass (getConfig γ)) τ + tx <- varRefType γ x + let t = mergeCastTys t0 tx let ce = if typeclass (getConfig γ) && noADT (getConfig γ) then F.expr x else eCoerc (typeSort (emb γ) $ Ghc.expandTypeSynonyms $ varType x) (typeSort (emb γ) τ) @@ -1077,6 +1077,24 @@ castTy' γ t (Tick _ e) castTy' _ _ e = panic Nothing $ "castTy cannot handle expr " ++ GM.showPpr e + +{- +mergeCastTys tcorrect trefined + tcorrect has the correct GHC skeleton, + trefined has the correct refinements (before coercion) + mergeCastTys keeps the trefined when the two GHC types match +-} + +mergeCastTys :: SpecType -> SpecType -> SpecType +mergeCastTys t1 t2 + | toType False t1 == toType False t2 + = t2 +mergeCastTys (RApp c1 ts1 ps1 r1) (RApp c2 ts2 _ _) + | c1 == c2 + = RApp c1 (zipWith mergeCastTys ts1 ts2) ps1 r1 +mergeCastTys t _ + = t + {- showCoercion :: Coercion -> String showCoercion (AxiomInstCo co1 co2 co3) diff --git a/tests/pos/T2091.hs b/tests/pos/T2091.hs new file mode 100644 index 0000000000..fc4f2de78b --- /dev/null +++ b/tests/pos/T2091.hs @@ -0,0 +1,21 @@ +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE GADTs #-} + +import Prelude (Bool(..)) +import GHC.TypeLits + +data Vec (n :: Nat) a where + VCons :: a -> Vec n a -> Vec (1 + n) a + VNil :: Vec 0 a + +{-@ ys0 :: Vec _ Bool @-} +ys0 :: Vec 0 Bool +ys0 = VNil + +type Vec1 = Vec 1 +{-@ type T = {v:Bool | v } @-} +{-@ ys1 :: Vec _ T @-} +ys1 :: Vec 1 Bool +ys1 = VCons True VNil From 347b933c52931debe63f47f6c3b1aa4082ede4a6 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 16 Nov 2022 09:40:44 +0100 Subject: [PATCH 017/219] add test for #2093 --- tests/pos/T2093.hs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/pos/T2093.hs diff --git a/tests/pos/T2093.hs b/tests/pos/T2093.hs new file mode 100644 index 0000000000..d4517d31c6 --- /dev/null +++ b/tests/pos/T2093.hs @@ -0,0 +1,23 @@ +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE GADTs #-} +{-@ embed GHC.Natural.Natural as int @-} +{-@ LIQUID "--no-totality" @-} + +import Prelude +import GHC.TypeLits +import GHC.Natural + +newtype Unsigned (n :: Nat) = U Natural +instance KnownNat n => Num (Unsigned n) + +instance Ord (Unsigned n) +instance Eq (Unsigned n) + +type Hex = Unsigned 4 +{-@ type Digit = {v : Hex | v <= 9 } @-} + +{-@ x :: Digit @-} +x :: Hex +x = 3 \ No newline at end of file From 8f2459d239c5c8ab1dfd6091c1e40be654ccda36 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 16 Nov 2022 11:38:09 +0100 Subject: [PATCH 018/219] fix #2096 and other dollar problems --- .../Haskell/Liquid/Transforms/Rewrite.hs | 53 ++++++++++++++++++- tests/pos/T2096.hs | 27 ++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 tests/pos/T2096.hs diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs index b685cecde3..a969c63f5e 100644 --- a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs +++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs @@ -45,13 +45,64 @@ import qualified Data.HashMap.Strict as M rewriteBinds :: Config -> [CoreBind] -> [CoreBind] rewriteBinds cfg | simplifyCore cfg - = fmap (normalizeTuples . rewriteBindWith tidyTuples . rewriteBindWith simplifyPatTuple) + = fmap (normalizeTuples + . rewriteBindWith undollar + . rewriteBindWith tidyTuples + . rewriteBindWith simplifyPatTuple) | otherwise = id simplifyCore :: Config -> Bool simplifyCore = not . noSimplifyCore +undollar :: RewriteRule +undollar = go + where + go e + -- matches `$ t1 t2 t3 f a` + | App e1 a <- untick e + , App e2 f <- untick e1 + , App e3 t3 <- untick e2 + , Type _ <- untick t3 + , App e4 t2 <- untick e3 + , Type _ <- untick t2 + , App d t1 <- untick e4 + , Type _ <- untick t1 + , Var v <- untick d + , show v == "GHC.Base.$" + = Just $ App f a + go (Tick t e) + = Tick t <$> go e + go (Let (NonRec x ex) e) + = do ex' <- go ex + e' <- go e + return $ Let (NonRec x ex') e' + go (Let (Rec bes) e) + = Let <$> (Rec <$> mapM goRec bes) <*> go e + go (Case e x t alts) + = Case e x t <$> mapM goAlt alts + go (App e1 e2) + = App <$> go e1 <*> go e2 + go (Lam x e) + = Lam x <$> go e + go (Cast e c) + = (`Cast` c) <$> go e + go e + = return e + + goRec (x, e) + = (x,) <$> go e + + goAlt (c, bs, e) + = (c, bs,) <$> go e + + + + +untick :: CoreExpr -> CoreExpr +untick (Tick _ e) = e +untick e = e + tidyTuples :: RewriteRule tidyTuples e = Just $ evalState (go e) [] where diff --git a/tests/pos/T2096.hs b/tests/pos/T2096.hs new file mode 100644 index 0000000000..23b83ee247 --- /dev/null +++ b/tests/pos/T2096.hs @@ -0,0 +1,27 @@ +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE GADTs #-} +{-@ embed GHC.Natural.Natural as int @-} +{-@ LIQUID "--no-totality" @-} + +import Prelude +import GHC.TypeLits +import GHC.Natural +import Unsafe.Coerce + +-- See https://github.com/ucsd-progsys/liquidhaskell/issues/2095 +workaround :: (n1 + 1) ~ (n2 + 1) => Vec n1 a -> Vec n2 a +workaround = unsafeCoerce + +data Vec (n :: Nat) a where + Nil :: Vec 0 a + Cons :: a -> Vec n a -> Vec (n + 1) a + +foo :: Vec n a -> Vec n a -> Vec n a +foo Nil Nil = Nil +foo (Cons x xs) (Cons y ys) = Cons x zs + where + zs = foo xs $ workaround ys +foo _ _ = undefined + From 2ac554a75f8fd8416b4fd32a2d3747b3b5b371ed Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 16 Nov 2022 16:36:43 +0100 Subject: [PATCH 019/219] better check for dollar --- src/Language/Haskell/Liquid/Transforms/Rewrite.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs index a969c63f5e..d3dd61c3e5 100644 --- a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs +++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs @@ -69,7 +69,7 @@ undollar = go , App d t1 <- untick e4 , Type _ <- untick t1 , Var v <- untick d - , show v == "GHC.Base.$" + , v `hasKey` dollarIdKey = Just $ App f a go (Tick t e) = Tick t <$> go e From 4b4764d1aaceacbb5613a3c7781474da1af0e398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 16 Nov 2022 12:41:46 -0300 Subject: [PATCH 020/219] Make untick recursive --- src/Language/Haskell/Liquid/Transforms/Rewrite.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs index d3dd61c3e5..43199634fd 100644 --- a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs +++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs @@ -100,7 +100,7 @@ undollar = go untick :: CoreExpr -> CoreExpr -untick (Tick _ e) = e +untick (Tick _ e) = untick e untick e = e tidyTuples :: RewriteRule From ccc369d7798f6096a88a40e92475b4a05ae6dc62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 16 Nov 2022 12:46:16 -0300 Subject: [PATCH 021/219] Reorder Type checks after finding the dollar operator --- src/Language/Haskell/Liquid/Transforms/Rewrite.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs index 43199634fd..78e3e2d0d9 100644 --- a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs +++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs @@ -63,13 +63,13 @@ undollar = go | App e1 a <- untick e , App e2 f <- untick e1 , App e3 t3 <- untick e2 - , Type _ <- untick t3 , App e4 t2 <- untick e3 - , Type _ <- untick t2 , App d t1 <- untick e4 - , Type _ <- untick t1 , Var v <- untick d , v `hasKey` dollarIdKey + , Type _ <- untick t1 + , Type _ <- untick t2 + , Type _ <- untick t3 = Just $ App f a go (Tick t e) = Tick t <$> go e From fd5d2bfb9d93cee309fec70b08f015d84fdbd702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 16 Nov 2022 12:56:29 -0300 Subject: [PATCH 022/219] Fix T2096 --- tests/pos/T2096.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/pos/T2096.hs b/tests/pos/T2096.hs index 23b83ee247..e501b133ed 100644 --- a/tests/pos/T2096.hs +++ b/tests/pos/T2096.hs @@ -5,6 +5,8 @@ {-@ embed GHC.Natural.Natural as int @-} {-@ LIQUID "--no-totality" @-} +module T2096 where + import Prelude import GHC.TypeLits import GHC.Natural From 9c556eac555e042d306ff53ffa9f17aec4683df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 16 Nov 2022 13:04:18 -0300 Subject: [PATCH 023/219] Reference new test in the cabal file --- tests/tests.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests.cabal b/tests/tests.cabal index 7d2fc30f1b..626a10e31d 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -1595,6 +1595,7 @@ executable unit-pos-1 , T1775 , T1812 , T1874 + , T2096 , T385 , T531 , T595a From 34b2daaf7b70d6076feb3df0631f757a55c5321e Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Thu, 17 Nov 2022 15:25:40 +0100 Subject: [PATCH 024/219] add tests in the cabal --- tests/pos/T2091.hs | 2 ++ tests/pos/T2093.hs | 2 ++ tests/tests.cabal | 2 ++ 3 files changed, 6 insertions(+) diff --git a/tests/pos/T2091.hs b/tests/pos/T2091.hs index fc4f2de78b..4f2e99266a 100644 --- a/tests/pos/T2091.hs +++ b/tests/pos/T2091.hs @@ -3,6 +3,8 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE GADTs #-} +module T2091 where + import Prelude (Bool(..)) import GHC.TypeLits diff --git a/tests/pos/T2093.hs b/tests/pos/T2093.hs index d4517d31c6..67a5591950 100644 --- a/tests/pos/T2093.hs +++ b/tests/pos/T2093.hs @@ -5,6 +5,8 @@ {-@ embed GHC.Natural.Natural as int @-} {-@ LIQUID "--no-totality" @-} +module T2093 where + import Prelude import GHC.TypeLits import GHC.Natural diff --git a/tests/tests.cabal b/tests/tests.cabal index 626a10e31d..2a524da3bb 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -1595,6 +1595,8 @@ executable unit-pos-1 , T1775 , T1812 , T1874 + , T2091 + , T2093 , T2096 , T385 , T531 From 8c80737f73155eb8201ea7a4e631e15b0212fafb Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Thu, 17 Nov 2022 18:21:05 +0100 Subject: [PATCH 025/219] fix test? --- tests/pos/T2093.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/pos/T2093.hs b/tests/pos/T2093.hs index 67a5591950..6273cf5f97 100644 --- a/tests/pos/T2093.hs +++ b/tests/pos/T2093.hs @@ -3,6 +3,7 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE GADTs #-} {-@ embed GHC.Natural.Natural as int @-} +{-@ embed GHC.Num.Natural.Natural as int @-} {-@ LIQUID "--no-totality" @-} module T2093 where From 417c031a4022151818e74ba175db815690f77f01 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 23 Nov 2022 16:31:10 +1300 Subject: [PATCH 026/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Constraint --- src/Language/Haskell/Liquid/Constraint/Constraint.hs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Constraint.hs b/src/Language/Haskell/Liquid/Constraint/Constraint.hs index e839a6d2a9..982d7ac9ec 100644 --- a/src/Language/Haskell/Liquid/Constraint/Constraint.hs +++ b/src/Language/Haskell/Liquid/Constraint/Constraint.hs @@ -1,7 +1,5 @@ {-# LANGUAGE FlexibleInstances #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -- TODO: what exactly is the purpose of this module? What do these functions do? module Language.Haskell.Liquid.Constraint.Constraint ( @@ -37,18 +35,18 @@ constraintToLogicOne γ binds (last (fst <$> xts), r)) | xts <- xss] where - xts = init binds - (xs, ts) = unzip xts + symRts = init binds + (xs, ts) = unzip symRts r = snd $ last binds xss = combinations ((\t -> [(x, t) | x <- localBindsOfType t γ]) <$> ts) subConstraintToLogicOne :: (Foldable t, Reftable r, Reftable r1) => t (Symbol, (Symbol, RType t1 t2 r)) -> (Symbol, (Symbol, RType t3 t4 r1)) -> Expr -subConstraintToLogicOne xts (x', (x, t)) = PImp (pAnd rs) r +subConstraintToLogicOne xts (sym', (sym, rt)) = PImp (pAnd rs) r where - (rs , su) = foldl go ([], []) xts - ([r], _ ) = go ([], su) (x', (x, t)) + (rs , symExprs) = foldl go ([], []) xts + ([r], _ ) = go ([], symExprs) (sym', (sym, rt)) go (acc, su) (x', (x, t)) = let (Reft(v, p)) = toReft (fromMaybe mempty (stripRTypeBase t)) su' = (x', EVar x):(v, EVar x) : su in From ca7c1787eafa21d7ddfe878607360192aec0bde7 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 23 Nov 2022 16:34:07 +1300 Subject: [PATCH 027/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Env --- src/Language/Haskell/Liquid/Constraint/Env.hs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Env.hs b/src/Language/Haskell/Liquid/Constraint/Env.hs index 02a9c60748..76fdb9009d 100644 --- a/src/Language/Haskell/Liquid/Constraint/Env.hs +++ b/src/Language/Haskell/Liquid/Constraint/Env.hs @@ -7,8 +7,6 @@ {-# LANGUAGE ImplicitParams #-} {-# LANGUAGE PartialTypeSignatures #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -- | This module defines the representation for Environments needed -- during constraint generation. @@ -165,8 +163,8 @@ addCGEnv tx γ (eMsg, x, REx y tyy tyx) = do γ' <- addCGEnv tx γ (eMsg, y', tyy) addCGEnv tx γ' (eMsg, x, tyx `F.subst1` (y, F.EVar y')) -addCGEnv tx γ (eMsg, x, RAllE yy tyy tyx) - = addCGEnv tx γ (eMsg, x, t) +addCGEnv tx γ (eMsg, sym, RAllE yy tyy tyx) + = addCGEnv tx γ (eMsg, sym, t) where xs = localBindsOfType tyy (renv γ) t = L.foldl' F.meet ttrue [ tyx' `F.subst1` (yy, F.EVar x) | x <- xs] From 4f5cf187569e82185eb48361d81c6ad4454d16e7 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 23 Nov 2022 16:55:57 +1300 Subject: [PATCH 028/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Generate --- .../Haskell/Liquid/Constraint/Generate.hs | 147 +++++++++--------- 1 file changed, 73 insertions(+), 74 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Generate.hs b/src/Language/Haskell/Liquid/Constraint/Generate.hs index 72ea564dcc..4d7cf34bb8 100644 --- a/src/Language/Haskell/Liquid/Constraint/Generate.hs +++ b/src/Language/Haskell/Liquid/Constraint/Generate.hs @@ -13,7 +13,6 @@ {-# LANGUAGE ImplicitParams #-} {-# OPTIONS_GHC -Wno-orphans #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} -- | This module defines the representation of Subtyping and WF Constraints, -- and the code for syntax-directed constraint generation. @@ -136,7 +135,7 @@ makeDecrIndex (x, Asserted t, args) makeDecrIndex _ = return [] makeDecrIndexTy :: Var -> SpecType -> [Var] -> CG (Either (TError t) [Int]) -makeDecrIndexTy x t args +makeDecrIndexTy x st args = do spDecr <- gets specDecr autosz <- gets autoSize hint <- checkHint' autosz (L.lookup x spDecr) @@ -148,7 +147,7 @@ makeDecrIndexTy x t args tvs = zip ts args msg = ErrTermin (getSrcSpan x) [F.pprint x] (text "No decreasing parameter") cenv = makeNumEnv ts - trep = toRTypeRep $ unOCons t + trep = toRTypeRep $ unOCons st p autosz (t, v) = isDecreasing autosz cenv t && not (isIdTRecBound v) checkHint' autosz = checkHint x ts (isDecreasing autosz cenv) @@ -260,9 +259,9 @@ consCBLet γ cb = do -------------------------------------------------------------------------------- consCBTop :: Config -> TargetInfo -> CGEnv -> CoreBind -> CG CGEnv -------------------------------------------------------------------------------- -consCBTop cfg info γ cb +consCBTop cfg info cgenv cb | all (trustVar cfg info) xs - = foldM addB γ xs + = foldM addB cgenv xs where xs = bindersOf cb tt = trueTy (typeclass cfg) . varType @@ -308,32 +307,32 @@ consCBSizedTys γ xes = do xets <- forM xes $ \(x, e) -> fmap (x, e,) (varTemplate γ (x, Just e)) autoenv <- gets autoSize ts <- mapM (T.mapM refreshArgs) (thd3 <$> xets) - let vs = zipWith collectArgs ts es - is <- mapM makeDecrIndex (zip3 xs ts vs) >>= checkSameLens - let xeets = (\vis -> [(vis, x) | x <- zip3 xs is $ map unTemplate ts]) <$> zip vs is - _ <- mapM checkIndex (zip4 xs vs ts is) >>= checkEqTypes . L.transpose + let vs = zipWith collectArgs' ts es + is <- mapM makeDecrIndex (zip3 vars ts vs) >>= checkSameLens + let xeets = (\vis -> [(vis, x) | x <- zip3 vars is $ map unTemplate ts]) <$> zip vs is + _ <- mapM checkIndex (zip4 vars vs ts is) >>= checkEqTypes . L.transpose let rts = (recType autoenv <$>) <$> xeets - let xts = zip xs ts + let xts = zip vars ts γ' <- foldM extender γ xts - let γs = zipWith makeRecInvariants [γ' `setTRec` zip xs rts' | rts' <- rts] (filter (not . noMakeRec) <$> vs) - let xets' = zip3 xs es ts + let γs = zipWith makeRecInvariants [γ' `setTRec` zip vars rts' | rts' <- rts] (filter (not . noMakeRec) <$> vs) + let xets' = zip3 vars es ts mapM_ (uncurry $ consBind True) (zip γs xets') return γ' where noMakeRec = if allowTC then GM.isEmbeddedDictVar else GM.isPredVar allowTC = typeclass (getConfig γ) - (xs, es) = unzip xes - dxs = F.pprint <$> xs - collectArgs = GM.collectArguments . length . ty_binds . toRTypeRep . unOCons . unTemplate + (vars, es) = unzip xes + dxs = F.pprint <$> vars + collectArgs' = GM.collectArguments . length . ty_binds . toRTypeRep . unOCons . unTemplate checkEqTypes :: [[Maybe SpecType]] -> CG [[SpecType]] - checkEqTypes x = mapM (checkAll err1 toRSort) (catMaybes <$> x) - checkSameLens = checkAll err2 length + checkEqTypes x = mapM (checkAll' err1 toRSort) (catMaybes <$> x) + checkSameLens = checkAll' err2 length err1 = ErrTermin loc dxs $ text "The decreasing parameters should be of same type" err2 = ErrTermin loc dxs $ text "All Recursive functions should have the same number of decreasing parameters" - loc = getSrcSpan (head xs) + loc = getSrcSpan (head vars) - checkAll _ _ [] = return [] - checkAll err f (x:xs) + checkAll' _ _ [] = return [] + checkAll' err f (x:xs) | all (== f x) (f <$> xs) = return (x:xs) | otherwise = addWarning err >> return [] @@ -341,7 +340,7 @@ consCBWithExprs :: CGEnv -> [(Var, CoreExpr)] -> CG CGEnv consCBWithExprs γ xes = do xets <- forM xes $ \(x, e) -> fmap (x, e,) (varTemplate γ (x, Just e)) texprs <- gets termExprs - let xtes = mapMaybe (`lookup` texprs) xs + let xtes = mapMaybe (`lookup'` texprs) xs let ts = safeFromAsserted err . thd3 <$> xets ts' <- mapM refreshArgs ts let xts = zip xs (Asserted <$> ts') @@ -351,8 +350,8 @@ consCBWithExprs γ xes mapM_ (uncurry $ consBind True) (zip γs xets') return γ' where (xs, es) = unzip xes - lookup k m | Just x <- M.lookup k m = Just (k, x) - | otherwise = Nothing + lookup' k m | Just x <- M.lookup k m = Just (k, x) + | otherwise = Nothing err = "Constant: consCBWithExprs" makeTermEnvs :: CGEnv -> [(Var, [F.Located F.Expr])] -> [(Var, CoreExpr)] @@ -360,19 +359,19 @@ makeTermEnvs :: CGEnv -> [(Var, [F.Located F.Expr])] -> [(Var, CoreExpr)] -> [CGEnv] makeTermEnvs γ xtes xes ts ts' = setTRec γ . zip xs <$> rts where - vs = zipWith collectArgs ts es - ys = fst5 . bkArrowDeep <$> ts - ys' = fst5 . bkArrowDeep <$> ts' - sus' = zipWith mkSub ys ys' - sus = zipWith mkSub ys ((F.symbol <$>) <$> vs) + vs = zipWith collectArgs' ts ces + syms = fst5 . bkArrowDeep <$> ts + syms' = fst5 . bkArrowDeep <$> ts' + sus' = zipWith mkSub syms syms' + sus = zipWith mkSub syms ((F.symbol <$>) <$> vs) ess = (\x -> safeFromJust (err x) (x `L.lookup` xtes)) <$> xs tes = zipWith (\su es -> F.subst su <$> es) sus ess tes' = zipWith (\su es -> F.subst su <$> es) sus' ess rss = zipWith makeLexRefa tes' <$> (repeat <$> tes) rts = zipWith (addObligation OTerm) ts' <$> rss - (xs, es) = unzip xes + (xs, ces) = unzip xes mkSub ys ys' = F.mkSubst [(x, F.EVar y) | (x, y) <- zip ys ys'] - collectArgs = GM.collectArguments . length . ty_binds . toRTypeRep + collectArgs' = GM.collectArguments . length . ty_binds . toRTypeRep err x = "Constant: makeTermEnvs: no terminating expression for " ++ GM.showPpr x addObligation :: Oblig -> SpecType -> RReft -> SpecType @@ -390,7 +389,7 @@ consCB :: Bool -> Bool -> CGEnv -> CoreBind -> CG CGEnv consCB True _ γ (Rec xes) = do texprs <- gets termExprs modify $ \i -> i { recCount = recCount i + length xes } - let xxes = mapMaybe (`lookup` texprs) xs + let xxes = mapMaybe (`lookup'` texprs) xs if null xxes then consCBSizedTys γ xes else check xxes <$> consCBWithExprs γ xes @@ -400,7 +399,7 @@ consCB True _ γ (Rec xes) | otherwise = panic (Just loc) msg msg = "Termination expressions must be provided for all mutually recursive binders" loc = getSrcSpan (head xs) - lookup k m = (k,) <$> M.lookup k m + lookup' k m = (k,) <$> M.lookup k m -- don't do termination checking, but some strata checks? consCB _ False γ (Rec xes) @@ -435,9 +434,9 @@ consCB _ _ γ (NonRec x _ ) | isHoleVar x && typedHoles (getConfig γ) consCB _ _ γ (NonRec x def) | Just (w, τ) <- grepDictionary def , Just d <- dlookup (denv γ) w - = do t <- mapM (trueTy (typeclass (getConfig γ))) τ - mapM_ addW (WfC γ <$> t) - let xts = dmap (fmap (f t)) d + = do st <- mapM (trueTy (typeclass (getConfig γ))) τ + mapM_ addW (WfC γ <$> st) + let xts = dmap (fmap (f st)) d let γ' = γ { denv = dinsert (denv γ) x xts } t <- trueTy (typeclass (getConfig γ)) (varType x) extender γ' (x, Assumed t) @@ -467,24 +466,24 @@ consBind _ _ (x, _, Assumed t) | RecSelId {} <- idDetails x -- don't check record selectors with assumed specs = return $ F.notracepp ("TYPE FOR SELECTOR " ++ show x) $ Assumed t -consBind isRec γ (x, e, Asserted spect) +consBind isRec' γ (x, e, Asserted spect) = do let γ' = γ `setBind` x (_,πs,_) = bkUniv spect - γπ <- foldM addPToEnv γ' πs + cgenv <- foldM addPToEnv γ' πs -- take implcits out of the function's SpecType and into the env let tyr = toRTypeRep spect let spect' = fromRTypeRep (tyr { ty_ebinds = [], ty_einfo = [], ty_eargs = [], ty_erefts = [] }) - γπ <- foldM (+=) γπ $ (\(y,t)->("implicitError",y,t)) <$> zip (ty_ebinds tyr) (ty_eargs tyr) + γπ <- foldM (+=) cgenv $ (\(y,t)->("implicitError",y,t)) <$> zip (ty_ebinds tyr) (ty_eargs tyr) cconsE γπ e (weakenResult (typeclass (getConfig γ)) x spect') when (F.symbol x `elemHEnv` holes γ) $ -- have to add the wf constraint here for HOLEs so we have the proper env addW $ WfC γπ $ fmap killSubst spect - addIdA x (defAnn isRec spect) + addIdA x (defAnn isRec' spect) return $ Asserted spect -consBind isRec γ (x, e, Internal spect) +consBind isRec' γ (x, e, Internal spect) = do let γ' = γ `setBind` x (_,πs,_) = bkUniv spect γπ <- foldM addPToEnv γ' πs @@ -493,23 +492,23 @@ consBind isRec γ (x, e, Internal spect) when (F.symbol x `elemHEnv` holes γ) $ -- have to add the wf constraint here for HOLEs so we have the proper env addW $ WfC γπ $ fmap killSubst spect - addIdA x (defAnn isRec spect) + addIdA x (defAnn isRec' spect) return $ Internal spect where explanation = "Cannot give singleton type to the function definition." -consBind isRec γ (x, e, Assumed spect) +consBind isRec' γ (x, e, Assumed spect) = do let γ' = γ `setBind` x γπ <- foldM addPToEnv γ' πs cconsE γπ e =<< true (typeclass (getConfig γ)) spect - addIdA x (defAnn isRec spect) + addIdA x (defAnn isRec' spect) return $ Asserted spect where πs = ty_preds $ toRTypeRep spect -consBind isRec γ (x, e, Unknown) +consBind isRec' γ (x, e, Unknown) = do t' <- consE (γ `setBind` x) e t <- topSpecType x t' - addIdA x (defAnn isRec t) + addIdA x (defAnn isRec' t) when (GM.isExternalId x) (addKuts x t) return $ Asserted t @@ -701,13 +700,13 @@ lambdaSingleton _ _ _ _ = return mempty addForAllConstraint :: CGEnv -> Var -> CoreExpr -> SpecType -> CG () -addForAllConstraint γ _ _ (RAllT a t r) - | F.isTauto r +addForAllConstraint γ _ _ (RAllT rtv rt rr) + | F.isTauto rr = return () | otherwise - = do t' <- true (typeclass (getConfig γ)) t - let truet = RAllT a $ unRAllP t' - addC (SubC γ (truet mempty) $ truet r) "forall constraint true" + = do t' <- true (typeclass (getConfig γ)) rt + let truet = RAllT rtv $ unRAllP t' + addC (SubC γ (truet mempty) $ truet rr) "forall constraint true" where unRAllP (RAllT a t r) = RAllT a (unRAllP t) r unRAllP (RAllP _ t) = unRAllP t unRAllP t = t @@ -867,12 +866,12 @@ consE γ e'@(App e a) | Just aDict <- getExprDict γ a consE γ e'@(App e a) = do ([], πs, te) <- bkUniv <$> consE γ {- GM.tracePpr ("APP-EXPR: " ++ GM.showPpr (exprType e)) -} e - te' <- instantiatePreds γ e' $ foldr RAllP te πs - (γ', te''') <- dropExists γ te' - te'' <- dropConstraints γ te''' - updateLocA (exprLoc e) te'' - (hasGhost, γ'', te''') <- instantiateGhosts γ' te'' - let RFun x _ tx t _ = checkFun ("Non-fun App with caller ", e') γ te''' + te1 <- instantiatePreds γ e' $ foldr RAllP te πs + (γ', te2) <- dropExists γ te1 + te3 <- dropConstraints γ te2 + updateLocA (exprLoc e) te3 + (hasGhost, γ'', te4) <- instantiateGhosts γ' te3 + let RFun x _ tx t _ = checkFun ("Non-fun App with caller ", e') γ te4 cconsE γ'' a tx tout <- makeSingleton γ'' (simplify e') <$> addPost γ'' (maybe (checkUnbound γ'' e' x t a) (F.subst1 t . (x,)) (argExpr γ $ simplify a)) if hasGhost @@ -1175,14 +1174,14 @@ dropExists γ (REx x tx t) = (, t) <$> γ += ("dropExists", x, tx) dropExists γ t = return (γ, t) dropConstraints :: CGEnv -> SpecType -> CG SpecType -dropConstraints γ (RFun x i tx@(RApp c _ _ _) t r) | isErasable c - = flip (RFun x i tx) r <$> dropConstraints γ t +dropConstraints cgenv (RFun x i tx@(RApp c _ _ _) t r) | isErasable c + = flip (RFun x i tx) r <$> dropConstraints cgenv t where - isErasable = if typeclass (getConfig γ) then isEmbeddedDict else isClass -dropConstraints γ (RRTy cts _ OCons t) - = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) γ xts + isErasable = if typeclass (getConfig cgenv) then isEmbeddedDict else isClass +dropConstraints cgenv (RRTy cts _ OCons rt) + = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) cgenv xts addC (SubC γ' t1 t2) "dropConstraints" - dropConstraints γ t + dropConstraints cgenv rt where (xts, t1, t2) = envToSub cts @@ -1212,9 +1211,9 @@ caseEnv γ x _ (DataAlt c) ys pIs = do let (x' : ys') = F.symbol <$> (x:ys) xt0 <- checkTyCon ("checkTycon cconsCase", x) γ <$> γ ??= x - let xt = shiftVV xt0 x' + let rt = shiftVV xt0 x' tdc <- γ ??= dataConWorkId c >>= refreshVV - let (rtd,yts',_) = unfoldR tdc xt ys + let (rtd,yts',_) = unfoldR tdc rt ys yts <- projectTypes (typeclass (getConfig γ)) pIs yts' let ys'' = F.symbol <$> filter (not . if allowTC then GM.isEmbeddedDictVar else GM.isEvVar) ys let r1 = dataConReft c ys'' @@ -1253,7 +1252,7 @@ ignoreSelf = F.mapExpr (\r -> if selfSymbol `elem` F.syms r then F.PTrue else r) -------------------------------------------------------------------------------- projectTypes :: Bool -> Maybe [Int] -> [SpecType] -> CG [SpecType] projectTypes _ Nothing ts = return ts -projectTypes allowTC (Just is) ts = mapM (projT is) (zip [0..] ts) +projectTypes allowTC (Just ints) ts = mapM (projT ints) (zip [0..] ts) where projT is (j, t) | j `elem` is = return t @@ -1324,8 +1323,8 @@ varAnn γ x t -- | Helpers: Creating Fresh Refinement ------------------------------- ----------------------------------------------------------------------- freshPredRef :: CGEnv -> CoreExpr -> PVar RSort -> CG SpecProp -freshPredRef γ e (PV _ (PVProp τ) _ as) - = do t <- freshTyType (typeclass (getConfig γ)) PredInstE e (toType False τ) +freshPredRef γ e (PV _ (PVProp rsort) _ as) + = do t <- freshTyType (typeclass (getConfig γ)) PredInstE e (toType False rsort) args <- mapM (const fresh) as let targs = [(x, s) | (x, (s, y, z)) <- zip args as, F.EVar y == z ] γ' <- foldM (+=) γ [("freshPredRef", x, ofRSort τ) | (x, τ) <- targs] @@ -1391,13 +1390,13 @@ varRefType γ x = varRefType' :: CGEnv -> Var -> SpecType -> SpecType varRefType' γ x t' | Just tys <- trec γ, Just tr <- M.lookup x' tys - = strengthen tr xr + = strengthen' tr xr | otherwise - = strengthen t' xr + = strengthen' t' xr where xr = singletonReft x x' = F.symbol x - strengthen + strengthen' | higherOrderFlag γ = strengthenMeet | otherwise @@ -1405,8 +1404,8 @@ varRefType' γ x t' -- | create singleton types for function application makeSingleton :: CGEnv -> CoreExpr -> SpecType -> SpecType -makeSingleton γ e t - | higherOrderFlag γ, App f x <- simplify e +makeSingleton γ cexpr t + | higherOrderFlag γ, App f x <- simplify cexpr = case (funExpr γ f, argForAllExpr x) of (Just f', Just x') | not (if typeclass (getConfig γ) then GM.isEmbeddedDictExpr x else GM.isPredExpr x) -- (isClassPred $ exprType x) @@ -1415,7 +1414,7 @@ makeSingleton γ e t -> strengthenMeet t (uTop $ F.exprReft f') _ -> t | rankNTypes (getConfig γ) - = case argExpr γ (simplify e) of + = case argExpr γ (simplify cexpr) of Just e' -> strengthenMeet t $ uTop (F.exprReft e') _ -> t | otherwise @@ -1494,7 +1493,7 @@ isType a = eqType (exprType a) predType -- | @isGenericVar@ determines whether the @RTyVar@ has no class constraints isGenericVar :: RTyVar -> SpecType -> Bool -isGenericVar α t = all (\(c, α') -> (α'/=α) || isGenericClass c ) (classConstrs t) +isGenericVar α st = all (\(c, α') -> (α'/=α) || isGenericClass c ) (classConstrs st) where classConstrs t = [(c, ty_var_value α') | (c, ts) <- tyClasses t From d7119d858ab8635501470f7750e67f8b267395cb Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 23 Nov 2022 17:03:43 +1300 Subject: [PATCH 029/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Init --- src/Language/Haskell/Liquid/Constraint/Init.hs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Init.hs b/src/Language/Haskell/Liquid/Constraint/Init.hs index df04319fb7..11f0d105f7 100644 --- a/src/Language/Haskell/Liquid/Constraint/Init.hs +++ b/src/Language/Haskell/Liquid/Constraint/Init.hs @@ -6,8 +6,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -- | This module defines the representation of Subtyping and WF Constraints, -- and the code for syntax-directed constraint generation. @@ -83,7 +81,6 @@ initEnv info is autoinv = mkRTyConInv (gsInvariants (gsData sp) ++ ((Nothing,) <$> autoinv)) addPolyInfo' = if reflection (getConfig info) then map (mapSnd addPolyInfo) else id - mapSndM f (x,y) = (x,) <$> f y makeExactDc dcs = if exactDCFlag info then map strengthenDataConType dcs else dcs addPolyInfo :: SpecType -> SpecType @@ -100,9 +97,9 @@ makeDataConTypes allowTC x = (x,) <$> trueTy allowTC (varType x) makeAutoDecrDataCons :: [(Id, SpecType)] -> S.HashSet TyCon -> [Id] -> ([LocSpecType], [(Id, SpecType)]) makeAutoDecrDataCons dcts specenv dcs - = (simplify invs, tys) + = (simplify rsorts, tys) where - (invs, tys) = unzip $ concatMap go tycons + (rsorts, tys) = unzip $ concatMap go tycons tycons = L.nub $ mapMaybe idTyCon dcs go tycon @@ -123,8 +120,8 @@ makeSizedDataCons :: [(Id, SpecType)] -> DataCon -> Integer -> (RSort, (Id, Spec makeSizedDataCons dcts x' n = (toRSort $ ty_res trep, (x, fromRTypeRep trep{ty_res = tres})) where x = dataConWorkId x' - t = fromMaybe (impossible Nothing "makeSizedDataCons: this should never happen") $ L.lookup x dcts - trep = toRTypeRep t + st = fromMaybe (impossible Nothing "makeSizedDataCons: this should never happen") $ L.lookup x dcts + trep = toRTypeRep st tres = ty_res trep `strengthen` MkUReft (F.Reft (F.vv_, F.PAtom F.Eq (lenOf F.vv_) computelen)) mempty recarguments = filter (\(t,_) -> toRSort t == toRSort tres) (zip (ty_args trep) (ty_binds trep)) From 9189fb000c3a5f602f2e7ecbf956468209b22c3e Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Wed, 23 Nov 2022 17:05:30 +1300 Subject: [PATCH 030/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Monad --- .../Haskell/Liquid/Constraint/Monad.hs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Monad.hs b/src/Language/Haskell/Liquid/Constraint/Monad.hs index 5da6107ebb..eeafc7db5a 100644 --- a/src/Language/Haskell/Liquid/Constraint/Monad.hs +++ b/src/Language/Haskell/Liquid/Constraint/Monad.hs @@ -4,8 +4,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Constraint.Monad where import qualified Data.HashMap.Strict as M @@ -41,18 +39,18 @@ addC c _msg -------------------------------------------------------------------------------- addPost :: CGEnv -> SpecType -> CG SpecType -------------------------------------------------------------------------------- -addPost γ (RRTy e r OInv t) - = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("addPost", x,t)) γ e - addC (SubR γ' OInv r) "precondition-oinv" >> return t +addPost cgenv (RRTy e r OInv rt) + = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("addPost", x,t)) cgenv e + addC (SubR γ' OInv r) "precondition-oinv" >> return rt -addPost γ (RRTy e r OTerm t) - = do γ' <- foldM (\γ (x, t) -> γ += ("addPost", x, t)) γ e - addC (SubR γ' OTerm r) "precondition-oterm" >> return t +addPost cgenv (RRTy e r OTerm rt) + = do γ' <- foldM (\γ (x, t) -> γ += ("addPost", x, t)) cgenv e + addC (SubR γ' OTerm r) "precondition-oterm" >> return rt -addPost γ (RRTy cts _ OCons t) - = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) γ xts +addPost cgenv (RRTy cts _ OCons rt) + = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) cgenv xts addC (SubC γ' t1 t2) "precondition-ocons" - addPost γ t + addPost cgenv rt where (xts, t1, t2) = envToSub cts addPost _ t From bff5406143341c10d755250bd4e15e9d72d3c8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 6 Aug 2022 22:44:46 -0300 Subject: [PATCH 031/219] A test verifying permutations --- tests/ple/pos/Permutations.hs | 831 ++++++++++++++++++++++++++++++++++ tests/tests.cabal | 1 + 2 files changed, 832 insertions(+) create mode 100644 tests/ple/pos/Permutations.hs diff --git a/tests/ple/pos/Permutations.hs b/tests/ple/pos/Permutations.hs new file mode 100644 index 0000000000..b349a1e0e2 --- /dev/null +++ b/tests/ple/pos/Permutations.hs @@ -0,0 +1,831 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +-- | This module proves that unoptimized implementations of +-- 'Data.List.permutations' are equivalent to the optimized +-- implementation in [1]. +-- +-- Additionally, this module offers a proof of an approximation of the +-- laziness requirement on permutations. See 'lemmaPermutationsDecomposition'. +-- +-- [1] https://gitlab.haskell.org/ghc/ghc/-/blob/aec5a443bc45ca99cfeedc1777edb0aceca142cf/libraries/base/Data/OldList.hs#L1263 +-- +module Permutations where + +import Language.Haskell.Liquid.ProofCombinators ((===), (***), QED(Admit, QED), (?), pleUnfold) + +-- We need to redefine operations from the base package in order to +-- have PLE reason with them. PLE is one of the algorithms in +-- liquid-fixpoint that unfolds definitions automatically in proofs. +-- +-- Therefore, we hide here the definitions comming from the Prelude. +-- In an ideal world, we would be able to use the original definitions +-- from base, and still would be able to use PLE. +-- +import Prelude hiding ((!!), (++), asTypeOf, concat, const, drop, foldr, id, map, take, reverse) + +-- The following infixr directives are processed by Liquid Haskell. +-- +-- They instruct the parser about the fixity and associativity of +-- operators when reading specifications. +-- +{-@ infixr 5 ++ @-} +{-@ infixr 5 : @-} +{-@ infixl 9 !! @-} + + +-- We write first the definition of the optimized permutations. +-- +-- The implementation in base uses local definitions in where clauses. +-- We split it here in top-level functions to better reason about +-- them in isolation. But it is possible to give Liquid Haskell +-- specifications to local functions as well. + +-- Liquid Haskell requires functions to be terminating, in order +-- to ensure soundness of the verified specifications. +-- +-- We disable the termination checker with the lazy directive though. +-- The termination checker is a bit tricky to convince once we start +-- adding lemmas that refer to permutations calls in their parameters. +-- +-- The termination of permutations is checked +-- [here](https://github.com/ucsd-progsys/liquidhaskell/blob/d20d80d53949efbb7d2ac6eb1509a0ec822d3bea/tests/pos/Permutation.hs) +-- though. +-- +{-@ lazy permutations @-} +{-@ reflect permutations @-} +{-@ permutations :: ts:[a] -> [[a]] / [(len ts), 1, 0] @-} +permutations :: [a] -> [[a]] +permutations xs0 = xs0 : perms xs0 [] + +-- @permutations xs0@ is equivalent to the following expressions +-- +-- > xs0 : concat [ interleave (ts!!n) (drop (n+1) xs0) xs [] | n <- [0..len xs0 - 1], xs <- permutations (reverse (take n xs0)) ] +-- > [ insertAt m (xs0!!n) xs ++ (drop (n+1) xs0) | n <- [0..len xs0 - 1], xs <- permutations (reverse (take n xs0)), m <- [0..len xs - 1] ] +-- + + +-- | @perms ts is@ is equivalent to the following expressions +-- +-- > concat [ interleave (ts!!n) (drop (n+1) ts) xs [] | n <- [0..len ts - 1], xs <- permutations (reverse (take n ts) ++ is) ] +-- > [ insertAt m (ts!!n) xs ++ (drop (n+1) ts) | n <- [0..len ts - 1], xs <- permutations (reverse (take n ts) ++ is), m <- [0..len xs - 1] ] +-- +-- The specification differs from this expressions in a few syntactic +-- aspects. +-- +-- 1) List ranges are not allowed in formulas. Therefore, we use the +-- function 'fromTo'. +-- 2) List comprehensions are not allowed in formulas. Therefore, we +-- use functions 'concat' and 'map' instead. +-- 3) Lambda expressions do not work well in formulas. Therefore, we +-- use top-level functions 'aux1' and 'aux2' instead. + +{-@ +reflect perms +perms + :: ts:[a] + -> is:[a] + -> { v:[[a]] + | v = concat (map (aux2 ts is) (fromTo 0 (len ts - 1))) + } / [((len ts)+(len is)), 0, (len ts)] +@-} +perms :: [a] -> [a] -> [[a]] +perms [] _ = [] +perms (t0:ts0) is = + mapInterleave t0 ts0 (permutations is) (perms ts0 (t0:is)) + `const` + lemmaMapAux2 t0 ts0 is 0 (length ts0 - 1) + `const` + lemmaAppendAssoc + (concat (map (aux1 t0 ts0 []) (permutations is))) + [] + (concat (map (aux2 (t0:ts0) is) (fromTo 1 (length (t0:ts0) - 1)))) + `const` + mapInterleave t0 ts0 (permutations is) [] + +-- For efficiency of the verification process, proofs are given in +-- condensed form as above. The form starts from an expressions that +-- is the result of the function, with multiple lemma applications +-- appended with 'const'. +-- +-- Discovering which lemma applications are needed is done by writing +-- a longer step-by-step proof, where the need for each lemma can be +-- observed between steps. +-- +-- We start by writing the step-by-step proof, testing each new addition +-- with Liquid Haskell. When we are finished, we comment out the +-- step-by-step proof, and collect the lemmas into the condensed proof. +-- + +{- + `asTypeOf` + const (concat (map (aux1 t0 ts0 []) (permutations is)) ++ perms ts0 (t0:is)) + (mapInterleave t0 ts0 (permutations is) (perms ts0 (t0:is))) + `asTypeOf` + const (concat (map (aux1 t0 ts0 []) (permutations is)) ++ concat (map (aux2 ts0 (t0:is)) (fromTo 0 (length ts0 - 1)))) + (perms ts0 (t0:is)) + `asTypeOf` + const (concat (map (aux1 t0 ts0 []) (permutations is)) ++ concat (map (aux2 (t0:ts0) is) (fromTo 1 (length (t0:ts0) - 1)))) + (lemmaMapAux2 t0 ts0 is 0 (length ts0 - 1)) + `asTypeOf` + (concat (map (aux1 t0 ts0 []) (permutations is)) ++ ([] ++ concat (map (aux2 (t0:ts0) is) (fromTo 1 (length (t0:ts0) - 1))))) + `asTypeOf` + const ((concat (map (aux1 t0 ts0 []) (permutations is)) ++ []) ++ concat (map (aux2 (t0:ts0) is) (fromTo 1 (length (t0:ts0) - 1)))) + (lemmaAppendAssoc + (concat (map (aux1 t0 ts0 []) (permutations is))) + [] + (concat (map (aux2 (t0:ts0) is) (fromTo 1 (length (t0:ts0) - 1)))) + ) + `asTypeOf` + (mapInterleave t0 ts0 (permutations is) [] ++ concat (map (aux2 (t0:ts0) is) (fromTo 1 (length (t0:ts0) - 1)))) + `asTypeOf` + concat (map (aux2 (t0:ts0) is) (fromTo 0 (len (t0:ts0) - 1))) +-} + +{-@ +reflect aux2 +aux2 :: ts:[a] -> [a] -> { n:Int | n < len ts && n >= 0 } -> [[a]] +@-} +aux2 :: [a] -> [a] -> Int -> [[a]] +aux2 ts is n = + mapInterleave (ts!!n) (drop (n+1) ts) (permutations (reverse (take n ts) ++ is)) [] + +{-@ reflect aux0 @-} +aux0 :: a -> ([a] -> b) -> [a] -> [a] -> Int -> b +aux0 t f ys ts n = f (insertAt n t ys ++ ts) + +{-@ reflect aux1 @-} +aux1 :: a -> [a] -> [[a]] -> [a] -> [[a]] +aux1 t ts r p = interleave t ts p r + +-- | 'mapInterleave' is not part of the optimized definition of +-- permutations. We factor it out from 'perms' to break down a +-- bit the complexity of the verification. +-- +-- @mapInterleave t ts ps r@ is equivalent to the expressions +-- +-- > concat [ interleave t ts xs [] | xs <- ps ] ++ r +-- > [ insertAt n t xs ++ ts | xs <- ps, n <- [0..len xs - 1] ] ++ r +-- + +{-@ +reflect mapInterleave +mapInterleave + :: t:a + -> ts:[a] + -> ps:[[a]] + -> r:[[a]] + -> { v:[[a]] | v == concat (map (aux1 t ts []) ps) ++ r } +@-} +mapInterleave :: a -> [a] -> [[a]] -> [[a]] -> [[a]] +mapInterleave t ts ps r = foldr (interleave t ts) r ps `const` lemmaFoldrInterleave t ts ps r + +-- | @interleave t ts xs r@ is equivalent to the expression +-- +-- > [ insertAt n t xs ++ ts | n <- [0..len xs - 1] ] ++ r +-- + +{-@ +reflect interleave +interleave + :: t:a + -> ts:[a] + -> xs:[a] + -> r:[[a]] + -> { v:[[a]] | v == map (aux0 t id xs ts) (fromTo 0 (len xs - 1)) ++ r } +@-} +interleave :: a -> [a] -> [a] -> [[a]] -> [[a]] +interleave t ts xs r = + let (_,zs) = interleave' t ts id xs r in zs + +-- | @interleave' t ts f ys r@ is equivalent to the expression +-- +-- > (ys ++ ts, [ f (insertAt n t ys ++ ts) | n <- [0..len ys - 1] ] ++ r) +-- + +{-@ +reflect interleave' +interleave' + :: t:a + -> ts:[a] + -> f:([a] -> b) + -> ys:[a] + -> r:[b] + -> ( { v:[a] | v == ys ++ ts } + , { v:[b] | v == map (aux0 t f ys ts) (fromTo 0 (len ys-1)) ++ r } + ) +@-} +interleave' :: a -> [a] -> ([a] -> b) -> [a] -> [b] -> ([a], [b]) +interleave' t ts _ [] r = (ts, r) +interleave' t ts f (y:ys) r = + let (us, zs) = interleave' t ts (snoc f y) ys r + in (y:us, f (t:y:us) : zs `const` (lemmaMapAux0 t f y ys ts 0 (length ys - 1))) + + +--------------------------------- +-- Laziness requirement +--------------------------------- + +-- | The documentation of 'Data.List.permutations' states the laziness +-- requirement as follows +-- +-- > map (take n) (take (factorial n) $ permutations ([1..n] ++ undefined)) +-- > = +-- > permutations [1..n] +-- +-- This property cannot be proved with Liquid Haskell as partially +-- defined lists are not representable in formulas. Therefore, we +-- would have to content ourselves with the weaker +-- +-- > map (take n) (take (factorial n) $ permutations ([1..n] ++ r)) +-- > = +-- > permutations [1..n] +-- +-- where @r@ stands for any list. +-- +-- Now, when working out the proof, I didn't feel in the mood of +-- computing the lengths of the lists returned by all of the functions +-- implementing permutations, and therefore I aimed to rephrase the +-- property without calls to 'take'. I arrived first to +-- +-- > take (factorial n) (permutations ([1..n] ++ r)) +-- > = +-- > map (++ r) (permutations [1..n]) +-- +-- and then to +-- +-- > permutations ([1..n] ++ r) +-- > = +-- > map (++ r) (permutations [1..n]) ++ residue n r +-- +-- where 'residue' is some expression that we really don't care about +-- when considering the laziness requirement. Below are two +-- formulations of it. +-- +-- > residue n sfx = concat (map (aux2 ([1..n] ++ sfx) []) (fromTo n (n + len sfx - 1))) +-- > residue n sfx = +-- > concat +-- > [ concat [ interleave (sfx!!m) (drop (m+1) sfx) xs [] +-- > | xs <- permutations (reverse ([1..n] ++ take m sfx)) +-- > ] +-- > | m <- [0 .. length sfx - 1] +-- > ] +-- + +{-@ +lemmaPermutationsDecomposition + :: { n:Int | n >= 0 } + -> r:[Int] + -> { permutations (fromTo 1 n ++ r) + == + map (flipAppend r) (permutations (fromTo 1 n)) ++ concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + len r - 1))) + } +@-} +lemmaPermutationsDecomposition :: Int -> [Int] -> () +lemmaPermutationsDecomposition n r = lemmaPermsDecomposition n r + + +{-@ +lemmaPermsDecomposition + :: { n:Int | n >= 0 } + -> r:[Int] + -> { perms (fromTo 1 n ++ r) [] + == + map (flipAppend r) (perms (fromTo 1 n) []) ++ concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + len r - 1))) + } +@-} +lemmaPermsDecomposition :: Int -> [Int] -> () +lemmaPermsDecomposition n r = + () + `const` perms (fromTo 1 n ++ r) [] + `const` lemmaLengthAppend (fromTo 1 n) r + `const` lemmaLengthFromTo 1 n + `const` lemmaFromToSplit 0 (n - 1) (n + length r - 1) + `const` lemmaMapAppend (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (n - 1)) (fromTo n (n + length r - 1)) + `const` lemmaConcatAppend + (map (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (n - 1))) + (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + length r - 1))) + `const` lemmaConcatMapInterleave (fromTo 1 n) r 0 (n - 1) + `const` perms (fromTo 1 n) [] +{- + perms (fromTo 1 n ++ r) [] + `asTypeOf` + concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (length (fromTo 1 n ++ r) - 1))) + `asTypeOf` case lemmaLengthAppend (fromTo 1 n) r of { () -> + concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (length (fromTo 1 n) + length r - 1))) + `asTypeOf` case lemmaLengthFromTo 1 n of { () -> + concat (map (aux2 ((fromTo 1 n ++ r)) []) (fromTo 0 (n + length r - 1))) + `asTypeOf` + const (concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (n - 1) ++ fromTo n (n + length r - 1)))) + (lemmaFromToSplit 0 (n - 1) (n + length r - 1)) + `asTypeOf` + const ( + const (concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (n - 1))) + ++ concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + length r - 1))) + ) + (lemmaMapAppend (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (n - 1)) (fromTo n (n + length r - 1))) + ) + (lemmaConcatAppend + (map (aux2 (fromTo 1 n ++ r) []) (fromTo 0 (n - 1))) + (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + length r - 1))) + ) + `asTypeOf` + const (map (flipAppend r) (concat (map (aux2 (fromTo 1 n) []) (fromTo 0 (n - 1)))) + ++ concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + length r - 1)))) + (lemmaConcatMapInterleave (fromTo 1 n) r 0 (n - 1)) + `asTypeOf` + (map (flipAppend r) (concat (map (aux2 (fromTo 1 n) []) (fromTo 0 (length (fromTo 1 n) - 1)))) + ++ concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + length r - 1)))) + `asTypeOf` + (map (flipAppend r) (perms (fromTo 1 n) []) + ++ concat (map (aux2 (fromTo 1 n ++ r) []) (fromTo n (n + length r - 1)))) + }} + *** + QED +-} + + +------------------------------ +-- Auxiliary functions +------------------------------ + +infixr 5 ++ + +{-@ reflect id @-} +id :: a -> a +id x = x + +{-@ inline const @-} +const :: a -> b -> a +const x _ = x + +{-@ +inline asTypeOf +asTypeOf :: x:a -> { y:a | x = y } -> { v:a | v = x } +@-} +asTypeOf :: a -> a -> a +asTypeOf x _ = x + +{-@ reflect concat @-} +concat :: [[a]] -> [a] +concat [] = [] +concat (x:xs) = x ++ concat xs + +{-@ +reflect !! +(!!) :: xs:[a] -> { n:Int | n < len xs && n >= 0 } -> a +@-} +(!!) :: [a] -> Int -> a +(x:xs) !! 0 = x +(x:xs) !! n = xs !! (n - 1) + +{-@ reflect take @-} +take :: Int -> [a] -> [a] +take n xs + | n > 0 = + case xs of + [] -> [] + x:xs -> x : take (n-1) xs + | otherwise = + [] + +{-@ reflect drop @-} +drop :: Int -> [a] -> [a] +drop n xs + | n > 0 = + case xs of + [] -> [] + _:xs -> drop (n-1) xs + | otherwise = + xs + +{-@ reflect ++ @-} +(++) :: [a] -> [a] -> [a] +[] ++ ys = ys +(x:xs) ++ ys = x : xs ++ ys + +{-@ reflect flipAppend @-} +flipAppend :: [a] -> [a] -> [a] +flipAppend xs ys = ys ++ xs + +{-@ reflect insertAt @-} +insertAt :: Int -> a -> [a] -> [a] +insertAt n y xs = take n xs ++ y : drop n xs + +{-@ reflect map @-} +map :: (a -> b) -> [a] -> [b] +map f [] = [] +map f (x:xs) = f x : map f xs + +{-@ reflect foldr @-} +foldr :: (a -> b -> b) -> b -> [a] -> b +foldr f z [] = z +foldr f z (x:xs) = f x (foldr f z xs) + +{-@ reflect fromTo @-} +{-@ +fromTo + :: a:Int + -> b:Int + -> [{c:Int | a <= c && c <= b}] + / [b-a+1] +@-} +fromTo :: Int -> Int -> [Int] +fromTo a b = if a <= b then a : fromTo (a + 1) b + else [] + +{-@ reflect reverse @-} +reverse :: [a] -> [a] +reverse [] = [] +reverse (x:xs) = reverse xs ++ [x] + +{-@ +lemmaElemAtAppend + :: xs:[a] + -> ys:[a] + -> { i:Int | 0 <= i && i < len xs } + -> { (xs ++ ys) !! i == xs !! i } +@-} +lemmaElemAtAppend :: [a] -> [a] -> Int -> () +lemmaElemAtAppend [] _ _ = () +lemmaElemAtAppend (_:xs) ys i = + if i > 0 then lemmaElemAtAppend xs ys (i - 1) else () + +{-@ +lemmaDropAppend + :: xs:[a] + -> ys:[a] + -> { i:Int | 0 <= i && i <= len xs } + -> { drop i (xs ++ ys) == drop i xs ++ ys } +@-} +lemmaDropAppend :: [a] -> [a] -> Int -> () +lemmaDropAppend [] _ _ = () +lemmaDropAppend (_:xs) ys i = + if i > 0 then lemmaDropAppend xs ys (i - 1) else () + +{-@ +lemmaTakeAppend + :: xs:[a] + -> ys:[a] + -> { i:Int | 0 <= i && i <= len xs } + -> { take i (xs ++ ys) == take i xs } +@-} +lemmaTakeAppend :: [a] -> [a] -> Int -> () +lemmaTakeAppend [] _ _ = () +lemmaTakeAppend (_:xs) ys i = + if i > 0 then lemmaTakeAppend xs ys (i - 1) else () + +{-@ +lemmaMapAppend + :: f:(a -> b) + -> xs:[a] + -> ys:[a] + -> { map f xs ++ map f ys == map f (xs ++ ys) } +@-} +lemmaMapAppend :: (a -> b) -> [a] -> [a] -> () +lemmaMapAppend f [] ys = () +lemmaMapAppend f (_:xs) ys = lemmaMapAppend f xs ys + +{-@ +lemmaConcatAppend + :: xs:[[a]] + -> ys:[[a]] + -> { concat (xs ++ ys) = concat xs ++ concat ys } +@-} +lemmaConcatAppend :: [[a]] -> [[a]] -> () +lemmaConcatAppend [] _ = () +lemmaConcatAppend (x:xs) ys = + lemmaConcatAppend xs ys + `const` lemmaAppendAssoc x (concat xs) (concat ys) + +{-@ +lemmaLengthFromTo + :: i:Int + -> { j:Int | i <= j + 1 } + -> { len (fromTo i j) == j - i + 1 } / [j - i + 1] +@-} +lemmaLengthFromTo :: Int -> Int -> () +lemmaLengthFromTo i j = if i <= j then lemmaLengthFromTo (i + 1) j else () + +{-@ +lemmaLengthAppend + :: xs:[a] + -> ys:[a] + -> { len (xs ++ ys) == len xs + len ys } +@-} +lemmaLengthAppend :: [a] -> [a] -> () +lemmaLengthAppend [] _ = () +lemmaLengthAppend (_:xs) ys = lemmaLengthAppend xs ys + +{-@ +lemmaFromToSplit + :: a:Int + -> { b:Int | a <= b + 1 } + -> { c:Int | b <= c } + -> { fromTo a b ++ fromTo (b + 1) c == fromTo a c } / [ b - a + 1 ] +@-} +lemmaFromToSplit :: Int -> Int -> Int -> () +lemmaFromToSplit a b c = + if a + 1 <= b then lemmaFromToSplit (a+1) b c else if a <= b then () else () + +{- + if a + 1 <= b then + (fromTo a b ++ fromTo (b + 1) c) + `asTypeOf` + (a:fromTo (a+1) b ++ fromTo (b + 1) c) + `asTypeOf` + const (a:fromTo (a+1) c) + (lemmaFromToSplit (a+1) b c) + `asTypeOf` + fromTo a c + *** + QED + else + () +-} + +{-@ lemmaAppendId :: xs:[a] -> { xs = xs ++ [] } @-} +lemmaAppendId :: [a] -> () +lemmaAppendId [] = () +lemmaAppendId (_:xs) = lemmaAppendId xs + +-- | The refinement predicate in the return type is equivalent to +-- +-- > [ f (y : insertAt n t ys ts) | n <- [i..j] ] +-- > = +-- > [ f (insertAt n t (y:ys) ts) | n <- [i+1 .. j+1] ] +-- + +{-@ +lemmaMapAux0 + :: t:a + -> f:([a] -> b) + -> y:a + -> ys:[a] + -> ts:[a] + -> { i:Int | 0 <= i } + -> j:Int + -> { map (aux0 t (snoc f y) ys ts) (fromTo i j) + == map (aux0 t f (y:ys) ts) (fromTo (i+1) (j+1)) + } / [j-i+1] +@-} +lemmaMapAux0 :: a -> ([a] -> b) -> a -> [a] -> [a] -> Int -> Int -> () +lemmaMapAux0 t f y ys ts i j = + if i <= j then lemmaMapAux0 t f y ys ts (i+1) j else () + +{-@ reflect snoc @-} +snoc :: ([a] -> b) -> a -> [a] -> b +snoc f y xs = f (y : xs) + +{-@ +lemmaInterleaveAppend + :: t:a + -> ts:[a] + -> p:[a] + -> r:[[a]] + -> { interleave t ts p r == interleave t ts p [] ++ r } +@-} +lemmaInterleaveAppend :: a -> [a] -> [a] -> [[a]] -> () +lemmaInterleaveAppend t ts p r = + () + ? interleave t ts p r + ? interleave t ts p [] + ? lemmaAppendAssoc (map (aux0 t id p ts) (fromTo 0 (length p - 1))) [] r + + +--------------------------------- + +-- Doesn't work: +-- rewriteWith lemmaInterleaveAppend [lemmaAppendAssoc] + +{-@ +lemmaFoldrInterleave + :: t:a + -> ts:[a] + -> ps:[[a]] + -> r:[[a]] + -> { foldr (interleave t ts) r ps == concat (map (aux1 t ts []) ps) ++ r } +@-} +lemmaFoldrInterleave :: a -> [a] -> [[a]] -> [[a]] -> () +lemmaFoldrInterleave t ts [] r = () +lemmaFoldrInterleave t ts (p:ps) r = + lemmaFoldrInterleave t ts ps r + ? lemmaInterleaveAppend t ts p (concat (map (aux1 t ts []) ps) ++ r) + ? lemmaAppendAssoc (interleave t ts p []) (concat (map (aux1 t ts []) ps)) r + +{-@ +lemmaAppendAssoc :: xs:[a] -> ys:[a] -> zs:[a] -> { xs ++ ys ++ zs = (xs ++ ys) ++ zs } +@-} +lemmaAppendAssoc :: [a] -> [a] -> [a] -> () +lemmaAppendAssoc [] _ _ = () +lemmaAppendAssoc (_:xs) ys zs = lemmaAppendAssoc xs ys zs + +{-@ +lemmaConcatMapInterleave + :: ts:[a] + -> r:[a] + -> { i:Int | i >= 0 } + -> { j:Int | j < len ts } + -> { concat (map (aux2 (ts ++ r) []) (fromTo i j)) + == map (flipAppend r) (concat (map (aux2 ts []) (fromTo i j))) } / [j - i + 1] +@-} +lemmaConcatMapInterleave :: [a] -> [a] -> Int -> Int -> () +lemmaConcatMapInterleave ts r i j = + if i <= j then + lemmaConcatMapInterleave ts r (i + 1) j + `const` lemmaLengthAppend ts r + `const` lemmaTakeAppend ts r i + `const` lemmaElemAtAppend ts r i + `const` lemmaDropAppend ts r (i + 1) + `const` lemmaAppendInterleave (ts !! i) (drop (i + 1) ts) r (permutations (reverse (take i ts) ++ [])) + `const` lemmaMapAppend (flipAppend r) (aux2 ts [] i) (concat (map (aux2 ts []) (fromTo (i + 1) j))) + else + () +{- + if i <= j then + case lemmaLengthAppend ts r of { () -> + concat (map (aux2 (ts ++ r) []) (fromTo i j)) + `asTypeOf` + concat (map (aux2 (ts ++ r) []) (i : fromTo (i + 1) j)) + `asTypeOf` + (aux2 (ts ++ r) [] i ++ concat (map (aux2 (ts ++ r) []) (fromTo (i + 1) j))) + `asTypeOf` + const (aux2 (ts ++ r) [] i ++ map (flipAppend r) (concat (map (aux2 ts []) (fromTo (i + 1) j)))) + (lemmaConcatMapInterleave ts r (i + 1) j) + `asTypeOf` + (mapInterleave ((ts ++ r) !! i) (drop (i + 1) (ts ++ r)) (permutations (reverse (take i (ts ++ r)) ++ [])) [] + ++ map (flipAppend r) (concat (map (aux2 ts []) (fromTo (i + 1) j)))) + `asTypeOf` + const (mapInterleave ((ts ++ r) !! i) (drop (i + 1) (ts ++ r)) (permutations (reverse (take i ts) ++ [])) [] + ++ map (flipAppend r) (concat (map (aux2 ts []) (fromTo (i + 1) j)))) + (lemmaTakeAppend ts r i) + `asTypeOf` + const (mapInterleave (ts !! i) (drop (i + 1) (ts ++ r)) (permutations (reverse (take i ts) ++ [])) [] + ++ map (flipAppend r) (concat (map (aux2 ts []) (fromTo (i + 1) j)))) + (lemmaElemAtAppend ts r i) + `asTypeOf` + const (mapInterleave (ts !! i) (drop (i + 1) ts ++ r) (permutations (reverse (take i ts) ++ [])) [] + ++ map (flipAppend r) (concat (map (aux2 ts []) (fromTo (i + 1) j)))) + (lemmaDropAppend ts r (i + 1)) + `asTypeOf` + const (map (flipAppend r) (aux2 ts [] i) ++ map (flipAppend r) (concat (map (aux2 ts []) (fromTo (i + 1) j)))) + (lemmaAppendInterleave (ts !! i) (drop (i + 1) ts) r (permutations (reverse (take i ts) ++ []))) + `asTypeOf` + const (map (flipAppend r) (aux2 ts [] i ++ concat (map (aux2 ts []) (fromTo (i + 1) j)))) + (lemmaMapAppend (flipAppend r) (aux2 ts [] i) (concat (map (aux2 ts []) (fromTo (i + 1) j)))) + `asTypeOf` + map (flipAppend r) (concat (map (aux2 ts []) (fromTo i j))) + } + *** + QED + else + () +-} + +{-@ +lemmaAppendInterleave + :: t:a + -> ts:[a] + -> r:[a] + -> ps:[[a]] + -> { mapInterleave t (ts ++ r) ps [] == map (flipAppend r) (mapInterleave t ts ps []) } +@-} +lemmaAppendInterleave :: a -> [a] -> [a] -> [[a]] -> () +lemmaAppendInterleave t ts r [] = () + ? mapInterleave t (ts ++ r) [] [] + ? mapInterleave t ts [] [] +lemmaAppendInterleave t ts r (p:ps) = + lemmaAppendInterleave t ts r ps + `const` mapInterleave t (ts ++ r) (p:ps) [] + `const` mapInterleave t ts (p:ps) [] + `const` mapInterleave t (ts ++ r) ps [] + `const` mapInterleave t ts ps [] + `const` lemmaAppendAssoc (aux1 t (ts ++ r) [] p) (concat (map (aux1 t (ts ++ r) []) ps)) [] + `const` interleave t (ts ++ r) p [] + `const` lemmaAppendAux0 t p ts r (fromTo 0 (length p - 1)) + `const` lemmaAppendId (map (aux0 t id p ts) (fromTo 0 (length p - 1))) + `const` lemmaAppendId (map (flipAppend r) (interleave t ts p [])) + `const` lemmaMapAppend (flipAppend r) (aux1 t ts [] p) (mapInterleave t ts ps []) + `const` lemmaAppendAssoc (aux1 t ts [] p) (concat (map (aux1 t ts []) ps)) [] + +{- + mapInterleave t (ts ++ r) (p:ps) [] + `asTypeOf` + const (concat (map (aux1 t (ts ++ r) []) (p:ps)) ++ []) + (mapInterleave t (ts ++ r) (p:ps) []) + `asTypeOf` + ((aux1 t (ts ++ r) [] p ++ concat (map (aux1 t (ts ++ r) []) ps)) ++ []) + `asTypeOf` + const (aux1 t (ts ++ r) [] p ++ concat (map (aux1 t (ts ++ r) []) ps) ++ []) + (lemmaAppendAssoc (aux1 t (ts ++ r) [] p) (concat (map (aux1 t (ts ++ r) []) ps)) []) + `asTypeOf` + const (aux1 t (ts ++ r) [] p ++ mapInterleave t (ts ++ r) ps []) + (mapInterleave t (ts ++ r) ps []) + `asTypeOf` + const (aux1 t (ts ++ r) [] p ++ map (flipAppend r) (mapInterleave t ts ps [])) + (lemmaAppendInterleave t ts r ps) + `asTypeOf` + const ((map (aux0 t id p (ts ++ r)) (fromTo 0 (length p - 1)) ++ []) ++ map (flipAppend r) (mapInterleave t ts ps [])) + (interleave t (ts ++ r) p []) + `asTypeOf` + const ((map (flipAppend r) (map (aux0 t id p ts) (fromTo 0 (length p - 1))) ++ []) ++ map (flipAppend r) (mapInterleave t ts ps [])) + (lemmaAppendAux0 t p ts r (fromTo 0 (length p - 1))) + `asTypeOf` + const ((map (flipAppend r) (interleave t ts p []) ++ []) ++ map (flipAppend r) (mapInterleave t ts ps [])) + (lemmaAppendId (map (aux0 t id p ts) (fromTo 0 (length p - 1)))) + `asTypeOf` + const (map (flipAppend r) (aux1 t ts [] p) ++ map (flipAppend r) (mapInterleave t ts ps [])) + (lemmaAppendId (map (flipAppend r) (interleave t ts p []))) + `asTypeOf` + const (map (flipAppend r) (aux1 t ts [] p ++ mapInterleave t ts ps [])) + (lemmaMapAppend (flipAppend r) (aux1 t ts [] p) (mapInterleave t ts ps [])) + `asTypeOf` + const (map (flipAppend r) (aux1 t ts [] p ++ concat (map (aux1 t ts []) ps) ++ [])) + (mapInterleave t ts ps []) + `asTypeOf` + const (map (flipAppend r) ((aux1 t ts [] p ++ concat (map (aux1 t ts []) ps)) ++ [])) + (lemmaAppendAssoc (aux1 t ts [] p) (concat (map (aux1 t ts []) ps)) []) + `asTypeOf` + map (flipAppend r) (mapInterleave t ts (p:ps) []) + *** + QED +-} + +{-@ +lemmaAppendAux0 + :: t:a + -> p:[a] + -> ts:[a] + -> r:[a] + -> xs:[Int] + -> { map (aux0 t id p (ts ++ r)) xs == map (flipAppend r) (map (aux0 t id p ts) xs) } +@-} +lemmaAppendAux0 :: a -> [a] -> [a] -> [a] -> [Int] -> () +lemmaAppendAux0 t p ts r [] = () +lemmaAppendAux0 t p ts r (x:xs) = + lemmaAppendAux0 t p ts r xs + ? lemmaAppendAssoc (insertAt x t p) ts r + +-- | The refinement predicate in the return type is equivalent to +-- +-- > [ interleave (ts!!n) (drop (n+1) ts) xs [] +-- > | n <- [i..j] +-- > , xs <- permutations (reverse (take n ts) ++ t:is) +-- > ] +-- > +-- > = +-- > +-- > [ interleave ((t:ts)!!n) (drop (n+1) (t:ts)) xs [] +-- > | n <- [i+1..j+1] +-- > , xs <- permutations (reverse (take n (t:ts)) ++ is) +-- > ] +-- + +{-@ +lemmaMapAux2 + :: t:a + -> ts:[a] + -> is:[a] + -> { i:Int | 0 <= i } + -> { j:Int | j < len ts } + -> { map (aux2 ts (t:is)) (fromTo i j) + == map (aux2 (t:ts) is) (fromTo (i+1) (j+1)) + } / [j-i+1] +@-} +lemmaMapAux2 :: a -> [a] -> [a] -> Int -> Int -> () +lemmaMapAux2 t ts is i j = + if i<=j then + lemmaMapAux2 t ts is (i+1) j + `const` lemmaAppendAssoc (reverse (take i ts)) [t] is + +{- + map (aux2 ts (t:is)) (fromTo i j) + === + aux2 ts (t:is) i : map (aux2 ts (t:is)) (fromTo (i+1) j) + === + const (aux2 ts (t:is) i : map (aux2 (t:ts) is) (fromTo (i+2) (j+1))) + (lemmaMapAux2 t ts is (i+1) j) + === + (mapInterleave (ts!!i) (drop (i+1) ts) (permutations (reverse (take i ts) ++ (t:is))) [] + : map (aux2 (t:ts) is) (fromTo (i+2) (j+1)) + ) + === + (mapInterleave (ts!!i) (drop (i+1) ts) (permutations (reverse (take i ts) ++ [t] ++ is)) [] + : map (aux2 (t:ts) is) (fromTo (i+2) (j+1)) + ) + === + const (mapInterleave (ts!!i) (drop (i+1) ts) (permutations ((reverse (take i ts) ++ [t]) ++ is)) [] + : map (aux2 (t:ts) is) (fromTo (i+2) (j+1)) + ) + (lemmaAppendAssoc (reverse (take i ts)) [t] is) + === + (mapInterleave ((t:ts)!!(i+1)) (drop (i+2) (t:ts)) (permutations (reverse (take (i+1) (t:ts)) ++ is)) [] + : map (aux2 (t:ts) is) (fromTo (i+2) (j+1)) + ) + === + (aux2 (t:ts) is (i+1) : map (aux2 (t:ts) is) (fromTo (i+2) (j+1)) + *** + QED + -} + else + () diff --git a/tests/tests.cabal b/tests/tests.cabal index 2a524da3bb..67d90c9a93 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2275,6 +2275,7 @@ executable ple-pos , Ple0 , PleORM , Ple_sum + , Permutations , ReflectDefault , RegexpDerivative , RosePLEDiv From 3495ac1a2ce168ee89dc9729a2b8ba2a897496d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 28 Nov 2022 23:11:49 -0300 Subject: [PATCH 032/219] Reference the laziness requirement in pos/Permutations.hs --- tests/pos/Permutation.hs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/pos/Permutation.hs b/tests/pos/Permutation.hs index 92356113a7..c78679cd58 100644 --- a/tests/pos/Permutation.hs +++ b/tests/pos/Permutation.hs @@ -1,3 +1,8 @@ +-- | This module contains a termination proof of Data.List.permutations. +-- +-- See tests/ple/pos/Permutations.hs for a proof of the laziness +-- requirement. +-- module Permutation () where {-@ permutations :: ts:[a] -> [[a]] / [(len ts), 1, 0] @-} @@ -13,4 +18,3 @@ perms (t:ts) is = foldr interleave (perms ts (t:is)) (permutations is) interleave' f (y:ys) r = let (us,zs) = interleave' (f . (y:)) ys r in (y:us, f (t:y:us) : zs) - From c55cb27b881dbf29ee3b09a42e2e1f9b44cddee9 Mon Sep 17 00:00:00 2001 From: Niklas Gruhn Date: Mon, 28 Nov 2022 17:36:20 +0100 Subject: [PATCH 033/219] Fix typos / dead link in blog post --- docs/blog/2013-01-01-refinement-types-101.lhs | 2 +- docs/blog/2013-01-27-refinements101-reax.lhs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/blog/2013-01-01-refinement-types-101.lhs b/docs/blog/2013-01-01-refinement-types-101.lhs index 2646210ae9..e9066d1487 100644 --- a/docs/blog/2013-01-01-refinement-types-101.lhs +++ b/docs/blog/2013-01-01-refinement-types-101.lhs @@ -180,7 +180,7 @@ How *does* LiquidHaskell verify the above function? The key step is that LiquidHaskell deduces that the expression `"divide by zero"` is not merely of type `String`, but in fact -has the the refined type `{v:String | false}` *in the context* +has the refined type `{v:String | false}` *in the context* in which the call to `error'` occurs. LiquidHaskell arrives at this conclusion by using the fact that diff --git a/docs/blog/2013-01-27-refinements101-reax.lhs b/docs/blog/2013-01-27-refinements101-reax.lhs index 317632342c..d13a7f76f9 100644 --- a/docs/blog/2013-01-27-refinements101-reax.lhs +++ b/docs/blog/2013-01-27-refinements101-reax.lhs @@ -155,7 +155,7 @@ non-negative `n` guarantee holds trivially. **Reason 2: The Specification is a Fib** If you run the above in the demo, you will see that LiquidHaskell still -doth protest loudly, and frankly, one might start getting a little +does protest loudly, and frankly, one might start getting a little frustrated at the stubbornness and petulance of the checker. \begin{code} However, if you stare at the implementation, you will see that it in fact, *does not* meet the specification, as @@ -194,7 +194,7 @@ recursive calls --- we get the above by plugging the parameters \end{code} \begin{code} Finally, to check the output guarantee is met, LiquidHaskell asks the SMT solver to prove that -(b >= 2n - 2) => (b >= n) +(b >= 2n - 3) => (b >= n) \end{code} The SMT solver will refuse, of course, since the above implication is @@ -258,5 +258,5 @@ There are several things to take away. [concolic]: http://en.wikipedia.org/wiki/Concolic_testing [icse04]: http://goto.ucsd.edu/~rjhala/papers/generating_tests_from_counterexamples.html [dsd]: http://dl.acm.org/citation.cfm?doid=1348250.1348254 -[mlton]: http://www.cs.purdue.edu/homes/zhu103/pubs/vmcai13.pdf +[mlton]: https://www.cs.purdue.edu/homes/suresh/papers/vmcai13.pdf From 5d5fb316f1d64efcd49e4e237c411764c585f66d Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Sun, 27 Nov 2022 20:59:27 +0200 Subject: [PATCH 034/219] reproducible nix --- nixpkgs.nix | 9 +++++++++ stack.yaml | 1 + 2 files changed, 10 insertions(+) create mode 100644 nixpkgs.nix diff --git a/nixpkgs.nix b/nixpkgs.nix new file mode 100644 index 0000000000..c5f229f06d --- /dev/null +++ b/nixpkgs.nix @@ -0,0 +1,9 @@ +let + # NixOS/Nixpkgs master 2022-11-27 + rev = "a115bb9bd56831941be3776c8a94005867f316a7"; + sha256 = "1501jzl4661qwr45b9ip7c7bpmbl94816draybhh60s9wgxn068d"; +in +import (fetchTarball { + inherit sha256; + url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz"; +}) diff --git a/stack.yaml b/stack.yaml index 3c9bf83aa8..f5c023fe3d 100644 --- a/stack.yaml +++ b/stack.yaml @@ -36,3 +36,4 @@ resolver: lts-18.27 nix: packages: [cacert, git, hostname, z3] + path: [nixpkgs=./nixpkgs.nix] From f2dc454dd45428e5d8213fc3fa713a2941d5b0a8 Mon Sep 17 00:00:00 2001 From: oquechy Date: Mon, 5 Dec 2022 19:53:34 +0100 Subject: [PATCH 035/219] Update relational syntax --- docs/mkDocs/docs/specifications.md | 75 ++++++++++++++---------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/docs/mkDocs/docs/specifications.md b/docs/mkDocs/docs/specifications.md index 9bff194388..e27dc3c0f2 100644 --- a/docs/mkDocs/docs/specifications.md +++ b/docs/mkDocs/docs/specifications.md @@ -1014,24 +1014,25 @@ incr = (+ 1) Monotonicity states that for any `x1, x2 :: Int` such that `x1 < x2`, inequality `incr x1 < incr x2` holds. This can be expressed as a comparison property on `incr`. ```haskell -{-@ relational incr ~ incr - :: x1:Int -> Int ~ x2:Int -> Int ~~ x1 < x2 => r1 x1 < r2 x2 @-} +{-@ relational incr ~ incr :: { x1:Int -> Int + ~ x2:Int -> Int + | x1 < x2 :=> r1 x1 < r2 x2 } @-} ``` Relational signature starts with the keyword `relational`. Next, it contains two functions being compared `incr ~ incr`. To prove monotonicity, we compare `incr` to itself. In the general case, it is possible to compare two different functions. -Related expressions are followed by their type signatures `x1:Int -> Int` and `x2:Int -> Int` separated with a tilde. The last component of the signature is a predicate `x1 < x2 => r1 x1 < r2 x2`. +Related expressions are followed by their type signatures `x1:Int -> Int` and `x2:Int -> Int` separated with a tilde. The last component of the signature is a predicate `x1 < x2 :=> r1 x1 < r2 x2`. -Binders `x1` and `x2` refer to the functions' arguments. Keywords `r1` and `r2` are aliases for lhs `incr` and rhs `incr` respectively. +Binders `x1` and `x2` refer to the functions' arguments. Keywords `r1` and `r2` are aliases for lhs `incr` and rhs `incr` respectively. The predicate is logically equivalent to `x1 < x2 => r1 x1 < r2 x2`. Implication symbol `:=>` separates the precondition on the arguments from the postcondition on the return values. ### Relational Predicate Syntax -A relational predicate is a sequence of clauses separated by top-level implication connectives `=>`: +A relational predicate is a sequence of clauses separated by top-level implication connectives `:=>` (logically equivalent to `=>`): ``` -x1 < x2 => y1 < y2 => r1 x1 y1 < r2 x2 y2 -^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^ - 1st 2nd 3rd clause +x1 < x2 :=> y1 < y2 :=> r1 x1 y1 < r2 x2 y2 +^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^ + 1st 2nd 3rd clause ``` * Number of Clauses @@ -1044,16 +1045,15 @@ x1 < x2 => y1 < y2 => r1 x1 y1 < r2 x2 y2 -- clauses == arguments + 1 - {-@ relational plus ~ plus - :: x1:Int -> y1:Int -> Int - ~ x2:Int -> y2:Int -> Int - ~~ x1 < x2 => y1 < y2 => r1 x1 y1 < r2 x2 y2 @-} - ^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^ + {-@ relational plus ~ plus :: { x1:Int -> y1:Int -> Int + ~ x2:Int -> y2:Int -> Int + | x1 < x2 :=> y1 < y2 :=> r1 x1 y1 < r2 x2 y2 } @-} + ^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ``` - For example, function `incr` has 1 argument. Its relational predicate has 1 implication that separates the precondition from the postcondition: `x1 < x2 => r1 x1 < r2 x2`. + For example, function `incr` has 1 argument. Its relational predicate has 1 implication that separates the precondition from the postcondition: `x1 < x2 :=> r1 x1 < r2 x2`. - Nested, non-top-level implications are allowed, e.g. `(true => x1 < x2) => (r1 x1 < r2 x2)`. + Nested, non-top-level implications are allowed, e.g. `(true => x1 < x2) :=> (r1 x1 < r2 x2)`. * Argument Scopes @@ -1063,43 +1063,38 @@ x1 < x2 => y1 < y2 => r1 x1 y1 < r2 x2 y2 ```haskell -- ERROR: clauses < arguments + 1 - {-@ relational plus ~ plus - :: x1:Int -> y1:Int -> Int - ~ x2:Int -> y2:Int -> Int - ~~ x1 < x2 && y1 < y2 => r1 x1 y1 < r2 x2 y2 @-} + {-@ relational plus ~ plus :: { x1:Int -> y1:Int -> Int + ~ x2:Int -> y2:Int -> Int + | x1 < x2 && y1 < y2 :=> r1 x1 y1 < r2 x2 y2 } @-} -- ERROR: y1 and y2 used before their introduction - {-@ relational plus ~ plus - :: x1:Int -> y1:Int -> Int - ~ x2:Int -> y2:Int -> Int - ~~ y1 < y2 => x1 < x2 => r1 x1 y1 < r2 x2 y2 @-} + {-@ relational plus ~ plus :: { x1:Int -> y1:Int -> Int + ~ x2:Int -> y2:Int -> Int + | y1 < y2 :=> x1 < x2 :=> r1 x1 y1 < r2 x2 y2 } @-} ``` Correct versions could look like this: ```haskell - {-@ relational plus ~ plus - :: x1:Int -> y1:Int -> Int - ~ x2:Int -> y2:Int -> Int - ~~ x1 < x2 => y1 < y2 => r1 x1 y1 < r2 x2 y2 @-} - - {-@ relational plus ~ plus - :: x1:Int -> y1:Int -> Int - ~ x2:Int -> y2:Int -> Int - ~~ true => x1 < x2 && y1 < y2 => r1 x1 y1 < r2 x2 y2 @-} - - {-@ relational plus ~ plus - :: x1:Int -> y1:Int -> Int - ~ x2:Int -> y2:Int -> Int - ~~ true => true => (x1 < x2 => y1 < y2 => r1 x1 y1 < r2 x2 y2) @-} + {-@ relational plus ~ plus :: { x1:Int -> y1:Int -> Int + ~ x2:Int -> y2:Int -> Int + | x1 < x2 :=> y1 < y2 :=> r1 x1 y1 < r2 x2 y2 } @-} + + {-@ relational plus ~ plus :: { x1:Int -> y1:Int -> Int + ~ x2:Int -> y2:Int -> Int + | true :=> x1 < x2 && y1 < y2 :=> r1 x1 y1 < r2 x2 y2 } @-} + + {-@ relational plus ~ plus :: { x1:Int -> y1:Int -> Int + ~ x2:Int -> y2:Int -> Int + | true :=> true :=> x1 < x2 => y1 < y2 => r1 x1 y1 < r2 x2 y2 } @-} ``` ### Provided Guarantees -For all possible inputs of the two compared functions, it is guaranteed that the relational predicate holds. +For all possible inputs of the two compared functions, it is guaranteed that the relational predicate holds. ### Running Relational Checks @@ -1115,6 +1110,6 @@ Or in a Haskell source file: ### Current limitations -- No support for abstract refinements. Notably, means no support for the standard list `[a]` and tuple `(a, b)` types which have implicit abstract refinements. Please use user-defined lists and tuples instead. +- No support for abstract refinements. All abstract refinements are erased before relational typechecking. Notably, this happens for the standard list `[a]` and tuple `(a, b)` types! -- Limited support for higher-order relational signatures. +- Limited support for higher-order relational signatures. Use `!=>` instead of `:=>` after the function arguments to enable higher-order checking. From 56c2e2f2fa192b147dc789d13e1c35183f5ba1c6 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Fri, 9 Dec 2022 16:10:56 +0100 Subject: [PATCH 036/219] remove empty tests --- tests/.DS_Store | Bin 0 -> 10244 bytes tests/relational/.DS_Store | Bin 0 -> 6148 bytes tests/relational/neg/AppNull.hs | 0 tests/relational/neg/BuiltInFib.hs | 0 tests/relational/neg/Fib.hs | 0 tests/relational/neg/FunReft.hs | 0 tests/relational/neg/IncrLet.hs | 0 tests/relational/neg/IndAssm.hs | 0 tests/relational/neg/Null.hs | 0 tests/relational/neg/PolyNull.hs | 0 tests/relational/pos/AppNull.hs | 0 tests/relational/pos/BuiltInNull.hs | 0 tests/relational/pos/FunReft.hs | 0 tests/relational/pos/IncrF.hs | 0 tests/relational/pos/IncrLet.hs | 0 tests/relational/pos/Max.hs | 0 tests/relational/pos/MutRecSame.hs | 0 tests/relational/pos/Null.hs | 0 tests/relational/pos/PMonad.hs | 0 tests/relational/pos/PolyNull.hs | 0 tests/relational/pos/Prims.hs | 0 tests/relational/pos/RecNonFunc.hs | 0 tests/relational/pos/SubRef1.hs | 0 tests/relational/pos/SubRef2.hs | 0 tests/relational/pos/SumType.hs | 0 tests/relational/pos/TrdOrdPredNonRel.hs | 0 tests/relational/pos/UnaryVsRelational.hs | 0 27 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/.DS_Store create mode 100644 tests/relational/.DS_Store delete mode 100644 tests/relational/neg/AppNull.hs delete mode 100644 tests/relational/neg/BuiltInFib.hs delete mode 100644 tests/relational/neg/Fib.hs delete mode 100644 tests/relational/neg/FunReft.hs delete mode 100644 tests/relational/neg/IncrLet.hs delete mode 100644 tests/relational/neg/IndAssm.hs delete mode 100644 tests/relational/neg/Null.hs delete mode 100644 tests/relational/neg/PolyNull.hs delete mode 100644 tests/relational/pos/AppNull.hs delete mode 100644 tests/relational/pos/BuiltInNull.hs delete mode 100644 tests/relational/pos/FunReft.hs delete mode 100644 tests/relational/pos/IncrF.hs delete mode 100644 tests/relational/pos/IncrLet.hs delete mode 100644 tests/relational/pos/Max.hs delete mode 100644 tests/relational/pos/MutRecSame.hs delete mode 100644 tests/relational/pos/Null.hs delete mode 100644 tests/relational/pos/PMonad.hs delete mode 100644 tests/relational/pos/PolyNull.hs delete mode 100644 tests/relational/pos/Prims.hs delete mode 100644 tests/relational/pos/RecNonFunc.hs delete mode 100644 tests/relational/pos/SubRef1.hs delete mode 100644 tests/relational/pos/SubRef2.hs delete mode 100644 tests/relational/pos/SumType.hs delete mode 100644 tests/relational/pos/TrdOrdPredNonRel.hs delete mode 100644 tests/relational/pos/UnaryVsRelational.hs diff --git a/tests/.DS_Store b/tests/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c7335174d320cbd8d25dfcf8d4b7b1ff5861624a GIT binary patch literal 10244 zcmeHML2nyH6n+hR+^UZs+nF$e@qg8y1C?ui) z7u(%yxLr~BcfM++Q9XGZ)__kmrc-*0)|AtthV~D<0$u^HfLFjP;1&2UD1di1m!Mx- zfA3>mr@4zVuPD?G+KbR)LSu#eULkux zPAG%FQ<{OZz`4UxasI4v#*|9?OPo<~ZLK+t6UFJEhb?EK(W1z&mLeUB(Q2t5N;xuc z70PeKk%MnncvePZp^SrVqSc&EREto;LA6Sh_LNm{a2@zLkvUwUZ>6uO@QbCw4#pn| zL(QKkU?ZENl=hOxZKK-Ih*e#3WT+AGxNU5g9{htv{!jJT3~OLBu3xs!F?51hdTRWM zE;hF#+yc459Gw}6j>hYjE=`$htsbJHhRSPRLlXzpqfar;4C})u^pMWbaxISyv~f6H zaPDEYj_G6Aeauj-)Pyz;;|9;RWEe+u3~ipVZm>EIyHl}KaK}1gIcgd|Tk7-#&8t#@ zILA7Jnp!J3e*T>^S}*6-`u_W9o+iuU;NTC_Xts9RognB1y_b4l4X62fSVYBYc@!(NHt4%3h9|=BrlJ?4S>Rw-$8f#xlo>gX{vsSvr$3 zaFnS`M zS~;i|P&u+OcX6W4PnI_9gW!<2oX6}zef4IYG^<=so{{UKmCf2ls<&PNuYgy;E8rD) zQ3^E6j>A6ey{G^G|3$gy`}GQV1)hTfrgc0#K0-&^ZI$km&)P#=k8yEf+@`cb!A*|i zVdXd;U-&rw4P1;pV9N#dL1j0k#S@h0{?7pCWYh2e$?yN=jGK3Bwf(uA6a4@7|9=CU Cy?eI+ literal 0 HcmV?d00001 diff --git a/tests/relational/.DS_Store b/tests/relational/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..aad75f85110d613486be946689cf6930fa993856 GIT binary patch literal 6148 zcmeHKy-vem3_Oz}RqE1_1?hVNB;MeoDg!ewP!$kMMG$TGY<-+QBAkDUNCGPZ*phvT zzq6y<5XS&yv46Y<<^ZO2MI1DYP0!Uwb{3h2DB7caSZ~@j@2uU3|6M|B8@%8N&v%<% z{S8m9-p#DA!7Ey92dv|Ob&fae*lmklpDC9ErZvrw3Zw$5Kq`<5{5u6Wv(=_E$Bd~! zDv%0%DxlwoLRYMTouhp^7;FU~PM9|1wf+1PizbLQuybUFCSFSPQi&BqVs{WP=Xni& z=ji1SdougPlO;A3iPb}j(IM3_V=9me^cB$En>N?^e@p*i|5r|0Dv%2NQ3YhOyk9Q( zaxq&+uc@=P&{y=6k!y4Y8^uH$#k|o`eDQ@>^qS{2uyeF>=B=EVKLV;tS}O1x3VZ-H C0WU=W literal 0 HcmV?d00001 diff --git a/tests/relational/neg/AppNull.hs b/tests/relational/neg/AppNull.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/neg/BuiltInFib.hs b/tests/relational/neg/BuiltInFib.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/neg/Fib.hs b/tests/relational/neg/Fib.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/neg/FunReft.hs b/tests/relational/neg/FunReft.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/neg/IncrLet.hs b/tests/relational/neg/IncrLet.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/neg/IndAssm.hs b/tests/relational/neg/IndAssm.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/neg/Null.hs b/tests/relational/neg/Null.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/neg/PolyNull.hs b/tests/relational/neg/PolyNull.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/AppNull.hs b/tests/relational/pos/AppNull.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/BuiltInNull.hs b/tests/relational/pos/BuiltInNull.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/FunReft.hs b/tests/relational/pos/FunReft.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/IncrF.hs b/tests/relational/pos/IncrF.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/IncrLet.hs b/tests/relational/pos/IncrLet.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/Max.hs b/tests/relational/pos/Max.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/MutRecSame.hs b/tests/relational/pos/MutRecSame.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/Null.hs b/tests/relational/pos/Null.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/PMonad.hs b/tests/relational/pos/PMonad.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/PolyNull.hs b/tests/relational/pos/PolyNull.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/Prims.hs b/tests/relational/pos/Prims.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/RecNonFunc.hs b/tests/relational/pos/RecNonFunc.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/SubRef1.hs b/tests/relational/pos/SubRef1.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/SubRef2.hs b/tests/relational/pos/SubRef2.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/SumType.hs b/tests/relational/pos/SumType.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/TrdOrdPredNonRel.hs b/tests/relational/pos/TrdOrdPredNonRel.hs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/relational/pos/UnaryVsRelational.hs b/tests/relational/pos/UnaryVsRelational.hs deleted file mode 100644 index e69de29bb2..0000000000 From 79dde45bef497c00c6f846cae5cccad20691447e Mon Sep 17 00:00:00 2001 From: oquechy Date: Fri, 9 Dec 2022 16:18:16 +0100 Subject: [PATCH 037/219] Fix ncurses version in hlint.yml --- .github/workflows/hlint.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/hlint.yml b/.github/workflows/hlint.yml index 3f657f6470..f815a094ae 100644 --- a/.github/workflows/hlint.yml +++ b/.github/workflows/hlint.yml @@ -9,7 +9,10 @@ jobs: name: hlint runs-on: ubuntu-latest - steps: + steps: + - name: fix ncurses version + run: sudo apt-get install libncurses5 + - uses: actions/checkout@v3 with: submodules: true @@ -17,10 +20,10 @@ jobs: - uses: haskell/actions/hlint-setup@v2 name: Set up HLint with: - version: "3.4" + version: "3.4" - uses: haskell/actions/hlint-run@v2 name: hlint with: path: '["src/", "src-ghc/"]' - fail-on: suggestion \ No newline at end of file + fail-on: suggestion From a3d108c2b5bacda8fab670c2a75efd7bd4b2bf0c Mon Sep 17 00:00:00 2001 From: oquechy Date: Fri, 9 Dec 2022 16:21:25 +0100 Subject: [PATCH 038/219] Update hlint.yml --- .github/workflows/hlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hlint.yml b/.github/workflows/hlint.yml index f815a094ae..3f7892a855 100644 --- a/.github/workflows/hlint.yml +++ b/.github/workflows/hlint.yml @@ -20,7 +20,7 @@ jobs: - uses: haskell/actions/hlint-setup@v2 name: Set up HLint with: - version: "3.4" + version: "3.4" - uses: haskell/actions/hlint-run@v2 name: hlint From d58d8ff9217230c170b3ff29e2ee0393975900dd Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 12 Dec 2022 13:09:23 +0100 Subject: [PATCH 039/219] rm empty file --- .github/workflows/haskell.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .github/workflows/haskell.yml diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml deleted file mode 100644 index e69de29bb2..0000000000 From 13ac1de29ada3e3638777b1cedb850d06edffdfa Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 13 Dec 2022 14:43:12 +0100 Subject: [PATCH 040/219] rm .DS_Store --- .gitignore | 2 ++ tests/.DS_Store | Bin 10244 -> 0 bytes tests/relational/.DS_Store | Bin 6148 -> 0 bytes 3 files changed, 2 insertions(+) delete mode 100644 tests/.DS_Store delete mode 100644 tests/relational/.DS_Store diff --git a/.gitignore b/.gitignore index d3b6e7da8b..6e06898f63 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,5 @@ tests/**/*.o-boot .idea *.iml + +.DS_Store \ No newline at end of file diff --git a/tests/.DS_Store b/tests/.DS_Store deleted file mode 100644 index c7335174d320cbd8d25dfcf8d4b7b1ff5861624a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHML2nyH6n+hR+^UZs+nF$e@qg8y1C?ui) z7u(%yxLr~BcfM++Q9XGZ)__kmrc-*0)|AtthV~D<0$u^HfLFjP;1&2UD1di1m!Mx- zfA3>mr@4zVuPD?G+KbR)LSu#eULkux zPAG%FQ<{OZz`4UxasI4v#*|9?OPo<~ZLK+t6UFJEhb?EK(W1z&mLeUB(Q2t5N;xuc z70PeKk%MnncvePZp^SrVqSc&EREto;LA6Sh_LNm{a2@zLkvUwUZ>6uO@QbCw4#pn| zL(QKkU?ZENl=hOxZKK-Ih*e#3WT+AGxNU5g9{htv{!jJT3~OLBu3xs!F?51hdTRWM zE;hF#+yc459Gw}6j>hYjE=`$htsbJHhRSPRLlXzpqfar;4C})u^pMWbaxISyv~f6H zaPDEYj_G6Aeauj-)Pyz;;|9;RWEe+u3~ipVZm>EIyHl}KaK}1gIcgd|Tk7-#&8t#@ zILA7Jnp!J3e*T>^S}*6-`u_W9o+iuU;NTC_Xts9RognB1y_b4l4X62fSVYBYc@!(NHt4%3h9|=BrlJ?4S>Rw-$8f#xlo>gX{vsSvr$3 zaFnS`M zS~;i|P&u+OcX6W4PnI_9gW!<2oX6}zef4IYG^<=so{{UKmCf2ls<&PNuYgy;E8rD) zQ3^E6j>A6ey{G^G|3$gy`}GQV1)hTfrgc0#K0-&^ZI$km&)P#=k8yEf+@`cb!A*|i zVdXd;U-&rw4P1;pV9N#dL1j0k#S@h0{?7pCWYh2e$?yN=jGK3Bwf(uA6a4@7|9=CU Cy?eI+ diff --git a/tests/relational/.DS_Store b/tests/relational/.DS_Store deleted file mode 100644 index aad75f85110d613486be946689cf6930fa993856..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-vem3_Oz}RqE1_1?hVNB;MeoDg!ewP!$kMMG$TGY<-+QBAkDUNCGPZ*phvT zzq6y<5XS&yv46Y<<^ZO2MI1DYP0!Uwb{3h2DB7caSZ~@j@2uU3|6M|B8@%8N&v%<% z{S8m9-p#DA!7Ey92dv|Ob&fae*lmklpDC9ErZvrw3Zw$5Kq`<5{5u6Wv(=_E$Bd~! zDv%0%DxlwoLRYMTouhp^7;FU~PM9|1wf+1PizbLQuybUFCSFSPQi&BqVs{WP=Xni& z=ji1SdougPlO;A3iPb}j(IM3_V=9me^cB$En>N?^e@p*i|5r|0Dv%2NQ3YhOyk9Q( zaxq&+uc@=P&{y=6k!y4Y8^uH$#k|o`eDQ@>^qS{2uyeF>=B=EVKLV;tS}O1x3VZ-H C0WU=W From 613dcdfb19dd4d6eb24fc5d80b4826ab3653093d Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Wed, 14 Dec 2022 15:30:41 -0800 Subject: [PATCH 041/219] LH compiles with BindEnv ann --- liquid-fixpoint | 2 +- src/Language/Haskell/Liquid/Constraint/Env.hs | 2 +- .../Haskell/Liquid/Constraint/Types.hs | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index e378d2ee86..891169d84c 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit e378d2ee8656da929e41c2d593a88a81e9620391 +Subproject commit 891169d84cc4495f26e8d65bfed59fab49091f4f diff --git a/src/Language/Haskell/Liquid/Constraint/Env.hs b/src/Language/Haskell/Liquid/Constraint/Env.hs index 76fdb9009d..71fb21fa54 100644 --- a/src/Language/Haskell/Liquid/Constraint/Env.hs +++ b/src/Language/Haskell/Liquid/Constraint/Env.hs @@ -149,7 +149,7 @@ addBinders γ0 x' cbs = foldM (++=) (γ0 -= x') [("addBinders", x, t) | (x, t) addBind :: SrcSpan -> F.Symbol -> F.SortedReft -> CG ((F.Symbol, F.Sort), F.BindId) addBind l x r = do st <- get - let (i, bs') = F.insertBindEnv x r (binds st) + let (i, bs') = F.insertBindEnv x r (Ci l Nothing Nothing) (binds st) put $ st { binds = bs' } { bindSpans = M.insert i l (bindSpans st) } return ((x, F.sr_sort r), {- traceShow ("addBind: " ++ showpp x) -} i) diff --git a/src/Language/Haskell/Liquid/Constraint/Types.hs b/src/Language/Haskell/Liquid/Constraint/Types.hs index dc674185ed..91c4aeb637 100644 --- a/src/Language/Haskell/Liquid/Constraint/Types.hs +++ b/src/Language/Haskell/Liquid/Constraint/Types.hs @@ -103,7 +103,7 @@ data CGEnv = CGE , tgKey :: !(Maybe Tg.TagKey) -- ^ Current top-level binder , trec :: !(Maybe (M.HashMap F.Symbol SpecType)) -- ^ Type of recursive function with decreasing constraints , lcb :: !(M.HashMap F.Symbol CoreExpr) -- ^ Let binding that have not been checked (c.f. LAZYVARs) - , forallcb :: !(M.HashMap Var F.Expr) -- ^ Polymorhic let bindings + , forallcb :: !(M.HashMap Var F.Expr) -- ^ Polymorhic let bindings , holes :: !HEnv -- ^ Types with holes, will need refreshing , lcs :: !LConstraint -- ^ Logical Constraints , cerr :: !(Maybe (TError SpecType)) -- ^ error that should be reported at the user @@ -150,15 +150,15 @@ data SubC = SubC { senv :: !CGEnv data WfC = WfC !CGEnv !SpecType -- deriving (Data, Typeable) -type FixSubC = F.SubC Cinfo -type FixWfC = F.WfC Cinfo - +type FixSubC = F.SubC Cinfo +type FixWfC = F.WfC Cinfo +type FixBindEnv = F.BindEnv Cinfo subVar :: FixSubC -> Maybe Var subVar = ci_var . F.sinfo instance PPrint SubC where - pprintTidy k c@(SubC {}) = + pprintTidy k c@SubC {} = "The environment:" $+$ "" @@ -177,7 +177,7 @@ instance PPrint SubC where , "<:" , pprintTidy k (rhs c) ] - pprintTidy k c@(SubR {}) = + pprintTidy k c@SubR {} = "The environment:" $+$ "" @@ -209,17 +209,17 @@ data CGInfo = CGInfo , fixCs :: ![FixSubC] -- ^ subtyping over Sort (post-splitting) , fixWfs :: ![FixWfC] -- ^ wellformedness constraints over Sort (post-splitting) , freshIndex :: !Integer -- ^ counter for generating fresh KVars - , binds :: !F.BindEnv -- ^ set of environment binders + , binds :: !FixBindEnv -- ^ set of environment binders , ebinds :: ![F.BindId] -- ^ existentials , annotMap :: !(AnnInfo (Annot SpecType)) -- ^ source-position annotation map , holesMap :: !(M.HashMap Var (HoleInfo (CGInfo, CGEnv) SpecType)) -- ^ information for ghc hole expressions , tyConInfo :: !TyConMap -- ^ information about type-constructors - , specDecr :: ![(Var, [Int])] -- ^ ^ Lexicographic order of decreasing args (DEPRECATED) + , specDecr :: ![(Var, [Int])] -- ^ ^ Lexicographic order of decreasing args (DEPRECATED) , newTyEnv :: !(M.HashMap Ghc.TyCon SpecType) -- ^ Mapping of new type type constructors with their refined types. , termExprs :: !(M.HashMap Var [F.Located F.Expr]) -- ^ Terminating Metrics for Recursive functions , specLVars :: !(S.HashSet Var) -- ^ Set of variables to ignore for termination checking , specLazy :: !(S.HashSet Var) -- ^ "Lazy binders", skip termination checking - , specTmVars :: !(S.HashSet Var) -- ^ Binders that FAILED struct termination check that MUST be checked + , specTmVars :: !(S.HashSet Var) -- ^ Binders that FAILED struct termination check that MUST be checked , autoSize :: !(S.HashSet Ghc.TyCon) -- ^ ? FIX THIS , tyConEmbed :: !(F.TCEmb Ghc.TyCon) -- ^ primitive Sorts into which TyCons should be embedded , kuts :: !F.Kuts -- ^ Fixpoint Kut variables (denoting "back-edges"/recursive KVars) From 52fec1b098b7c4906cf21043feaa453836da49ea Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Wed, 14 Dec 2022 16:01:01 -0800 Subject: [PATCH 042/219] fixpoint compiles with BindEnv ann --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 891169d84c..672ca3cab0 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 891169d84cc4495f26e8d65bfed59fab49091f4f +Subproject commit 672ca3cab0f964cebb95fec754e9ee98dc246bbf From 7d7894ef887f70fe066b4e2f3bed0b03cc7fe05c Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Wed, 14 Dec 2022 20:16:57 -0800 Subject: [PATCH 043/219] fixpoint compiles with BindEnv ann --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 672ca3cab0..59652cbdbd 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 672ca3cab0f964cebb95fec754e9ee98dc246bbf +Subproject commit 59652cbdbda23b3ad05bc921ab82a3c49ab0cd55 From cd04279fdbad6284016840075d5b9986c9455517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Thu, 15 Dec 2022 07:49:11 -0300 Subject: [PATCH 044/219] Fix environment of the hlint workflow --- .github/workflows/hlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/hlint.yml b/.github/workflows/hlint.yml index 3f7892a855..486cf55660 100644 --- a/.github/workflows/hlint.yml +++ b/.github/workflows/hlint.yml @@ -7,7 +7,7 @@ on: jobs: build: name: hlint - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - name: fix ncurses version From 0e9c489157cc3fd32734278ff4f87f300002a5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Thu, 15 Dec 2022 10:13:51 -0300 Subject: [PATCH 045/219] Remove alternative fix to hlint dependencies Installing libncurses5 also gets hlint succeeding. LF and LH now pin the version of ubuntu though, and this requires a bit less trouble in CI to get a usable environment. --- .github/workflows/hlint.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/hlint.yml b/.github/workflows/hlint.yml index 486cf55660..7e198862fe 100644 --- a/.github/workflows/hlint.yml +++ b/.github/workflows/hlint.yml @@ -10,9 +10,6 @@ jobs: runs-on: ubuntu-20.04 steps: - - name: fix ncurses version - run: sudo apt-get install libncurses5 - - uses: actions/checkout@v3 with: submodules: true From a560ca0c68443485993b08088d0c07c497c10f53 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Thu, 15 Dec 2022 09:10:37 -0800 Subject: [PATCH 046/219] elab-err-new --- liquid-fixpoint | 2 +- src/Language/Haskell/Liquid/Constraint/Env.hs | 2 +- src/Language/Haskell/Liquid/Constraint/Types.hs | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 59652cbdbd..cead0518e4 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 59652cbdbda23b3ad05bc921ab82a3c49ab0cd55 +Subproject commit cead0518e43251a1f79b1fcceb18f4ea8c2f4635 diff --git a/src/Language/Haskell/Liquid/Constraint/Env.hs b/src/Language/Haskell/Liquid/Constraint/Env.hs index 71fb21fa54..76fdb9009d 100644 --- a/src/Language/Haskell/Liquid/Constraint/Env.hs +++ b/src/Language/Haskell/Liquid/Constraint/Env.hs @@ -149,7 +149,7 @@ addBinders γ0 x' cbs = foldM (++=) (γ0 -= x') [("addBinders", x, t) | (x, t) addBind :: SrcSpan -> F.Symbol -> F.SortedReft -> CG ((F.Symbol, F.Sort), F.BindId) addBind l x r = do st <- get - let (i, bs') = F.insertBindEnv x r (Ci l Nothing Nothing) (binds st) + let (i, bs') = F.insertBindEnv x r (binds st) put $ st { binds = bs' } { bindSpans = M.insert i l (bindSpans st) } return ((x, F.sr_sort r), {- traceShow ("addBind: " ++ showpp x) -} i) diff --git a/src/Language/Haskell/Liquid/Constraint/Types.hs b/src/Language/Haskell/Liquid/Constraint/Types.hs index 91c4aeb637..0eba906572 100644 --- a/src/Language/Haskell/Liquid/Constraint/Types.hs +++ b/src/Language/Haskell/Liquid/Constraint/Types.hs @@ -152,7 +152,6 @@ data WfC = WfC !CGEnv !SpecType type FixSubC = F.SubC Cinfo type FixWfC = F.WfC Cinfo -type FixBindEnv = F.BindEnv Cinfo subVar :: FixSubC -> Maybe Var subVar = ci_var . F.sinfo @@ -209,7 +208,7 @@ data CGInfo = CGInfo , fixCs :: ![FixSubC] -- ^ subtyping over Sort (post-splitting) , fixWfs :: ![FixWfC] -- ^ wellformedness constraints over Sort (post-splitting) , freshIndex :: !Integer -- ^ counter for generating fresh KVars - , binds :: !FixBindEnv -- ^ set of environment binders + , binds :: !F.BindEnv -- ^ set of environment binders , ebinds :: ![F.BindId] -- ^ existentials , annotMap :: !(AnnInfo (Annot SpecType)) -- ^ source-position annotation map , holesMap :: !(M.HashMap Var (HoleInfo (CGInfo, CGEnv) SpecType)) -- ^ information for ghc hole expressions From 00f4f7ae9db5898f3d2e7bae0eb8dab99c1feb5d Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Thu, 15 Dec 2022 09:11:13 -0800 Subject: [PATCH 047/219] link against elab-err-new --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index cead0518e4..8fce5418b0 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit cead0518e43251a1f79b1fcceb18f4ea8c2f4635 +Subproject commit 8fce5418b00fd3aa26340c93e0011738668f470f From 2b6472e59ccc6720878e2bf88d4c98164ddb9eb7 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Thu, 15 Dec 2022 21:16:23 -0800 Subject: [PATCH 048/219] add elab-location-crash tests --- liquid-fixpoint | 2 +- src/Language/Haskell/Liquid/Constraint/Env.hs | 2 +- .../Haskell/Liquid/Constraint/Types.hs | 3 +- src/Language/Haskell/Liquid/GHC/Plugin.hs | 2 +- .../Haskell/Liquid/Types/PrettyPrint.hs | 19 +- tests/errors/ElabLocation.hs | 2 + tests/errors/ElabLocation2.hs | 18 ++ tests/errors/ElabLocation3.hs | 210 ++++++++++++++++++ tests/errors/ErrLocation2.hs | 2 +- tests/tests.cabal | 12 +- 10 files changed, 254 insertions(+), 18 deletions(-) create mode 100644 tests/errors/ElabLocation2.hs create mode 100644 tests/errors/ElabLocation3.hs diff --git a/liquid-fixpoint b/liquid-fixpoint index 8fce5418b0..965d4497fb 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 8fce5418b00fd3aa26340c93e0011738668f470f +Subproject commit 965d4497fbee4eec98ad5cf3504ce40d1f9a4fd9 diff --git a/src/Language/Haskell/Liquid/Constraint/Env.hs b/src/Language/Haskell/Liquid/Constraint/Env.hs index 76fdb9009d..71fb21fa54 100644 --- a/src/Language/Haskell/Liquid/Constraint/Env.hs +++ b/src/Language/Haskell/Liquid/Constraint/Env.hs @@ -149,7 +149,7 @@ addBinders γ0 x' cbs = foldM (++=) (γ0 -= x') [("addBinders", x, t) | (x, t) addBind :: SrcSpan -> F.Symbol -> F.SortedReft -> CG ((F.Symbol, F.Sort), F.BindId) addBind l x r = do st <- get - let (i, bs') = F.insertBindEnv x r (binds st) + let (i, bs') = F.insertBindEnv x r (Ci l Nothing Nothing) (binds st) put $ st { binds = bs' } { bindSpans = M.insert i l (bindSpans st) } return ((x, F.sr_sort r), {- traceShow ("addBind: " ++ showpp x) -} i) diff --git a/src/Language/Haskell/Liquid/Constraint/Types.hs b/src/Language/Haskell/Liquid/Constraint/Types.hs index 0eba906572..91c4aeb637 100644 --- a/src/Language/Haskell/Liquid/Constraint/Types.hs +++ b/src/Language/Haskell/Liquid/Constraint/Types.hs @@ -152,6 +152,7 @@ data WfC = WfC !CGEnv !SpecType type FixSubC = F.SubC Cinfo type FixWfC = F.WfC Cinfo +type FixBindEnv = F.BindEnv Cinfo subVar :: FixSubC -> Maybe Var subVar = ci_var . F.sinfo @@ -208,7 +209,7 @@ data CGInfo = CGInfo , fixCs :: ![FixSubC] -- ^ subtyping over Sort (post-splitting) , fixWfs :: ![FixWfC] -- ^ wellformedness constraints over Sort (post-splitting) , freshIndex :: !Integer -- ^ counter for generating fresh KVars - , binds :: !F.BindEnv -- ^ set of environment binders + , binds :: !FixBindEnv -- ^ set of environment binders , ebinds :: ![F.BindId] -- ^ existentials , annotMap :: !(AnnInfo (Annot SpecType)) -- ^ source-position annotation map , holesMap :: !(M.HashMap Var (HoleInfo (CGInfo, CGEnv) SpecType)) -- ^ information for ghc hole expressions diff --git a/src/Language/Haskell/Liquid/GHC/Plugin.hs b/src/Language/Haskell/Liquid/GHC/Plugin.hs index 92be3eab7a..b66b357b8b 100644 --- a/src/Language/Haskell/Liquid/GHC/Plugin.hs +++ b/src/Language/Haskell/Liquid/GHC/Plugin.hs @@ -383,7 +383,7 @@ errorLogger file filters outputResult = do , failure = GHC.failM , continue = pure () , pprinter = \(spn, e) -> mkLongErrAt spn (LH.fromPJDoc e) O.empty - , matchingFilters = LH.reduceFilters (PJ.render . snd) filters + , matchingFilters = LH.reduceFilters (\(src, doc) -> PJ.render doc ++ showpp src) filters , filters = filters } (LH.orMessages outputResult) diff --git a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs index 6d29ef2fe2..38fb14f9cb 100644 --- a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs +++ b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs @@ -475,8 +475,8 @@ filterReportErrors path failure continue filters k = , filters = filters } where - renderer :: TError e' -> String - renderer = render . ppError k empty + renderer e = render (ppError k empty e $+$ pprint (pos e)) + -- | Retrieve the `Filter`s from the Config. getFilters :: Config -> [Filter] @@ -487,12 +487,15 @@ getFilters cfg = anyFilter <> stringFilters -- | Return the list of @filters@ that matched the @err@ , given a @renderer@ -- for the @err@ and some @filters@ -reduceFilters :: forall e. (e -> String) -> [Filter] -> e -> [Filter] -reduceFilters renderer fs err = filter (filterDoesMatchErr err) fs - where - filterDoesMatchErr :: e -> Filter -> Bool - filterDoesMatchErr _ AnyFilter = True - filterDoesMatchErr e (StringFilter filter) = filter `L.isInfixOf` renderer e +reduceFilters :: (e -> String) -> [Filter] -> e -> [Filter] +reduceFilters renderer fs err = filter (filterDoesMatchErr renderer err) fs + +filterDoesMatchErr :: (e -> String) -> e -> Filter -> Bool +filterDoesMatchErr _ _ AnyFilter = True +filterDoesMatchErr renderer e (StringFilter filter) = stringMatch filter (renderer e) + +stringMatch :: String -> String -> Bool +stringMatch filter str = F.notracepp ("TRACE: stringMatch " ++ show (filter, str)) $ filter `L.isInfixOf` str -- | Used in `filterReportErrorsWith'` data FilterReportErrorsArgs m filter msg e a = diff --git a/tests/errors/ElabLocation.hs b/tests/errors/ElabLocation.hs index 5f48c087ea..edf4c39e0b 100644 --- a/tests/errors/ElabLocation.hs +++ b/tests/errors/ElabLocation.hs @@ -3,6 +3,8 @@ -- is compared against '0' which appears in the refinement for '/'.) -- You can fix this by `embed Ratio * as Int` +{-@ LIQUID "--expect-error-containing=ElabLocation.hs:15:14-15:15" @-} + module ElabLocation where import Data.Ratio diff --git a/tests/errors/ElabLocation2.hs b/tests/errors/ElabLocation2.hs new file mode 100644 index 0000000000..290d262dc3 --- /dev/null +++ b/tests/errors/ElabLocation2.hs @@ -0,0 +1,18 @@ +{-@ LIQUID "--expect-error-containing=ElabLocation2.hs:18:54-66" @-} +module ElabLocation2 where +type Range = (Int,Int) + +{-@ measure start @-} +start :: Range -> Int +start (a,b) = a + +{-@ measure end @-} +end :: Range -> Int +end (a,b) = b + +{-@ using (Range) as {r:Range | start r <= end r} @-} + +-- seemed to work earlier, now fails +{-@ intsToRanges :: Int -> Int -> Int -> Int -> Maybe (Range,Range) @-} +intsToRanges :: Int -> Int -> Int -> Int -> Maybe (Range,Range) +intsToRanges a b c d = if a <= b && c <= d then Just ((a,b),(c,d)) else Nothing diff --git a/tests/errors/ElabLocation3.hs b/tests/errors/ElabLocation3.hs new file mode 100644 index 0000000000..c2edf55092 --- /dev/null +++ b/tests/errors/ElabLocation3.hs @@ -0,0 +1,210 @@ +module ElabLocation3 where +{-@ LIQUID "--expect-error-containing=ElabLocation3.hs:174:1-5" @-} +{-@ LIQUID "--reflection" @-} + +import Language.Haskell.Liquid.ProofCombinators +import Prelude hiding (id) + +{-@ type Pos = {v:Int | 0 < v} @-} + +{-@ incr :: Pos -> Pos @-} +incr :: Int -> Int +incr x = x + 1 + + + +{-@ +data Monkey = + M { number :: Nat, + items :: [Int], + operation :: Int -> Int, + testMod :: {n:Int | n > 0 }, + ifTrue :: Nat, + ifFalse :: Nat, + count :: Nat + } +@-} +data Monkey = + M { number :: Int, + items :: [Int], + operation :: Int -> Int, + testMod :: Int, + ifTrue :: Int, + ifFalse :: Int, + count :: Int } + +{-@ myCount :: _ -> Nat @-} +myCount :: Monkey -> Int +myCount M { count = k} = k + + +showMonkey :: Monkey -> String +showMonkey (M n i o m ifT ifF count) = + "#" ++ (show n) ++ " items " ++ (show i) ++ " examined " ++ (show count) ++ "\n" + +instance Show Monkey where show = showMonkey + +{-@ type MonkeyIR X = {m:Monkey | number m < X && ifTrue m < X && ifFalse m < X } @-} + +-- fst = item +-- snd = destination +{-@ type MonkeyItem X = (Int, {n:Nat | n < X}) @-} + +{-@ turn :: x:Int -> {worry:Int | worry /= 0 } -> {modulus:Int | modulus /= 0} -> m:MonkeyIR x -> {d:[MonkeyItem x] | len d = len (items m)} @-} +turn :: Int -> Int -> Int -> Monkey -> [(Int, Int)] +turn _ worry modulus (M _ oldItems op m dTrue dFalse _) = + map toDestination oldItems where + toDestination i = let newWorry = (( op i ) `div` worry) `mod` modulus in + (newWorry, if newWorry `mod` m == 0 then dTrue else dFalse) + +-- What I would like to do: +-- measure countOfItems :: [Monkey] -> Int +-- countOfItems [] = 0 +-- countOfItems (m:ms) = len (items m) + countOfItems ms +-- +-- -> {m2:[MonkeyIR x] | len m2 = len m && countOfItems m2 = countOfItems m + len mi} +-- +-- But this measure gets applied to all lists, which doesn't work + +{-@ data MonkeyList = Empty | MCons { headMonkey :: MonkeyIR 8, barrel :: MonkeyList } @-} +data MonkeyList = + Empty | + MCons Monkey MonkeyList + +{-@ measure mLen :: MonkeyList -> Int + mLen Empty = 0 + mLen (MCons m ms) = 1 + mLen ms + @-} + +{-@ measure countOfItems :: MonkeyList -> Int + countOfItems Empty = 0 + countOfItems (MCons m ms) = len (items m) + countOfItems ms @-} + +{- +{-@ distribute2 :: m:MonkeyList -> {mi:[MonkeyItem 8] | len mi <= mLen m} + -> {m2:MonkeyList | mLen m2 = mLen m && countOfItems m2 = countOfItems m + len mi} @-} +distribute2 :: MonkeyList -> [(Int,Int)] -> MonkeyList +distribute2 Empty [] = Empty +distribute2 Empty _ = error "Shouldn't happen" +distribute2 (MCons m ms) destinations = + MCons (m {items = (items m) ++ newItems}) (distribute2 ms (filter (notP toMe) destinations)) where + newItems = map fst (filter toMe destinations) + toMe (_,d) = d == number m +-} + +{-@ distribute :: x:Int -> m:[MonkeyIR x] -> mi:[MonkeyItem x] + -> {m2:[MonkeyIR x] | len m2 = len m} @-} +distribute :: Int -> [Monkey] -> [(Int,Int)] -> [Monkey] +distribute _ [] _ = [] +distribute x (m:ms) destinations = + (m {items = (items m) ++ newItems}):(distribute x ms destinations) where + newItems = map fst (filter toMe destinations) + toMe (_,d) = d == number m + +-- Monkey N's turn in the round +{-@ roundN :: x:Int -> + {worry:Int | worry /= 0 } -> + {modulus:Int | modulus /= 0} -> + {before:[MonkeyIR x] | len before = x} -> + {n:Nat | n < x } -> + {after:[m:MonkeyIR x] | len after = x} @-} +roundN :: Int -> Int -> Int -> [Monkey] -> Int -> [Monkey] +roundN x worry modulus monkeys n = + let m = (monkeys !! n) + destinations = turn x worry modulus m + newCount = (myCount m) + length (items m) + afterRemoval = (take n monkeys) ++ [(m {items = [], count = newCount} )] ++ (drop (n+1) monkeys) in + distribute x afterRemoval destinations + +-- One round of all monkeys +-- Complicated by the need to prove termination. +{-@ round :: x:Int -> {worry:Int | worry /= 0} -> {modulus:Int | modulus /= 0 } -> + {before:[MonkeyIR x] | len before = x} -> + {after:[MonkeyIR x] | len after = x} @-} +round :: Int -> Int -> Int -> [Monkey] -> [Monkey] +round x worry modulus monkeys = go 0 monkeys where + {-@ go :: {n:Int | n >= 0 && n <= x} -> {m:[MonkeyIR x] | len m = x} -> {m2:[MonkeyIR x] | len m2 = x} / [ x - n ] @-} + go n ms = if n == x then ms + else go (n+1) (roundN x worry modulus ms n) + + +{-@ m0 :: MonkeyIR 4 @-} +m0 = M { number=0, items=[79,98], operation=(\o -> o * 19), testMod=23, ifTrue=2, ifFalse=3, count=0 } +{-@ m1 :: MonkeyIR 4 @-} +m1 = M { number=1, items=[54,65,75,74], operation=(\o -> o + 6), testMod=19, ifTrue=2, ifFalse=0, count=0 } +{-@ m2 :: MonkeyIR 4 @-} +m2 = M { number=2, items=[79,60,97], operation=(\o -> o * o), testMod=13, ifTrue=1, ifFalse=3, count=0 } +{-@ m3 :: MonkeyIR 4 @-} +m3 = M { number=3, items=[74], operation=(\o -> o + 3), testMod=17, ifTrue=0, ifFalse=1, count=0 } + +{-@ example :: {m:[MonkeyIR 4] | len m = 4} @-} +example :: [Monkey] +example = [ m0, m1, m2, m3 ] + +{-@ i0 :: MonkeyIR 8 @-} +i0 = M { number=0, items=[59,74,65,86], operation=(\o -> o * 19), testMod=7, ifTrue=6, ifFalse=2, count=0 } +{-@ i1 :: MonkeyIR 8 @-} +i1 = M { number=1, items=[62,84,72,91,68,78,51], operation=(\o -> o + 1), testMod=2, ifTrue=2, ifFalse=0, count=0 } +{-@ i2 :: MonkeyIR 8 @-} +i2 = M { number=2, items=[78,84,96], operation=(\o -> o + 8), testMod=19, ifTrue=6, ifFalse=5, count=0 } +{-@ i3 :: MonkeyIR 8 @-} +i3 = M { number=3, items=[97,86], operation=(\o -> o * o), testMod=3, ifTrue=1, ifFalse=0, count=0 } +{-@ i4 :: MonkeyIR 8 @-} +i4 = M { number=4, items=[50], operation=(\o -> o + 6), testMod=13, ifTrue=3, ifFalse=1, count=0 } +{-@ i5 :: MonkeyIR 8 @-} +i5 = M { number=5, items=[73,65,69,65,51], operation=(\o -> o * 17), testMod=11, ifTrue=4, ifFalse=7, count=0 } +{-@ i6 :: MonkeyIR 8 @-} +i6 = M { number=6, items=[69, 82, 97, 93, 82, 84, 58, 63], operation=(\o -> o + 5), testMod=5, ifTrue=5, ifFalse=7, count=0 } +{-@ i7 :: MonkeyIR 8 @-} +i7 = M { number=7, items=[81, 78, 82, 76, 79, 80], operation=(\o -> o + 3), testMod=17, ifTrue=3, ifFalse=4, count=0 } + +{-@ input :: {m:[MonkeyIR 8] | len m = 8} @-} +input :: [Monkey] +input = [ i0, i1, i2, i3, i4, i5, i6, i7 ] + +{-@ assume iterate :: (a -> a) -> a -> {l:[a] | len l >= 1000000 } @-} + +computeModulus :: [Monkey] -> Int +computeModulus ms = foldl1 (*) (map testMod ms) + + +id z = z + +part1 :: () -> IO () +part1 _ = do + putStrLn "Part 1" + let m1 = computeModulus example in do + putStrLn $ "Working mod " ++ show m1 + let allRounds = iterate {- (Main.round 4 3 m1) -} id example in + print $ allRounds !! 20 + + let m2 = computeModulus input in do + putStrLn $ "Working mod " ++ show m2 + let allRounds2 = iterate {- (Main.round 8 3 m2) -} id input in + print $ allRounds2 !! 20 + +part2 :: () -> IO () +part2 _ = do + putStrLn "Part 2" + let m1 = computeModulus example in do + putStrLn $ "Working mod " ++ show m1 + let allRounds = iterate {- (Main.round 4 1 m1) -} id example in do + print $ allRounds !! 1000 + print $ allRounds !! 2000 + print $ allRounds !! 3000 + print $ allRounds !! 4000 + print $ allRounds !! 5000 + print $ allRounds !! 6000 + print $ allRounds !! 7000 + print $ allRounds !! 8000 + print $ allRounds !! 9000 + print $ allRounds !! 10000 + + let m2 = computeModulus input in do + putStrLn $ "Working mod " ++ show m2 + let allRounds2 = iterate {- (Main.round 8 1 m2) -} id input in + print $ allRounds2 !! 10000 + +mymain :: IO () +mymain = part1 () >> part2 () + diff --git a/tests/errors/ErrLocation2.hs b/tests/errors/ErrLocation2.hs index a0323315ca..0cfbfc5f79 100644 --- a/tests/errors/ErrLocation2.hs +++ b/tests/errors/ErrLocation2.hs @@ -1,4 +1,4 @@ -{-@ LIQUID "--expect-error-containing=ErrLocation2.hs:12:20: error" @-} +{-@ LIQUID "--expect-error-containing=ErrLocation2.hs:12:20" @-} module ErrLocation2 where diff --git a/tests/tests.cabal b/tests/tests.cabal index 67d90c9a93..767a893b27 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -11,7 +11,7 @@ version: 0.1.0.0 author: The Liquid Haskell Developers flag stack - default: False + default: True description: Enable when building with stack to prevent tests from using cabal-install, and to mark all executables as " buildable: False " by default @@ -606,7 +606,7 @@ flag errors executable errors main-is: Main.hs if !flag(errors) && flag(stack) - buildable: False + buildable: True other-modules: BadAliasApp @@ -650,10 +650,12 @@ executable errors , DupData , DupFunSigs , DupMeasure - -- , ElabLocation + , ElabLocation + , ElabLocation2 + , ElabLocation3 , EmptyData - -- , ErrLocation2 - -- , ErrLocation + , ErrLocation + , ErrLocation2 -- , ExportMeasure0 -- , ExportReflect0 , Fractional From fb3a20bd426e5bc145968abb1b09d14b5007a575 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Thu, 15 Dec 2022 21:17:45 -0800 Subject: [PATCH 049/219] add elab-location-crash tests --- tests/tests.cabal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests.cabal b/tests/tests.cabal index 767a893b27..1c83e5b380 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -11,7 +11,7 @@ version: 0.1.0.0 author: The Liquid Haskell Developers flag stack - default: True + default: False description: Enable when building with stack to prevent tests from using cabal-install, and to mark all executables as " buildable: False " by default @@ -606,7 +606,7 @@ flag errors executable errors main-is: Main.hs if !flag(errors) && flag(stack) - buildable: True + buildable: False other-modules: BadAliasApp From 24ada7ed3c7b1fb870d22250ff84531257188899 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Thu, 15 Dec 2022 21:18:06 -0800 Subject: [PATCH 050/219] add elab-location-crash tests --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 965d4497fb..3f3ac7d1d2 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 965d4497fbee4eec98ad5cf3504ce40d1f9a4fd9 +Subproject commit 3f3ac7d1d2fb334a2bd77e63a220e133291319e1 From 33f520bc3b3c72992eb6eada12f74801fb61ae74 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 16 Dec 2022 05:51:42 -0800 Subject: [PATCH 051/219] try again LH --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 3f3ac7d1d2..a1ae268186 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 3f3ac7d1d2fb334a2bd77e63a220e133291319e1 +Subproject commit a1ae268186db8ecf9e8d7689594b360c62b8ca54 From cdfe689d749da075544b476243184f480684062e Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 16 Dec 2022 06:11:22 -0800 Subject: [PATCH 052/219] rerun --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f12a7db862..76334df197 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ ![LiquidHaskell](/resources/logo.png) - [![Hackage](https://img.shields.io/hackage/v/liquidhaskell.svg)](https://hackage.haskell.org/package/liquidhaskell) [![Hackage-Deps](https://img.shields.io/hackage-deps/v/liquidhaskell.svg)](http://packdeps.haskellers.com/feed?needle=liquidhaskell) [![Build Status](https://img.shields.io/circleci/project/ucsd-progsys/liquidhaskell/master.svg)](https://circleci.com/gh/ucsd-progsys/liquidhaskell) [![Windows build status](https://ci.appveyor.com/api/projects/status/78y7uusjcgor5p16/branch/develop?svg=true)](https://ci.appveyor.com/project/varosi/liquidhaskell-nlhra/branch/develop) From 8c9ff8d3e0593652350a43619eb4ef9567436e17 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 16 Dec 2022 08:50:43 -0800 Subject: [PATCH 053/219] link LH-LF --- cabal.project | 2 ++ liquid-fixpoint | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cabal.project b/cabal.project index e9af472858..6a5acaecb9 100644 --- a/cabal.project +++ b/cabal.project @@ -1,3 +1,5 @@ +with-compiler: ghc-8.10.7 + packages: . ./liquid-base ./liquid-bytestring diff --git a/liquid-fixpoint b/liquid-fixpoint index a1ae268186..021d7af56a 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit a1ae268186db8ecf9e8d7689594b360c62b8ca54 +Subproject commit 021d7af56a39985170c78b07c842b853a6180f77 From dc35e4e20340b46af7b759931e2305a91dc73b91 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 16 Dec 2022 09:41:55 -0800 Subject: [PATCH 054/219] make ERROR not barf out location. --- src/Language/Haskell/Liquid/GHC/Plugin.hs | 2 +- src/Language/Haskell/Liquid/Types/PrettyPrint.hs | 4 ++-- tests/README.md | 16 ++++++++++++++++ tests/errors/ElabLocation2.hs | 4 ++-- tests/errors/ElabLocation3.hs | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Language/Haskell/Liquid/GHC/Plugin.hs b/src/Language/Haskell/Liquid/GHC/Plugin.hs index b66b357b8b..3a1561af21 100644 --- a/src/Language/Haskell/Liquid/GHC/Plugin.hs +++ b/src/Language/Haskell/Liquid/GHC/Plugin.hs @@ -383,7 +383,7 @@ errorLogger file filters outputResult = do , failure = GHC.failM , continue = pure () , pprinter = \(spn, e) -> mkLongErrAt spn (LH.fromPJDoc e) O.empty - , matchingFilters = LH.reduceFilters (\(src, doc) -> PJ.render doc ++ showpp src) filters + , matchingFilters = LH.reduceFilters (\(src, doc) -> PJ.render doc ++ " at " ++ LH.showPpr src) filters , filters = filters } (LH.orMessages outputResult) diff --git a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs index 38fb14f9cb..e4f89a378d 100644 --- a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs +++ b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs @@ -345,7 +345,7 @@ pprRtyFun bb prefix t = hsep (prefix : dArgs ++ [dOut]) ppArg (b, t, a) = [pprDbind bb funPrec b t, a] (args, out) = brkFun t -{- +{- pprRtyFun bb prefix t = prefix <+> pprRtyFun' bb t @@ -495,7 +495,7 @@ filterDoesMatchErr _ _ AnyFilter = True filterDoesMatchErr renderer e (StringFilter filter) = stringMatch filter (renderer e) stringMatch :: String -> String -> Bool -stringMatch filter str = F.notracepp ("TRACE: stringMatch " ++ show (filter, str)) $ filter `L.isInfixOf` str +stringMatch filter str = F.tracepp ("TRACE: stringMatch " ++ show (filter, str)) $ filter `L.isInfixOf` str -- | Used in `filterReportErrorsWith'` data FilterReportErrorsArgs m filter msg e a = diff --git a/tests/README.md b/tests/README.md index e71a907340..b073c47ca0 100644 --- a/tests/README.md +++ b/tests/README.md @@ -22,6 +22,22 @@ invoke either stack or cabal to compile specific test groups, kept in `tests.cabal` as separate executables. The rest of this file describes how to modify the test suite by adding new tests. +### Running a Particular Test Suite + +With `stack` you can do (you may have to set certain flags to `True` in `tests.cabal`) + +``` +$ cd tests +$ stack test tests:exe:errors --fast +``` + +and with `cabal` you could try + +``` +$ cd tests +$ cabal v2-run tests:errors +``` + ### Adding a New Test to an Existing Test Group Create a new file in the source directory specified in the cabal file for that diff --git a/tests/errors/ElabLocation2.hs b/tests/errors/ElabLocation2.hs index 290d262dc3..6b32ee4eb6 100644 --- a/tests/errors/ElabLocation2.hs +++ b/tests/errors/ElabLocation2.hs @@ -1,5 +1,5 @@ -{-@ LIQUID "--expect-error-containing=ElabLocation2.hs:18:54-66" @-} -module ElabLocation2 where +{-@ LIQUID "--expect-error-containing=ElabLocation2.hs:18:54-67" @-} +module ElabLocation2 where type Range = (Int,Int) {-@ measure start @-} diff --git a/tests/errors/ElabLocation3.hs b/tests/errors/ElabLocation3.hs index c2edf55092..d92c6705d1 100644 --- a/tests/errors/ElabLocation3.hs +++ b/tests/errors/ElabLocation3.hs @@ -9,7 +9,7 @@ import Prelude hiding (id) {-@ incr :: Pos -> Pos @-} incr :: Int -> Int -incr x = x + 1 +incr x = x + 2 From 72730c832e81e58ab82c25db48409a8c73df687f Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 16 Dec 2022 11:45:50 -0800 Subject: [PATCH 055/219] more cleanup for fixpoint/elab/crash/error --- src-ghc/Liquid/GHC/Interface.hs | 62 ++++++++--------- .../Haskell/Liquid/Types/PrettyPrint.hs | 2 +- src/Language/Haskell/Liquid/Types/Types.hs | 53 +++++++------- src/Language/Haskell/Liquid/UX/Annotate.hs | 34 ++++----- src/Language/Haskell/Liquid/UX/CmdLine.hs | 21 ++++-- src/Language/Haskell/Liquid/UX/DiffCheck.hs | 69 +++++++++---------- src/Language/Haskell/Liquid/UX/Tidy.hs | 24 +++---- tests/errors/ElabLocation.hs | 12 ++-- tests/errors/ElabLocation2.hs | 2 +- 9 files changed, 145 insertions(+), 134 deletions(-) diff --git a/src-ghc/Liquid/GHC/Interface.hs b/src-ghc/Liquid/GHC/Interface.hs index 6a6394a8cc..6214bc9003 100644 --- a/src-ghc/Liquid/GHC/Interface.hs +++ b/src-ghc/Liquid/GHC/Interface.hs @@ -123,14 +123,14 @@ import qualified Debug.Trace as Debug -------------------------------------------------------------------------------- -{- | @realTargets mE cfg targets@ uses `Interface.configureGhcTargets` to +{- | @realTargets mE cfg targets@ uses `Interface.configureGhcTargets` to return a list of files [i1, i2, ... ] ++ [f1, f2, ...] - 1. Where each file only (transitively imports) PRECEDIING ones; + 1. Where each file only (transitively imports) PRECEDIING ones; 2. `f1..` are a permutation of the original `targets`; - 3. `i1..` either don't have "fresh" .bspec files. + 3. `i1..` either don't have "fresh" .bspec files. -} -------------------------------------------------------------------------------- @@ -159,7 +159,7 @@ orderTargets mbEnv cfg tgtFiles = runLiquidGhc mbEnv cfg $ do skipTarget :: S.HashSet FilePath -> FilePath -> IO Bool skipTarget tgts f - | S.member f tgts = return False -- Always check target file + | S.member f tgts = return False -- Always check target file | otherwise = hasFreshBinSpec f -- But skip an import with fresh .bspec hasFreshBinSpec :: FilePath -> IO Bool @@ -224,7 +224,7 @@ configureDynFlags cfg tmp = do loud <- liftIO isLoud let df'' = df' { importPaths = nub $ idirs cfg ++ importPaths df' , libraryPaths = nub $ idirs cfg ++ libraryPaths df' - , includePaths = updateIncludePaths df' (idirs cfg) -- addGlobalInclude (includePaths df') (idirs cfg) + , includePaths = updateIncludePaths df' (idirs cfg) -- addGlobalInclude (includePaths df') (idirs cfg) , packageFlags = ExposePackage "" (PackageArg "ghc-prim") (ModRenaming True []) @@ -298,9 +298,9 @@ compileCFiles cfg = do Bar.hs --> Foo.hs --> Bar.hs-boot we'll get - + [Bar.hs, Foo.hs] - + which is backwards.. -} -------------------------------------------------------------------------------- @@ -484,10 +484,10 @@ loadModule' tm = loadModule tm' -- Ghc.execOptions -- void $ Ghc.execStmt -- "let {infixl 7 /; (/) :: Num a => a -> a -> a; _ / _ = undefined}" - -- Ghc.execOptions + -- Ghc.execOptions -- void $ Ghc.execStmt -- "let {len :: [a] -> Int; len _ = undefined}" - -- Ghc.execOptions + -- Ghc.execOptions processTargetModule :: Config -> LogicMap -> DepGraph -> SpecEnv -> FilePath -> TypecheckedModule -> Ms.BareSpec -> Ghc TargetInfo processTargetModule cfg0 logicMap depGraph specEnv file typechecked bareSpec = do @@ -569,7 +569,7 @@ loadContext bareSpec dependencies targetSrc = do legacyBareSpec = review bareSpecIso bareSpec --------------------------------------------------------------------------------------- --- | @makeGhcSrc@ builds all the source-related information needed for consgen +-- | @makeGhcSrc@ builds all the source-related information needed for consgen --------------------------------------------------------------------------------------- makeGhcSrc :: Config -> FilePath -> TypecheckedModule -> ModSummary -> Ghc GhcSrc @@ -646,9 +646,9 @@ qImports qns = QImports --------------------------------------------------------------------------------------- --- | @lookupTyThings@ grabs all the @Name@s and associated @TyThing@ known to GHC --- for this module; we will use this to create our name-resolution environment --- (see `Bare.Resolve`) +-- | @lookupTyThings@ grabs all the @Name@s and associated @TyThing@ known to GHC +-- for this module; we will use this to create our name-resolution environment +-- (see `Bare.Resolve`) --------------------------------------------------------------------------------------- lookupTyThings :: GhcMonadLike m => HscEnv -> ModSummary -> TcGblEnv -> m [(Name, Maybe TyThing)] lookupTyThings hscEnv modSum tcGblEnv = forM names (lookupTyThing hscEnv modSum tcGblEnv) @@ -685,22 +685,22 @@ availableVars :: GhcMonadLike m => HscEnv -> ModSummary -> TcGblEnv -> [AvailInf availableVars hscEnv modSum tcGblEnv avails = fmap (\things -> [var | (AnId var) <- things]) (availableTyThings hscEnv modSum tcGblEnv avails) --- lookupTyThings :: HscEnv -> TypecheckedModule -> MGIModGuts -> Ghc [(Name, Maybe TyThing)] +-- lookupTyThings :: HscEnv -> TypecheckedModule -> MGIModGuts -> Ghc [(Name, Maybe TyThing)] -- lookupTyThings hscEnv tcm mg = --- forM (mgNames mg ++ instNames mg) $ \n -> do --- tt1 <- lookupName n --- tt2 <- liftIO $ Ghc.hscTcRcLookupName hscEnv n --- tt3 <- modInfoLookupName mi n --- tt4 <- lookupGlobalName n +-- forM (mgNames mg ++ instNames mg) $ \n -> do +-- tt1 <- lookupName n +-- tt2 <- liftIO $ Ghc.hscTcRcLookupName hscEnv n +-- tt3 <- modInfoLookupName mi n +-- tt4 <- lookupGlobalName n -- return (n, Misc.firstMaybes [tt1, tt2, tt3, tt4]) --- where +-- where -- mi = tm_checked_module_info tcm --- lookupName :: GhcMonad m => Name -> m (Maybe TyThing) +-- lookupName :: GhcMonad m => Name -> m (Maybe TyThing) -- hscTcRcLookupName :: HscEnv -> Name -> IO (Maybe TyThing) --- modInfoLookupName :: GhcMonad m => ModuleInfo -> Name -> m (Maybe TyThing) --- lookupGlobalName :: GhcMonad m => Name -> m (Maybe TyThing) +-- modInfoLookupName :: GhcMonad m => ModuleInfo -> Name -> m (Maybe TyThing) +-- lookupGlobalName :: GhcMonad m => Name -> m (Maybe TyThing) _dumpTypeEnv :: TypecheckedModule -> IO () _dumpTypeEnv tm = do @@ -710,8 +710,8 @@ _dumpTypeEnv tm = do tcmTyThings :: TypecheckedModule -> Maybe [Name] tcmTyThings = - -- typeEnvElts - -- . tcg_type_env . fst + -- typeEnvElts + -- . tcg_type_env . fst -- . md_types . snd -- . tm_internals_ modInfoTopLevelScope @@ -722,8 +722,8 @@ _dumpRdrEnv :: HscEnv -> MGIModGuts -> IO () _dumpRdrEnv _hscEnv modGuts = do print ("DUMP-RDR-ENV" :: String) print (mgNames modGuts) - -- print (hscNames hscEnv) - -- print (mgDeps modGuts) + -- print (hscNames hscEnv) + -- print (mgDeps modGuts) where _mgDeps = Ghc.dep_mods . mgi_deps _hscNames = fmap showPpr . Ghc.ic_tythings . Ghc.hsc_IC @@ -732,8 +732,8 @@ mgNames :: MGIModGuts -> [Ghc.Name] mgNames = fmap Ghc.gre_name . Ghc.globalRdrEnvElts . mgi_rdr_env --------------------------------------------------------------------------------------- --- | @makeDependencies@ loads BareSpec for target and imported modules --- /IMPORTANT(adn)/: We \"cheat\" a bit by creating a 'Module' out the 'ModuleName' we +-- | @makeDependencies@ loads BareSpec for target and imported modules +-- /IMPORTANT(adn)/: We \"cheat\" a bit by creating a 'Module' out the 'ModuleName' we -- parse from the spec, and convert the former into a 'StableModule' for the purpose -- of dependency tracking. This means, in practice, that all the \"wired-in-prelude\" -- specs will share the same `UnitId`, which for the sake of the executable is an @@ -1039,7 +1039,7 @@ instance PPrint TargetInfo where pprintCBs :: [CoreBind] -> Doc pprintCBs = pprDoc . tidyCBs - -- To print verbosely + -- To print verbosely -- = text . O.showSDocDebug unsafeGlobalDynFlags . O.ppr . tidyCBs instance Show TargetInfo where @@ -1054,4 +1054,4 @@ instance PPrint TargetVars where ------------------------------------------------------------------------ instance Result SourceError where - result = (`Crash` "Invalid Source") . sourceErrors "" + result e = Crash ((, Nothing) <$> sourceErrors "" e) "Invalid Source" diff --git a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs index e4f89a378d..416661c6e3 100644 --- a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs +++ b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs @@ -495,7 +495,7 @@ filterDoesMatchErr _ _ AnyFilter = True filterDoesMatchErr renderer e (StringFilter filter) = stringMatch filter (renderer e) stringMatch :: String -> String -> Bool -stringMatch filter str = F.tracepp ("TRACE: stringMatch " ++ show (filter, str)) $ filter `L.isInfixOf` str +stringMatch filter str = filter `L.isInfixOf` str -- | Used in `filterReportErrorsWith'` data FilterReportErrorsArgs m filter msg e a = diff --git a/src/Language/Haskell/Liquid/Types/Types.hs b/src/Language/Haskell/Liquid/Types/Types.hs index 3d76c870d0..6294cb19e2 100644 --- a/src/Language/Haskell/Liquid/Types/Types.hs +++ b/src/Language/Haskell/Liquid/Types/Types.hs @@ -143,7 +143,7 @@ module Language.Haskell.Liquid.Types.Types ( , AnnInfo (..) , Annot (..) - -- * Hole Information + -- * Hole Information , HoleInfo(..) -- * Overall Output @@ -238,7 +238,7 @@ module Language.Haskell.Liquid.Types.Types ( -- , rtyVarUniqueSymbol, tyVarUniqueSymbol , rtyVarType, tyVarVar - -- * Refined Function Info + -- * Refined Function Info , RFInfo(..), defRFInfo, mkRFInfo, classRFInfo, classRFInfoType , ordSrcSpan @@ -321,9 +321,9 @@ type BScope = Bool -- | Information about Type Constructors ----------------------------------------------------------------------------- data TyConMap = TyConMap - { tcmTyRTy :: M.HashMap TyCon RTyCon -- ^ Map from GHC TyCon to RTyCon + { tcmTyRTy :: M.HashMap TyCon RTyCon -- ^ Map from GHC TyCon to RTyCon , tcmFIRTy :: M.HashMap (TyCon, [F.Sort]) RTyCon -- ^ Map from GHC Family-Instances to RTyCon - , tcmFtcArity :: M.HashMap TyCon Int -- ^ Arity of each Family-Tycon + , tcmFtcArity :: M.HashMap TyCon Int -- ^ Arity of each Family-Tycon } @@ -353,9 +353,9 @@ instance B.Binary RFInfo ----------------------------------------------------------------------------- data PPEnv = PP - { ppPs :: Bool -- ^ print abstract-predicates + { ppPs :: Bool -- ^ print abstract-predicates , ppTyVar :: Bool -- ^ print the unique suffix for each tyvar - , ppShort :: Bool -- ^ print the tycons without qualification + , ppShort :: Bool -- ^ print the tycons without qualification , ppDebug :: Bool -- ^ gross with full info } deriving (Show) @@ -456,7 +456,7 @@ instance F.Loc TyConP where -- TODO: just use Located instead of dc_loc, dc_locE data DataConP = DataConP { dcpLoc :: !F.SourcePos - , dcpCon :: !DataCon -- ^ Corresponding GHC DataCon + , dcpCon :: !DataCon -- ^ Corresponding GHC DataCon , dcpFreeTyVars :: ![RTyVar] -- ^ Type parameters , dcpFreePred :: ![PVar RSort] -- ^ Abstract Refinement parameters , dcpTyConstrs :: ![SpecType] -- ^ ? Class constraints (via `dataConStupidTheta`) @@ -882,9 +882,9 @@ data RTVInfo s | RTVInfo { rtv_name :: Symbol , rtv_kind :: s , rtv_is_val :: Bool - , rtv_is_pol :: Bool -- true iff the type variable gets instantiated with - -- any refinement (ie is polymorphic on refinements), - -- false iff instantiation is with true refinement + , rtv_is_pol :: Bool -- true iff the type variable gets instantiated with + -- any refinement (ie is polymorphic on refinements), + -- false iff instantiation is with true refinement } deriving (Generic, Data, Typeable, Functor) deriving Hashable via Generically (RTVInfo s) @@ -1231,7 +1231,7 @@ data DataCtor = DataCtor { dcName :: F.LocSymbol -- ^ DataCon name , dcTyVars :: [F.Symbol] -- ^ Type parameters , dcTheta :: [BareType] -- ^ The GHC ThetaType corresponding to DataCon.dataConSig - , dcFields :: [(Symbol, BareType)] -- ^ field-name and field-Type pairs + , dcFields :: [(Symbol, BareType)] -- ^ field-name and field-Type pairs , dcResult :: Maybe BareType -- ^ Possible output (if in GADT form) } deriving (Data, Typeable, Generic) deriving Hashable via Generically DataCtor @@ -2088,11 +2088,12 @@ instance NFData a => NFData (TError a) -- | Source Information Associated With Constraints ---------------------------- -------------------------------------------------------------------------------- -data Cinfo = Ci { ci_loc :: !SrcSpan - , ci_err :: !(Maybe Error) - , ci_var :: !(Maybe Var) - } - deriving (Eq, Generic) +data Cinfo = Ci + { ci_loc :: !SrcSpan + , ci_err :: !(Maybe Error) + , ci_var :: !(Maybe Var) + } + deriving (Eq, Generic) instance F.Loc Cinfo where srcSpan = srcSpanFSrcSpan . ci_loc @@ -2109,8 +2110,8 @@ data ModName = ModName !ModType !ModuleName data ModType = Target | SrcImport | SpecImport deriving (Eq, Ord, Show, Generic, Data, Typeable) --- instance B.Binary ModType --- instance B.Binary ModName +-- instance B.Binary ModType +-- instance B.Binary ModName instance Hashable ModType @@ -2166,7 +2167,7 @@ instance Monoid (RTEnv tv t) where instance Semigroup (RTEnv tv t) where RTE x y <> RTE x' y' = RTE (x `M.union` x') (y `M.union` y') --- mapRT :: (M.HashMap Symbol (RTAlias tv t) -> M.HashMap Symbol (RTAlias tv t)) +-- mapRT :: (M.HashMap Symbol (RTAlias tv t) -> M.HashMap Symbol (RTAlias tv t)) -- -> RTEnv tv t -> RTEnv tv t -- mapRT f e = e { typeAliases = f (typeAliases e) } @@ -2208,13 +2209,13 @@ type UnSortedExprs = [UnSortedExpr] -- mempty = [] type UnSortedExpr = ([F.Symbol], F.Expr) data MeasureKind - = MsReflect -- ^ due to `reflect foo` + = MsReflect -- ^ due to `reflect foo` | MsMeasure -- ^ due to `measure foo` with old-style (non-haskell) equations | MsLifted -- ^ due to `measure foo` with new-style haskell equations - | MsClass -- ^ due to `class measure` definition + | MsClass -- ^ due to `class measure` definition | MsAbsMeasure -- ^ due to `measure foo` without equations c.f. tests/pos/T1223.hs - | MsSelector -- ^ due to selector-fields e.g. `data Foo = Foo { fld :: Int }` - | MsChecker -- ^ due to checkers e.g. `is-F` for `data Foo = F ... | G ...` + | MsSelector -- ^ due to selector-fields e.g. `data Foo = Foo { fld :: Int }` + | MsChecker -- ^ due to checkers e.g. `is-F` for `data Foo = F ... | G ...` deriving (Eq, Ord, Show, Data, Typeable, Generic) deriving Hashable via Generically MeasureKind @@ -2358,7 +2359,7 @@ ppMethods k hdr name args mts dName = parens (F.pprintTidy k name <+> dArgs) dArgs = gaps (F.pprintTidy k <$> args) gaps = hcat . punctuate " " - bind m t = ppRISig k m t -- F.pprintTidy k m <+> "::" <+> F.pprintTidy k t + bind m t = ppRISig k m t -- F.pprintTidy k m <+> "::" <+> F.pprintTidy k t instance B.Binary ty => B.Binary (RClass ty) @@ -2508,8 +2509,8 @@ instance F.PPrint TyThing where instance Show DataCon where show = F.showpp --- instance F.Symbolic TyThing where --- symbol = tyThingSymbol +-- instance F.Symbolic TyThing where +-- symbol = tyThingSymbol liquidBegin :: String liquidBegin = ['{', '-', '@'] diff --git a/src/Language/Haskell/Liquid/UX/Annotate.hs b/src/Language/Haskell/Liquid/UX/Annotate.hs index 725d8def32..0e9de20afa 100644 --- a/src/Language/Haskell/Liquid/UX/Annotate.hs +++ b/src/Language/Haskell/Liquid/UX/Annotate.hs @@ -51,7 +51,7 @@ import qualified Data.Vector as V import qualified Data.ByteString.Lazy as B import qualified Data.Text as T import qualified Data.HashMap.Strict as M -import qualified Language.Haskell.Liquid.Misc as Misc +import qualified Language.Haskell.Liquid.Misc as Misc import qualified Language.Haskell.Liquid.UX.ACSS as ACSS import Language.Haskell.HsColour.Classify import Language.Fixpoint.Utils.Files @@ -112,7 +112,7 @@ doGenerate cfg tplAnnMap typAnnMap annTyp srcF writeFile vimF $ vimAnnot cfg annTyp B.writeFile jsonF $ encode typAnnMap where - pandocF = pandocHtml cfg + pandocF = pandocHtml cfg tyHtmlF = extFileName Html srcF tpHtmlF = extFileName Html $ extFileName Cst srcF _annF = extFileName Annot srcF @@ -123,7 +123,7 @@ mkBots :: Reftable r => AnnInfo (RType c tv r) -> [GHC.SrcSpan] mkBots (AI m) = [ src | (src, (Just _, t) : _) <- sortBy (ordSrcSpan `on` fst) $ M.toList m , isFalse (rTypeReft t) ] --- | Like 'copyFile' from 'System.Directory', but ensure that the parent /temporary/ directory +-- | Like 'copyFile' from 'System.Directory', but ensure that the parent /temporary/ directory -- (i.e. \".liquid\") exists on disk, creating it if necessary. copyFileCreateParentDirIfMissing :: FilePath -> FilePath -> IO () copyFileCreateParentDirIfMissing src tgt = do @@ -134,7 +134,7 @@ writeFilesOrStrings :: FilePath -> [Either FilePath String] -> IO () writeFilesOrStrings tgtFile = mapM_ $ either (`copyFileCreateParentDirIfMissing` tgtFile) (tgtFile `appendFile`) generateHtml :: Bool -> FilePath -> FilePath -> ACSS.AnnMap -> IO () -generateHtml pandocF srcF htmlF annm = do +generateHtml pandocF srcF htmlF annm = do src <- Misc.sayReadFile srcF let lhs = isExtFile LHs srcF let body = {-# SCC "hsannot" #-} ACSS.hsannot False (Just tokAnnot) lhs (src, annm) @@ -237,10 +237,10 @@ cssHTML css = unlines -- annotations. mkAnnMap :: Config -> ErrorResult -> AnnInfo Doc -> ACSS.AnnMap -mkAnnMap cfg res ann = ACSS.Ann - { ACSS.types = mkAnnMapTyp cfg ann - , ACSS.errors = mkAnnMapErr res - , ACSS.status = mkStatus res +mkAnnMap cfg res ann = ACSS.Ann + { ACSS.types = mkAnnMapTyp cfg ann + , ACSS.errors = mkAnnMapErr res + , ACSS.status = mkStatus res , ACSS.sptypes = mkAnnMapBinders cfg ann } @@ -254,7 +254,7 @@ mkStatus (Crash _ _) = ACSS.Error mkAnnMapErr :: PPrint (TError t) => FixResult (TError t) -> [(Loc, Loc, String)] mkAnnMapErr (Unsafe _ ls) = mapMaybe cinfoErr ls -mkAnnMapErr (Crash ls _) = mapMaybe cinfoErr ls +mkAnnMapErr (Crash ls _) = mapMaybe cinfoErr (fst <$> ls) mkAnnMapErr _ = [] cinfoErr :: PPrint (TError t) => TError t -> Maybe (Loc, Loc, String) @@ -453,15 +453,15 @@ instance ToJSON ACSS.AnnMap where toJSON a = object [ "types" .= toJSON (annTypes a) , "errors" .= toJSON (annErrors a) , "status" .= toJSON (ACSS.status a) - , "sptypes" .= (toJ <$> ACSS.sptypes a) + , "sptypes" .= (toJ <$> ACSS.sptypes a) ] - where - toJ (sp, (x,t)) = object [ "start" .= toJSON (srcSpanStartLoc sp) - , "stop" .= toJSON (srcSpanEndLoc sp) - , "ident" .= toJSON x - , "ann" .= toJSON t - ] - + where + toJ (sp, (x,t)) = object [ "start" .= toJSON (srcSpanStartLoc sp) + , "stop" .= toJSON (srcSpanEndLoc sp) + , "ident" .= toJSON x + , "ann" .= toJSON t + ] + annErrors :: ACSS.AnnMap -> AnnErrors annErrors = AnnErrors . ACSS.errors diff --git a/src/Language/Haskell/Liquid/UX/CmdLine.hs b/src/Language/Haskell/Liquid/UX/CmdLine.hs index 1ea9517014..8cacbc58ab 100644 --- a/src/Language/Haskell/Liquid/UX/CmdLine.hs +++ b/src/Language/Haskell/Liquid/UX/CmdLine.hs @@ -10,6 +10,7 @@ {-# OPTIONS_GHC -Wwarn=deprecations #-} {-# OPTIONS_GHC -fno-cse #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# LANGUAGE FlexibleContexts #-} -- | This module contains all the code needed to output the result which -- is either: `SAFE` or `WARNING` with some reasonable error message when @@ -791,8 +792,14 @@ reportResultJson annm = do resultWithContext :: F.FixResult UserError -> IO (FixResult CError) resultWithContext (F.Unsafe s es) = F.Unsafe s <$> errorsWithContext es -resultWithContext (F.Crash es s) = (`F.Crash` s) <$> errorsWithContext es resultWithContext (F.Safe stats) = return (F.Safe stats) +resultWithContext (F.Crash es s) = do + let (errs, msgs) = unzip es + errs' <- errorsWithContext errs + return (F.Crash (zip errs' msgs) s) + + + instance Show (CtxError Doc) where show = showpp @@ -842,7 +849,7 @@ resDocs _k (F.Crash [] s) = } resDocs k (F.Crash xs s) = OutputResult { - orHeader = text "LIQUID: ERROR" <+> text s + orHeader = text "LIQUID: ERROR:" <+> text s , orMessages = map (cErrToSpanned k . errToFCrash) xs } resDocs k (F.Unsafe _ xs) = @@ -855,11 +862,15 @@ resDocs k (F.Unsafe _ xs) = cErrToSpanned :: F.Tidy -> CError -> (GHC.SrcSpan, Doc) cErrToSpanned k CtxError{ctErr} = (pos ctErr, pprintTidy k ctErr) -errToFCrash :: CtxError a -> CtxError a -errToFCrash ce = ce { ctErr = tx $ ctErr ce} +errToFCrash :: (CError, Maybe String) -> CError +errToFCrash (ce, Just msg) = ce { ctErr = ErrOther (pos (ctErr ce)) (fixMessageDoc msg) } +errToFCrash (ce, Nothing) = ce { ctErr = tx $ ctErr ce} where tx (ErrSubType l m _ g t t') = ErrFCrash l m g t t' - tx e = e + tx e = F.notracepp "errToFCrash?" e + +fixMessageDoc :: String -> Doc +fixMessageDoc msg = vcat (text <$> lines msg) {- TODO: Never used, do I need to exist? diff --git a/src/Language/Haskell/Liquid/UX/DiffCheck.hs b/src/Language/Haskell/Liquid/UX/DiffCheck.hs index b338806332..24b0aa41d9 100644 --- a/src/Language/Haskell/Liquid/UX/DiffCheck.hs +++ b/src/Language/Haskell/Liquid/UX/DiffCheck.hs @@ -9,6 +9,7 @@ {-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# LANGUAGE TupleSections #-} module Language.Haskell.Liquid.UX.DiffCheck ( @@ -50,7 +51,7 @@ import System.Directory (copyFile, doesFileExist import Language.Fixpoint.Types (atLoc, FixResult (..), SourcePos(..), safeSourcePos, unPos) -- import qualified Language.Fixpoint.Misc as Misc import Language.Fixpoint.Utils.Files -import Language.Fixpoint.Solver.Stats () +import Language.Fixpoint.Solver.Stats () import Language.Haskell.Liquid.Misc (mkGraph) import Liquid.GHC.Misc import Liquid.GHC.API as Ghc hiding ( Located @@ -61,7 +62,7 @@ import Liquid.GHC.API as Ghc hiding ( Located ) import Text.PrettyPrint.HughesPJ (text, render, Doc) import qualified Data.ByteString as B -import qualified Data.ByteString.Lazy as LB +import qualified Data.ByteString.Lazy as LB import Language.Haskell.Liquid.Types hiding (Def, LMap) @@ -70,7 +71,7 @@ import Language.Haskell.Liquid.Types hiding (Def, LMap) -------------------------------------------------------------------------------- -- | Main type of value returned for diff-check. -data DiffCheck = DC +data DiffCheck = DC { newBinds :: [CoreBind] , oldOutput :: !(Output Doc) , newSpec :: !TargetSpec @@ -81,7 +82,7 @@ instance PPrint DiffCheck where -- | Variable definitions -data Def = D +data Def = D { start :: Int -- ^ line at which binder definition starts , end :: Int -- ^ line at which binder definition ends , binder :: Var -- ^ name of binder @@ -116,10 +117,10 @@ checkedVars = concatMap names . newBinds -------------------------------------------------------------------------------- slice :: FilePath -> [CoreBind] -> TargetSpec -> IO (Maybe DiffCheck) -------------------------------------------------------------------------------- -slice target cbs sp = do +slice target cbs sp = do ex <- doesFileExist savedFile - if ex - then doDiffCheck + if ex + then doDiffCheck else return Nothing where savedFile = extFileName Saved target @@ -151,7 +152,7 @@ sliceSaved' srcF is lm (DC coreBinds result spec) assumeSpec :: M.HashMap Var LocSpecType -> TargetSpec -> TargetSpec assumeSpec sigm sp = sp { gsSig = gsig { gsAsmSigs = M.toList $ M.union sigm assm } } where - assm = M.fromList (gsAsmSigs gsig) + assm = M.fromList (gsAsmSigs gsig) gsig = gsSig sp diffVars :: [Int] -> [Def] -> [Var] @@ -211,7 +212,7 @@ thinWith :: S.HashSet Var -> [CoreBind] -> [Var] -> [CoreBind] thinWith sigs cbs xs = filterBinds cbs calls where calls = txClosure cbDeps sigs (S.fromList xs) - cbDeps = coreDeps cbs + cbDeps = coreDeps cbs coreDeps :: [CoreBind] -> Deps coreDeps bs = mkGraph $ calls ++ calls' @@ -220,7 +221,7 @@ coreDeps bs = mkGraph $ calls ++ calls' calls' = [(y, x) | (x, y) <- calls] deps b = [(x, y) | x <- bindersOf b , y <- freeVars S.empty b - , S.member y defVars + , S.member y defVars ] defVars = S.fromList (letVars bs) @@ -268,8 +269,8 @@ specDefs srcF = map def . filter sameFile . specSigs sameFile = (srcF ==) . file . snd specSigs :: TargetSpec -> [(Var, LocSpecType)] -specSigs sp = gsTySigs (gsSig sp) - ++ gsAsmSigs (gsSig sp) +specSigs sp = gsTySigs (gsSig sp) + ++ gsAsmSigs (gsSig sp) ++ gsCtors (gsData sp) instance PPrint Def where @@ -285,9 +286,9 @@ coreDefs cbs = coreExprDefs xm xes xm = varBounds xes coreExprDefs :: M.HashMap Var (Int, Int) -> [(Var, CoreExpr)]-> [Def] -coreExprDefs xm xes = - L.sort - [ D l l' x +coreExprDefs xm xes = + L.sort + [ D l l' x | (x, e) <- xes , (l, l') <- maybeToList $ coreExprDef xm (x, e) ] @@ -302,43 +303,43 @@ coreExprDef m (x, e) = meetSpans eSp vSp coreVarExprs :: [CoreBind] -> [(Var, CoreExpr)] coreVarExprs = filter ok . concatMap varExprs where - ok = isGoodSrcSpan . getSrcSpan . fst + ok = isGoodSrcSpan . getSrcSpan . fst varExprs :: Bind a -> [(a, Expr a)] varExprs (NonRec x e) = [(x, e)] varExprs (Rec xes) = xes --- | varBounds computes upper and lower bounds on where each top-level binder's +-- | varBounds computes upper and lower bounds on where each top-level binder's -- definition can be by using ONLY the lines where the binder is defined. varBounds :: [(Var, CoreExpr)] -> M.HashMap Var (Int, Int) -varBounds = M.fromList . defBounds . varDefs +varBounds = M.fromList . defBounds . varDefs varDefs :: [(Var, CoreExpr)] -> [(Int, Var)] -varDefs xes = +varDefs xes = L.sort [ (l, x) | (x,_) <- xes, let Just (l, _) = lineSpan x (getSrcSpan x) ] defBounds :: [(Int, Var)] -> [(Var, (Int, Int) )] defBounds ((l, x) : lxs@((l', _) : _ )) = (x, (l, l' - 1)) : defBounds lxs defBounds _ = [] -{- +{- -------------------------------------------------------------------------------- coreDefs :: [CoreBind] -> [Def] -------------------------------------------------------------------------------- -coreDefs cbs = tracepp "coreDefs" $ +coreDefs cbs = tracepp "coreDefs" $ L.sort [D l l' x | b <- cbs , x <- bindersOf b , isGoodSrcSpan (getSrcSpan x) , (l, l') <- coreDef b] coreDef :: CoreBind -> [(Int, Int)] -coreDef b +coreDef b | True = tracepp ("coreDef: " ++ showpp (vs, vSp)) $ maybeToList vSp | False = tracepp ("coreDef: " ++ showpp (b, eSp, vSp)) $ meetSpans b eSp vSp where eSp = lineSpan b $ catSpans b $ bindSpans b vSp = lineSpan b $ catSpans b $ getSrcSpan <$> vs - vs = bindersOf b + vs = bindersOf b meetSpans :: Maybe (Int, Int) -> Maybe (Int, Int) -> Maybe (Int, Int) meetSpans Nothing _ @@ -478,7 +479,7 @@ diffShifts = go 1 1 -------------------------------------------------------------------------------- saveResult :: FilePath -> Output Doc -> IO () -------------------------------------------------------------------------------- -saveResult target res = do +saveResult target res = do copyFile target saveF B.writeFile errF $ LB.toStrict $ encode res where @@ -488,13 +489,13 @@ saveResult target res = do -------------------------------------------------------------------------------- loadResult :: FilePath -> IO (Output Doc) -------------------------------------------------------------------------------- -loadResult f = do +loadResult f = do ex <- doesFileExist jsonF - if ex + if ex then convert <$> B.readFile jsonF else return mempty where - convert = fromMaybe mempty . decode . LB.fromStrict + convert = fromMaybe mempty . decode . LB.fromStrict jsonF = extFileName Cache f -------------------------------------------------------------------------------- @@ -509,20 +510,18 @@ adjustTypes lm cm (AI m) = AI $ if True then mempty else M.fromList -- , Just sp' <- [adjustSrcSpan lm cm sp]] adjustResult :: LMap -> ChkItv -> ErrorResult -> ErrorResult -adjustResult lm cm (Unsafe s es) = errorsResult (Unsafe s) $ adjustErrors lm cm es -adjustResult lm cm (Crash es z) = errorsResult (`Crash` z) $ adjustErrors lm cm es +adjustResult lm cm (Unsafe s es) = errorsResult (Unsafe s) $ mapMaybe (adjustError lm cm) es +adjustResult lm cm (Crash es z) = errorsResult (`Crash` z) $ (, Nothing) <$> mapMaybe (adjustError lm cm) (fst <$> es) adjustResult _ _ r = r errorsResult :: ([a] -> FixResult b) -> [a] -> FixResult b errorsResult _ [] = Safe mempty errorsResult f es = f es -adjustErrors :: (PPrint (TError a)) => LMap -> ChkItv -> [TError a] -> [TError a] -adjustErrors lm cm = mapMaybe adjustError - where - adjustError e = case adjustSrcSpan lm cm (pos e) of - Just sp' -> Just (e {pos = sp'}) - Nothing -> Nothing +adjustError :: (PPrint (TError a)) => LMap -> ChkItv -> TError a -> Maybe (TError a) +adjustError lm cm e = case adjustSrcSpan lm cm (pos e) of + Just sp' -> Just (e {pos = sp'}) + Nothing -> Nothing -------------------------------------------------------------------------------- adjustSrcSpan :: LMap -> ChkItv -> SrcSpan -> Maybe SrcSpan diff --git a/src/Language/Haskell/Liquid/UX/Tidy.hs b/src/Language/Haskell/Liquid/UX/Tidy.hs index 27acfcc4b9..e16192240f 100644 --- a/src/Language/Haskell/Liquid/UX/Tidy.hs +++ b/src/Language/Haskell/Liquid/UX/Tidy.hs @@ -36,7 +36,7 @@ import qualified Data.HashSet as S import qualified Data.List as L import qualified Data.Text as T import qualified Control.Exception as Ex -import qualified Liquid.GHC.Misc as GM +import qualified Liquid.GHC.Misc as GM -- (dropModuleNames, showPpr, stringTyVar) import Language.Fixpoint.Types hiding (Result, SrcSpan, Error) import Language.Haskell.Liquid.Types.Types @@ -54,10 +54,10 @@ class Result a where result :: a -> FixResult UserError instance Result UserError where - result e = Crash [e] "" + result e = Crash [(e, Nothing)] "" instance Result [Error] where - result es = Crash (errorToUserError <$> es) "" + result es = Crash ([ (errorToUserError e, Nothing) | e <- es]) "" instance Result Error where result e = result [e] -- Crash [pprint e] "" @@ -71,16 +71,16 @@ errorToUserError = fmap ppSpecTypeErr -- TODO: move to Types.hs cinfoError :: Cinfo -> Error cinfoError (Ci _ (Just e) _) = e -cinfoError (Ci l _ _) = ErrOther l (text $ "Cinfo:" ++ GM.showPpr l) +cinfoError (Ci l _ _) = ErrOther l (text $ "Cinfo: " ++ GM.showPpr l) ------------------------------------------------------------------------- tidySpecType :: Tidy -> SpecType -> SpecType ------------------------------------------------------------------------- -tidySpecType k - = tidyEqual +tidySpecType k + = tidyEqual . tidyValueVars . tidyDSymbols - . tidySymbols k + . tidySymbols k . tidyInternalRefas . tidyLocalRefas k . tidyFunBinds @@ -105,9 +105,9 @@ tidySymbols k t = substa (shortSymbol k . tidySymbol) $ mapBind dropBind t xs = S.fromList (syms t) dropBind x = if x `S.member` xs then tidySymbol x else nonSymbol -shortSymbol :: Tidy -> Symbol -> Symbol -shortSymbol Lossy = GM.dropModuleNames -shortSymbol _ = id +shortSymbol :: Tidy -> Symbol -> Symbol +shortSymbol Lossy = GM.dropModuleNames +shortSymbol _ = id tidyLocalRefas :: Tidy -> SpecType -> SpecType tidyLocalRefas k = mapReft (txReft' k) @@ -120,7 +120,7 @@ tidyLocalRefas k = mapReft (txReft' k) tidyEqual :: SpecType -> SpecType tidyEqual = mapReft txReft - where + where txReft u = u { ur_reft = mapPredReft dropInternals $ ur_reft u } dropInternals = pAnd . L.nub . conjuncts @@ -230,7 +230,7 @@ instance PPrint (CtxError SpecType) where instance PPrint Error where pprintTidy k = ppError k empty . fmap ppSpecTypeErr - + ppSpecTypeErr :: SpecType -> Doc ppSpecTypeErr = ppSpecType Lossy diff --git a/tests/errors/ElabLocation.hs b/tests/errors/ElabLocation.hs index edf4c39e0b..06d2348a3c 100644 --- a/tests/errors/ElabLocation.hs +++ b/tests/errors/ElabLocation.hs @@ -1,15 +1,15 @@ --- | This file tests that LH correctly localizes the elaboration error +-- | This file tests that LH correctly localizes the elaboration error -- to the '10 / x' term (where we get a sort-error as the 'Ratio Int' -- is compared against '0' which appears in the refinement for '/'.) --- You can fix this by `embed Ratio * as Int` +-- You can fix this by `embed Ratio * as Int` -{-@ LIQUID "--expect-error-containing=ElabLocation.hs:15:14-15:15" @-} +{-@ LIQUID "--expect-error-containing=ElabLocation.hs:15:14" @-} module ElabLocation where -import Data.Ratio +import Data.Ratio foo :: Ratio Int -> Bool -foo x = y == y - where +foo x = y == y + where y = 10 / x diff --git a/tests/errors/ElabLocation2.hs b/tests/errors/ElabLocation2.hs index 6b32ee4eb6..7f5ee37d27 100644 --- a/tests/errors/ElabLocation2.hs +++ b/tests/errors/ElabLocation2.hs @@ -1,4 +1,4 @@ -{-@ LIQUID "--expect-error-containing=ElabLocation2.hs:18:54-67" @-} +{-@ LIQUID "--expect-error-containing=ElabLocation2.hs:18:54-66" @-} module ElabLocation2 where type Range = (Int,Int) From cff8cc67deadcddcc8f0df0478e61967bb138832 Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 16 Dec 2022 11:46:27 -0800 Subject: [PATCH 056/219] more cleanup for fixpoint/elab/crash/error --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 021d7af56a..11a773a08e 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 021d7af56a39985170c78b07c842b853a6180f77 +Subproject commit 11a773a08e66cea13d8ddbf203ca32bd5cea97b2 From 83658ed56e3c6d9456cc11071f2f29769ffdddde Mon Sep 17 00:00:00 2001 From: Ranjit Jhala Date: Fri, 16 Dec 2022 11:53:23 -0800 Subject: [PATCH 057/219] fix hlint --- src/Language/Haskell/Liquid/UX/Annotate.hs | 2 +- src/Language/Haskell/Liquid/UX/DiffCheck.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Language/Haskell/Liquid/UX/Annotate.hs b/src/Language/Haskell/Liquid/UX/Annotate.hs index 0e9de20afa..6e3e972180 100644 --- a/src/Language/Haskell/Liquid/UX/Annotate.hs +++ b/src/Language/Haskell/Liquid/UX/Annotate.hs @@ -254,7 +254,7 @@ mkStatus (Crash _ _) = ACSS.Error mkAnnMapErr :: PPrint (TError t) => FixResult (TError t) -> [(Loc, Loc, String)] mkAnnMapErr (Unsafe _ ls) = mapMaybe cinfoErr ls -mkAnnMapErr (Crash ls _) = mapMaybe cinfoErr (fst <$> ls) +mkAnnMapErr (Crash ls _) = mapMaybe (cinfoErr . fst) ls mkAnnMapErr _ = [] cinfoErr :: PPrint (TError t) => TError t -> Maybe (Loc, Loc, String) diff --git a/src/Language/Haskell/Liquid/UX/DiffCheck.hs b/src/Language/Haskell/Liquid/UX/DiffCheck.hs index 24b0aa41d9..6a5c653d3c 100644 --- a/src/Language/Haskell/Liquid/UX/DiffCheck.hs +++ b/src/Language/Haskell/Liquid/UX/DiffCheck.hs @@ -511,7 +511,7 @@ adjustTypes lm cm (AI m) = AI $ if True then mempty else M.fromList -- adjustResult :: LMap -> ChkItv -> ErrorResult -> ErrorResult adjustResult lm cm (Unsafe s es) = errorsResult (Unsafe s) $ mapMaybe (adjustError lm cm) es -adjustResult lm cm (Crash es z) = errorsResult (`Crash` z) $ (, Nothing) <$> mapMaybe (adjustError lm cm) (fst <$> es) +adjustResult lm cm (Crash es z) = errorsResult (`Crash` z) $ (, Nothing) <$>mapMaybe (adjustError lm cm . fst) es adjustResult _ _ r = r errorsResult :: ([a] -> FixResult b) -> [a] -> FixResult b From 3de1e7b64fb6ba3c4a4760f189f9129d21382a3c Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Thu, 8 Dec 2022 16:27:44 +0200 Subject: [PATCH 058/219] benchmark-timings: Loosen bound on aeson --- benchmark-timings/benchmark-timings.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark-timings/benchmark-timings.cabal b/benchmark-timings/benchmark-timings.cabal index f7e9373c30..4e066749a3 100644 --- a/benchmark-timings/benchmark-timings.cabal +++ b/benchmark-timings/benchmark-timings.cabal @@ -34,7 +34,7 @@ executable benchmark-timings -- LANGUAGE extensions used by modules in this package. -- other-extensions: build-depends: base - , aeson ^>=1.5.6 + , aeson >= 1.5.6 && < 2.1 , cassava ^>=0.5.2 , bytestring ^>=0.10.12 , optparse-applicative ^>=0.16.1 From ad2ec11190f51826358910107eef4dbce8200fac Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Thu, 8 Dec 2022 16:29:38 +0200 Subject: [PATCH 059/219] Loosen bounds for compatibility with GHC 9.0.2 --- liquid-base/liquid-base.cabal | 4 ++-- liquid-ghc-prim/liquid-ghc-prim.cabal | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/liquid-base/liquid-base.cabal b/liquid-base/liquid-base.cabal index 30087528f9..659c8fa8ee 100644 --- a/liquid-base/liquid-base.cabal +++ b/liquid-base/liquid-base.cabal @@ -1,4 +1,4 @@ -cabal-version: 1.24 +cabal-version: 2.0 name: liquid-base version: 4.14.3.0 synopsis: Drop-in base replacement for LiquidHaskell @@ -251,7 +251,7 @@ library build-depends: integer-gmp < 1.0.4.0 , base == 4.14.3.0 else - build-depends: base == 4.15.0.0 + build-depends: base ^>= 4.15.0.0 default-language: Haskell2010 default-extensions: PackageImports NoImplicitPrelude diff --git a/liquid-ghc-prim/liquid-ghc-prim.cabal b/liquid-ghc-prim/liquid-ghc-prim.cabal index fe6db2cbfe..1b229d75d7 100644 --- a/liquid-ghc-prim/liquid-ghc-prim.cabal +++ b/liquid-ghc-prim/liquid-ghc-prim.cabal @@ -36,7 +36,7 @@ library GHC.Types hs-source-dirs: src - build-depends: ghc-prim == 0.6.1 + build-depends: ghc-prim >= 0.6.1 && < 0.8 , liquidhaskell >= 0.8.10.1 default-language: Haskell2010 default-extensions: PackageImports From 3d254afa903ed8f65c901b4df9978b1a8a16963d Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Thu, 8 Dec 2022 16:32:37 +0200 Subject: [PATCH 060/219] Move to LTS-19.33 --- stack.yaml | 2 +- stack.yaml.lock | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/stack.yaml b/stack.yaml index f5c023fe3d..865554838b 100644 --- a/stack.yaml +++ b/stack.yaml @@ -32,7 +32,7 @@ extra-deps: # for tests - strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 -resolver: lts-18.27 +resolver: lts-19.33 nix: packages: [cacert, git, hostname, z3] diff --git a/stack.yaml.lock b/stack.yaml.lock index f6705bb519..fc33be4d53 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -5,54 +5,54 @@ packages: - completed: - hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 pantry-tree: - size: 279 sha256: e1a52f56ec0cab647ec7af0d75bfbb45f09cccea4a8127996cb7b132bd73bd2c + size: 279 + hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 original: hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 - completed: - hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 pantry-tree: - size: 327 sha256: 2010fda4c4af2dd9da64786d9e902f387b6a9cb034eb6573d678e752deecc319 + size: 327 + hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 original: hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 - completed: - hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 pantry-tree: - size: 1248 sha256: 4df2f6b536a0fcc5f7d562cb29e373f27dc4a2747452ac5cc74c1599cab22fc5 + size: 1248 + hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 original: hackage: hashable-1.3.5.0 - completed: - hackage: rest-rewrite-0.3.0@sha256:398f937a5faf6bd3329650ee9aed31bbfe7ed1c23252710908ad7295e3252c94,3890 pantry-tree: - size: 3943 sha256: 6e42cf85257cbc2abf50a9c8f3bac8777920f1b970e6f2cae9358690e1186e99 + size: 3943 + hackage: rest-rewrite-0.3.0@sha256:398f937a5faf6bd3329650ee9aed31bbfe7ed1c23252710908ad7295e3252c94,3890 original: hackage: rest-rewrite-0.3.0 - completed: name: ghc-timings - version: '0.1' - git: https://github.com/qnikst/ghc-timings-report pantry-tree: - size: 7544 sha256: 72622264696c78cda23cf96382dee7a3d14e3eafdb8977486338f113681dcec4 + size: 7544 commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 - original: git: https://github.com/qnikst/ghc-timings-report + version: '0.1' + original: commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 + git: https://github.com/qnikst/ghc-timings-report - completed: - hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 pantry-tree: - size: 671 sha256: cf7712453587e8ea69b96f33e2e8015c22d3b448259d4cace663cc15657309d7 + size: 671 + hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 original: hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 snapshots: - completed: - size: 590102 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/27.yaml - sha256: 79a786674930a89301b0e908fad2822a48882f3d01486117693c377b8edffdbe - original: lts-18.27 + sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 + size: 619204 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml + original: lts-19.33 From df5ebf61e158c86c3beb7db7083d7dff4674cb02 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Thu, 8 Dec 2022 18:10:25 +0200 Subject: [PATCH 061/219] Remove liquid-base from stack.yaml, to mirror cabal.ghc9.project --- stack.yaml | 3 ++- stack.yaml.lock | 41 ++++++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/stack.yaml b/stack.yaml index 865554838b..453801b46f 100644 --- a/stack.yaml +++ b/stack.yaml @@ -11,7 +11,6 @@ ghc-options: packages: - liquid-fixpoint - liquid-ghc-prim -- liquid-base - liquid-bytestring - liquid-prelude - liquid-vector @@ -31,6 +30,8 @@ extra-deps: commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 # for tests - strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 +- git: https://github.com/facundominguez/liquid-base + commit: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 resolver: lts-19.33 diff --git a/stack.yaml.lock b/stack.yaml.lock index fc33be4d53..7ec970ef41 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -5,54 +5,65 @@ packages: - completed: + hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 pantry-tree: - sha256: e1a52f56ec0cab647ec7af0d75bfbb45f09cccea4a8127996cb7b132bd73bd2c size: 279 - hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 + sha256: e1a52f56ec0cab647ec7af0d75bfbb45f09cccea4a8127996cb7b132bd73bd2c original: hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 - completed: + hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 pantry-tree: - sha256: 2010fda4c4af2dd9da64786d9e902f387b6a9cb034eb6573d678e752deecc319 size: 327 - hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 + sha256: 2010fda4c4af2dd9da64786d9e902f387b6a9cb034eb6573d678e752deecc319 original: hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 - completed: + hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 pantry-tree: - sha256: 4df2f6b536a0fcc5f7d562cb29e373f27dc4a2747452ac5cc74c1599cab22fc5 size: 1248 - hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 + sha256: 4df2f6b536a0fcc5f7d562cb29e373f27dc4a2747452ac5cc74c1599cab22fc5 original: hackage: hashable-1.3.5.0 - completed: + hackage: rest-rewrite-0.3.0@sha256:398f937a5faf6bd3329650ee9aed31bbfe7ed1c23252710908ad7295e3252c94,3890 pantry-tree: - sha256: 6e42cf85257cbc2abf50a9c8f3bac8777920f1b970e6f2cae9358690e1186e99 size: 3943 - hackage: rest-rewrite-0.3.0@sha256:398f937a5faf6bd3329650ee9aed31bbfe7ed1c23252710908ad7295e3252c94,3890 + sha256: 6e42cf85257cbc2abf50a9c8f3bac8777920f1b970e6f2cae9358690e1186e99 original: hackage: rest-rewrite-0.3.0 - completed: name: ghc-timings + version: '0.1' + git: https://github.com/qnikst/ghc-timings-report pantry-tree: - sha256: 72622264696c78cda23cf96382dee7a3d14e3eafdb8977486338f113681dcec4 size: 7544 + sha256: 72622264696c78cda23cf96382dee7a3d14e3eafdb8977486338f113681dcec4 commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 - git: https://github.com/qnikst/ghc-timings-report - version: '0.1' original: - commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 git: https://github.com/qnikst/ghc-timings-report + commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 - completed: + hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 pantry-tree: - sha256: cf7712453587e8ea69b96f33e2e8015c22d3b448259d4cace663cc15657309d7 size: 671 - hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 + sha256: cf7712453587e8ea69b96f33e2e8015c22d3b448259d4cace663cc15657309d7 original: hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 +- completed: + name: liquid-base + version: 4.15.0.1 + git: https://github.com/facundominguez/liquid-base + pantry-tree: + size: 15554 + sha256: 464e5c7c7cc77fa5c039e614232e562bf0de9e44554a22d0e6193ea4e8b2fe85 + commit: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 + original: + git: https://github.com/facundominguez/liquid-base + commit: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 snapshots: - completed: - sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 size: 619204 url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml + sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 original: lts-19.33 From 6bd982fce0b776f75544095705a0057ec06f667b Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Mon, 12 Dec 2022 15:04:43 +0200 Subject: [PATCH 062/219] CircleCI: Rename Stack jobs since switching to LTS-19 --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f33699cb69..7b20343732 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -147,7 +147,7 @@ commands: jobs: - stack_810: + stack_900: machine: image: ubuntu-2004:202107-02 steps: @@ -180,6 +180,6 @@ workflows: version: 2 build_stack_and_cabal: jobs: - - stack_810 + - stack_900 - cabal_810 - cabal_900 From 79ff6e4e641018f48c16cc59e5aea7284f42f930 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Mon, 12 Dec 2022 16:00:49 +0200 Subject: [PATCH 063/219] stack.yaml Set allow-newer temporarily --- stack.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/stack.yaml b/stack.yaml index 453801b46f..fc5172b4cd 100644 --- a/stack.yaml +++ b/stack.yaml @@ -34,6 +34,7 @@ extra-deps: commit: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 resolver: lts-19.33 +allow-newer: true nix: packages: [cacert, git, hostname, z3] From e420ee5f5b36c852e16f37c2c577f182785326e6 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Fri, 23 Dec 2022 17:24:20 +0200 Subject: [PATCH 064/219] Fix test cases to pass when using GHC 9 --- tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Nat.hs | 1 - tests/pos/Elim_ex_let.hs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Nat.hs b/tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Nat.hs index e101348458..98e050fb82 100644 --- a/tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Nat.hs +++ b/tests/benchmarks/stitch-lh/src/Language/Stitch/LH/Data/Nat.hs @@ -2,7 +2,6 @@ module Language.Stitch.LH.Data.Nat where import Prelude hiding (max) -{-@ type Nat = { v : Int | v >= 0 } @-} type Nat = Int {-@ inline max @-} diff --git a/tests/pos/Elim_ex_let.hs b/tests/pos/Elim_ex_let.hs index c554d8b787..dad884bcf2 100644 --- a/tests/pos/Elim_ex_let.hs +++ b/tests/pos/Elim_ex_let.hs @@ -5,9 +5,9 @@ module Elim_ex_let (prop) where import LiquidHaskell -[lq| type Nat = {v:Int | 0 <= v} |] +[lq| type MyNat = {v:Int | 0 <= v} |] -[lq| prop :: a -> Nat |] +[lq| prop :: a -> MyNat |] prop _ = let x _ = let y = 0 in y - 1 From 32a8c4d37d94e171418a2186d0ea0aa1796fab5a Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Thu, 8 Dec 2022 12:44:42 +0200 Subject: [PATCH 065/219] Change #ifdef to test correct macro --- liquid-bytestring/src/Data/ByteString/Char8.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-bytestring/src/Data/ByteString/Char8.hs b/liquid-bytestring/src/Data/ByteString/Char8.hs index 121247fb45..3dbfc5ccd3 100644 --- a/liquid-bytestring/src/Data/ByteString/Char8.hs +++ b/liquid-bytestring/src/Data/ByteString/Char8.hs @@ -6,7 +6,7 @@ import Data.Int import GHC.IO.Handle -#ifdef MIN_VERSION_GLASGOW_HASKELL +#ifdef MIN_VERSION_bytestring #if MIN_VERSION_bytestring(0,10,12) -- bytestring >= 0.10.12.0 is now exporting 'partition' as part of 'Data.ByteString.Char8', which means From 9271a6bc99165eb6e63c80e79358ef771988ae8a Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Thu, 8 Dec 2022 13:04:21 +0200 Subject: [PATCH 066/219] Remove code supporting GHC < 9 As argued in #2116, supporting multiple GHC versions at once is onerous, especially given how closely tied Liquid Haskell is to the GHC API and considering how much the GHC API changes and the fact that this API has no release management (no release notes, no effort to retain backwards compatibility). After this patch, only GHC 9 is supported. --- liquidhaskell.cabal | 31 +- src-ghc/Liquid/GHC/API.hs | 686 +----------------- src-ghc/Liquid/GHC/API/StableModule.hs | 22 - src-ghc/Liquid/GHC/GhcMonadLike.hs | 32 - src-ghc/Liquid/GHC/Interface.hs | 9 - src-ghc/Liquid/GHC/Logging.hs | 23 - src-ghc/Liquid/GHC/Misc.hs | 56 +- src-ghc/Liquid/GHC/Resugar.hs | 1 - src-ghc/Liquid/GHC/TypeRep.hs | 24 - src/Language/Haskell/Liquid/Bare/Elaborate.hs | 42 -- .../Haskell/Liquid/Constraint/Generate.hs | 5 - .../Haskell/Liquid/Constraint/Relational.hs | 7 - src/Language/Haskell/Liquid/Synthesize/GHC.hs | 1 - .../Haskell/Liquid/Transforms/CoreToLogic.hs | 7 +- .../Haskell/Liquid/Transforms/InlineAux.hs | 9 +- .../Haskell/Liquid/Transforms/Rewrite.hs | 1 - src/Language/Haskell/Liquid/UX/QuasiQuoter.hs | 9 - src/LiquidHaskell.hs | 11 - 18 files changed, 14 insertions(+), 962 deletions(-) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index bae66745d6..d44ba32696 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -11,7 +11,7 @@ maintainer: Ranjit Jhala category: Language homepage: https://github.com/ucsd-progsys/liquidhaskell build-type: Simple -tested-with: GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.1, GHC == 8.10.7, GHC == 9.0.1 +tested-with: GHC == 9.0.2 extra-source-files: CHANGES.md README.md devel/Paths_liquidhaskell.hs @@ -190,25 +190,12 @@ library -- Once the source plugin is out, we should also removed the duplicate \"liquid-prelude\" files from -- the \"include\" directory. - if impl(ghc >= 8.10) - exposed-modules: Language.Haskell.Liquid.GHC.Plugin - Language.Haskell.Liquid.GHC.Plugin.Tutorial - other-modules: Language.Haskell.Liquid.GHC.Plugin.SpecFinder - Language.Haskell.Liquid.GHC.Plugin.Types - Language.Haskell.Liquid.GHC.Plugin.Util - hs-source-dirs: src src-ghc - else - hs-source-dirs: src src-ghc include - exposed-modules: Language.Haskell.Liquid.RTick - Language.Haskell.Liquid.Prelude - Language.Haskell.Liquid.Foreign - Language.Haskell.Liquid.RTick.Combinators - Language.Haskell.Liquid.String - Language.Haskell.Liquid.List - Language.Haskell.Liquid.Equational - Language.Haskell.Liquid.Bag - Language.Haskell.Liquid.ProofCombinators - KMeansHelper + exposed-modules: Language.Haskell.Liquid.GHC.Plugin + Language.Haskell.Liquid.GHC.Plugin.Tutorial + other-modules: Language.Haskell.Liquid.GHC.Plugin.SpecFinder + Language.Haskell.Liquid.GHC.Plugin.Types + Language.Haskell.Liquid.GHC.Plugin.Util + hs-source-dirs: src src-ghc build-depends: base >= 4.11.1.0 && < 5 , Diff >= 0.3 && < 0.5 @@ -225,7 +212,7 @@ library , filepath >= 1.3 , fingertree >= 0.1 , exceptions < 0.11 - , ghc + , ghc ^>= 9 , ghc-boot , ghc-paths >= 0.1 , ghc-prim @@ -266,7 +253,7 @@ library if flag(deterministic-profiling) cpp-options: -DDETERMINISTIC_PROFILING - if impl(ghc < 8.10) || flag(no-plugin) + if flag(no-plugin) cpp-options: -DLIQUID_NO_PLUGIN -- This is the (legacy) 'liquid' executable which uses the old GHC Interface. diff --git a/src-ghc/Liquid/GHC/API.hs b/src-ghc/Liquid/GHC/API.hs index 98c20a5791..66036be82e 100644 --- a/src-ghc/Liquid/GHC/API.hs +++ b/src-ghc/Liquid/GHC/API.hs @@ -5,7 +5,6 @@ The intended use of this module is to shelter LiquidHaskell from changes to the --} -{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE PatternSynonyms #-} @@ -18,90 +17,8 @@ The intended use of this module is to shelter LiquidHaskell from changes to the module Liquid.GHC.API ( module Ghc , module StableModule - --- Specific exports for 8.6.5 -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) - , pattern Bndr - , pattern LitString - , pattern LitFloat - , pattern LitDouble - , pattern LitChar - , VarBndr -#endif -#endif - --- Specific exports for 8.6.5 and 8.8.x -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,10,1,0) - , AnonArgFlag(..) - , pattern FunTy - , pattern AnonTCB - , ft_af, ft_mult, ft_arg, ft_res - , bytesFS - , mkFunTy - , isEvVarType - , isEqPrimPred - , noExtField - , Mult - , pattern Many -#endif -#endif - , tyConRealArity , dataConExTyVars - --- Specific exports for 8.8.x -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) && !MIN_VERSION_GLASGOW_HASKELL(8,10,1,0) - , isEqPred -#endif -#endif - --- Specific exports for 8.10.x -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) && !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - , Mult - , pattern Many - , pattern FunTy - , mkFunTy - , ft_af, ft_mult, ft_arg, ft_res -#endif -#endif - --- Shared exports for GHC < 9 -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - , pattern RealSrcSpan - , pattern UnhelpfulSpan - , UnhelpfulSpanReason(..) - , scaledThing - , Scaled(..) - , mkScaled - , irrelevantMult - , dataConInstArgTys - , dataConOrigArgTys - , dataConRepArgTys - , mkLocalVar - , DataConAppContext(..) - , deepSplitProductType_maybe - , splitFunTys - , mkUserLocal - , dataConWrapperType - , apiAnnComments - , getDependenciesModuleNames - , GenWithIsBoot(..) - , ModuleNameWithIsBoot - , IsBootInterface - , isBootSummary - , mkIntExprInt - , dataConFullSig -#endif -#endif - --- Specific exports for 9.x -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) , fsToUnitId , moduleUnitId , thisPackage @@ -111,9 +28,6 @@ module Liquid.GHC.API ( , dataConSig , getDependenciesModuleNames , gcatch -#endif -#endif - ) where import Liquid.GHC.API.StableModule as StableModule @@ -122,183 +36,6 @@ import GHC as Ghc hiding , exprType ) --- Shared imports for GHC < 9 -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - -import CoreFVs as Ghc (exprFreeVarsList) -import OccurAnal as Ghc (occurAnalysePgm) -import Annotations as Ghc -import ApiAnnotation as Ghc -import Avail as Ghc -import Bag as Ghc -import BasicTypes as Ghc -import Class as Ghc -import CoAxiom as Ghc -import Coercion as Ghc -import ConLike as Ghc -import CoreLint as Ghc hiding (dumpIfSet) -import CoreMonad as Ghc (CoreToDo(..)) -import CoreSubst as Ghc (deShadowBinds, substExpr, emptySubst, extendCvSubst) -import CoreSyn as Ghc hiding (AnnExpr, AnnExpr' (..), AnnRec, AnnCase) -import CoreUtils as Ghc (exprType) -import CostCentre as Ghc -import Data.Map.Strict (Map) -import DataCon as Ghc hiding (dataConInstArgTys, dataConOrigArgTys, dataConRepArgTys, dataConFullSig) -import qualified DataCon as Ghc -import Digraph as Ghc -import DriverPhases as Ghc (Phase(StopLn)) -import DriverPipeline as Ghc hiding (P, getLocation) -import DsMonad as Ghc -import DynFlags as Ghc -import ErrUtils as Ghc -import FamInst as Ghc -import FamInstEnv as Ghc hiding (pprFamInst) -import Finder as Ghc -import ForeignCall (CType) -import GHC as Ghc (SrcSpan) -import GhcMonad as Ghc (withSession) -import GhcPlugins as Ghc (deserializeWithData , fromSerialized , toSerialized, extendIdSubst) -import HscMain as Ghc -import HscTypes as Ghc hiding (IsBootInterface, isBootSummary) -import Id as Ghc hiding (lazySetIdInfo, setIdExported, setIdNotExported, mkUserLocal) -import IdInfo as Ghc -import IfaceSyn as Ghc -import InstEnv as Ghc -import Literal as Ghc -import MkCore as Ghc hiding (mkIntExprInt) -import MkId (mkDataConWorkId) -import Module as Ghc -import Name as Ghc hiding (varName) -import NameEnv (lookupNameEnv_NF) -import NameSet as Ghc -import Outputable as Ghc hiding ((<>)) -import Pair as Ghc -import Panic as Ghc -import Plugins as Ghc (defaultPlugin, Plugin(..), CommandLineOption, purePlugin) -import PrelInfo as Ghc -import PrelNames as Ghc hiding (wildCardName) -import RdrName as Ghc -import SrcLoc as Ghc hiding (RealSrcSpan, SrcSpan(UnhelpfulSpan)) -import TcRnDriver as Ghc -import TcRnMonad as Ghc hiding (getGHCiMonad) -import TysPrim as Ghc -import TysWiredIn as Ghc -import Unify as Ghc -import UniqDFM as Ghc -import UniqFM as Ghc -import UniqSet as Ghc -import UniqSupply as Ghc -import Unique as Ghc -import Var as Ghc hiding (mkLocalVar) -import VarEnv as Ghc -import VarSet as Ghc -import qualified SrcLoc -import qualified Data.Bifunctor as Bi -import qualified Data.Data as Data -import qualified GhcMake -import qualified HscTypes as Ghc -import qualified Id as Ghc -import qualified MkCore as Ghc -import qualified Var as Ghc -import qualified WwLib as Ghc -import RnExpr as Ghc (rnLExpr) -import TcExpr as Ghc (tcInferSigma) -import TcBinds as Ghc (tcValBinds) -import Inst as Ghc (deeplyInstantiate) -import TcSimplify as Ghc ( simplifyInfer, simplifyInteractive - , InferMode (..)) -import TcHsSyn as Ghc (zonkTopLExpr) -import TcEvidence as Ghc ( TcEvBinds (EvBinds)) -import DsExpr as Ghc (dsLExpr) -#endif -#endif - --- --- Compatibility layer for different GHC versions. --- - --- --- Specific imports for GHC 8.6.5 --- -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) - -import qualified Literal as Lit -import FastString as Ghc hiding (bytesFS, LitString) -import TcType as Ghc hiding (typeKind, mkFunTy) -import Type as Ghc hiding (typeKind, mkFunTy, splitFunTys, extendCvSubst) -import qualified Type as Ghc -import qualified Var as Var -import qualified GHC.Real --- import PrelNames (eqPrimTyConKey, eqReprPrimTyConKey, gHC_REAL, varQual_RDR) -#endif -#endif - --- --- Specific imports for GHC 8.6.5 & 8.8.x --- -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,10,1,0) - -import Binary -import Data.ByteString (ByteString) -import Data.Data (Data) -import Kind as Ghc -import TyCoRep as Ghc hiding (Type (FunTy), mkFunTy, extendCvSubst) -import TyCon as Ghc hiding (mkAnonTyConBinders, TyConBndrVis(AnonTCB)) -import qualified TyCoRep as Ty hiding (extendCvSubst) -import qualified TyCon as Ty -import Platform as Ghc -import qualified HsExtension --- import PrelNames (eqPrimTyConKey, eqReprPrimTyConKey, gHC_REAL, varQual_RDR) - -#endif -#endif - --- --- Specific imports for 8.8.x --- -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) && !MIN_VERSION_GLASGOW_HASKELL(8,10,1,0) - -import FastString as Ghc hiding (bytesFS) -import TcType as Ghc hiding (typeKind, mkFunTy, isEqPred) -import Type as Ghc hiding (typeKind, mkFunTy, isEvVarType, isEqPred, splitFunTys, extendCvSubst) -import qualified Type as Ghc -import qualified Type as Ghc (isEvVarType) -import qualified PrelNames as Ghc -import Data.Foldable (asum) --- import PrelNames (eqPrimTyConKey, eqReprPrimTyConKey, gHC_REAL, varQual_RDR) -#endif -#endif - --- --- Specific imports for GHC 8.10 --- -#ifdef MIN_VERSION_GLASGOW_HASKELL - -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) && !MIN_VERSION_GLASGOW_HASKELL (9,0,0,0) -import GHC.Platform as Ghc (Platform) -import Type as Ghc hiding (mapType, typeKind, isPredTy, splitFunTys, extendCvSubst) -import qualified Type as Ghc hiding (extendCvSubst) -import TyCon as Ghc -import qualified TyCoRep as Ty -import TcType as Ghc -import TyCoRep as Ghc hiding (Type (FunTy), mkFunTy, ft_arg, ft_res, ft_af) -import FastString as Ghc -import Predicate as Ghc (getClassPredTys_maybe, isEvVarType, getClassPredTys, isDictId) -import TcOrigin as Ghc (lexprCtOrigin) -import Data.Foldable (asum) -#endif -#endif - --- --- Specific imports for GHC 9 --- -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) && !MIN_VERSION_GLASGOW_HASKELL (9,1,0,0) - import Optics import qualified Control.Monad.Catch as Ex @@ -319,7 +56,7 @@ import GHC.Core.Lint as Ghc hiding (dumpIfSet) import GHC.Core.Make as Ghc import GHC.Core.Opt.Monad as Ghc (CoreToDo(..)) import GHC.Core.Opt.WorkWrap.Utils as Ghc -import GHC.Core.Predicate as Ghc (getClassPredTys_maybe, getClassPredTys, isEvVarType, isEqPrimPred, isEqPred, isClassPred, isDictId) +import GHC.Core.Predicate as Ghc (getClassPredTys_maybe, getClassPredTys, isEvVarType, isEqPrimPred, isEqPred, isClassPred, isDictId, mkClassPred) import GHC.Core.Subst as Ghc (deShadowBinds, emptySubst, extendCvSubst) import GHC.Core.TyCo.Rep as Ghc import GHC.Core.TyCon as Ghc @@ -388,421 +125,7 @@ import GHC.Tc.Utils.Zonk as Ghc import GHC.Core.FVs as Ghc (exprFreeVarsList) import GHC.Tc.Types.Evidence as Ghc import GHC.HsToCore.Expr as Ghc -import GHC.Core.Predicate as Ghc (mkClassPred) import GHC.Core.Opt.OccurAnal as Ghc -#endif -#endif - --- --- Compat shim for GHC < 9 (shared parts) --- -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - -data BufSpan - -pattern RealSrcSpan :: SrcLoc.RealSrcSpan -> Maybe BufSpan -> SrcLoc.SrcSpan -pattern RealSrcSpan rss mbSpan <- ((,Nothing) -> (SrcLoc.RealSrcSpan rss, mbSpan)) - where - RealSrcSpan rss _mbSpan = SrcLoc.RealSrcSpan rss - -data UnhelpfulSpanReason - = UnhelpfulNoLocationInfo - | UnhelpfulWiredIn - | UnhelpfulInteractive - | UnhelpfulGenerated - | UnhelpfulOther !FastString - deriving (Eq, Show) - -pattern UnhelpfulSpan :: UnhelpfulSpanReason -> SrcLoc.SrcSpan -pattern UnhelpfulSpan reason <- (toUnhelpfulReason -> Just reason) - where - UnhelpfulSpan reason = SrcLoc.UnhelpfulSpan (fromUnhelpfulReason reason) - -fromUnhelpfulReason :: UnhelpfulSpanReason -> FastString -fromUnhelpfulReason = \case - UnhelpfulNoLocationInfo -> fsLit "UnhelpfulNoLocationInfo" - UnhelpfulWiredIn -> fsLit "UnhelpfulWiredIn" - UnhelpfulInteractive -> fsLit "UnhelpfulInteractive" - UnhelpfulGenerated -> fsLit "UnhelpfulGenerated" - UnhelpfulOther fs -> fs - -toUnhelpfulReason :: SrcLoc.SrcSpan -> Maybe UnhelpfulSpanReason -toUnhelpfulReason (SrcLoc.RealSrcSpan _) = Nothing -toUnhelpfulReason (SrcLoc.UnhelpfulSpan fs) = Just $ case unpackFS fs of - "UnhelpfulNoLocationInfo" -> UnhelpfulNoLocationInfo - "UnhelpfulWiredIn" -> UnhelpfulWiredIn - "UnhelpfulInteractive" -> UnhelpfulInteractive - "UnhelpfulGenerated" -> UnhelpfulGenerated - _ -> UnhelpfulOther fs - --- Backporting multiplicity - -data Scaled a = Scaled Mult a - deriving (Data.Data) - -instance (Outputable a) => Outputable (Scaled a) where - ppr (Scaled _cnt t) = ppr t - -irrelevantMult :: Scaled a -> a -irrelevantMult = scaledThing - -mkScaled :: Mult -> a -> Scaled a -mkScaled = Scaled - -scaledThing :: Scaled a -> a -scaledThing (Scaled _ t) = t - -type Mult = Type - -pcDataCon :: Name -> [TyVar] -> [Type] -> TyCon -> DataCon -pcDataCon n univs tys tycon = data_con - where - data_con = mkDataCon n - False - (mkPrelTyConRepName n) - (map (const (HsSrcBang NoSourceText NoSrcUnpack NoSrcStrict)) tys) - [] - univs - [] - (error "[TyVarBinder]") - [] - [] - tys - (mkTyConApp tycon (mkTyVarTys univs)) - NoRRI - tycon - (lookupNameEnv_NF (mkTyConTagMap tycon) n) - [] - (mkDataConWorkId (mkDataConWorkerName data_con (dataConWorkerUnique (nameUnique n))) data_con) - NoDataConRep - - -mkDataConWorkerName :: DataCon -> Unique -> Name -mkDataConWorkerName data_con wrk_key = - mkWiredInName modu wrk_occ wrk_key - (AnId (dataConWorkId data_con)) UserSyntax - where - modu = nameModule dc_name - dc_name = dataConName data_con - dc_occ = nameOccName dc_name - wrk_occ = mkDataConWorkerOcc dc_occ - -pcTyCon :: Name -> Maybe CType -> [TyVar] -> [DataCon] -> TyCon -pcTyCon name cType tyvars cons - = mkAlgTyCon name - (mkAnonTyConBinders VisArg tyvars) - liftedTypeKind - (map (const Representational) tyvars) - cType - [] -- No stupid theta - (mkDataTyConRhs cons) - (VanillaAlgTyCon (mkPrelTyConRepName name)) - False -- Not in GADT syntax - - -mkWiredInDataConName :: BuiltInSyntax -> Module -> FastString -> Unique -> DataCon -> Name -mkWiredInDataConName built_in modu fs unique datacon - = mkWiredInName modu (mkDataOccFS fs) unique - (AConLike (RealDataCon datacon)) -- Relevant DataCon - built_in - -multiplicityTyConKey :: Unique -multiplicityTyConKey = mkPreludeTyConUnique 192 - -multiplicityTyConName :: Name -multiplicityTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Multiplicity") - multiplicityTyConKey multiplicityTyCon - -manyDataConName :: Name -manyDataConName = mkWiredInDataConName BuiltInSyntax gHC_TYPES (fsLit "Many") manyDataConKey manyDataCon - -multiplicityTyCon :: TyCon -multiplicityTyCon = pcTyCon multiplicityTyConName Nothing [] [manyDataCon] - -manyDataCon :: DataCon -manyDataCon = pcDataCon manyDataConName [] [] multiplicityTyCon - -manyDataConKey :: Unique -manyDataConKey = mkPreludeDataConUnique 116 - -manyDataConTy :: Type -manyDataConTy = mkTyConTy manyDataConTyCon - -manyDataConTyCon :: TyCon -manyDataConTyCon = promoteDataCon manyDataCon - -pattern Many :: Mult -pattern Many <- (isManyDataConTy -> True) - where Many = manyDataConTy - -isManyDataConTy :: Mult -> Bool -isManyDataConTy ty - | Just tc <- tyConAppTyCon_maybe ty - = tc `hasKey` manyDataConKey -isManyDataConTy _ = False - --- --- Dependencies and Boot --- -type IsBootInterface = GhcMake.IsBoot - --- | This data type just pairs a value 'mod' with an IsBootInterface flag. In --- practice, 'mod' is usually a @Module@ or @ModuleName@'. -data GenWithIsBoot mod = GWIB - { gwib_mod :: mod - , gwib_isBoot :: IsBootInterface - } deriving ( Eq, Ord, Show - , Functor, Foldable, Traversable - ) - -type ModuleNameWithIsBoot = GenWithIsBoot ModuleName - -isBootSummary :: ModSummary -> IsBootInterface -isBootSummary ms = case Ghc.isBootSummary ms of - True -> GhcMake.IsBoot - False -> GhcMake.NotBoot - -getDependenciesModuleNames :: Dependencies -> [ModuleNameWithIsBoot] -getDependenciesModuleNames = map f . dep_mods - where - f :: (ModuleName, Bool) -> ModuleNameWithIsBoot - f (modName, b) = let isBoot = if b then GhcMake.IsBoot else GhcMake.NotBoot in GWIB modName isBoot - -dataConInstArgTys :: DataCon -> [Type] -> [Scaled Type] -dataConInstArgTys dc tys = map (mkScaled Many) (Ghc.dataConInstArgTys dc tys) - -dataConOrigArgTys :: DataCon -> [Scaled Type] -dataConOrigArgTys dc = map (mkScaled Many) (Ghc.dataConOrigArgTys dc) - -dataConRepArgTys :: DataCon -> [Scaled Type] -dataConRepArgTys dc = map (mkScaled Many) (Ghc.dataConRepArgTys dc) - -mkLocalVar :: IdDetails -> Name -> Mult -> Type -> IdInfo -> Id -mkLocalVar idDetails' name _ ty info = Ghc.mkLocalVar idDetails' name ty info - -mkUserLocal :: OccName -> Unique -> Mult -> Type -> SrcSpan -> Id -mkUserLocal occName' u _mult ty srcSpan = Ghc.mkUserLocal occName' u ty srcSpan - -dataConWrapperType :: DataCon -> Type -dataConWrapperType = dataConUserType - --- WWlib - -data DataConAppContext - = DataConAppContext - { dcac_dc :: !DataCon - , dcac_tys :: ![Type] - , dcac_arg_tys :: ![(Scaled Type, StrictnessMark)] - , dcac_co :: !Coercion - } - -deepSplitProductType_maybe :: FamInstEnvs -> Type -> Maybe DataConAppContext -deepSplitProductType_maybe famInstEnv ty = do - (dc, tys, tysWithStricts, co) <- Ghc.deepSplitProductType_maybe famInstEnv ty - pure $ DataConAppContext dc tys (map (Bi.first (mkScaled Many)) tysWithStricts) co - -splitFunTys :: Type -> ([Scaled Type], Type) -splitFunTys ty = Bi.first (map (mkScaled Many)) $ Ghc.splitFunTys ty - -apiAnnComments :: (Map ApiAnnKey [SrcSpan], Map SrcSpan [Located AnnotationComment]) - -> Map SrcSpan [Located AnnotationComment] -apiAnnComments = snd - -mkIntExprInt :: Platform -> Int -> CoreExpr -mkIntExprInt _ = Ghc.mkIntExprInt unsafeGlobalDynFlags - -dataConFullSig :: DataCon -> ([TyVar], [TyCoVar], [EqSpec], ThetaType, [Scaled Type], Type) -dataConFullSig dc = - let (tyvars, tycovars, eqspecs, theta, tys, ty) = Ghc.dataConFullSig dc - in (tyvars, tycovars, eqspecs, theta, map (mkScaled Many) tys, ty) - - -#endif -#endif - --- --- Compat shim for GHC 8.6.5 - -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) - -pattern LitString :: ByteString -> Lit.Literal -pattern LitString bs <- Lit.MachStr bs where - LitString bs = Lit.MachStr bs - -pattern LitFloat :: GHC.Real.Ratio Integer -> Lit.Literal -pattern LitFloat f <- Lit.MachFloat f where - LitFloat f = Lit.MachFloat f - -pattern LitDouble :: GHC.Real.Ratio Integer -> Lit.Literal -pattern LitDouble d <- Lit.MachDouble d where - LitDouble d = Lit.MachDouble d - -pattern LitChar :: Char -> Lit.Literal -pattern LitChar c <- Lit.MachChar c where - LitChar c = Lit.MachChar c - -pattern Bndr :: var -> argf -> Var.TyVarBndr var argf -pattern Bndr var argf <- TvBndr var argf where - Bndr var argf = TvBndr var argf - -type VarBndr = TyVarBndr - -isEqPrimPred :: Type -> Bool -isEqPrimPred = Ghc.isPredTy - --- See NOTE [isEvVarType]. -isEvVarType :: Type -> Bool -isEvVarType = Ghc.isPredTy - -tyConRealArity :: TyCon -> Int -tyConRealArity = tyConArity - -#endif -#endif - --- --- Compat shim for GHC-8.6.5 and GHC-8.8.x --- -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,10,1,0) - --- | The non-dependent version of 'ArgFlag'. - --- Appears here partly so that it's together with its friend ArgFlag, --- but also because it is used in IfaceType, rather early in the --- compilation chain --- See Note [AnonArgFlag vs. ForallVisFlag] -data AnonArgFlag - = VisArg -- ^ Used for @(->)@: an ordinary non-dependent arrow. - -- The argument is visible in source code. - | InvisArg -- ^ Used for @(=>)@: a non-dependent predicate arrow. - -- The argument is invisible in source code. - deriving (Eq, Ord, Data) - -instance Outputable AnonArgFlag where - ppr VisArg = text "[vis]" - ppr InvisArg = text "[invis]" - -instance Binary AnonArgFlag where - put_ bh VisArg = putByte bh 0 - put_ bh InvisArg = putByte bh 1 - - get bh = do - h <- getByte bh - case h of - 0 -> return VisArg - _ -> return InvisArg - -mkAnonTyConBinders :: AnonArgFlag -> [TyVar] -> [TyConBinder] -mkAnonTyConBinders _ = Ty.mkAnonTyConBinders - -bytesFS :: FastString -> ByteString -bytesFS = fastStringToByteString - -mkFunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type -mkFunTy _ _ = Ty.FunTy - -pattern FunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type -pattern FunTy { ft_af, ft_mult, ft_arg, ft_res } <- ((VisArg,Many,) -> (ft_af, ft_mult, Ty.FunTy ft_arg ft_res)) where - FunTy _ft_af _ft_mult ft_arg ft_res = Ty.FunTy ft_arg ft_res - -pattern AnonTCB :: AnonArgFlag -> Ty.TyConBndrVis -pattern AnonTCB af <- ((VisArg,) -> (af, Ty.AnonTCB)) where - AnonTCB _af = Ty.AnonTCB - -noExtField :: NoExt -noExtField = NoExt - -#endif - --- Compat shim for GHC 8.8.x - -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) && !MIN_VERSION_GLASGOW_HASKELL(8,10,1,0) - -isEqPrimPred :: Type -> Bool -isEqPrimPred ty - | Just tc <- tyConAppTyCon_maybe ty - = tc `hasKey` Ghc.eqPrimTyConKey || tc `hasKey` Ghc.eqReprPrimTyConKey - | otherwise - = False - -isEqPred :: Type -> Bool -isEqPred ty - | Just tc <- tyConAppTyCon_maybe ty - , Just cls <- tyConClass_maybe tc - = cls `hasKey` Ghc.eqTyConKey || cls `hasKey` Ghc.heqTyConKey - | otherwise - = False - --- See NOTE [isEvVarType]. -isEvVarType :: Type -> Bool -isEvVarType = Ghc.isEvVarType - -#endif -#endif - -{- | [NOTE:tyConRealArity] - -The semantics of 'tyConArity' changed between GHC 8.6.5 and GHC 8.10, mostly due to the -Visible Dependent Quantification (VDQ). As a result, given the following: - -data family EntityField record :: * -> * - -Calling `tyConArity` on this would yield @2@ for 8.6.5 but @1@ an 8.10, so we try to backport -the old behaviour in 8.10 by \"looking\" at the 'Kind' of the input 'TyCon' and trying to recursively -split the type apart with either 'splitFunTy_maybe' or 'splitForAllTy_maybe'. - --} - -{- | [NOTE:isEvVarType] - -For GHC < 8.8.1 'isPredTy' is effectively the same as the new 'isEvVarType', which covers the cases -for coercion types and \"normal\" type coercions. The 8.6.5 version of 'isPredTy' had a special case to -handle a 'TyConApp' in the case of type equality (i.e. ~ ) which was removed in the implementation -for 8.8.1, which essentially calls 'tcIsConstraintKind' straight away. --} - --- --- Support for GHC >= 8.8 --- - -#if MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) && !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - --- See NOTE [tyConRealArity]. -tyConRealArity :: TyCon -> Int -tyConRealArity tc = go 0 (tyConKind tc) - where - go :: Int -> Kind -> Int - go !acc k = - case asum [fmap snd (splitFunTy_maybe k), fmap snd (splitForAllTy_maybe k)] of - Nothing -> acc - Just ks -> go (acc + 1) ks - -dataConExTyVars :: DataCon -> [TyVar] -dataConExTyVars = dataConExTyCoVars - -#endif - --- --- Compat shim for 8.10.x --- - -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) && !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -pattern FunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type -pattern FunTy { ft_af, ft_mult, ft_arg, ft_res } <- ((Many,) -> (ft_mult, Ty.FunTy ft_af ft_arg ft_res)) where - FunTy ft_af' _ft_mult' ft_arg' ft_res' = Ty.FunTy ft_af' ft_arg' ft_res' - -mkFunTy :: AnonArgFlag -> Mult -> Type -> Type -> Type -mkFunTy af _ arg res = Ty.FunTy af arg res -#endif - --- --- Compat shim for 9.0.x - -#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -- 'fsToUnitId' is gone in GHC 9, but we can bring code it in terms of 'fsToUnit' and 'toUnitId'. fsToUnitId :: FastString -> UnitId @@ -854,10 +177,3 @@ dataConSig dc gcatch :: (Ex.MonadCatch m, Exception e) => m a -> (e -> m a) -> m a gcatch = Ex.catch - -#endif - --- --- End of compatibility shim. --- -#endif diff --git a/src-ghc/Liquid/GHC/API/StableModule.hs b/src-ghc/Liquid/GHC/API/StableModule.hs index 57c131c4bc..d048cc415b 100644 --- a/src-ghc/Liquid/GHC/API/StableModule.hs +++ b/src-ghc/Liquid/GHC/API/StableModule.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} {-# OPTIONS_GHC -Wno-orphans #-} @@ -15,16 +14,8 @@ module Liquid.GHC.API.StableModule ( ) where import qualified GHC - -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -import qualified Module as GHC -#else import qualified GHC.Unit.Types as GHC import qualified GHC.Unit.Module as GHC -#endif -#endif - import Data.Hashable import GHC.Generics hiding (to, moduleName) import Data.Binary @@ -43,13 +34,7 @@ toStableModule :: GHC.Module -> StableModule toStableModule = StableModule moduleUnitId :: GHC.Module -> GHC.UnitId -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -moduleUnitId = GHC.moduleUnitId -#else moduleUnitId = GHC.toUnitId . GHC.moduleUnit -#endif -#endif renderModule :: GHC.Module -> String renderModule m = "Module { unitId = " <> (GHC.unitIdString . moduleUnitId $ m) @@ -91,13 +76,6 @@ instance Binary StableModule where -- | Creates a new 'StableModule' out of a 'ModuleName' and a 'UnitId'. mkStableModule :: GHC.UnitId -> GHC.ModuleName -> StableModule -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -mkStableModule uid modName = StableModule (GHC.mkModule uid modName) -#else mkStableModule uid modName = let realUnit = GHC.RealUnit $ GHC.Definite uid in StableModule (GHC.Module realUnit modName) -#endif -#endif - diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index 26547938a2..37a3dcfdbb 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} @@ -54,22 +53,11 @@ import Liquid.GHC.API hiding ( ModuleInfo , tm_renamed_source ) --- Shared imports for GHC < 9 -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -import qualified CoreMonad -import qualified EnumSet -import Maybes -import GhcMake -import Exception (ExceptionMonad) -#else import GHC.Data.Maybe import GHC.Driver.Make import GHC.Utils.Exception (ExceptionMonad) import qualified GHC.Core.Opt.Monad as CoreMonad import qualified GHC.Data.EnumSet as EnumSet -#endif -#endif import qualified Data.Map.Strict as M import Optics @@ -155,17 +143,7 @@ lookupName name = do -- | Our own simplified version of 'ModuleInfo' to overcome the fact we cannot construct the \"original\" -- one as the constructor is not exported, and 'getHomeModuleInfo' and 'getPackageModuleInfo' are not -- exported either, so we had to backport them as well. -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - --- For GHC < 9, UniqFM has a single parameter. -data ModuleInfo = ModuleInfo { minf_type_env :: UniqFM TyThing } -#else --- For GHC >= 9, UniqFM has two parameters. --- just fine. data ModuleInfo = ModuleInfo { minf_type_env :: UniqFM Name TyThing } -#endif -#endif modInfoLookupName :: GhcMonadLike m => ModuleInfo @@ -320,14 +298,6 @@ lookupModule mod_name Nothing = do -- Compatibility shim to extract the comments out of an 'ApiAnns', as modern GHCs now puts the -- comments (i.e. Haskell comments) in a different field ('apiAnnRogueComments'). -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -apiComments :: ApiAnns -> [Ghc.Located AnnotationComment] -apiComments apiAnns = - let comments = concat . M.elems . apiAnnComments $ apiAnns - in - comments -#else apiComments :: ApiAnns -> [Ghc.Located AnnotationComment] apiComments apiAnns = let comments = concat . M.elems . apiAnnComments $ apiAnns @@ -335,5 +305,3 @@ apiComments apiAnns = map toRealSrc $ mappend comments (apiAnnRogueComments apiAnns) where toRealSrc (L x e) = L (RealSrcSpan x Nothing) e -#endif -#endif diff --git a/src-ghc/Liquid/GHC/Interface.hs b/src-ghc/Liquid/GHC/Interface.hs index 6214bc9003..8b8dddbb56 100644 --- a/src-ghc/Liquid/GHC/Interface.hs +++ b/src-ghc/Liquid/GHC/Interface.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeSynonymInstances #-} @@ -236,17 +235,9 @@ configureDynFlags cfg tmp = do , hscTarget = HscInterpreted , ghcMode = CompManager -- prevent GHC from printing anything, unless in Loud mode -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - , log_action = if loud - then defaultLogAction - else \_ _ _ _ _ _ -> return () -#else , log_action = if loud then defaultLogAction else \_ _ _ _ _ -> return () -#endif -#endif -- redirect .hi/.o/etc files to temp directory , objectDir = Just tmp , hiDir = Just tmp diff --git a/src-ghc/Liquid/GHC/Logging.hs b/src-ghc/Liquid/GHC/Logging.hs index ba4bdedf44..94889c40a8 100644 --- a/src-ghc/Liquid/GHC/Logging.hs +++ b/src-ghc/Liquid/GHC/Logging.hs @@ -9,8 +9,6 @@ to pay the price of a pretty-printing \"roundtrip\". -} -{-# LANGUAGE CPP #-} - module Liquid.GHC.Logging ( fromPJDoc , putWarnMsg @@ -37,31 +35,10 @@ putLogMsg :: GHC.DynFlags -> PJ.Doc -> IO () putLogMsg dynFlags reason sev srcSpan _mbStyle = -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - GHC.putLogMsg dynFlags reason sev srcSpan style' . GHC.text . PJ.render - where - style' :: GHC.PprStyle - style' = case _mbStyle of - Nothing -> defaultErrStyle dynFlags - Just sty -> sty -#else GHC.putLogMsg dynFlags reason sev srcSpan . GHC.text . PJ.render -#endif -#endif - -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -defaultErrStyle :: GHC.DynFlags -> GHC.PprStyle -defaultErrStyle _dynFlags = GHC.defaultErrStyle _dynFlags -#else defaultErrStyle :: GHC.DynFlags -> GHC.PprStyle defaultErrStyle _dynFlags = GHC.defaultErrStyle -#endif -#else - #error MIN_VERSION_GLASGOW_HASKELL is not defined -#endif putWarnMsg :: GHC.DynFlags -> GHC.SrcSpan -> PJ.Doc -> IO () putWarnMsg dynFlags srcSpan doc = diff --git a/src-ghc/Liquid/GHC/Misc.hs b/src-ghc/Liquid/GHC/Misc.hs index 77bb8f2aad..9d63845009 100644 --- a/src-ghc/Liquid/GHC/Misc.hs +++ b/src-ghc/Liquid/GHC/Misc.hs @@ -904,35 +904,6 @@ isEvVar x = isPredVar x || isTyVar x || isCoVar x -- hsc_env <- Ghc.getHscEnv -- liftIO $ elabRnExpr hsc_env mode expr -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -elabRnExpr - :: TcRnExprMode -> LHsExpr GhcPs -> TcRn CoreExpr -elabRnExpr mode rdr_expr = do - (rn_expr, _fvs) <- rnLExpr rdr_expr - failIfErrsM - uniq <- newUnique - let fresh_it = itName uniq (getLoc rdr_expr) - orig = Ghc.lexprCtOrigin rn_expr - (tclvl, lie, (tc_expr, res_ty)) <- pushLevelAndCaptureConstraints $ do - (_tc_expr, expr_ty) <- tcInferSigma rn_expr - expr_ty' <- if inst - then snd <$> deeplyInstantiate orig expr_ty - else return expr_ty - return (_tc_expr, expr_ty') - (_, _, evbs, residual, _) <- simplifyInfer tclvl - infer_mode - [] {- No sig vars -} - [(fresh_it, res_ty)] - lie - evbs' <- perhaps_disable_default_warnings $ simplifyInteractive residual - full_expr <- zonkTopLExpr (mkHsDictLet (EvBinds evbs') (mkHsDictLet evbs tc_expr)) - initDsTc $ dsLExpr full_expr - where - (inst, infer_mode, perhaps_disable_default_warnings) = case mode of - TM_Inst -> (True, NoRestrictions, id) - TM_NoInst -> (False, NoRestrictions, id) - TM_Default -> (True, EagerDefaulting, unsetWOptM Opt_WarnTypeDefaults) -#else elabRnExpr :: TcRnExprMode -> LHsExpr GhcPs -> TcRn CoreExpr elabRnExpr mode rdr_expr = do @@ -970,7 +941,7 @@ elabRnExpr mode rdr_expr = do TM_Inst -> (True, NoRestrictions, id) TM_NoInst -> (False, NoRestrictions, id) TM_Default -> (True, EagerDefaulting, unsetWOptM Opt_WarnTypeDefaults) -#endif + newtype HashableType = HashableType {getHType :: Type} instance Eq HashableType where @@ -1064,15 +1035,7 @@ withWiredIn m = discardConstraints $ do sigs = sigsExt cppExt -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) - cppExt = HsIBRn {hsib_vars = [], hsib_closed = True} in -- TODO: What goes here? XXX -#else - cppExt = [] -#endif -#else cppExt = [] -#endif locSpan = UnhelpfulSpan (UnhelpfulOther "Liquid.GHC.Misc: WiredIn") @@ -1113,14 +1076,7 @@ withWiredIn m = discardConstraints $ do aName <- Ghc.L locSpan <$> toName "a" let aTy = nameToTy aName let ty = noLoc $ HsForAllTy Ghc.noExtField -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) - ForallInvis -#endif - [Ghc.L locSpan $ UserTyVar Ghc.noExtField aName] $ mkHsFunTy aTy (mkHsFunTy aTy boolTy') -#else (mkHsForAllInvisTele [Ghc.L locSpan $ UserTyVar Ghc.noExtField SpecifiedSpec aName]) $ mkHsFunTy aTy (mkHsFunTy aTy boolTy') -#endif return $ TcWiredIn n (Just (4, Ghc.InfixN)) ty -- TODO: This is defined as a measure in liquid-base GHC.Base. We probably want to insert all measures to the environment. @@ -1131,18 +1087,8 @@ withWiredIn m = discardConstraints $ do let aTy = nameToTy aName let ty = noLoc $ HsForAllTy Ghc.noExtField -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) - ForallInvis -#endif - [Ghc.L locSpan $ UserTyVar Ghc.noExtField aName] $ mkHsFunTy (listTy aTy) intTy' - return $ TcWiredIn n Nothing ty -#else (mkHsForAllInvisTele [Ghc.L locSpan $ UserTyVar Ghc.noExtField SpecifiedSpec aName]) $ mkHsFunTy (listTy aTy) intTy' return $ TcWiredIn n Nothing ty -#endif - - prependGHCRealQual :: FastString -> RdrName prependGHCRealQual = varQual_RDR gHC_REAL diff --git a/src-ghc/Liquid/GHC/Resugar.hs b/src-ghc/Liquid/GHC/Resugar.hs index 4a0aa408ec..2f5e7a34c4 100644 --- a/src-ghc/Liquid/GHC/Resugar.hs +++ b/src-ghc/Liquid/GHC/Resugar.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} diff --git a/src-ghc/Liquid/GHC/TypeRep.hs b/src-ghc/Liquid/GHC/TypeRep.hs index e3cd30e2ac..64e3b89047 100644 --- a/src-ghc/Liquid/GHC/TypeRep.hs +++ b/src-ghc/Liquid/GHC/TypeRep.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} @@ -116,15 +115,8 @@ substCoercion x tx (TyConAppCo r c cs) = TyConAppCo (subst x tx r) c (subst x tx <$> cs) substCoercion x tx (AppCo c1 c2) = AppCo (subst x tx c1) (subst x tx c2) -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -substCoercion x tx (FunCo r c1 c2) - = FunCo r (subst x tx c1) (subst x tx c2) -#else substCoercion x tx (FunCo r cN c1 c2) = FunCo r cN (subst x tx c1) (subst x tx c2) -- TODO(adinapoli) Is this the correct substitution? -#endif -#endif substCoercion x tx (ForAllCo y c1 c2) | symbol x == symbol y = ForAllCo y c1 c2 @@ -152,22 +144,6 @@ substCoercion x tx (KindCo c) = KindCo (subst x tx c) substCoercion x tx (SubCo c) = SubCo (subst x tx c) -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) -substCoercion x tx (Refl r t) - = Refl (subst x tx r) (subst x tx t) -substCoercion x tx (CoherenceCo c1 c2) - = CoherenceCo (subst x tx c1) (subst x tx c2) -#endif -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) -substCoercion x tx (Refl t) - = Refl (subst x tx t) -substCoercion x tx (GRefl r t co) -- FIXME(adn) Is this a correct substitution? - = GRefl r (subst x tx t) co -- FIXME(adn) Is this a correct substitution? -substCoercion _x _tx (HoleCo cH) - = HoleCo cH -- FIXME(adn) Is this a correct substitution? -#endif -#endif instance SubstTy Role where instance SubstTy (CoAxiom Branched) where diff --git a/src/Language/Haskell/Liquid/Bare/Elaborate.hs b/src/Language/Haskell/Liquid/Bare/Elaborate.hs index d2cd729159..7b058ac6f1 100644 --- a/src/Language/Haskell/Liquid/Bare/Elaborate.hs +++ b/src/Language/Haskell/Liquid/Bare/Elaborate.hs @@ -42,33 +42,12 @@ import Data.Functor.Foldable hiding (Fix) import Data.Functor.Foldable #endif --- import TcRnMonad (TcRn) import Data.Char ( isUpper ) -#if MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) import GHC.Types.Name.Occurrence -#else -import OccName -#endif --- import GHC --- import GhcPlugins ( isDFunId --- ) - --- import FastString --- import CoreSyn --- import PrelNames import qualified Liquid.GHC.API as Ghc (noExtField) - --- import qualified Outputable as O --- import TysWiredIn ( boolTyCon --- , true_RDR --- ) --- import RdrName --- import BasicTypes import Data.Default ( def ) import qualified Data.Maybe as Mb --- import qualified CoreUtils as Utils - -- TODO: make elaboration monadic so typeclass names are unified to something -- that is generated in advance. This can greatly simplify the implementation @@ -535,20 +514,10 @@ elaborateSpecType' partialTp coreToLogic simplify t = hsExpr = buildHsExpr (fixExprToHsExpr (S.fromList origBinders) e) querySpecType :: LHsExpr GhcPs -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,6,5,0) && !MIN_VERSION_GLASGOW_HASKELL(8,8,1,0) - exprWithTySigs = noLoc $ ExprWithTySig - (mkLHsSigWcType (specTypeToLHsType querySpecType)) - hsExpr -#else exprWithTySigs = noLoc $ ExprWithTySig Ghc.noExtField hsExpr (mkLHsSigWcType (specTypeToLHsType querySpecType)) -#endif -#else - exprWithTySigs = noLoc ExprWithTySig -#endif eeWithLamsCore <- GM.elabRnExpr TM_Inst exprWithTySigs eeWithLamsCore' <- simplify eeWithLamsCore let @@ -638,11 +607,7 @@ renameBinderSort f = rename mkHsTyConApp :: IdP (GhcPass p) -> [LHsType (GhcPass p)] -> LHsType (GhcPass p) -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -mkHsTyConApp = nlHsTyConApp -#else mkHsTyConApp tyconId tyargs = nlHsTyConApp Prefix tyconId (map HsValArg tyargs) -#endif -- | Embed fixpoint expressions into parsed haskell expressions. -- It allows us to bypass the GHC parser and use arbitrary symbols @@ -770,14 +735,7 @@ specTypeToLHsType = RImpFF _ _ (_, tin) (_, tout) _ -> nlHsFunTy tin tout RAllTF (ty_var_value -> (RTV tv)) (_, t) _ -> noLoc $ HsForAllTy Ghc.noExtField -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) - ForallInvis -#endif - [noLoc $ UserTyVar Ghc.noExtField (noLoc $ symbolToRdrNameNs tvName (F.symbol tv))] -#else (mkHsForAllInvisTele [noLoc $ UserTyVar Ghc.noExtField SpecifiedSpec (noLoc $ symbolToRdrNameNs tvName (F.symbol tv))]) -#endif t RAllPF _ (_, ty) -> ty RAppF RTyCon { rtc_tc = tc } ts _ _ -> mkHsTyConApp diff --git a/src/Language/Haskell/Liquid/Constraint/Generate.hs b/src/Language/Haskell/Liquid/Constraint/Generate.hs index 4d7cf34bb8..9d8a296d37 100644 --- a/src/Language/Haskell/Liquid/Constraint/Generate.hs +++ b/src/Language/Haskell/Liquid/Constraint/Generate.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE StandaloneDeriving #-} @@ -19,10 +18,6 @@ module Language.Haskell.Liquid.Constraint.Generate ( generateConstraints, generateConstraintsWithEnv, caseEnv, consE ) where -#if !MIN_VERSION_base(4,14,0) -import Control.Monad.Fail -#endif - import Prelude hiding (error) import GHC.Stack import Liquid.GHC.API as Ghc hiding ( panic diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index 383ddf1a88..ffb930ad32 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} @@ -12,12 +11,6 @@ module Language.Haskell.Liquid.Constraint.Relational (consAssmRel, consRelTop) where - -#if !MIN_VERSION_base(4,14,0) -import Control.Monad.Fail -#endif - - import Control.Monad.State import Data.Bifunctor ( Bifunctor(bimap) ) import qualified Data.HashMap.Strict as M diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 41a5002388..cfeac9a303 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} -{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} diff --git a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs index 8d888410ec..5c6981daee 100644 --- a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs +++ b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs @@ -1,5 +1,4 @@ {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE OverloadedStrings #-} @@ -261,11 +260,7 @@ coreToLogic allowTC cb = coreToLg allowTC (normalize allowTC cb) coreToLg :: Bool -> C.CoreExpr -> LogicM Expr coreToLg allowTC (C.Let (C.NonRec x (C.Coercion c)) e) - = coreToLg allowTC (C.substExpr -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - C.empty -#endif - (C.extendCvSubst C.emptySubst x c) e) + = coreToLg allowTC (C.substExpr (C.extendCvSubst C.emptySubst x c) e) coreToLg allowTC (C.Let b e) = subst1 <$> coreToLg allowTC e <*> makesub allowTC b coreToLg allowTC (C.Tick _ e) = coreToLg allowTC e diff --git a/src/Language/Haskell/Liquid/Transforms/InlineAux.hs b/src/Language/Haskell/Liquid/Transforms/InlineAux.hs index 3c503d654e..5d7605dbb9 100644 --- a/src/Language/Haskell/Liquid/Transforms/InlineAux.hs +++ b/src/Language/Haskell/Liquid/Transforms/InlineAux.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} @@ -78,12 +77,8 @@ inlineAuxExpr dfunId methodToAux e = go e go :: CoreExpr -> CoreExpr go (Lam b body) = Lam b (go body) go (Let b body) - | NonRec x e <- b, isDictId x = go - $ substExpr -#if !MIN_VERSION_GLASGOW_HASKELL(9,0,0,0) - empty -#endif - (extendIdSubst emptySubst x e) body + | NonRec x e <- b, isDictId x = + go $ substExpr (extendIdSubst emptySubst x e) body | otherwise = Let (mapBnd go b) (go body) go (Case e x t alts) = Case (go e) x t (fmap (mapAlt go) alts) go (Cast e c ) = Cast (go e) c diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs index 78e3e2d0d9..99c3f01430 100644 --- a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs +++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} diff --git a/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs index f8ed5da868..5ef1af4ca8 100644 --- a/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs +++ b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE TemplateHaskellQuotes #-} @@ -94,11 +93,7 @@ mkSpecDecs (Alias rta) = lsym = F.atLoc rta n name = symbolName n n = rtName (val rta) -#if MIN_VERSION_template_haskell(2,17,0) tvs = (\a -> PlainTV (symbolName a) ()) <$> rtTArgs (val rta) -#else - tvs = PlainTV . symbolName <$> rtTArgs (val rta) -#endif mkSpecDecs _ = Right [] @@ -160,11 +155,7 @@ simplifyBareType'' (tvs, cls) (RAllT tv t _) = simplifyBareType'' (ty_var_value tv : tvs, cls) t simplifyBareType'' (tvs, cls) t = -#if MIN_VERSION_template_haskell(2,17,0) ForallT ((\t -> PlainTV (symbolName t) SpecifiedSpec) <$> reverse tvs) -#else - ForallT (PlainTV . symbolName <$> reverse tvs) -#endif <$> mapM simplifyBareType' (reverse cls) <*> simplifyBareType' t diff --git a/src/LiquidHaskell.hs b/src/LiquidHaskell.hs index 6b3e46df70..ae600702c6 100644 --- a/src/LiquidHaskell.hs +++ b/src/LiquidHaskell.hs @@ -1,20 +1,9 @@ -{-# LANGUAGE CPP #-} - module LiquidHaskell ( -- * LiquidHaskell Specification QuasiQuoter lq -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) -- * LiquidHaskell as a compiler plugin , plugin -#endif -#endif ) where import Language.Haskell.Liquid.UX.QuasiQuoter - -#ifdef MIN_VERSION_GLASGOW_HASKELL -#if MIN_VERSION_GLASGOW_HASKELL(8,10,0,0) import Language.Haskell.Liquid.GHC.Plugin (plugin) -#endif -#endif From af8d29f1124d7f06f5a292658d00933f02ecf6b6 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Tue, 20 Dec 2022 12:42:49 +0200 Subject: [PATCH 067/219] Remove seemingly outdated comment --- liquidhaskell.cabal | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index d44ba32696..06356a6779 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -130,6 +130,8 @@ library Liquid.GHC.SpanStack Liquid.GHC.Types Liquid.GHC.TypeRep + Language.Haskell.Liquid.GHC.Plugin + Language.Haskell.Liquid.GHC.Plugin.Tutorial Language.Haskell.Liquid.Interactive.Handler Language.Haskell.Liquid.Interactive.Types Language.Haskell.Liquid.LawInstances @@ -183,15 +185,6 @@ library Language.Haskell.Liquid.WiredIn LiquidHaskell Paths_liquidhaskell - - -- FIXME: Temporary measure to ensure that if the source plugin is available, then: - -- 1. we compile it; - -- 2. We don't rely on the \"liquid-prelude\" Haskell files previously shipped as part of LH itself. - -- Once the source plugin is out, we should also removed the duplicate \"liquid-prelude\" files from - -- the \"include\" directory. - - exposed-modules: Language.Haskell.Liquid.GHC.Plugin - Language.Haskell.Liquid.GHC.Plugin.Tutorial other-modules: Language.Haskell.Liquid.GHC.Plugin.SpecFinder Language.Haskell.Liquid.GHC.Plugin.Types Language.Haskell.Liquid.GHC.Plugin.Util From d42a2f9de2472364b04119c6fc3a10c3be1a1f81 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Thu, 8 Dec 2022 13:37:06 +0200 Subject: [PATCH 068/219] Document GHC support policy Closes #2116 --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76334df197..cc0e7f49c3 100644 --- a/README.md +++ b/README.md @@ -300,10 +300,22 @@ Bash script. The script doesn't accept any argument and it tries to determine th to upload by scanning the `$PWD` for packages named appropriately. It will ask the user for confirmation before proceeding, and `stack upload` will be used under the hood. +## GHC support policy + +LH supports only one version of GHC at any given time. This is because LH depends heavily on the `ghc` library +and there is currently no distinction between public API's and API's internal to GHC. There are currently no +release notes for the `ghc` library and breaking changes happen without notice and without deprecation +periods. Supporting only one GHC version saves developer time because it obviates the need for `#ifdef`'s +throughout the codebase, or for an compatibility layer that becomes increasingly difficult to write as we +attempt to support more GHC versions. Porting to newer GHC versions takes less time, the code is easier to +read and there is less code duplication. + +Users of older versions of GHC can still use older versions of LH. + ## The GHC.API module -In order to allow LH to work with multiple GHC versions, we need a way to abstract over all the breaking -changes of the `ghc` library, which might change substantially with every major GHC release. This is +In order to minimize the effort in porting LH to new releases of GHC, we need a way to abstract over breaking +changes in the `ghc` library, which might change substantially with every major GHC release. This is accomplished by the [GHC.API][] module. The idea is that **rather than importing multiple `ghc` modules, LH developers must import this single module in order to write future-proof code**. This is especially important for versions of the compiler greater than 9, where the module hierarchy changed substantially, From 3b0cdf69e98f0b99d5ba984166f03e65796cd35e Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Mon, 12 Dec 2022 15:08:12 +0200 Subject: [PATCH 069/219] CircleCI: Remove cabal_810 job and cabal.ghc9.project The cabal.ghc9.project is no longer needed, because the cabal_900 job reuses cabal.project. --- .circleci/config.yml | 17 +---- cabal.ghc9.project | 143 ------------------------------------------- cabal.project | 2 +- 3 files changed, 3 insertions(+), 159 deletions(-) delete mode 100644 cabal.ghc9.project diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b20343732..5a1e2dffcd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -34,7 +34,6 @@ commands: default: "cabal v2-update" ghc_version: type: string - default: "8.10.7" project_file: type: string default: "cabal.project" @@ -155,31 +154,19 @@ jobs: stack_yaml_file: "stack.yaml" extra_build_flags: "--flag liquidhaskell:devel" extra_test_flags: " liquid-platform:liquidhaskell " - - cabal_810: + cabal_900: machine: image: ubuntu-2004:202107-02 steps: - cabal_build_and_test: + ghc_version: "9.0.2" liquid_runner: "--liquid-runner=cabal -v0 v2-exec liquidhaskell -- -v0 \ -package-env=$(./scripts/generate_testing_ghc_env) \ -package=liquidhaskell -package=Cabal " - cabal_900: - machine: - image: ubuntu-2004:202107-02 - steps: - - cabal_build_and_test: - ghc_version: "9.0.1" - project_file: "cabal.ghc9.project" - liquid_runner: "--liquid-runner=cabal -v0 v2-exec --project-file cabal.ghc9.project liquidhaskell -- -v0 \ - -package-env=$(./scripts/generate_testing_ghc_env cabal.ghc9.project) \ - -package=liquidhaskell -package=Cabal " - workflows: version: 2 build_stack_and_cabal: jobs: - stack_900 - - cabal_810 - cabal_900 diff --git a/cabal.ghc9.project b/cabal.ghc9.project deleted file mode 100644 index b1847f3909..0000000000 --- a/cabal.ghc9.project +++ /dev/null @@ -1,143 +0,0 @@ -packages: . - ./liquid-bytestring - ./liquid-containers - ./liquid-fixpoint - ./liquid-parallel - ./liquid-prelude - ./liquid-vector - ./liquid-platform - ./tests - ./tests/benchmarks/popl18/lib - ./benchmark-timings - -package liquid-fixpoint - flags: +devel - -package liquid-platform - flags: +devel - -tests: True - -with-compiler: ghc-9.0.1 - -source-repository-package - type: git - location: https://github.com/liquidhaskell/liquid-ghc-prim.git - tag: v0.7.0 - -source-repository-package - type: git - location: https://github.com/facundominguez/liquid-base.git - tag: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 - -source-repository-package - type: git - location: https://github.com/qnikst/ghc-timings-report - tag: 45ef3498e35897712bde8e002ce18df6d55f8b15 - -constraints: - any.Cabal ==3.4.0.0, - Decimal ==0.5.1, - EdisonAPI ==1.3.1, - EdisonCore ==1.3.2.1, - FPretty ==1.1, - HTTP ==4000.3.15, - ListLike ==4.7.2, - QuickCheck ==2.14.2, - active ==0.2.0.14, - aivika ==5.9, - aivika-transformers ==5.9, - alex ==3.2.5, - arith-encode ==1.0.2, - basement ==0.0.11, - cassava ==0.5.2.0, - chaselev-deque ==0.5.0.5, - combinat ==0.2.9.0, - commonmark ==0.1.0.2, - conduit ==1.3.4.2, - cql ==4.0.2, - critbit ==0.2.0.0, - cryptonite ==0.27, - data-r-tree ==0.6.0, - diagrams-lib ==1.4.3, - doctest ==0.16.3 || ==0.17, - drinkery ==0.4, - emacs-module ==0.1.1, - enumeration ==0.2.0, - fclabels ==2.0.5, - foundation ==0.0.25, - free ==5.1.7, - recursion-schemes ==5.2.2, - free-algebras ==0.1.0.0, - generic-deriving ==1.14.1, - generic-lens ==2.0.0.0, - generic-lens-core ==2.0.0.0, - generics-sop ==0.5.1.0, - haskeline ==0.8.2, - haskell-src-meta ==0.8.5, - heterocephalus ==1.0.5.4, - hgeometry ==0.11.0.0, - hgeometry-ipe ==0.11.0.0, - hmatrix ==0.20.0.0, - hslua ==1.2.0, - hxt ==9.3.1.18, - hxt-regex-xmlschema ==9.2.0.3, - inspection-testing ==0.4.2.4, - io-choice ==0.0.7, - io-streams ==1.5.2.0, - iproute ==1.7.9, - kind-generics-th ==0.2.2.1, - language-haskell-extract ==0.2.4, - lens ==4.19.2, - lens-family ==2.1.1, - lens-family-th ==0.5.2.1, - memory ==0.15.0, - microlens ==0.4.11.2, - microlens-th ==0.4.3.6, - monadplus ==1.4.2, - mustache ==2.3.1, - network-uri ==2.6.3.0, - obdd ==0.8.2, - optics-extra ==0.4, - optics-th ==0.4, - packman ==0.5.0, - pandoc ==2.11, - parameterized-utils ==2.1.1, - partial-isomorphisms ==0.2.2.1, - persistent-template ==2.8.2.3, - pipes ==4.3.14, - pipes-bytestring ==2.1.6, - pipes-parse ==3.0.8, - pipes-safe ==2.3.2, - plots ==0.1.1.2, - pretty-types ==0.3.0.1, - proto3-wire ==1.2.0, - ral-lens ==0.1, - regex-base ==0.94.0.0, - regex-compat ==0.95.2.0, - row-types ==1.0.0.0, - scheduler ==1.4.2.3, - semirings ==0.5.4, - shake ==0.19.1, - singletons ==2.6 || ==2.7, - store ==0.7.12, - store-core ==0.4.4.4, - streaming-bytestring ==0.1.6, - syb ==0.7.2.1, - texmath ==0.12.0.3, - text-show ==3.9.6, - th-abstraction ==0.4.2.0, - th-desugar ==1.10 || ==1.11, - th-expand-syns ==0.4.8.0, - th-lift-instances ==0.1.18, - th-utilities ==0.2.4.3, - tpdb ==2.2.0, - trivial-constraint ==0.6.0.0, - true-name ==0.1.0.3, - typenums ==0.1.2.1, - uniplate ==1.6.12, - unique ==0, - vec-lens ==0.3, - vinyl ==0.13.0, - xlsx ==0.8.1, - yesod-core ==1.6.18.4 diff --git a/cabal.project b/cabal.project index 6a5acaecb9..978ece7fc8 100644 --- a/cabal.project +++ b/cabal.project @@ -1,4 +1,4 @@ -with-compiler: ghc-8.10.7 +with-compiler: ghc-9.0.2 packages: . ./liquid-base From 0b6120b01a342d6f4f8d1a75a8e7cc74db22108c Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Mon, 12 Dec 2022 16:04:43 +0200 Subject: [PATCH 070/219] stack.yaml: Restore in-repo liquid-base --- liquid-base/src/Foreign/ForeignPtr.spec | 2 +- stack.yaml | 3 +- stack.yaml.lock | 41 +++++++++---------------- 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/liquid-base/src/Foreign/ForeignPtr.spec b/liquid-base/src/Foreign/ForeignPtr.spec index 5c1bd76ba9..f9ff6e5f07 100644 --- a/liquid-base/src/Foreign/ForeignPtr.spec +++ b/liquid-base/src/Foreign/ForeignPtr.spec @@ -3,7 +3,7 @@ module spec Foreign.ForeignPtr where import GHC.ForeignPtr import Foreign.Ptr -Foreign.ForeignPtr.withForeignPtr :: forall a b. fp:(GHC.ForeignPtr.ForeignPtr a) +GHC.ForeignPtr.withForeignPtr :: forall a b. fp:(GHC.ForeignPtr.ForeignPtr a) -> ((PtrN a (fplen fp)) -> GHC.Types.IO b) -> (GHC.Types.IO b) diff --git a/stack.yaml b/stack.yaml index fc5172b4cd..5a3476fbdc 100644 --- a/stack.yaml +++ b/stack.yaml @@ -11,6 +11,7 @@ ghc-options: packages: - liquid-fixpoint - liquid-ghc-prim +- liquid-base - liquid-bytestring - liquid-prelude - liquid-vector @@ -30,8 +31,6 @@ extra-deps: commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 # for tests - strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 -- git: https://github.com/facundominguez/liquid-base - commit: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 resolver: lts-19.33 allow-newer: true diff --git a/stack.yaml.lock b/stack.yaml.lock index 7ec970ef41..fc33be4d53 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -5,65 +5,54 @@ packages: - completed: - hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 pantry-tree: - size: 279 sha256: e1a52f56ec0cab647ec7af0d75bfbb45f09cccea4a8127996cb7b132bd73bd2c + size: 279 + hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 original: hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 - completed: - hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 pantry-tree: - size: 327 sha256: 2010fda4c4af2dd9da64786d9e902f387b6a9cb034eb6573d678e752deecc319 + size: 327 + hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 original: hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 - completed: - hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 pantry-tree: - size: 1248 sha256: 4df2f6b536a0fcc5f7d562cb29e373f27dc4a2747452ac5cc74c1599cab22fc5 + size: 1248 + hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 original: hackage: hashable-1.3.5.0 - completed: - hackage: rest-rewrite-0.3.0@sha256:398f937a5faf6bd3329650ee9aed31bbfe7ed1c23252710908ad7295e3252c94,3890 pantry-tree: - size: 3943 sha256: 6e42cf85257cbc2abf50a9c8f3bac8777920f1b970e6f2cae9358690e1186e99 + size: 3943 + hackage: rest-rewrite-0.3.0@sha256:398f937a5faf6bd3329650ee9aed31bbfe7ed1c23252710908ad7295e3252c94,3890 original: hackage: rest-rewrite-0.3.0 - completed: name: ghc-timings - version: '0.1' - git: https://github.com/qnikst/ghc-timings-report pantry-tree: - size: 7544 sha256: 72622264696c78cda23cf96382dee7a3d14e3eafdb8977486338f113681dcec4 + size: 7544 commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 - original: git: https://github.com/qnikst/ghc-timings-report + version: '0.1' + original: commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 + git: https://github.com/qnikst/ghc-timings-report - completed: - hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 pantry-tree: - size: 671 sha256: cf7712453587e8ea69b96f33e2e8015c22d3b448259d4cace663cc15657309d7 - original: + size: 671 hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 -- completed: - name: liquid-base - version: 4.15.0.1 - git: https://github.com/facundominguez/liquid-base - pantry-tree: - size: 15554 - sha256: 464e5c7c7cc77fa5c039e614232e562bf0de9e44554a22d0e6193ea4e8b2fe85 - commit: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 original: - git: https://github.com/facundominguez/liquid-base - commit: 8ad2378cee5ccf7937d9e08aacd5c5b7128318e8 + hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 snapshots: - completed: + sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 size: 619204 url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml - sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 original: lts-19.33 From 8dec256f96471f7b7248d390bcb5db6e250bb6c6 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Mon, 12 Dec 2022 16:05:22 +0200 Subject: [PATCH 071/219] Revert "stack.yaml Set allow-newer temporarily" This reverts commit 1297ee68257c21f7ad492865618918ec1d14f111. --- stack.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/stack.yaml b/stack.yaml index 5a3476fbdc..865554838b 100644 --- a/stack.yaml +++ b/stack.yaml @@ -33,7 +33,6 @@ extra-deps: - strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 resolver: lts-19.33 -allow-newer: true nix: packages: [cacert, git, hostname, z3] From 4d510039d87fc57f6d04a9d0201e18ebc591e077 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Tue, 20 Dec 2022 13:01:36 +0200 Subject: [PATCH 072/219] Appease hlint --- src-ghc/Liquid/GHC/GhcMonadLike.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index 37a3dcfdbb..9797c6eb67 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -143,7 +143,7 @@ lookupName name = do -- | Our own simplified version of 'ModuleInfo' to overcome the fact we cannot construct the \"original\" -- one as the constructor is not exported, and 'getHomeModuleInfo' and 'getPackageModuleInfo' are not -- exported either, so we had to backport them as well. -data ModuleInfo = ModuleInfo { minf_type_env :: UniqFM Name TyThing } +newtype ModuleInfo = ModuleInfo { minf_type_env :: UniqFM Name TyThing } modInfoLookupName :: GhcMonadLike m => ModuleInfo From 7506926e61a4df3d530da75ebc882d37436a21e8 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Sun, 27 Nov 2022 20:59:27 +0200 Subject: [PATCH 073/219] Port to GHC 9.2. --- benchmark-timings/benchmark-timings.cabal | 4 +- cabal.project | 4 +- liquid-base/liquid-base.cabal | 6 +- liquid-bytestring/liquid-bytestring.cabal | 2 +- liquid-ghc-prim/liquid-ghc-prim.cabal | 2 +- liquid-prelude/liquid-prelude.cabal | 2 +- liquidhaskell.cabal | 6 +- src-ghc/Liquid/GHC/API.hs | 63 ++++++++----- src-ghc/Liquid/GHC/API/StableModule.hs | 7 +- src-ghc/Liquid/GHC/GhcMonadLike.hs | 60 +++++++------ src-ghc/Liquid/GHC/Interface.hs | 55 +++++++----- src-ghc/Liquid/GHC/Logging.hs | 20 +++-- src-ghc/Liquid/GHC/Misc.hs | 89 ++++++++----------- src-ghc/Liquid/GHC/Play.hs | 6 +- src-ghc/Liquid/GHC/Resugar.hs | 4 +- src-ghc/Liquid/GHC/SpanStack.hs | 4 +- src/Language/Haskell/Liquid/Bare/Axiom.hs | 4 +- src/Language/Haskell/Liquid/Bare/Check.hs | 24 ++--- src/Language/Haskell/Liquid/Bare/Class.hs | 2 + src/Language/Haskell/Liquid/Bare/Elaborate.hs | 26 +++--- src/Language/Haskell/Liquid/Bare/Expand.hs | 4 +- src/Language/Haskell/Liquid/Bare/Measure.hs | 2 +- src/Language/Haskell/Liquid/Bare/Misc.hs | 2 +- src/Language/Haskell/Liquid/Bare/Plugged.hs | 3 + src/Language/Haskell/Liquid/Bare/Resolve.hs | 2 +- src/Language/Haskell/Liquid/Bare/Typeclass.hs | 2 + .../Haskell/Liquid/Constraint/Constraint.hs | 2 + .../Haskell/Liquid/Constraint/Generate.hs | 9 +- .../Haskell/Liquid/Constraint/Relational.hs | 8 +- .../Haskell/Liquid/Constraint/Split.hs | 1 + .../Haskell/Liquid/Constraint/ToFixpoint.hs | 3 +- src/Language/Haskell/Liquid/GHC/Plugin.hs | 49 +++++----- src/Language/Haskell/Liquid/Measure.hs | 8 +- src/Language/Haskell/Liquid/Synthesize.hs | 5 +- .../Haskell/Liquid/Synthesize/Check.hs | 5 +- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 8 +- .../Haskell/Liquid/Synthesize/Misc.hs | 2 +- .../Haskell/Liquid/Synthesize/Termination.hs | 2 + .../Haskell/Liquid/Termination/Structural.hs | 6 +- src/Language/Haskell/Liquid/Transforms/ANF.hs | 41 ++++----- .../Haskell/Liquid/Transforms/CoreToLogic.hs | 34 +++---- .../Haskell/Liquid/Transforms/InlineAux.hs | 4 +- src/Language/Haskell/Liquid/Transforms/Rec.hs | 8 +- .../Haskell/Liquid/Transforms/Rewrite.hs | 39 ++++---- src/Language/Haskell/Liquid/Types/Bounds.hs | 1 + src/Language/Haskell/Liquid/Types/Errors.hs | 36 ++++---- src/Language/Haskell/Liquid/Types/PredType.hs | 3 +- .../Haskell/Liquid/Types/PrettyPrint.hs | 8 +- src/Language/Haskell/Liquid/Types/RefType.hs | 50 ++++++++--- src/Language/Haskell/Liquid/Types/Types.hs | 5 +- src/Language/Haskell/Liquid/Types/Visitors.hs | 11 +-- src/Language/Haskell/Liquid/UX/ACSS.hs | 2 +- src/Language/Haskell/Liquid/UX/DiffCheck.hs | 9 +- src/Language/Haskell/Liquid/UX/QuasiQuoter.hs | 2 - src/Language/Haskell/Liquid/WiredIn.hs | 2 + stack.yaml | 7 +- stack.yaml.lock | 38 +++----- 57 files changed, 430 insertions(+), 383 deletions(-) diff --git a/benchmark-timings/benchmark-timings.cabal b/benchmark-timings/benchmark-timings.cabal index 4e066749a3..39d086e70d 100644 --- a/benchmark-timings/benchmark-timings.cabal +++ b/benchmark-timings/benchmark-timings.cabal @@ -36,8 +36,8 @@ executable benchmark-timings build-depends: base , aeson >= 1.5.6 && < 2.1 , cassava ^>=0.5.2 - , bytestring ^>=0.10.12 - , optparse-applicative ^>=0.16.1 + , bytestring >=0.10.12 && <0.12 + , optparse-applicative >=0.16.1 && <0.18 ghc-options: -Wall hs-source-dirs: app default-language: Haskell2010 diff --git a/cabal.project b/cabal.project index 978ece7fc8..58824c772f 100644 --- a/cabal.project +++ b/cabal.project @@ -1,4 +1,4 @@ -with-compiler: ghc-9.0.2 +with-compiler: ghc-9.2.5 packages: . ./liquid-base @@ -19,6 +19,8 @@ source-repository-package location: https://github.com/qnikst/ghc-timings-report tag: 45ef3498e35897712bde8e002ce18df6d55f8b15 +allow-newer: ghc-timings:base, rest-rewrite:time + package liquid-fixpoint flags: +devel diff --git a/liquid-base/liquid-base.cabal b/liquid-base/liquid-base.cabal index 659c8fa8ee..18efbe59ad 100644 --- a/liquid-base/liquid-base.cabal +++ b/liquid-base/liquid-base.cabal @@ -247,11 +247,7 @@ library build-depends: liquid-ghc-prim , liquidhaskell >= 0.8.10.1 - if impl(ghc < 9) - build-depends: integer-gmp < 1.0.4.0 - , base == 4.14.3.0 - else - build-depends: base ^>= 4.15.0.0 + build-depends: base ^>= 4.16.0.0 default-language: Haskell2010 default-extensions: PackageImports NoImplicitPrelude diff --git a/liquid-bytestring/liquid-bytestring.cabal b/liquid-bytestring/liquid-bytestring.cabal index 94400d4dd4..8f0c26c819 100644 --- a/liquid-bytestring/liquid-bytestring.cabal +++ b/liquid-bytestring/liquid-bytestring.cabal @@ -48,7 +48,7 @@ library hs-source-dirs: src build-depends: liquid-base < 5 - , bytestring >= 0.10.10.0 && < 0.11 + , bytestring >= 0.10.10.0 && < 0.12 , liquidhaskell >= 0.8.10.1 default-language: Haskell2010 default-extensions: PackageImports diff --git a/liquid-ghc-prim/liquid-ghc-prim.cabal b/liquid-ghc-prim/liquid-ghc-prim.cabal index 1b229d75d7..7aa2a62ddf 100644 --- a/liquid-ghc-prim/liquid-ghc-prim.cabal +++ b/liquid-ghc-prim/liquid-ghc-prim.cabal @@ -36,7 +36,7 @@ library GHC.Types hs-source-dirs: src - build-depends: ghc-prim >= 0.6.1 && < 0.8 + build-depends: ghc-prim >= 0.6.1 && < 0.9 , liquidhaskell >= 0.8.10.1 default-language: Haskell2010 default-extensions: PackageImports diff --git a/liquid-prelude/liquid-prelude.cabal b/liquid-prelude/liquid-prelude.cabal index f4e9a130d5..c81001ab29 100644 --- a/liquid-prelude/liquid-prelude.cabal +++ b/liquid-prelude/liquid-prelude.cabal @@ -29,7 +29,7 @@ library KMeansHelper hs-source-dirs: src build-depends: liquid-base < 5 - , bytestring >= 0.10.0.0 && < 0.11 + , bytestring >= 0.10.0.0 && < 0.12 , containers >= 0.6.0.0 && < 0.7 , liquidhaskell >= 0.8.10.2 default-language: Haskell2010 diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 06356a6779..55d96afd06 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -195,7 +195,7 @@ library , aeson , binary , bytestring >= 0.10 - , Cabal < 3.5 + , Cabal < 3.7 , cereal , cmdargs >= 0.10 , containers >= 0.5 @@ -205,7 +205,7 @@ library , filepath >= 1.3 , fingertree >= 0.1 , exceptions < 0.11 - , ghc ^>= 9 + , ghc ^>= 9.2 , ghc-boot , ghc-paths >= 0.1 , ghc-prim @@ -215,7 +215,7 @@ library , liquid-fixpoint >= 0.8.10.2.1 && < 0.9 , mtl >= 2.1 , optics >= 0.2 - , optparse-applicative < 0.17 + , optparse-applicative < 0.18 , githash , megaparsec >= 8 , pretty >= 1.1 diff --git a/src-ghc/Liquid/GHC/API.hs b/src-ghc/Liquid/GHC/API.hs index 66036be82e..ce19399bcf 100644 --- a/src-ghc/Liquid/GHC/API.hs +++ b/src-ghc/Liquid/GHC/API.hs @@ -23,7 +23,6 @@ module Liquid.GHC.API ( , moduleUnitId , thisPackage , renderWithStyle - , mkUserStyle , pattern LitNumber , dataConSig , getDependenciesModuleNames @@ -45,7 +44,7 @@ import GHC.Builtin.Types as Ghc import GHC.Builtin.Types.Prim as Ghc import GHC.Builtin.Utils as Ghc import GHC.Core as Ghc hiding (AnnExpr, AnnExpr' (..), AnnRec, AnnCase) -import GHC.Core.Class as Ghc +import GHC.Core.Class as Ghc hiding (FunDep) import GHC.Core.Coercion as Ghc import GHC.Core.Coercion.Axiom as Ghc import GHC.Core.ConLike as Ghc @@ -67,12 +66,10 @@ import GHC.Data.Bag as Ghc import GHC.Data.FastString as Ghc import GHC.Data.Graph.Directed as Ghc import GHC.Data.Pair as Ghc -import GHC.Driver.Finder as Ghc import GHC.Driver.Main as Ghc import GHC.Driver.Phases as Ghc (Phase(StopLn)) import GHC.Driver.Pipeline as Ghc (compileFile) -import GHC.Driver.Session as Ghc hiding (isHomeModule) -import GHC.Driver.Types as Ghc +import GHC.Driver.Session as Ghc import GHC.Driver.Monad as Ghc (withSession) import GHC.HsToCore.Monad as Ghc import GHC.Iface.Syntax as Ghc @@ -86,22 +83,44 @@ import GHC.Plugins as Ghc ( deserializeWithData , extendIdSubst , substExpr ) +import GHC.Core.FVs as Ghc (exprFreeVarsList) +import GHC.Core.Opt.OccurAnal as Ghc +import GHC.Driver.Env as Ghc +import GHC.Driver.Ppr as Ghc +import GHC.HsToCore.Expr as Ghc +import GHC.Iface.Load as Ghc +import GHC.Rename.Expr as Ghc (rnLExpr) +import GHC.Runtime.Context as Ghc +import GHC.Tc.Gen.App as Ghc (tcInferSigma) +import GHC.Tc.Gen.Bind as Ghc (tcValBinds) +import GHC.Tc.Gen.Expr as Ghc (tcInferRho) import GHC.Tc.Instance.Family as Ghc import GHC.Tc.Module as Ghc +import GHC.Tc.Solver as Ghc import GHC.Tc.Types as Ghc +import GHC.Tc.Types.Evidence as Ghc +import GHC.Tc.Types.Origin as Ghc (lexprCtOrigin) import GHC.Tc.Utils.Monad as Ghc hiding (getGHCiMonad) import GHC.Tc.Utils.TcType as Ghc (tcSplitDFunTy, tcSplitMethodTy) +import GHC.Tc.Utils.Zonk as Ghc import GHC.Types.Annotations as Ghc import GHC.Types.Avail as Ghc import GHC.Types.Basic as Ghc import GHC.Types.CostCentre as Ghc +import GHC.Types.Error as Ghc +import GHC.Types.Fixity as Ghc import GHC.Types.Id as Ghc hiding (lazySetIdInfo, setIdExported, setIdNotExported) import GHC.Types.Id.Info as Ghc import GHC.Types.Literal as Ghc hiding (LitNumber) +import qualified GHC.Types.Literal as Ghc import GHC.Types.Name as Ghc hiding (varName, isWiredIn) import GHC.Types.Name.Reader as Ghc import GHC.Types.Name.Set as Ghc +import GHC.Types.SourceError as Ghc +import GHC.Types.SourceText as Ghc import GHC.Types.SrcLoc as Ghc +import GHC.Types.Tickish as Ghc +import GHC.Types.TypeEnv as Ghc import GHC.Types.Unique as Ghc import GHC.Types.Unique.DFM as Ghc import GHC.Types.Unique.FM as Ghc @@ -110,22 +129,21 @@ import GHC.Types.Unique.Supply as Ghc import GHC.Types.Var as Ghc import GHC.Types.Var.Env as Ghc import GHC.Types.Var.Set as Ghc +import GHC.Unit.External as Ghc +import GHC.Unit.Finder as Ghc +import GHC.Unit.Home.ModInfo as Ghc import GHC.Unit.Module as Ghc +import GHC.Unit.Module.Deps as Ghc +import GHC.Unit.Module.Graph as Ghc +import GHC.Unit.Module.ModDetails as Ghc +import GHC.Unit.Module.ModGuts as Ghc +import GHC.Unit.Module.ModSummary as Ghc import GHC.Utils.Error as Ghc -import GHC.Utils.Outputable as Ghc hiding ((<>), integer, renderWithStyle, mkUserStyle) +import GHC.Utils.Logger as Ghc +import GHC.Utils.Misc as Ghc (zipEqual) +import GHC.Utils.Outputable as Ghc (mkUserStyle) +import GHC.Utils.Outputable as Ghc hiding ((<>), integer, mkUserStyle) import GHC.Utils.Panic as Ghc -import qualified GHC.Types.Literal as Ghc -import qualified GHC.Utils.Outputable as Ghc -import GHC.Tc.Types.Origin as Ghc (lexprCtOrigin) -import GHC.Rename.Expr as Ghc (rnLExpr) -import GHC.Tc.Gen.Expr as Ghc (tcInferSigma, tcInferRho) -import GHC.Tc.Gen.Bind as Ghc (tcValBinds) -import GHC.Tc.Solver as Ghc -import GHC.Tc.Utils.Zonk as Ghc -import GHC.Core.FVs as Ghc (exprFreeVarsList) -import GHC.Tc.Types.Evidence as Ghc -import GHC.HsToCore.Expr as Ghc -import GHC.Core.Opt.OccurAnal as Ghc -- 'fsToUnitId' is gone in GHC 9, but we can bring code it in terms of 'fsToUnit' and 'toUnitId'. fsToUnitId :: FastString -> UnitId @@ -135,7 +153,7 @@ moduleUnitId :: Module -> UnitId moduleUnitId = toUnitId . moduleUnit thisPackage :: DynFlags -> UnitId -thisPackage = toUnitId . homeUnit +thisPackage = homeUnitId_ -- See NOTE [tyConRealArity]. tyConRealArity :: TyCon -> Int @@ -143,7 +161,7 @@ tyConRealArity tc = go 0 (tyConKind tc) where go :: Int -> Kind -> Int go !acc k = - case asum [fmap (view _3) (splitFunTy_maybe k), fmap snd (splitForAllTy_maybe k)] of + case asum [fmap (view _3) (splitFunTy_maybe k), fmap snd (splitForAllTyCoVar_maybe k)] of Nothing -> acc Just ks -> go (acc + 1) ks @@ -154,10 +172,7 @@ getDependenciesModuleNames :: Dependencies -> [ModuleNameWithIsBoot] getDependenciesModuleNames = dep_mods renderWithStyle :: DynFlags -> SDoc -> PprStyle -> String -renderWithStyle dynflags sdoc style = Ghc.renderWithStyle (Ghc.initSDocContext dynflags style) sdoc - -mkUserStyle :: DynFlags -> PrintUnqualified -> Depth -> PprStyle -mkUserStyle _ = Ghc.mkUserStyle +renderWithStyle dynflags sdoc style = Ghc.renderWithContext (Ghc.initSDocContext dynflags style) sdoc -- -- Literal diff --git a/src-ghc/Liquid/GHC/API/StableModule.hs b/src-ghc/Liquid/GHC/API/StableModule.hs index d048cc415b..72568af491 100644 --- a/src-ghc/Liquid/GHC/API/StableModule.hs +++ b/src-ghc/Liquid/GHC/API/StableModule.hs @@ -38,15 +38,12 @@ moduleUnitId = GHC.toUnitId . GHC.moduleUnit renderModule :: GHC.Module -> String renderModule m = "Module { unitId = " <> (GHC.unitIdString . moduleUnitId $ m) - <> ", name = " <> show (GHC.moduleName m) + <> ", name = " <> GHC.moduleNameString (GHC.moduleName m) <> " }" -- These two orphans originally lived inside module 'Language.Haskell.Liquid.Types.Types'. instance Hashable GHC.ModuleName where - hashWithSalt i = hashWithSalt i . show - -instance Show GHC.ModuleName where - show = GHC.moduleNameString + hashWithSalt i = hashWithSalt i . GHC.moduleNameString instance Hashable StableModule where hashWithSalt s (StableModule mdl) = hashWithSalt s (GHC.moduleStableString mdl) diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index 9797c6eb67..f97a61d85c 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -28,14 +28,13 @@ module Liquid.GHC.GhcMonadLike ( , findModule , lookupModule , isBootInterface + , ApiComment(..) , apiComments ) where import Control.Monad.IO.Class import Control.Exception (throwIO) -import Data.IORef (readIORef) - import qualified Liquid.GHC.API as Ghc import Liquid.GHC.API hiding ( ModuleInfo , findModule @@ -59,7 +58,6 @@ import GHC.Utils.Exception (ExceptionMonad) import qualified GHC.Core.Opt.Monad as CoreMonad import qualified GHC.Data.EnumSet as EnumSet -import qualified Data.Map.Strict as M import Optics class HasHscEnv m where @@ -107,10 +105,10 @@ getModSummary mdl = do , not (isBootInterface . isBootSummary $ ms) ] case mods_by_name of [] -> do dflags <- getDynFlags - liftIO $ throwIO $ mkApiErr dflags (text "Module not part of module graph") + liftIO $ throwIO $ GhcApiError (showSDoc dflags (text "Module not part of module graph")) [ms] -> return ms multiple -> do dflags <- getDynFlags - liftIO $ throwIO $ mkApiErr dflags (text "getModSummary is ambiguous: " <+> ppr multiple) + liftIO $ throwIO $ GhcApiError (showSDoc dflags (text "getModSummary is ambiguous: " <+> ppr multiple)) -- Converts a 'IsBootInterface' into a 'Bool'. @@ -132,7 +130,7 @@ lookupModSummary mdl = do lookupGlobalName :: GhcMonadLike m => Name -> m (Maybe TyThing) lookupGlobalName name = do hsc_env <- askHscEnv - liftIO $ lookupTypeHscEnv hsc_env name + liftIO $ lookupType hsc_env name -- NOTE(adn) Taken from the GHC API, adapted to work for a 'GhcMonadLike' monad. lookupName :: GhcMonadLike m => Name -> m (Maybe TyThing) @@ -153,9 +151,8 @@ modInfoLookupName minf name = do hsc_env <- askHscEnv case lookupTypeEnv (minf_type_env minf) name of Just tyThing -> return (Just tyThing) - Nothing -> do - eps <- liftIO $ readIORef (hsc_EPS hsc_env) - return $! lookupType (hsc_dflags hsc_env) (hsc_HPT hsc_env) (eps_PTE eps) name + Nothing -> liftIO $ do + lookupType hsc_env name moduleInfoTc :: GhcMonadLike m => ModSummary -> TcGblEnv -> m ModuleInfo moduleInfoTc ms tcGblEnv = do @@ -172,8 +169,7 @@ parseModule ms = do hsc_env <- askHscEnv let hsc_env_tmp = hsc_env { hsc_dflags = ms_hspp_opts ms } hpm <- liftIO $ hscParse hsc_env_tmp ms - return (ParsedModule ms (hpm_module hpm) (hpm_src_files hpm) - (hpm_annotations hpm)) + return (ParsedModule ms (hpm_module hpm) (hpm_src_files hpm)) -- | Our own simplified version of 'TypecheckedModule'. data TypecheckedModule = TypecheckedModule { @@ -194,8 +190,7 @@ typecheckModule pmod = do (tc_gbl_env, rn_info) <- liftIO $ hscTypecheckRename hsc_env_tmp ms $ HsParsedModule { hpm_module = parsedSource pmod, - hpm_src_files = pm_extra_src_files pmod, - hpm_annotations = pm_annotations pmod } + hpm_src_files = pm_extra_src_files pmod } return TypecheckedModule { tm_parsed_module = pmod , tm_renamed_source = rn_info @@ -249,13 +244,13 @@ findModule mod_name maybe_pkg = do let dflags = hsc_dflags hsc_env this_pkg = thisPackage dflags - -- + throwNoModError err = throwOneError $ noModError hsc_env noSrcSpan mod_name err case maybe_pkg of Just pkg | fsToUnitId pkg /= this_pkg && pkg /= fsLit "this" -> liftIO $ do res <- findImportedModule hsc_env mod_name maybe_pkg case res of Found _ m -> return m - err -> throwOneError $ noModError dflags noSrcSpan mod_name err + err -> throwNoModError err _otherwise -> do home <- lookupLoadedHomeModule mod_name case home of @@ -265,7 +260,7 @@ findModule mod_name maybe_pkg = do case res of Found loc m | moduleUnitId m /= this_pkg -> return m | otherwise -> modNotLoadedError dflags m loc - err -> throwOneError $ noModError dflags noSrcSpan mod_name err + err -> throwNoModError err lookupLoadedHomeModule :: GhcMonadLike m => ModuleName -> m (Maybe Module) @@ -294,14 +289,27 @@ lookupModule mod_name Nothing = do res <- findExposedPackageModule hsc_env mod_name Nothing case res of Found _ m -> return m - err -> throwOneError $ noModError (hsc_dflags hsc_env) noSrcSpan mod_name err - --- Compatibility shim to extract the comments out of an 'ApiAnns', as modern GHCs now puts the --- comments (i.e. Haskell comments) in a different field ('apiAnnRogueComments'). -apiComments :: ApiAnns -> [Ghc.Located AnnotationComment] -apiComments apiAnns = - let comments = concat . M.elems . apiAnnComments $ apiAnns - in - map toRealSrc $ mappend comments (apiAnnRogueComments apiAnns) + err -> + throwOneError $ noModError hsc_env noSrcSpan mod_name err + +-- | Abstraction of 'EpaComment'. +data ApiComment + = ApiLineComment String + | ApiBlockComment String + +-- | Extract top-level comments from a module. +apiComments :: ParsedModule -> [Ghc.Located ApiComment] +apiComments pm = + case pm_parsed_source pm of + L _ (HsModule { hsmodAnn = anns' }) -> + mapMaybe (tokComment . toRealSrc) $ + priorComments $ + epAnnComments anns' where - toRealSrc (L x e) = L (RealSrcSpan x Nothing) e + tokComment (L sp (EpaComment (EpaLineComment s) _)) = Just (L sp (ApiLineComment s)) + tokComment (L sp (EpaComment (EpaBlockComment s) _)) = Just (L sp (ApiBlockComment s)) + tokComment _ = Nothing + + -- TODO: take into account anchor_op, which only matters if the source was + -- pre-processed by an exact-print-aware tool. + toRealSrc (L a e) = L (RealSrcSpan (anchor a) Nothing) e diff --git a/src-ghc/Liquid/GHC/Interface.hs b/src-ghc/Liquid/GHC/Interface.hs index 8b8dddbb56..25ec16efb3 100644 --- a/src-ghc/Liquid/GHC/Interface.hs +++ b/src-ghc/Liquid/GHC/Interface.hs @@ -12,6 +12,7 @@ {-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wwarn=deprecations #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Liquid.GHC.Interface ( @@ -219,8 +220,11 @@ updateIncludePaths df ps = addGlobalInclude (includePaths df) ps configureDynFlags :: Config -> FilePath -> Ghc DynFlags configureDynFlags cfg tmp = do df <- getSessionDynFlags - (df',_,_) <- parseDynamicFlags df $ map noLoc $ ghcOptions cfg + logger <- getLogger + (df',_,_) <- parseDynamicFlags logger df $ map noLoc $ ghcOptions cfg loud <- liftIO isLoud + pushLogHookM $ \_ -> + if loud then defaultLogAction else \_ _ _ _ _ -> return () let df'' = df' { importPaths = nub $ idirs cfg ++ importPaths df' , libraryPaths = nub $ idirs cfg ++ libraryPaths df' , includePaths = updateIncludePaths df' (idirs cfg) -- addGlobalInclude (includePaths df') (idirs cfg) @@ -232,12 +236,8 @@ configureDynFlags cfg tmp = do , debugLevel = 1 -- insert SourceNotes -- , profAuto = ProfAutoCalls , ghcLink = LinkInMemory - , hscTarget = HscInterpreted + , backend = Interpreter , ghcMode = CompManager - -- prevent GHC from printing anything, unless in Loud mode - , log_action = if loud - then defaultLogAction - else \_ _ _ _ _ -> return () -- redirect .hi/.o/etc files to temp directory , objectDir = Just tmp , hiDir = Just tmp @@ -258,11 +258,12 @@ configureGhcTargets tgtFiles = do moduleGraph <- depanal [] False -- see [NOTE:DROP-BOOT-FILES] let homeModules = filter (not . isBootInterface . isBootSummary) $ - flattenSCCs $ topSortModuleGraph False moduleGraph Nothing + flattenSCCs $ filterToposortToModules $ + topSortModuleGraph False moduleGraph Nothing let homeNames = moduleName . ms_mod <$> homeModules _ <- setTargetModules homeNames liftIO $ whenLoud $ print ("Module Dependencies" :: String, homeNames) - return $ mkModuleGraph homeModules + return $ mkModuleGraph (map Ghc.extendModSummaryNoDeps homeModules) setTargetModules :: [ModuleName] -> Ghc () setTargetModules modNames = setTargets $ mkTarget <$> modNames @@ -334,7 +335,7 @@ importDeclModule fromMod (mpkgQual, locModName) = do dflags <- getDynFlags liftIO $ throwGhcExceptionIO $ ProgramError $ O.showPpr dflags (moduleName fromMod) ++ ": " ++ - O.showSDoc dflags (cannotFindModule dflags modName res) + O.showSDoc dflags (cannotFindModule hscEnv modName res) -------------------------------------------------------------------------------- -- | Extract Ids --------------------------------------------------------------- @@ -408,7 +409,7 @@ processModule cfg logicMap tgtFiles depGraph specEnv modSummary = do let isTarget' = file `S.member` tgtFiles _ <- loadDependenciesOf $ moduleName mod' parsed <- parseModule $ keepRawTokenStream modSummary - let specComments = extractSpecComments (pm_annotations parsed) + let specComments = extractSpecComments parsed typechecked <- typecheckModule $ ignoreInline parsed let specQuotes = extractSpecQuotes typechecked _ <- loadModule' typechecked @@ -445,7 +446,7 @@ loadModule' tm = loadModule tm' pm = tm_parsed_module tm ms = pm_mod_summary pm df = ms_hspp_opts ms - df' = df { hscTarget = HscNothing, ghcLink = NoLink } + df' = df { backend = NoBackend, ghcLink = NoLink } ms' = ms { ms_hspp_opts = df' } pm' = pm { pm_mod_summary = ms' } tm' = tm { tm_parsed_module = pm' } @@ -495,14 +496,21 @@ processTargetModule cfg0 logicMap depGraph specEnv file typechecked bareSpec = d (msgs, specM) <- Ghc.withSession $ \hsc_env -> liftIO $ runTcInteractive hsc_env (makeTargetSpec cfg logicMap targetSrc (view bareSpecIso bareSpec) dependencies) case specM of - Nothing -> panic Nothing $ O.showSDoc dynFlags $ O.sep (Ghc.pprErrMsgBagWithLoc (snd msgs)) - Just spec -> + Nothing -> + panic Nothing $ + O.showSDoc dynFlags $ + O.sep $ + Ghc.pprMsgEnvelopeBagWithLoc + -- TODO use getMessages from GHC 9.4 onwards. + (Ghc.getErrorMessages msgs `Ghc.unionBags` Ghc.getWarningMessages msgs) + Just spec -> do + logger <- getLogger case spec of Left diagnostics -> do - mapM_ (liftIO . printWarning dynFlags) (allWarnings diagnostics) + mapM_ (liftIO . printWarning logger dynFlags) (allWarnings diagnostics) throw (allErrors diagnostics) Right (warns, targetSpec, liftedSpec) -> do - mapM_ (liftIO . printWarning dynFlags) warns + mapM_ (liftIO . printWarning logger dynFlags) warns -- The call below is temporary, we should really load & save directly 'LiftedSpec's. _ <- liftIO $ saveLiftedSpec (_giTarget ghcSrc) (unsafeFromLiftedSpec liftedSpec) return $ TargetInfo targetSrc targetSpec @@ -646,7 +654,7 @@ lookupTyThings hscEnv modSum tcGblEnv = forM names (lookupTyThing hscEnv modSum where names :: [Ghc.Name] names = liftM2 (++) - (fmap Ghc.gre_name . Ghc.globalRdrEnvElts . tcg_rdr_env) + (fmap Ghc.greMangledName . Ghc.globalRdrEnvElts . tcg_rdr_env) (fmap is_dfun_name . tcg_insts) tcGblEnv -- | Lookup a single 'Name' in the GHC environment, yielding back the 'Name' alongside the 'TyThing', -- if one is found. @@ -662,8 +670,11 @@ lookupTyThing hscEnv modSum tcGblEnv n = do availableTyThings :: GhcMonadLike m => HscEnv -> ModSummary -> TcGblEnv -> [AvailInfo] -> m [TyThing] availableTyThings hscEnv modSum tcGblEnv avails = fmap (catMaybes . mconcat) $ forM avails $ \a -> do results <- case a of - Avail n -> pure <$> lookupTyThing hscEnv modSum tcGblEnv n - AvailTC n ns _ -> forM (n : ns) $ lookupTyThing hscEnv modSum tcGblEnv + Avail n -> + pure <$> lookupTyThing hscEnv modSum tcGblEnv (Ghc.greNameMangledName n) + AvailTC n ns -> + forM (n : map Ghc.greNameMangledName ns) $ + lookupTyThing hscEnv modSum tcGblEnv pure . map snd $ results -- | Returns all the available (i.e. exported) 'TyCon's (type constructors) for the input 'Module'. @@ -720,7 +731,7 @@ _dumpRdrEnv _hscEnv modGuts = do _hscNames = fmap showPpr . Ghc.ic_tythings . Ghc.hsc_IC mgNames :: MGIModGuts -> [Ghc.Name] -mgNames = fmap Ghc.gre_name . Ghc.globalRdrEnvElts . mgi_rdr_env +mgNames = fmap Ghc.greMangledName . Ghc.globalRdrEnvElts . mgi_rdr_env --------------------------------------------------------------------------------------- -- | @makeDependencies@ loads BareSpec for target and imported modules @@ -804,7 +815,7 @@ getFamInstances env = do -------------------------------------------------------------------------------- -- | Extract Specifications from GHC ------------------------------------------- -------------------------------------------------------------------------------- -extractSpecComments :: ApiAnns -> [(SourcePos, String)] +extractSpecComments :: ParsedModule -> [(SourcePos, String)] extractSpecComments = mapMaybe extractSpecComment . GhcMonadLike.apiComments -- | 'extractSpecComment' pulls out the specification part from a full comment @@ -813,8 +824,8 @@ extractSpecComments = mapMaybe extractSpecComment . GhcMonadLike.apiComments -- 2. '{-@ ... -}' then it throws a malformed SPECIFICATION ERROR, and -- 3. Otherwise it is just treated as a plain comment so we return Nothing. -extractSpecComment :: Ghc.Located AnnotationComment -> Maybe (SourcePos, String) -extractSpecComment (Ghc.L sp (AnnBlockComment txt)) +extractSpecComment :: Ghc.Located GhcMonadLike.ApiComment -> Maybe (SourcePos, String) +extractSpecComment (Ghc.L sp (GhcMonadLike.ApiBlockComment txt)) | isPrefixOf "{-@" txt && isSuffixOf "@-}" txt -- valid specification = Just (offsetPos, take (length txt - 6) $ drop 3 txt) | isPrefixOf "{-@" txt -- invalid specification diff --git a/src-ghc/Liquid/GHC/Logging.hs b/src-ghc/Liquid/GHC/Logging.hs index 94889c40a8..e64b9b2b4a 100644 --- a/src-ghc/Liquid/GHC/Logging.hs +++ b/src-ghc/Liquid/GHC/Logging.hs @@ -27,26 +27,28 @@ fromPJDoc = GHC.text . PJ.render -- | Like the original 'putLogMsg', but internally converts the input 'Doc' (from the \"pretty\" library) -- into GHC's internal 'SDoc'. -putLogMsg :: GHC.DynFlags +putLogMsg :: GHC.Logger + -> GHC.DynFlags -> GHC.WarnReason -> GHC.Severity -> GHC.SrcSpan -> Maybe GHC.PprStyle -> PJ.Doc -> IO () -putLogMsg dynFlags reason sev srcSpan _mbStyle = - GHC.putLogMsg dynFlags reason sev srcSpan . GHC.text . PJ.render +putLogMsg logger dynFlags reason sev srcSpan _mbStyle = + GHC.putLogMsg logger dynFlags reason sev srcSpan . GHC.text . PJ.render defaultErrStyle :: GHC.DynFlags -> GHC.PprStyle defaultErrStyle _dynFlags = GHC.defaultErrStyle -putWarnMsg :: GHC.DynFlags -> GHC.SrcSpan -> PJ.Doc -> IO () -putWarnMsg dynFlags srcSpan doc = - putLogMsg dynFlags GHC.NoReason GHC.SevWarning srcSpan (Just $ defaultErrStyle dynFlags) doc +putWarnMsg :: GHC.Logger -> GHC.DynFlags -> GHC.SrcSpan -> PJ.Doc -> IO () +putWarnMsg logger dynFlags srcSpan doc = + putLogMsg logger dynFlags GHC.NoReason GHC.SevWarning srcSpan (Just $ defaultErrStyle dynFlags) doc -putErrMsg :: GHC.DynFlags -> GHC.SrcSpan -> PJ.Doc -> IO () -putErrMsg dynFlags srcSpan doc = putLogMsg dynFlags GHC.NoReason GHC.SevError srcSpan Nothing doc +putErrMsg :: GHC.Logger -> GHC.DynFlags -> GHC.SrcSpan -> PJ.Doc -> IO () +putErrMsg logger dynFlags srcSpan doc = + putLogMsg logger dynFlags GHC.NoReason GHC.SevError srcSpan Nothing doc -- | Like GHC's 'mkLongErrAt', but it builds the final 'ErrMsg' out of two \"HughesPJ\"'s 'Doc's. -mkLongErrAt :: GHC.SrcSpan -> PJ.Doc -> PJ.Doc -> GHC.TcRn GHC.ErrMsg +mkLongErrAt :: GHC.SrcSpan -> PJ.Doc -> PJ.Doc -> GHC.TcRn (GHC.MsgEnvelope GHC.DecoratedSDoc) mkLongErrAt srcSpan msg extra = GHC.mkLongErrAt srcSpan (fromPJDoc msg) (fromPJDoc extra) diff --git a/src-ghc/Liquid/GHC/Misc.hs b/src-ghc/Liquid/GHC/Misc.hs index 9d63845009..2f3f7c52d0 100644 --- a/src-ghc/Liquid/GHC/Misc.hs +++ b/src-ghc/Liquid/GHC/Misc.hs @@ -71,10 +71,10 @@ mkAlive x -------------------------------------------------------------------------------- -- | Encoding and Decoding Location -------------------------------------------- -------------------------------------------------------------------------------- -srcSpanTick :: Module -> SrcSpan -> Tickish a +srcSpanTick :: Module -> SrcSpan -> CoreTickish srcSpanTick m sp = ProfNote (AllCafsCC m sp) False True -tickSrcSpan :: Outputable a => Tickish a -> SrcSpan +tickSrcSpan :: CoreTickish -> SrcSpan tickSrcSpan (ProfNote cc _ _) = cc_loc cc tickSrcSpan (SourceNote ss _) = RealSrcSpan ss Nothing tickSrcSpan _ = noSrcSpan @@ -156,7 +156,7 @@ unTickExpr (App e a) = App (unTickExpr e) (unTickExpr a) unTickExpr (Lam b e) = Lam b (unTickExpr e) unTickExpr (Let b e) = Let (unTick b) (unTickExpr e) unTickExpr (Case e b t as) = Case (unTickExpr e) b t (map unTickAlt as) - where unTickAlt (a, b', e') = (a, b', unTickExpr e') + where unTickAlt (Alt a b' e') = Alt a b' (unTickExpr e') unTickExpr (Cast e c) = Cast (unTickExpr e) c unTickExpr (Tick _ e) = unTickExpr e unTickExpr x = x @@ -196,14 +196,17 @@ showPpr = showSDoc . ppr -- FIXME: somewhere we depend on this printing out all GHC entities with -- fully-qualified names... showSDoc :: Ghc.SDoc -> String -showSDoc sdoc = Ghc.renderWithStyle unsafeGlobalDynFlags sdoc (Ghc.mkUserStyle unsafeGlobalDynFlags myQualify {- Ghc.alwaysQualify -} Ghc.AllTheWay) +showSDoc = Ghc.renderWithContext ctx + where + style = Ghc.mkUserStyle myQualify Ghc.AllTheWay + ctx = Ghc.defaultSDocContext { sdocStyle = style } myQualify :: Ghc.PrintUnqualified myQualify = Ghc.neverQualify { Ghc.queryQualifyName = Ghc.alwaysQualifyNames } -- { Ghc.queryQualifyName = \_ _ -> Ghc.NameNotInScope1 } showSDocDump :: Ghc.SDoc -> String -showSDocDump = Ghc.showSDocDump unsafeGlobalDynFlags +showSDocDump = Ghc.showSDocDump Ghc.defaultSDocContext instance Outputable a => Outputable (S.HashSet a) where ppr = ppr . S.toList @@ -248,7 +251,7 @@ srcSpanFSrcSpan sp = F.SS p p' p' = srcSpanSourcePosE sp sourcePos2SrcSpan :: SourcePos -> SourcePos -> SrcSpan -sourcePos2SrcSpan p p' = RealSrcSpan (realSrcSpan f (unPos l) (unPos c) (unPos l') (unPos c')) Nothing +sourcePos2SrcSpan p p' = RealSrcSpan (packRealSrcSpan f (unPos l) (unPos c) (unPos l') (unPos c')) Nothing where (f, l, c) = F.sourcePosElts p (_, l', c') = F.sourcePosElts p' @@ -431,11 +434,11 @@ lookupRdrName hsc_env mod_name rdr_name = do Nothing -> mkGlobalRdrEnv (gresFromAvails provenance (mi_exports iface)) Just e -> e case lookupGRE_RdrName rdr_name env of - [gre] -> return (Just (gre_name gre)) +-- XXX [gre] -> return (Just (gre_name gre)) [] -> return Nothing _ -> Ghc.panic "lookupRdrNameInModule" Nothing -> throwCmdLineErrorS dflags $ Ghc.hsep [Ghc.ptext (sLit "Could not determine the exports of the module"), ppr mod_name] - err' -> throwCmdLineErrorS dflags $ cannotFindModule dflags mod_name err' + err' -> throwCmdLineErrorS dflags $ cannotFindModule hsc_env mod_name err' where dflags = hsc_dflags hsc_env throwCmdLineErrorS dflags' = throwCmdLineError . Ghc.showSDoc dflags' throwCmdLineError = throwGhcException . CmdLineError @@ -724,20 +727,22 @@ gHC_VERSION = show (__GLASGOW_HASKELL__ :: Int) symbolFastString :: Symbol -> FastString symbolFastString = mkFastStringByteString . T.encodeUtf8 . symbolText -lintCoreBindings :: [Var] -> CoreProgram -> (Bag MsgDoc, Bag MsgDoc) +lintCoreBindings :: [Var] -> CoreProgram -> (Bag SDoc, Bag SDoc) lintCoreBindings = Ghc.lintCoreBindings (defaultDynFlags undefined (undefined ("LlvmTargets" :: String))) CoreDoNothing synTyConRhs_maybe :: TyCon -> Maybe Type synTyConRhs_maybe = Ghc.synTyConRhs_maybe -tcRnLookupRdrName :: HscEnv -> Ghc.Located RdrName -> IO (Messages, Maybe [Name]) +tcRnLookupRdrName :: HscEnv -> Ghc.LocatedN RdrName -> IO (Messages DecoratedSDoc, Maybe [Name]) tcRnLookupRdrName = Ghc.tcRnLookupRdrName showCBs :: Bool -> [CoreBind] -> String showCBs untidy - | untidy = Ghc.showSDocDebug unsafeGlobalDynFlags . ppr . tidyCBs + | untidy = + Ghc.renderWithContext ctx . ppr . tidyCBs | otherwise = showPpr - + where + ctx = Ghc.defaultSDocContext { sdocPprDebug = True } ignoreCoreBinds :: S.HashSet Var -> [CoreBind] -> [CoreBind] ignoreCoreBinds vs cbs @@ -904,43 +909,31 @@ isEvVar x = isPredVar x || isTyVar x || isCoVar x -- hsc_env <- Ghc.getHscEnv -- liftIO $ elabRnExpr hsc_env mode expr -elabRnExpr - :: TcRnExprMode -> LHsExpr GhcPs -> TcRn CoreExpr -elabRnExpr mode rdr_expr = do +elabRnExpr :: LHsExpr GhcPs -> TcRn CoreExpr +elabRnExpr rdr_expr = do (rn_expr, _fvs) <- rnLExpr rdr_expr failIfErrsM - -- Now typecheck the expression, and generalise its type - -- it might have a rank-2 type (e.g. :t runST) - uniq <- newUnique ; - let fresh_it = itName uniq (getLoc rdr_expr) + -- Typecheck the expression ((tclvl, (tc_expr, res_ty)), lie) <- captureTopConstraints $ pushTcLevelM $ - tc_infer rn_expr + tcInferRho rn_expr -- Generalise - (_qtvs, _dicts, evbs, residual, _) - <- simplifyInfer tclvl infer_mode + uniq <- newUnique + let { fresh_it = itName uniq (getLocA rdr_expr) } + ((_qtvs, _dicts, evbs, _), residual) + <- captureConstraints $ + simplifyInfer tclvl NoRestrictions [] {- No sig vars -} [(fresh_it, res_ty)] lie -- Ignore the dictionary bindings - evbs' <- perhaps_disable_default_warnings $ - simplifyInteractive residual + evbs' <- simplifyInteractive residual full_expr <- zonkTopLExpr (mkHsDictLet (EvBinds evbs') (mkHsDictLet evbs tc_expr)) initDsTc $ dsLExpr full_expr - where - tc_infer expr' | inst = tcInferRho expr' - | otherwise = tcInferSigma expr' - -- tcInferSigma: see Note [Implementing :type] - - -- See Note [TcRnExprMode] - (inst, infer_mode, perhaps_disable_default_warnings) = case mode of - TM_Inst -> (True, NoRestrictions, id) - TM_NoInst -> (False, NoRestrictions, id) - TM_Default -> (True, EagerDefaulting, unsetWOptM Opt_WarnTypeDefaults) newtype HashableType = HashableType {getHType :: Type} @@ -1024,20 +1017,17 @@ withWiredIn m = discardConstraints $ do -- (Ghc.NonRecursive, unitBag (Ghc.L locSpan b)) -- ) wiredIns - sigsExt ext wiredIns = concatMap (\w -> - let inf = maybeToList $ (\(fPrec, fDir) -> Ghc.L locSpan $ FixSig Ghc.noExtField $ FixitySig Ghc.noExtField [Ghc.L locSpan (tcWiredInName w)] $ Ghc.Fixity Ghc.NoSourceText fPrec fDir) <$> tcWiredInFixity w in + sigs wiredIns = concatMap (\w -> + let inf = maybeToList $ (\(fPrec, fDir) -> Ghc.L locSpanAnn $ Ghc.FixSig Ghc.noAnn $ Ghc.FixitySig Ghc.noExtField [Ghc.L locSpanAnn (tcWiredInName w)] $ Ghc.Fixity Ghc.NoSourceText fPrec fDir) <$> tcWiredInFixity w in let t = let ext' = [] in - [Ghc.L locSpan $ TypeSig Ghc.noExtField [Ghc.L locSpan (tcWiredInName w)] $ HsWC ext' $ HsIB ext $ tcWiredInType w] + [Ghc.L locSpanAnn $ TypeSig Ghc.noAnn [Ghc.L locSpanAnn (tcWiredInName w)] $ HsWC ext' $ Ghc.L locSpanAnn $ HsSig Ghc.noExtField (HsOuterImplicit ext') $ tcWiredInType w] in inf <> t ) wiredIns - sigs = sigsExt cppExt - - cppExt = [] - locSpan = UnhelpfulSpan (UnhelpfulOther "Liquid.GHC.Misc: WiredIn") + locSpanAnn = noAnnSrcSpan locSpan mkHsFunTy :: LHsType GhcRn -> LHsType GhcRn -> LHsType GhcRn mkHsFunTy a b = nlHsFunTy a b @@ -1048,8 +1038,8 @@ withWiredIn m = discardConstraints $ do u <- getUniqueM return $ Ghc.mkInternalName u (Ghc.mkVarOcc s) locSpan - toLoc = Ghc.L locSpan - nameToTy = Ghc.L locSpan . HsTyVar Ghc.noExtField Ghc.NotPromoted + toLoc = Ghc.L locSpanAnn + nameToTy = Ghc.L locSpanAnn . HsTyVar Ghc.noAnn Ghc.NotPromoted boolTy' :: LHsType GhcRn boolTy' = nameToTy $ toLoc boolTyConName @@ -1073,21 +1063,20 @@ withWiredIn m = discardConstraints $ do -- infix 4 == :: forall a . a -> a -> Bool eq = do n <- toName "==" - aName <- Ghc.L locSpan <$> toName "a" + aName <- toLoc <$> toName "a" let aTy = nameToTy aName - let ty = noLoc $ HsForAllTy Ghc.noExtField - (mkHsForAllInvisTele [Ghc.L locSpan $ UserTyVar Ghc.noExtField SpecifiedSpec aName]) $ mkHsFunTy aTy (mkHsFunTy aTy boolTy') + let ty = toLoc $ HsForAllTy Ghc.noExtField + (mkHsForAllInvisTele Ghc.noAnn [toLoc $ UserTyVar Ghc.noAnn SpecifiedSpec aName]) $ mkHsFunTy aTy (mkHsFunTy aTy boolTy') return $ TcWiredIn n (Just (4, Ghc.InfixN)) ty -- TODO: This is defined as a measure in liquid-base GHC.Base. We probably want to insert all measures to the environment. -- len :: forall a. [a] -> Int len = do n <- toName "len" - aName <- Ghc.L locSpan <$> toName "a" + aName <- toLoc <$> toName "a" let aTy = nameToTy aName - let ty = - noLoc $ HsForAllTy Ghc.noExtField - (mkHsForAllInvisTele [Ghc.L locSpan $ UserTyVar Ghc.noExtField SpecifiedSpec aName]) $ mkHsFunTy (listTy aTy) intTy' + let ty = toLoc $ HsForAllTy Ghc.noExtField + (mkHsForAllInvisTele Ghc.noAnn [toLoc $ UserTyVar Ghc.noAnn SpecifiedSpec aName]) $ mkHsFunTy (listTy aTy) intTy' return $ TcWiredIn n Nothing ty prependGHCRealQual :: FastString -> RdrName diff --git a/src-ghc/Liquid/GHC/Play.hs b/src-ghc/Liquid/GHC/Play.hs index 1194703c98..7dced56c34 100644 --- a/src-ghc/Liquid/GHC/Play.hs +++ b/src-ghc/Liquid/GHC/Play.hs @@ -187,8 +187,8 @@ instance Subable Coercion where subTy _ _ = panic Nothing "subTy Coercion" instance Subable (Alt Var) where - sub s (a, b, e) = (a, map (sub s) b, sub s e) - subTy s (a, b, e) = (a, map (subTy s) b, subTy s e) + sub s (Alt a b e) = Alt a (map (sub s) b) (sub s e) + subTy s (Alt a b e) = Alt a (map (subTy s) b) (subTy s e) instance Subable Var where sub s v | M.member v s = subVar $ s M.! v @@ -230,7 +230,7 @@ substExpr s = go go (Lam x e) = Lam (subsVar x) (go e) go (Let (NonRec x ex) e) = Let (NonRec (subsVar x) (go ex)) (go e) go (Let (Rec xes) e) = Let (Rec [(subsVar x', go e') | (x',e') <- xes]) (go e) - go (Case e b t alts) = Case (go e) (subsVar b) t [(c, subsVar <$> xs, go e') | (c, xs, e') <- alts] + go (Case e b t alts) = Case (go e) (subsVar b) t [Alt c (subsVar <$> xs) (go e') | Alt c xs e' <- alts] go (Cast e c) = Cast (go e) c go (Tick t e) = Tick t (go e) go (Type t) = Type t diff --git a/src-ghc/Liquid/GHC/Resugar.hs b/src-ghc/Liquid/GHC/Resugar.hs index 2f5e7a34c4..7e3ad4580f 100644 --- a/src-ghc/Liquid/GHC/Resugar.hs +++ b/src-ghc/Liquid/GHC/Resugar.hs @@ -104,7 +104,7 @@ exprArgs _e (Var op, [Type m, d, Type a, Type b, e1, Lam x e2]) | op `is` Ghc.bindMName = Just (PatBind e1 x e2 m d a b op) -exprArgs (Case (Var xe) x t [(DataAlt c, ys, Var y)]) _ +exprArgs (Case (Var xe) x t [Alt (DataAlt c) ys (Var y)]) _ | Just i <- y `L.elemIndex` ys = Just (PatProject xe x t c ys i) @@ -153,7 +153,7 @@ lower (PatReturn e m d t op) = Ghc.mkCoreApps (Var op) [Type m, d, Type t, e] lower (PatProject xe x t c ys i) - = Case (Var xe) x t [(DataAlt c, ys, Var yi)] where yi = ys !! i + = Case (Var xe) x t [Alt (DataAlt c) ys (Var yi)] where yi = ys !! i lower (PatSelfBind x e) = Let (NonRec x e) (Var x) diff --git a/src-ghc/Liquid/GHC/SpanStack.hs b/src-ghc/Liquid/GHC/SpanStack.hs index 021c8ed484..2767ca2f0f 100644 --- a/src-ghc/Liquid/GHC/SpanStack.hs +++ b/src-ghc/Liquid/GHC/SpanStack.hs @@ -43,8 +43,8 @@ push !s stk -- @(SpanStack stk) -- | A single span data Span - = Var !Ghc.Var -- ^ binder for whom we are generating constraint - | Tick !(Ghc.Tickish Ghc.Var) -- ^ nearest known Source Span + = Var !Ghc.Var -- ^ binder for whom we are generating constraint + | Tick !Ghc.CoreTickish -- ^ nearest known Source Span | Span SrcSpan instance Show Span where diff --git a/src/Language/Haskell/Liquid/Bare/Axiom.hs b/src/Language/Haskell/Liquid/Bare/Axiom.hs index e5e4f1c66d..4412425a2f 100644 --- a/src/Language/Haskell/Liquid/Bare/Axiom.hs +++ b/src/Language/Haskell/Liquid/Bare/Axiom.hs @@ -2,6 +2,8 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + -- | This module contains the code that DOES reflection; i.e. converts Haskell -- definitions into refinements. @@ -175,7 +177,7 @@ instance Subable Ghc.CoreExpr where = e instance Subable Ghc.CoreAlt where - subst su (c, xs, e) = (c, xs, subst su e) + subst su (Ghc.Alt c xs e) = Ghc.Alt c xs (subst su e) data AxiomType = AT { aty :: SpecType, aargs :: [(F.Symbol, SpecType)], ares :: SpecType } diff --git a/src/Language/Haskell/Liquid/Bare/Check.hs b/src/Language/Haskell/Liquid/Bare/Check.hs index ef79934baf..e7410e16e5 100644 --- a/src/Language/Haskell/Liquid/Bare/Check.hs +++ b/src/Language/Haskell/Liquid/Bare/Check.hs @@ -187,10 +187,10 @@ checkTargetSpec specs src env cbs tsp checkPlugged :: PPrint v => [(v, LocSpecType)] -> Diagnostics -checkPlugged xs = mkDiagnostics mempty (map mkErr (filter (hasHoleTy . val . snd) xs)) +checkPlugged xs = mkDiagnostics mempty (map mkError (filter (hasHoleTy . val . snd) xs)) where - mkErr (x,t) = ErrBadData (GM.sourcePosSrcSpan $ loc t) (pprint x) msg - msg = "Cannot resolve type hole `_`. Use explicit type instead." + mkError (x,t) = ErrBadData (GM.sourcePosSrcSpan $ loc t) (pprint x) msg + msg = "Cannot resolve type hole `_`. Use explicit type instead." -------------------------------------------------------------------------------- @@ -294,9 +294,9 @@ _checkDuplicateFieldNames :: [(DataCon, DataConP)] -> [Error] _checkDuplicateFieldNames = mapMaybe go where go (d, dts) = checkNoDups (dcpLoc dts) d (fst <$> dcpTyArgs dts) - checkNoDups l d xs = mkErr l d <$> _firstDuplicate xs + checkNoDups l d xs = mkError l d <$> _firstDuplicate xs - mkErr l d x = ErrBadData (GM.sourcePosSrcSpan l) + mkError l d x = ErrBadData (GM.sourcePosSrcSpan l) (pprint d) (text "Multiple declarations of record selector" <+> pprintSymbol x) @@ -373,12 +373,12 @@ checkTerminationExpr :: (Eq v, PPrint v) -> (v, LocSpecType, [F.Located F.Expr]) -> Diagnostics checkTerminationExpr emb env (v, Loc l _ st, les) - = mkErr "ill-sorted" (go les) <> mkErr "non-numeric" (go' les) + = mkError "ill-sorted" (go les) <> mkError "non-numeric" (go' les) where -- es = val <$> les - mkErr :: Doc -> Maybe (F.Expr, Doc) -> Diagnostics - mkErr _ Nothing = emptyDiagnostics - mkErr k (Just expr') = + mkError :: Doc -> Maybe (F.Expr, Doc) -> Diagnostics + mkError _ Nothing = emptyDiagnostics + mkError k (Just expr') = mkDiagnostics mempty [(\ (e, d) -> ErrTermSpec (GM.sourcePosSrcSpan l) (pprint v) k e st d) expr'] -- mkErr = uncurry (\ e d -> ErrTermSpec (GM.sourcePosSrcSpan l) (pprint v) (text "ill-sorted" ) e t d) -- mkErr' = uncurry (\ e d -> ErrTermSpec (GM.sourcePosSrcSpan l) (pprint v) (text "non-numeric") e t d) @@ -440,13 +440,13 @@ checkClassMethods (Just clsis) cms xts = cls = F.notracepp "CLS" cms checkDuplicateRTAlias :: String -> [Located (RTAlias s a)] -> Diagnostics -checkDuplicateRTAlias s tas = mkDiagnostics mempty (map mkErr dups) +checkDuplicateRTAlias s tas = mkDiagnostics mempty (map mkError dups) where - mkErr xs@(x:_) = ErrDupAlias (GM.fSrcSpan x) + mkError xs@(x:_) = ErrDupAlias (GM.fSrcSpan x) (text s) (pprint . rtName . val $ x) (GM.fSrcSpan <$> xs) - mkErr [] = panic Nothing "mkError: called on empty list" + mkError [] = panic Nothing "mkError: called on empty list" dups = [z | z@(_:_:_) <- L.groupBy ((==) `on` (rtName . val)) tas] diff --git a/src/Language/Haskell/Liquid/Bare/Class.hs b/src/Language/Haskell/Liquid/Bare/Class.hs index e25fe050f1..796f7c8272 100644 --- a/src/Language/Haskell/Liquid/Bare/Class.hs +++ b/src/Language/Haskell/Liquid/Bare/Class.hs @@ -3,6 +3,8 @@ {-# LANGUAGE ParallelListComp #-} {-# LANGUAGE TupleSections #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + module Language.Haskell.Liquid.Bare.Class ( makeClasses , makeCLaws diff --git a/src/Language/Haskell/Liquid/Bare/Elaborate.hs b/src/Language/Haskell/Liquid/Bare/Elaborate.hs index 7b058ac6f1..5a4802f63e 100644 --- a/src/Language/Haskell/Liquid/Bare/Elaborate.hs +++ b/src/Language/Haskell/Liquid/Bare/Elaborate.hs @@ -514,11 +514,11 @@ elaborateSpecType' partialTp coreToLogic simplify t = hsExpr = buildHsExpr (fixExprToHsExpr (S.fromList origBinders) e) querySpecType :: LHsExpr GhcPs - exprWithTySigs = noLoc $ ExprWithTySig - Ghc.noExtField + exprWithTySigs = noLocA $ ExprWithTySig + noAnn hsExpr - (mkLHsSigWcType (specTypeToLHsType querySpecType)) - eeWithLamsCore <- GM.elabRnExpr TM_Inst exprWithTySigs + (hsTypeToHsSigWcType (specTypeToLHsType querySpecType)) + eeWithLamsCore <- GM.elabRnExpr exprWithTySigs eeWithLamsCore' <- simplify eeWithLamsCore let (_, tyBinders) = @@ -606,7 +606,7 @@ renameBinderSort f = rename rename ( F.FApp t0 t1 ) = F.FApp (rename t0) (rename t1) -mkHsTyConApp :: IdP (GhcPass p) -> [LHsType (GhcPass p)] -> LHsType (GhcPass p) +mkHsTyConApp :: IdP GhcPs -> [LHsType GhcPs] -> LHsType GhcPs mkHsTyConApp tyconId tyargs = nlHsTyConApp Prefix tyconId (map HsValArg tyargs) -- | Embed fixpoint expressions into parsed haskell expressions. @@ -667,15 +667,15 @@ fixExprToHsExpr _ e = constantToHsExpr :: F.Constant -> LHsExpr GhcPs -- constantToHsExpr (F.I c) = noLoc (HsLit NoExt (HsInt NoExt (mkIntegralLit c))) constantToHsExpr (F.I i) = - noLoc (HsOverLit Ghc.noExtField (mkHsIntegral (mkIntegralLit i))) + noLocA (HsOverLit noAnn (mkHsIntegral (mkIntegralLit i))) constantToHsExpr (F.R d) = - noLoc (HsOverLit Ghc.noExtField (mkHsFractional (mkFractionalLit d))) + noLocA (HsOverLit noAnn (mkHsFractional (mkTHFractionalLit (toRational d)))) constantToHsExpr _ = todo Nothing "constantToHsExpr: Not sure how to handle constructor L" -- This probably won't work because of the qualifiers bopToHsExpr :: F.Bop -> LHsExpr GhcPs -bopToHsExpr bop = noLoc (HsVar Ghc.noExtField (noLoc (f bop))) +bopToHsExpr bop = noLocA (HsVar Ghc.noExtField (noLocA (f bop))) where f F.Plus = plus_RDR f F.Minus = minus_RDR @@ -686,7 +686,7 @@ bopToHsExpr bop = noLoc (HsVar Ghc.noExtField (noLoc (f bop))) f F.RDiv = GM.prependGHCRealQual (fsLit "/") brelToHsExpr :: F.Brel -> LHsExpr GhcPs -brelToHsExpr brel = noLoc (HsVar Ghc.noExtField (noLoc (f brel))) +brelToHsExpr brel = noLocA (HsVar Ghc.noExtField (noLocA (f brel))) where f F.Eq = mkVarUnqual (mkFastString "==") f F.Gt = gt_RDR @@ -730,12 +730,12 @@ specTypeToLHsType = -- (GM.notracePpr ("varRdr" ++ F.showpp (F.symbol tv)) $ getRdrName tv) (symbolToRdrNameNs tvName (F.symbol tv)) RFunF _ _ (tin, tin') (_, tout) _ - | isClassType tin -> noLoc $ HsQualTy Ghc.noExtField (noLoc [tin']) tout + | isClassType tin -> noLocA $ HsQualTy Ghc.noExtField (Just (noLocA [tin'])) tout | otherwise -> nlHsFunTy tin' tout RImpFF _ _ (_, tin) (_, tout) _ -> nlHsFunTy tin tout - RAllTF (ty_var_value -> (RTV tv)) (_, t) _ -> noLoc $ HsForAllTy + RAllTF (ty_var_value -> (RTV tv)) (_, t) _ -> noLocA $ HsForAllTy Ghc.noExtField - (mkHsForAllInvisTele [noLoc $ UserTyVar Ghc.noExtField SpecifiedSpec (noLoc $ symbolToRdrNameNs tvName (F.symbol tv))]) + (mkHsForAllInvisTele noAnn [noLocA $ UserTyVar noAnn SpecifiedSpec (noLocA $ symbolToRdrNameNs tvName (F.symbol tv))]) t RAllPF _ (_, ty) -> ty RAppF RTyCon { rtc_tc = tc } ts _ _ -> mkHsTyConApp @@ -752,6 +752,6 @@ specTypeToLHsType = RAppTyF (_, t) (_, t') _ -> nlHsAppTy t t' -- YL: todo.. RRTyF _ _ _ (_, t) -> t - RHoleF _ -> noLoc $ HsWildCardTy Ghc.noExtField + RHoleF _ -> noLocA $ HsWildCardTy Ghc.noExtField RExprArgF _ -> todo Nothing "Oops, specTypeToLHsType doesn't know how to handle RExprArg" diff --git a/src/Language/Haskell/Liquid/Bare/Expand.hs b/src/Language/Haskell/Liquid/Bare/Expand.hs index 79352c53a4..0a4fc9b2ac 100644 --- a/src/Language/Haskell/Liquid/Bare/Expand.hs +++ b/src/Language/Haskell/Liquid/Bare/Expand.hs @@ -532,10 +532,10 @@ generalizeVar :: Ghc.Var -> SpecType -> SpecType generalizeVar v t = mkUnivs (zip as (repeat mempty)) [] t where as = filter isGen (freeTyVars t) - (vas,_) = Ghc.splitForAllTys (GM.expandVarType v) + (vas,_) = Ghc.splitForAllTyCoVars (GM.expandVarType v) isGen (RTVar (RTV a) _) = a `elem` vas --- splitForAllTys :: Type -> ([TyVar], Type) +-- splitForAllTyCoVars :: Type -> ([TyVar], Type) -- -- generalize :: (Eq tv) => RType c tv r -> RType c tv r -- generalize t = mkUnivs (freeTyVars t) [] [] t diff --git a/src/Language/Haskell/Liquid/Bare/Measure.hs b/src/Language/Haskell/Liquid/Bare/Measure.hs index a53d8c1eba..8c2121e408 100644 --- a/src/Language/Haskell/Liquid/Bare/Measure.hs +++ b/src/Language/Haskell/Liquid/Bare/Measure.hs @@ -488,7 +488,7 @@ toBound v x (vs, Left p) = (x', Bound x' fvs ps xs p) (ps , xs) = (txp <$> ps', txx <$> xs') txp v = (dummyLoc $ simpleSymbolVar v, RT.ofType $ varType v) txx v = (dummyLoc $ symbol v, RT.ofType $ varType v) - fvs = (((`RVar` mempty) . RTV) <$> fst (splitForAllTys $ varType v)) :: [RSort] + fvs = (((`RVar` mempty) . RTV) <$> fst (splitForAllTyCoVars $ varType v)) :: [RSort] toBound v x (vs, Right e) = toBound v x (vs, Left e) diff --git a/src/Language/Haskell/Liquid/Bare/Misc.hs b/src/Language/Haskell/Liquid/Bare/Misc.hs index a07c144408..d6998e8468 100644 --- a/src/Language/Haskell/Liquid/Bare/Misc.hs +++ b/src/Language/Haskell/Liquid/Bare/Misc.hs @@ -192,7 +192,7 @@ varFunSymbol = dummyLoc . F.symbol . idDataCon isFunVar :: Id -> Bool isFunVar v = isDataConId v && not (null αs) && Mb.isNothing tf where - (αs, t) = splitForAllTys $ varType v + (αs, t) = splitForAllTyCoVars $ varType v tf = splitFunTy_maybe t -- the Vars we lookup in GHC don't always have the same tyvars as the Vars diff --git a/src/Language/Haskell/Liquid/Bare/Plugged.hs b/src/Language/Haskell/Liquid/Bare/Plugged.hs index 274f41bc47..1d2f73820f 100644 --- a/src/Language/Haskell/Liquid/Bare/Plugged.hs +++ b/src/Language/Haskell/Liquid/Bare/Plugged.hs @@ -1,6 +1,9 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PartialTypeSignatures #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + module Language.Haskell.Liquid.Bare.Plugged ( makePluggedSig , makePluggedDataCon diff --git a/src/Language/Haskell/Liquid/Bare/Resolve.hs b/src/Language/Haskell/Liquid/Bare/Resolve.hs index ef611bc97b..f06368613d 100644 --- a/src/Language/Haskell/Liquid/Bare/Resolve.hs +++ b/src/Language/Haskell/Liquid/Bare/Resolve.hs @@ -132,7 +132,7 @@ localBinds = concatMap (bgo S.empty) go g (Ghc.Let b e) = bgo g b ++ go (adds b g) e go g (Ghc.Tick _ e) = go g e go g (Ghc.Cast e _) = go g e - go g (Ghc.Case e _ _ cs) = go g e ++ concatMap (go g . Misc.thd3) cs + go g (Ghc.Case e _ _ cs) = go g e ++ concatMap (go g . (\(Ghc.Alt _ _ e') -> e')) cs go _ (Ghc.Var _) = [] go _ _ = [] diff --git a/src/Language/Haskell/Liquid/Bare/Typeclass.hs b/src/Language/Haskell/Liquid/Bare/Typeclass.hs index 4fa4b95c4f..08d37d0c1a 100644 --- a/src/Language/Haskell/Liquid/Bare/Typeclass.hs +++ b/src/Language/Haskell/Liquid/Bare/Typeclass.hs @@ -1,6 +1,8 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + module Language.Haskell.Liquid.Bare.Typeclass ( compileClasses , elaborateClassDcp diff --git a/src/Language/Haskell/Liquid/Constraint/Constraint.hs b/src/Language/Haskell/Liquid/Constraint/Constraint.hs index 982d7ac9ec..0e3e9f6dbf 100644 --- a/src/Language/Haskell/Liquid/Constraint/Constraint.hs +++ b/src/Language/Haskell/Liquid/Constraint/Constraint.hs @@ -1,5 +1,7 @@ {-# LANGUAGE FlexibleInstances #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + -- TODO: what exactly is the purpose of this module? What do these functions do? module Language.Haskell.Liquid.Constraint.Constraint ( diff --git a/src/Language/Haskell/Liquid/Constraint/Generate.hs b/src/Language/Haskell/Liquid/Constraint/Generate.hs index 9d8a296d37..64417c570e 100644 --- a/src/Language/Haskell/Liquid/Constraint/Generate.hs +++ b/src/Language/Haskell/Liquid/Constraint/Generate.hs @@ -12,6 +12,7 @@ {-# LANGUAGE ImplicitParams #-} {-# OPTIONS_GHC -Wno-orphans #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | This module defines the representation of Subtyping and WF Constraints, -- and the code for syntax-directed constraint generation. @@ -644,7 +645,7 @@ cconsE' γ (Case e x _ cases) t = do γ' <- consCBLet γ (NonRec x e) forM_ cases $ cconsCase γ' x t nonDefAlts where - nonDefAlts = [a | (a, _, _) <- cases, a /= DEFAULT] + nonDefAlts = [a | Alt a _ _ <- cases, a /= DEFAULT] _msg = "cconsE' #nonDefAlts = " ++ show (length nonDefAlts) cconsE' γ (Lam α e) (RAllT α' t r) | isTyVar α @@ -924,7 +925,7 @@ consE _ e@(Type t) = panic Nothing $ "consE cannot handle type " ++ GM.showPpr (e, t) caseKVKind ::[Alt Var] -> KVKind -caseKVKind [(DataAlt _, _, Var _)] = ProjectE +caseKVKind [Alt (DataAlt _) _ (Var _)] = ProjectE caseKVKind cs = CaseE (length cs) updateEnvironment :: CGEnv -> TyVar -> CG CGEnv @@ -1183,9 +1184,9 @@ dropConstraints cgenv (RRTy cts _ OCons rt) dropConstraints _ t = return t ------------------------------------------------------------------------------------- -cconsCase :: CGEnv -> Var -> SpecType -> [AltCon] -> (AltCon, [Var], CoreExpr) -> CG () +cconsCase :: CGEnv -> Var -> SpecType -> [AltCon] -> CoreAlt -> CG () ------------------------------------------------------------------------------------- -cconsCase γ x t acs (ac, ys, ce) +cconsCase γ x t acs (Alt ac ys ce) = do cγ <- caseEnv γ x acs ac ys mempty cconsE cγ ce t diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index ffb930ad32..5eb943518b 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -6,6 +6,8 @@ {-# LANGUAGE PatternGuards #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + -- | This module defines the representation of Subtyping and WF Constraints, -- and the code for syntax-directed constraint generation. @@ -294,13 +296,13 @@ consExtAltEnv γ x s c bs e suf = do consRelCheckAltAsyncL :: CGEnv -> PrEnv -> SpecType -> SpecType -> F.Expr -> F.Symbol -> SpecType -> CoreExpr -> Alt CoreBndr -> CG () -consRelCheckAltAsyncL γ ψ t1 t2 p x1 s1 e2 (c, bs1, e1) = do +consRelCheckAltAsyncL γ ψ t1 t2 p x1 s1 e2 (Ghc.Alt c bs1 e1) = do (γ', e1') <- consExtAltEnv γ x1 s1 c bs1 e1 relSuffixL consRelCheck γ' ψ e1' e2 t1 t2 p consRelCheckAltAsyncR :: CGEnv -> PrEnv -> SpecType -> SpecType -> F.Expr -> CoreExpr -> F.Symbol -> SpecType -> Alt CoreBndr -> CG () -consRelCheckAltAsyncR γ ψ t1 t2 p e1 x2 s2 (c, bs2, e2) = do +consRelCheckAltAsyncR γ ψ t1 t2 p e1 x2 s2 (Ghc.Alt c bs2 e2) = do (γ', e2') <- consExtAltEnv γ x2 s2 c bs2 e2 relSuffixR consRelCheck γ' ψ e1 e2' t1 t2 p @@ -467,7 +469,7 @@ consUnarySynth _ e@(Type _) = F.panic $ "consUnarySynth is undefined for Type " consUnarySynth _ e@(Coercion _) = F.panic $ "consUnarySynth is undefined for Coercion " ++ F.showpp e caseKVKind :: [Alt Var] -> KVKind -caseKVKind [(DataAlt _, _, Var _)] = ProjectE +caseKVKind [Ghc.Alt (DataAlt _) _ (Var _)] = ProjectE caseKVKind cs = CaseE (length cs) checkFun :: CoreExpr -> Type -> Type diff --git a/src/Language/Haskell/Liquid/Constraint/Split.hs b/src/Language/Haskell/Liquid/Constraint/Split.hs index 52b7fc8548..d81d38eca7 100644 --- a/src/Language/Haskell/Liquid/Constraint/Split.hs +++ b/src/Language/Haskell/Liquid/Constraint/Split.hs @@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -------------------------------------------------------------------------------- -- | Constraint Splitting ------------------------------------------------------ diff --git a/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs b/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs index 4af01fad8a..0381c45f75 100644 --- a/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs +++ b/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs @@ -1,6 +1,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Language.Haskell.Liquid.Constraint.ToFixpoint ( cgInfoFInfo @@ -193,7 +194,7 @@ hasClassArg :: Id -> Bool hasClassArg x = F.tracepp msg (GM.isDataConId x && any Ghc.isClassPred (t:ts')) where msg = "hasClassArg: " ++ showpp (x, t:ts') - (ts, t) = Ghc.splitFunTys . snd . Ghc.splitForAllTys . Ghc.varType $ x + (ts, t) = Ghc.splitFunTys . snd . Ghc.splitForAllTyCoVars . Ghc.varType $ x ts' = map Ghc.irrelevantMult ts diff --git a/src/Language/Haskell/Liquid/GHC/Plugin.hs b/src/Language/Haskell/Liquid/GHC/Plugin.hs index 3a1561af21..cb15a41497 100644 --- a/src/Language/Haskell/Liquid/GHC/Plugin.hs +++ b/src/Language/Haskell/Liquid/GHC/Plugin.hs @@ -114,7 +114,7 @@ debugLog msg = when debugLogs $ liftIO (putStrLn msg) plugin :: GHC.Plugin plugin = GHC.defaultPlugin { typeCheckResultAction = liquidPlugin - , dynflagsPlugin = customDynFlags + , driverPlugin = customDynFlags , pluginRecompile = purePlugin } where @@ -126,8 +126,9 @@ plugin = GHC.defaultPlugin { -- for a post-mortem. liquidPlugin :: [CommandLineOption] -> ModSummary -> TcGblEnv -> TcM TcGblEnv liquidPlugin opts summary gblEnv = do + logger <- getLogger dynFlags <- getDynFlags - withTiming dynFlags (text "LiquidHaskell" <+> brackets (ppr $ ms_mod_name summary)) (const ()) $ do + withTiming logger dynFlags (text "LiquidHaskell" <+> brackets (ppr $ ms_mod_name summary)) (const ()) $ do if gopt Opt_Haddock dynFlags then do -- Warn the user @@ -136,7 +137,7 @@ plugin = GHC.defaultPlugin { ] let srcLoc = mkSrcLoc (mkFastString $ ms_hspp_file summary) 1 1 let warning = mkWarning (mkSrcSpan srcLoc srcLoc) msg - liftIO $ printWarning dynFlags warning + liftIO $ printWarning logger dynFlags warning pure gblEnv else do newGblEnv <- typecheckHook opts summary gblEnv @@ -157,21 +158,21 @@ plugin = GHC.defaultPlugin { -- | Overrides the default 'DynFlags' options. Specifically, we need the GHC -- lexer not to throw away block comments, as this is where the LH spec comments -- would live. This is why we set the 'Opt_KeepRawTokenStream' option. -customDynFlags :: [CommandLineOption] -> DynFlags -> IO DynFlags -customDynFlags opts dflags = do +customDynFlags :: [CommandLineOption] -> HscEnv -> IO HscEnv +customDynFlags opts hscEnv = do cfg <- liftIO $ LH.getOpts opts writeIORef cfgRef cfg - configureDynFlags dflags + return (hscEnv { hsc_dflags = configureDynFlags (hsc_dflags hscEnv) }) where - configureDynFlags :: DynFlags -> IO DynFlags + configureDynFlags :: DynFlags -> DynFlags configureDynFlags df = - pure $ df `gopt_set` Opt_ImplicitImportQualified - `gopt_set` Opt_PIC - `gopt_set` Opt_DeferTypedHoles - `gopt_set` Opt_KeepRawTokenStream - `xopt_set` MagicHash - `xopt_set` DeriveGeneric - `xopt_set` StandaloneDeriving + df `gopt_set` Opt_ImplicitImportQualified + `gopt_set` Opt_PIC + `gopt_set` Opt_DeferTypedHoles + `gopt_set` Opt_KeepRawTokenStream + `xopt_set` MagicHash + `xopt_set` DeriveGeneric + `xopt_set` StandaloneDeriving -------------------------------------------------------------------------------- -- | \"Unoptimising\" things ---------------------------------------------------- @@ -190,7 +191,7 @@ instance Unoptimise DynFlags where unoptimise df = updOptLevel 0 df { debugLevel = 1 , ghcLink = LinkInMemory - , hscTarget = HscInterpreted + , backend = Interpreter , ghcMode = CompManager } @@ -222,9 +223,9 @@ typecheckHook :: [CommandLineOption] -> ModSummary -> TcGblEnv -> TcM (Either Li typecheckHook _ (unoptimise -> modSummary) tcGblEnv = do debugLog $ "We are in module: " <> show (toStableModule thisModule) - parsed <- GhcMonadLike.parseModule (LH.keepRawTokenStream cleanedSummary) - let comments = LH.extractSpecComments (pm_annotations parsed) - typechecked <- GhcMonadLike.typecheckModule (LH.ignoreInline parsed) + parsed <- GhcMonadLike.parseModule (LH.keepRawTokenStream modSummary) + let comments = LH.extractSpecComments parsed + typechecked <- updTopEnv dropPlugins $ GhcMonadLike.typecheckModule (LH.ignoreInline parsed) env <- askHscEnv resolvedNames <- LH.lookupTyThings env modSummary tcGblEnv availTyCons <- LH.availableTyCons env modSummary tcGblEnv (tcg_exports tcGblEnv) @@ -241,12 +242,7 @@ typecheckHook _ (unoptimise -> modSummary) tcGblEnv = do thisModule :: Module thisModule = tcg_mod tcGblEnv - cleanedSummary :: ModSummary - cleanedSummary = - modSummary { ms_hspp_opts = (ms_hspp_opts modSummary) { cachedPlugins = [] - , staticPlugins = [] - } - } + dropPlugins hsc_env = hsc_env { hsc_plugins = [], hsc_static_plugins = [] } serialiseSpec :: Module -> TcGblEnv -> LiquidLib -> TcM TcGblEnv serialiseSpec thisModule tcGblEnv liquidLib = do @@ -531,6 +527,7 @@ processModule LiquidHaskellContext{..} = do debugLog $ "mg_tcs => " ++ O.showSDocUnsafe (O.ppr $ mg_tcs modGuts) targetSrc <- makeTargetSrc moduleCfg file lhModuleTcData modGuts hscEnv + logger <- getLogger dynFlags <- getDynFlags -- See https://github.com/ucsd-progsys/liquidhaskell/issues/1711 @@ -548,10 +545,10 @@ processModule LiquidHaskellContext{..} = do (case result of -- Print warnings and errors, aborting the compilation. Left diagnostics -> do - liftIO $ mapM_ (printWarning dynFlags) (allWarnings diagnostics) + liftIO $ mapM_ (printWarning logger dynFlags) (allWarnings diagnostics) reportErrs $ allErrors diagnostics Right (warnings, targetSpec, liftedSpec) -> do - liftIO $ mapM_ (printWarning dynFlags) warnings + liftIO $ mapM_ (printWarning logger dynFlags) warnings let targetInfo = TargetInfo targetSrc targetSpec debugLog $ "bareSpec ==> " ++ show bareSpec diff --git a/src/Language/Haskell/Liquid/Measure.hs b/src/Language/Haskell/Liquid/Measure.hs index d19ccb3926..fdaa50e5c4 100644 --- a/src/Language/Haskell/Liquid/Measure.hs +++ b/src/Language/Haskell/Liquid/Measure.hs @@ -71,11 +71,11 @@ checkDuplicateMeasure :: [Measure ty ctor] -> [Measure ty ctor] checkDuplicateMeasure measures = case M.toList dups of [] -> measures - (m,ms):_ -> uError $ mkErr m (msName <$> ms) + (m,ms):_ -> uError $ mkError m (msName <$> ms) where gms = group [(msName m , m) | m <- measures] dups = M.filter ((1 <) . length) gms - mkErr m ms = ErrDupMeas (fSrcSpan m) (pprint (val m)) (fSrcSpan <$> ms) + mkError m ms = ErrDupMeas (fSrcSpan m) (pprint (val m)) (fSrcSpan <$> ms) dataConTypes :: Bool -> MSpec (RRType Reft) DataCon -> ([(Var, RRType Reft)], [(LocSymbol, RRType Reft)]) @@ -119,7 +119,7 @@ makeDataConType allowTC ds | any Mb.isNothing (snd <$> binds def) = True | otherwise - = length (binds def) == length (fst $ splitFunTys $ snd $ splitForAllTys wot) + = length (binds def) == length (fst $ splitFunTys $ snd $ splitForAllTyCoVars wot) extend :: Bool @@ -194,7 +194,7 @@ defRefType allowTC tdc (Def f dc mt xs body) splitType :: Type -> ([TyVar],[Type], Type) splitType t = (αs, map irrelevantMult ts, tr) where - (αs, tb) = splitForAllTys t + (αs, tb) = splitForAllTyCoVars t (ts, tr) = splitFunTys tb stitchArgs :: (Monoid t1, PPrint a) diff --git a/src/Language/Haskell/Liquid/Synthesize.hs b/src/Language/Haskell/Liquid/Synthesize.hs index 8f03c605cc..c54ee0091c 100644 --- a/src/Language/Haskell/Liquid/Synthesize.hs +++ b/src/Language/Haskell/Liquid/Synthesize.hs @@ -1,5 +1,4 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TupleSections #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} module Language.Haskell.Liquid.Synthesize ( @@ -174,7 +173,7 @@ makeAlt t (x, TyConApp _ kts) c = locally $ do addDecrTerm x xs liftCG0 (\γ -> caseEnv γ x mempty (GHC.DataAlt c) xs Nothing) es <- synthesizeBasic t - return $ (GHC.DataAlt c, xs, ) <$> es + return $ Alt (GHC.DataAlt c) xs <$> es where (_, _, τs) = dataConInstSig c kts makeAlt _ _ _ = error "makeAlt.bad argument " diff --git a/src/Language/Haskell/Liquid/Synthesize/Check.hs b/src/Language/Haskell/Liquid/Synthesize/Check.hs index 1bbf75953b..f38aca4dad 100644 --- a/src/Language/Haskell/Liquid/Synthesize/Check.hs +++ b/src/Language/Haskell/Liquid/Synthesize/Check.hs @@ -22,7 +22,6 @@ import Language.Haskell.Liquid.Constraint.ToFixpoint import Language.Haskell.Liquid.Synthesize.Monad import Language.Haskell.Liquid.Synthesize.GHC import Liquid.GHC.API as Ghc -import Language.Haskell.Liquid.Misc ( mapThd3 ) import Control.Monad.State.Lazy import System.Console.CmdArgs.Verbosity import Liquid.GHC.TypeRep @@ -47,7 +46,7 @@ isWellTyped e = do tx :: CoreExpr -> CoreExpr -tx (Case e b t alts) = Case e b t (mapThd3 tx <$> alts) +tx (Case e b t alts) = Case e b t ((\(Alt c bs e) -> Alt c bs (tx e)) <$> alts) tx e@(Let _ _) = let (bs,e') = unbind e in foldr Let e' bs tx e = e @@ -80,7 +79,7 @@ checkError :: SpecType -> SM (Maybe CoreExpr) checkError t = do errVar <- varError let errorExpr = App (App (Var errVar) (Type (toType False t))) errorInt - globalFlags = unsafeGlobalDynFlags + globalFlags = undefined platform = targetPlatform globalFlags errorInt = mkIntExprInt platform 42 b <- hasType t errorExpr diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index cfeac9a303..83c7d02112 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -89,7 +89,7 @@ fromAnf' (Let bnd e) bnds fromAnf' (Var var) bnds = (fromMaybe (Var var) (lookup var bnds), bnds) fromAnf' (Case scr bnd tp alts) bnds - = (Case scr bnd tp (map (\(altc, xs, e) -> (altc, xs, fst $ fromAnf' e bnds)) alts), bnds) + = (Case scr bnd tp (map (\(Alt altc xs e) -> Alt altc xs (fst $ fromAnf' e bnds)) alts), bnds) fromAnf' (App e1 e2) bnds = let (e1', bnds') = fromAnf' e1 bnds (e2', bnds'') = fromAnf' e2 bnds' @@ -249,7 +249,7 @@ replaceNewLine (c:cs) else c : replaceNewLine cs pprintAlts :: [Var] -> Int -> Alt Var -> String -pprintAlts vars i (DataAlt dataCon, vs, e) +pprintAlts vars i (Alt (DataAlt dataCon) vs e) = indent i ++ show dataCon ++ concatMap (\v -> " " ++ show v) vs ++ " ->" ++ pprintBody vars (i+caseIndent) e ++ "\n" pprintAlts _ _ _ @@ -370,14 +370,14 @@ varsCB (GHC.Rec _) _ = notrace " [ symbolToVarCB ] Rec " [] varsE :: GHC.CoreExpr -> [Var] varsE (GHC.Lam a e) = a : varsE e varsE (GHC.Let (GHC.NonRec b _) e) = b : varsE e -varsE (GHC.Case _ b _ alts) = foldr (\(_, vars, e) res -> vars ++ varsE e ++ res) [b] alts +varsE (GHC.Case _ b _ alts) = foldr (\(Alt _ vars e) res -> vars ++ varsE e ++ res) [b] alts varsE (GHC.Tick _ e) = varsE e varsE _ = [] caseVarsE :: GHC.CoreExpr -> [Var] caseVarsE (GHC.Lam _ e) = caseVarsE e caseVarsE (GHC.Let (GHC.NonRec _ _) e) = caseVarsE e -caseVarsE (GHC.Case _ b _ alts) = foldr (\(_, _, e) res -> caseVarsE e ++ res) [b] alts +caseVarsE (GHC.Case _ b _ alts) = foldr (\(Alt _ _ e) res -> caseVarsE e ++ res) [b] alts caseVarsE (GHC.Tick _ e) = caseVarsE e caseVarsE _ = [] diff --git a/src/Language/Haskell/Liquid/Synthesize/Misc.hs b/src/Language/Haskell/Liquid/Synthesize/Misc.hs index d2475d41cc..2c16fa05a2 100644 --- a/src/Language/Haskell/Liquid/Synthesize/Misc.hs +++ b/src/Language/Haskell/Liquid/Synthesize/Misc.hs @@ -86,7 +86,7 @@ notrace _ a = a instance PPrint AltCon showCoreAlt :: CoreAlt -> String -showCoreAlt (DataAlt altCon, vars, expr) = +showCoreAlt (Alt (DataAlt altCon) vars expr) = " For " ++ show altCon ++ " vars " ++ show vars ++ " expr " ++ show expr showCoreAlt _ = " No! " diff --git a/src/Language/Haskell/Liquid/Synthesize/Termination.hs b/src/Language/Haskell/Liquid/Synthesize/Termination.hs index 4fbf173acb..bef4f99229 100644 --- a/src/Language/Haskell/Liquid/Synthesize/Termination.hs +++ b/src/Language/Haskell/Liquid/Synthesize/Termination.hs @@ -1,5 +1,7 @@ {-# LANGUAGE FlexibleInstances #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + module Language.Haskell.Liquid.Synthesize.Termination ( decrType ) where diff --git a/src/Language/Haskell/Liquid/Termination/Structural.hs b/src/Language/Haskell/Liquid/Termination/Structural.hs index 5b4d6fb7b2..ddb152f94b 100644 --- a/src/Language/Haskell/Liquid/Termination/Structural.hs +++ b/src/Language/Haskell/Liquid/Termination/Structural.hs @@ -62,7 +62,7 @@ nextBinds = \case App e a -> nextBinds e ++ nextBinds a Lam _ e -> nextBinds e Let b e -> b : nextBinds e - Case scrut _ _ alts -> nextBinds scrut ++ ([body | (_, _, body) <- alts] >>= nextBinds) + Case scrut _ _ alts -> nextBinds scrut ++ ([body | Alt _ _ body <- alts] >>= nextBinds) Cast e _ -> nextBinds e Tick _ e -> nextBinds e Var{} -> [] @@ -269,12 +269,12 @@ getCallInfoExpr env = \case Case (toVar -> Just var) bndr _ alts -> foldMap getCallInfoAlt alts where - getCallInfoAlt (_, subterms, body) = getCallInfoExpr (branchEnv subterms) body + getCallInfoAlt (Alt _ subterms body) = getCallInfoExpr (branchEnv subterms) body branchEnv subterms = addSubterms var subterms . addSynonym var bndr $ env Case scrut _ _ alts -> getCallInfoExpr env scrut <> foldMap getCallInfoAlt alts where - getCallInfoAlt (_, _, body) = getCallInfoExpr env body + getCallInfoAlt (Alt _ _ body) = getCallInfoExpr env body Cast e _ -> getCallInfoExpr env e Tick _ e -> getCallInfoExpr env e diff --git a/src/Language/Haskell/Liquid/Transforms/ANF.hs b/src/Language/Haskell/Liquid/Transforms/ANF.hs index 32a46545be..2f0c5e11e3 100644 --- a/src/Language/Haskell/Liquid/Transforms/ANF.hs +++ b/src/Language/Haskell/Liquid/Transforms/ANF.hs @@ -3,13 +3,12 @@ -------------------------------------------------------------------------------- {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE NoMonomorphismRestriction #-} -{-# LANGUAGE TupleSections #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} - module Language.Haskell.Liquid.Transforms.ANF (anormalize) where import Prelude hiding (error) @@ -21,7 +20,6 @@ import Liquid.GHC.API as Ghc hiding ( mkTyArg import qualified Liquid.GHC.API as Ghc import Control.Monad.State.Lazy import System.Console.CmdArgs.Verbosity (whenLoud) -import qualified Language.Fixpoint.Misc as F import qualified Language.Fixpoint.Types as F import Language.Haskell.Liquid.UX.Config as UX @@ -36,7 +34,6 @@ import qualified Liquid.GHC.SpanStack as Sp import qualified Liquid.GHC.Resugar as Rs import Data.Maybe (fromMaybe) import Data.List (sortBy, (\\)) -import Data.Function (on) import qualified Text.Printf as Printf import Data.Hashable import Data.HashMap.Strict (HashMap) @@ -99,12 +96,12 @@ normalizeTyVars (NonRec x e) = NonRec (setVarType x t') $ normalizeForAllTys e where t' = subst msg as as' bt msg = "WARNING: unable to renameVars on " ++ GM.showPpr x - as' = fst $ splitForAllTys $ exprType e - (as, bt) = splitForAllTys (varType x) + as' = fst $ splitForAllTyCoVars $ exprType e + (as, bt) = splitForAllTyCoVars (varType x) normalizeTyVars (Rec xes) = Rec xes' where nrec = normalizeTyVars <$> (uncurry NonRec <$> xes) - xes' = (\(NonRec x e) -> (x, e)) <$> nrec + xes' = (\case NonRec x e -> (x, e); _ -> impossible Nothing "This cannot happen") <$> nrec subst :: String -> [TyVar] -> [TyVar] -> Type -> Type subst msg as as' bt @@ -121,7 +118,7 @@ normalizeForAllTys e = case e of -> e _ -> mkLams tvs (mkTyApps e (map mkTyVarTy tvs)) where - (tvs, _) = splitForAllTys (exprType e) + (tvs, _) = splitForAllTyCoVars (exprType e) newtype DsM a = DsM {runDsM :: Ghc.DsM a} @@ -220,7 +217,7 @@ normalize γ (Case e x t as) = do n <- normalizeName γ e x' <- lift $ freshNormalVar γ τx -- rename "wild" to avoid shadowing let γ' = extendAnfEnv γ x x' - as' <- forM as $ \(c, xs, e') -> fmap (c, xs,) (stitch (incrCaseDepth c γ') e') + as' <- forM as $ \(Alt c xs e') -> fmap (Alt c xs) (stitch (incrCaseDepth c γ') e') as'' <- lift $ expandDefaultCase γ τx as' return $ Case n x' t as'' where τx = GM.expandVarType x @@ -303,15 +300,15 @@ expandDefault γ = aeCaseDepth γ <= maxCaseExpand γ -------------------------------------------------------------------------------- expandDefaultCase :: AnfEnv -> Type - -> [(AltCon, [Id], CoreExpr)] - -> DsM [(AltCon, [Id], CoreExpr)] + -> [CoreAlt] + -> DsM [CoreAlt] -------------------------------------------------------------------------------- -expandDefaultCase γ tyapp zs@((DEFAULT, _ ,_) : _) | expandDefault γ +expandDefaultCase γ tyapp zs@(Alt DEFAULT _ _ : _) | expandDefault γ = expandDefaultCase' γ tyapp zs -expandDefaultCase γ tyapp@(TyConApp tc _) z@((DEFAULT, _ ,_):dcs) +expandDefaultCase γ tyapp@(TyConApp tc _) z@(Alt DEFAULT _ _:dcs) = case tyConDataCons_maybe tc of - Just ds -> do let ds' = ds \\ [ d | (DataAlt d, _ , _) <- dcs] + Just ds -> do let ds' = ds \\ [ d | Alt (DataAlt d) _ _ <- dcs] let n = length ds' if n == 1 then expandDefaultCase' γ tyapp z @@ -324,21 +321,21 @@ expandDefaultCase _ _ z = return z expandDefaultCase' - :: AnfEnv -> Type -> [(AltCon, [Id], c)] -> DsM [(AltCon, [Id], c)] -expandDefaultCase' γ t ((DEFAULT, _, e) : dcs) - | Just dtss <- GM.defaultDataCons t (F.fst3 <$> dcs) = do + :: AnfEnv -> Type -> [CoreAlt] -> DsM [CoreAlt] +expandDefaultCase' γ t (Alt DEFAULT _ e : dcs) + | Just dtss <- GM.defaultDataCons t ((\(Alt dc _ _) -> dc) <$> dcs) = do dcs' <- warnCaseExpand γ <$> forM dtss (cloneCase γ e) return $ sortCases (dcs' ++ dcs) expandDefaultCase' _ _ z = return z -cloneCase :: AnfEnv -> e -> (DataCon, [TyVar], [Type]) -> DsM (AltCon, [Id], e) +cloneCase :: AnfEnv -> CoreExpr -> (DataCon, [TyVar], [Type]) -> DsM CoreAlt cloneCase γ e (d, as, ts) = do xs <- mapM (freshNormalVar γ) ts - return (DataAlt d, as ++ xs, e) + return (Alt (DataAlt d) (as ++ xs) e) -sortCases :: [(AltCon, b, c)] -> [(AltCon, b, c)] -sortCases = sortBy (cmpAltCon `on` F.fst3) +sortCases :: [CoreAlt] -> [CoreAlt] +sortCases = sortBy Ghc.cmpAlt warnCaseExpand :: AnfEnv -> [a] -> [a] warnCaseExpand γ xs @@ -430,5 +427,5 @@ incrCaseDepth :: AltCon -> AnfEnv -> AnfEnv incrCaseDepth DEFAULT γ = γ { aeCaseDepth = 1 + aeCaseDepth γ } incrCaseDepth _ γ = γ -at :: AnfEnv -> Tickish Id -> AnfEnv +at :: AnfEnv -> CoreTickish -> AnfEnv at γ tt = γ { aeSrcSpan = Sp.push (Sp.Tick tt) (aeSrcSpan γ)} diff --git a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs index 5c6981daee..7ee621eca8 100644 --- a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs +++ b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs @@ -173,13 +173,13 @@ coreAltToDef allowTC x z zs y t alts where myArgs = reverse zs cc = if eqType t boolTy then P else E - defAlts = GM.defaultDataCons (GM.expandVarType y) (Misc.fst3 <$> alts) - defExpr = listToMaybe [ e | (C.DEFAULT , _, e) <- alts ] - dataAlts = [ a | a@(C.DataAlt _, _, _) <- alts ] - litAlts = [ a | a@(C.LitAlt _, _, _) <- alts ] + defAlts = GM.defaultDataCons (GM.expandVarType y) ((\(Alt c _ _) -> c) <$> alts) + defExpr = listToMaybe [ e | (Alt C.DEFAULT _ e) <- alts ] + dataAlts = [ a | a@(Alt (C.DataAlt _) _ _) <- alts ] + litAlts = [ a | a@(Alt (C.LitAlt _) _ _) <- alts ] -- mkAlt :: LocSymbol -> (Expr -> Body) -> [Var] -> Var -> (C.AltCon, [Var], C.CoreExpr) - mkAlt x ctor _args dx (C.DataAlt d, xs, e) + mkAlt x ctor _args dx (Alt (C.DataAlt d) xs e) = Def x {- (toArgs id args) -} d (Just $ varRType dx) (toArgs Just xs') . ctor . (`subst1` (F.symbol dx, F.mkEApp (GM.namedLocSymbol d) (F.eVar <$> xs'))) @@ -214,7 +214,7 @@ coreToDef allowTC x _ e = go [] $ inlinePreds $ simplify allow go args (C.Tick _ e) = go args e go (z:zs) (C.Case _ y t alts) = coreAltToDef allowTC x z zs y t alts go (z:zs) e - | Just t <- isMeasureArg z = coreAltToDef allowTC x z zs z t [(C.DEFAULT, [], e)] + | Just t <- isMeasureArg z = coreAltToDef allowTC x z zs z t [Alt C.DEFAULT [] e] go _ _ = measureFail x "Does not have a case-of at the top-level" inlinePreds = inline (eqType boolTy . GM.expandVarType) @@ -312,11 +312,11 @@ typeEqToLg (s, t) = do return $ F.notracepp "TYPE-EQ-TO-LOGIC" (tx s, tx t) checkBoolAlts :: [C.CoreAlt] -> LogicM (C.CoreExpr, C.CoreExpr) -checkBoolAlts [(C.DataAlt false, [], efalse), (C.DataAlt true, [], etrue)] +checkBoolAlts [Alt (C.DataAlt false) [] efalse, Alt (C.DataAlt true) [] etrue] | false == falseDataCon, true == trueDataCon = return (efalse, etrue) -checkBoolAlts [(C.DataAlt true, [], etrue), (C.DataAlt false, [], efalse)] +checkBoolAlts [Alt (C.DataAlt true) [] etrue, Alt (C.DataAlt false) [] efalse] | false == falseDataCon, true == trueDataCon = return (efalse, etrue) checkBoolAlts alts @@ -346,16 +346,16 @@ normalizeAlts :: [C.CoreAlt] -> [C.CoreAlt] normalizeAlts alts = ctorAlts ++ defAlts where (defAlts, ctorAlts) = L.partition isDefault alts - isDefault (c,_,_) = c == C.DEFAULT + isDefault (Alt c _ _) = c == C.DEFAULT altToLg :: Bool -> Expr -> C.CoreAlt -> LogicM (C.AltCon, Expr) -altToLg allowTC de (a@(C.DataAlt d), xs, e) = do +altToLg allowTC de (Alt a@(C.DataAlt d) xs e) = do p <- coreToLg allowTC e dm <- gets lsDCMap let su = mkSubst $ concat [ dataConProj dm de d x i | (x, i) <- zip (filter (not . if allowTC then GM.isEmbeddedDictVar else GM.isEvVar) xs) [1..]] return (a, subst su p) -altToLg allowTC _ (a, _, e) +altToLg allowTC _ (Alt a _ e) = (a, ) <$> coreToLg allowTC e dataConProj :: DataConMap -> Expr -> DataCon -> Var -> Int -> [(Symbol, Expr)] @@ -558,7 +558,7 @@ ignoreVar i = simpleSymbolVar i `elem` ["I#", "D#"] -- We need the disjuction for GHC >= 9, where the Integer now comes from the \"ghc-bignum\" package, -- and it has different names for the constructors. isBangInteger :: [C.CoreAlt] -> Bool -isBangInteger [(C.DataAlt s, _, _), (C.DataAlt jp,_,_), (C.DataAlt jn,_,_)] +isBangInteger [Alt (C.DataAlt s) _ _, Alt (C.DataAlt jp) _ _, Alt (C.DataAlt jn) _ _] = (symbol s == "GHC.Integer.Type.S#" || symbol s == "GHC.Num.Integer.IS") && (symbol jp == "GHC.Integer.Type.Jp#" || symbol jp == "GHC.Num.Integer.IP") && (symbol jn == "GHC.Integer.Type.Jn#" || symbol jn == "GHC.Num.Integer.IN") @@ -619,7 +619,7 @@ instance Simplify C.CoreExpr where = simplify allowTC e simplify allowTC (C.Let xes e) = C.Let (simplify allowTC xes) (simplify allowTC e) - simplify allowTC (C.Case e x _t alts@[(_,_,ee),_,_]) | isBangInteger alts + simplify allowTC (C.Case e x _t alts@[Alt _ _ ee,_,_]) | isBangInteger alts -- XXX(matt): seems to be for debugging? = -- Misc.traceShow ("To simplify allowTC case") $ sub (M.singleton x (simplify allowTC e)) (simplify allowTC ee) @@ -647,8 +647,8 @@ instance Simplify C.CoreExpr where inline _ (C.Coercion c) = C.Coercion c inline _ (C.Type t) = C.Type t -isUndefined :: (t, t1, C.Expr t2) -> Bool -isUndefined (_, _, e) = isUndefinedExpr e +isUndefined :: Alt b -> Bool +isUndefined (Alt _ _ e) = isUndefinedExpr e where -- auto generated undefined case: (\_ -> (patError @type "error message")) void isUndefinedExpr (C.App (C.Var x) _) | show x `elem` perrors = True @@ -667,7 +667,7 @@ instance Simplify C.CoreBind where inline p (C.Rec xes) = C.Rec (Misc.mapSnd (inline p) <$> xes) instance Simplify C.CoreAlt where - simplify allowTC (c, xs, e) = (c, xs, simplify allowTC e) + simplify allowTC (Alt c xs e) = Alt c xs (simplify allowTC e) -- where xs = F.tracepp _msg xs0 -- _msg = "isCoVars? " ++ F.showpp [(x, isCoVar x, varType x) | x <- xs0] - inline p (c, xs, e) = (c, xs, inline p e) + inline p (Alt c xs e) = Alt c xs (inline p e) diff --git a/src/Language/Haskell/Liquid/Transforms/InlineAux.hs b/src/Language/Haskell/Liquid/Transforms/InlineAux.hs index 5d7605dbb9..b10af00f1a 100644 --- a/src/Language/Haskell/Liquid/Transforms/InlineAux.hs +++ b/src/Language/Haskell/Liquid/Transforms/InlineAux.hs @@ -100,5 +100,5 @@ mapBnd :: (Expr b -> Expr b) -> Bind b -> Bind b mapBnd f (NonRec b e) = NonRec b (f e) mapBnd f (Rec bs ) = Rec (map (second f) bs) -mapAlt :: (Expr b -> Expr b) -> (t, t1, Expr b) -> (t, t1, Expr b) -mapAlt f (d, bs, e) = (d, bs, f e) +mapAlt :: (Expr b -> Expr b) -> Alt b -> Alt b +mapAlt f (Alt d bs e) = Alt d bs (f e) diff --git a/src/Language/Haskell/Liquid/Transforms/Rec.hs b/src/Language/Haskell/Liquid/Transforms/Rec.hs index f13ab69ff3..a4a1b8f898 100644 --- a/src/Language/Haskell/Liquid/Transforms/Rec.hs +++ b/src/Language/Haskell/Liquid/Transforms/Rec.hs @@ -73,7 +73,7 @@ inlineFailCases = (go [] <$>) go' su (Tick t e) = Tick t (go' su e) go' _ e = e - goalt su (c, xs, e) = (c, xs, go' su e) + goalt su (Alt c xs e) = Alt c xs (go' su e) isFailId x = isLocalId x && isSystemName (varName x) && L.isPrefixOf "fail" (show x) getFailExpr = L.lookup @@ -142,7 +142,7 @@ isNonPolyRec (Let (Rec xes) _) = any nonPoly (snd <$> xes) isNonPolyRec _ = False nonPoly :: CoreExpr -> Bool -nonPoly = null . fst . splitForAllTys . exprType +nonPoly = null . fst . splitForAllTyCoVars . exprType collectNonRecLets :: Expr t -> ([Bind t], Expr t) collectNonRecLets = go [] @@ -275,8 +275,8 @@ mapExpr f (Case e b t alt) = Case e b t (map (mapAlt f) alt) mapExpr f (Tick t e) = Tick t (mapExpr f e) mapExpr _ e = e -mapAlt :: (b -> Expr b -> Expr b) -> (t, t1, Expr b) -> (t, t1, Expr b) -mapAlt f (d, bs, e) = (d, bs, mapExpr f e) +mapAlt :: (b -> Expr b -> Expr b) -> Alt b -> Alt b +mapAlt f (Alt d bs e) = Alt d bs (mapExpr f e) -- Do not apply transformations to inner code diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs index 99c3f01430..b8d4499030 100644 --- a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs +++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- | This module contains functions for recursively "rewriting" -- GHC core using "rules". @@ -30,7 +31,7 @@ import Data.Maybe (fromMaybe) import Control.Monad.State hiding (lift) import Language.Fixpoint.Misc ({- mapFst, -} mapSnd) import qualified Language.Fixpoint.Types as F -import Language.Haskell.Liquid.Misc (safeZipWithError, mapThd3, Nat) +import Language.Haskell.Liquid.Misc (safeZipWithError, Nat) import Liquid.GHC.Play (substExpr) import Liquid.GHC.Resugar import Liquid.GHC.Misc (unTickExpr, isTupleId, showPpr, mkAlive) -- , showPpr, tracePpr) @@ -92,8 +93,8 @@ undollar = go goRec (x, e) = (x,) <$> go e - goAlt (c, bs, e) - = (c, bs,) <$> go e + goAlt (Alt c bs e) + = Alt c bs <$> go e @@ -129,16 +130,16 @@ tidyTuples e = Just $ evalState (go e) [] goRec (x, e) = (x,) <$> go e - goAlt (c, bs, e) - = (c, bs,) <$> go e + goAlt (Alt c bs e) + = Alt c bs <$> go e - goAltR v (c, bs, e) + goAltR v (Alt c bs e) = do m <- get case L.lookup (c,v) m of - Just bs' -> return (c, bs', substTuple bs' bs e) + Just bs' -> return (Alt c bs' (substTuple bs' bs e)) Nothing -> do let bs' = mkAlive <$> bs modify (((c,v),bs'):) - return (c, bs', e) + return (Alt c bs' e) @@ -152,7 +153,7 @@ normalizeTuples b where go (Let (NonRec x ex) e) | Case _ _ _ alts <- unTickExpr ex - , [(_, vs, Var z)] <- alts + , [Alt _ vs (Var z)] <- alts , z `elem` vs = Let (NonRec z (go ex)) (substTuple [z] [x] (go e)) go (Let (NonRec x ex) e) @@ -164,7 +165,7 @@ normalizeTuples b go (Lam x e) = Lam x (go e) go (Case e b t alt) - = Case (go e) b t (mapThd3 go <$> alt) + = Case (go e) b t ((\(Alt c bs e') -> Alt c bs (go e')) <$> alt) go (Cast e c) = Cast (go e) c go (Tick t e) @@ -205,7 +206,7 @@ rewriteWith tx = go step (Lam x e) = Lam x (go e) step (Cast e c) = Cast (go e) c step (Tick t e) = Tick t (go e) - step (Case e x t cs) = Case (go e) x t (mapThd3 go <$> cs) + step (Case e x t cs) = Case (go e) x t ((\(Alt c bs e') -> Alt c bs (go e')) <$> cs) step e@(Type _) = e step e@(Lit _) = e step e@(Var _) = e @@ -309,13 +310,13 @@ _tidyAlt n (Just (Let (NonRec x e) rest)) replaceBinds bs (Case c x t alt) = Case c x t (replaceBindsAlt bs <$> alt) replaceBinds bs (Tick t e) = Tick t (replaceBinds bs e) replaceBinds _ e = e - replaceBindsAlt bs (c, _, e) = (c, bs, e) + replaceBindsAlt bs (Alt c _ e) = Alt c bs e grapBinds (Case _ _ _ alt) = grapBinds' alt grapBinds (Tick _ e) = grapBinds e grapBinds _ = [] grapBinds' [] = [] - grapBinds' ((_,bs,_):_) = bs + grapBinds' (Alt _ bs _ : _) = bs _tidyAlt _ e = e @@ -376,8 +377,8 @@ hasTuple ys = stepE stepE e | Just xs <- isVarTup ys e = Just xs | otherwise = go e - stepA (DEFAULT,_,_) = Nothing - stepA (_, _, e) = stepE e + stepA (Alt DEFAULT _ _) = Nothing + stepA (Alt _ _ e) = stepE e go (Let _ e) = stepE e go (Case _ _ _ cs) = msum (stepA <$> cs) go _ = Nothing @@ -393,8 +394,8 @@ replaceTuple ys e e' = stepE e stepE e | Just xs <- isVarTup ys e = Just $ substTuple xs ys e' | otherwise = go e - stepA (DEFAULT, xs, err) = Just (DEFAULT, xs, replaceIrrefutPat t' err) - stepA (c, xs, e) = (c, xs,) <$> stepE e + stepA (Alt DEFAULT xs err) = Just (Alt DEFAULT xs (replaceIrrefutPat t' err)) + stepA (Alt c xs e) = Alt c xs <$> stepE e go (Let b e) = Let b <$> stepE e go (Case e x t cs) = fixCase e x t <$> mapM stepA cs go _ = Nothing @@ -409,7 +410,7 @@ _showExpr e = show' e show' (Case e x _ alt) = "Case " ++ _showVar x ++ " = " ++ show' e ++ " OF " ++ unlines (showAlt' <$> alt) show' e = showPpr e - showAlt' (c, bs, e) = showPpr c ++ unwords (_showVar <$> bs) ++ " -> " ++ show' e + showAlt' (Alt c bs e) = showPpr c ++ unwords (_showVar <$> bs) ++ " -> " ++ show' e _showVar :: Var -> String _showVar = show . F.symbol @@ -433,7 +434,7 @@ fixCase :: CoreExpr -> Var -> Type -> ListNE (Alt Var) -> CoreExpr fixCase e x _t cs' = Case e x t' cs' where t' = Ghc.exprType body - (_,_,body) = c + Alt _ _ body = c c:_ = cs' {-@ type ListNE a = {v:[a] | len v > 0} @-} diff --git a/src/Language/Haskell/Liquid/Types/Bounds.hs b/src/Language/Haskell/Liquid/Types/Bounds.hs index 11910d0b43..1df13a33f4 100644 --- a/src/Language/Haskell/Liquid/Types/Bounds.hs +++ b/src/Language/Haskell/Liquid/Types/Bounds.hs @@ -5,6 +5,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Language.Haskell.Liquid.Types.Bounds ( diff --git a/src/Language/Haskell/Liquid/Types/Errors.hs b/src/Language/Haskell/Liquid/Types/Errors.hs index 31eda58043..0dede9fb46 100644 --- a/src/Language/Haskell/Liquid/Types/Errors.hs +++ b/src/Language/Haskell/Liquid/Types/Errors.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DeriveGeneric #-} @@ -44,7 +45,7 @@ module Language.Haskell.Liquid.Types.Errors ( , ppTicks -- * SrcSpan Helpers - , realSrcSpan + , packRealSrcSpan , unpackRealSrcSpan , srcSpanFileMb ) where @@ -700,15 +701,17 @@ unpackRealSrcSpan rsp = (f, l1, c1, l2, c2) instance FromJSON RealSrcSpan where - parseJSON (Object v) = realSrcSpan <$> v .: "filename" - <*> v .: "startLine" - <*> v .: "startCol" - <*> v .: "endLine" - <*> v .: "endCol" + parseJSON (Object v) = + packRealSrcSpan + <$> v .: "filename" + <*> v .: "startLine" + <*> v .: "startCol" + <*> v .: "endLine" + <*> v .: "endCol" parseJSON _ = mempty -realSrcSpan :: FilePath -> Int -> Int -> Int -> Int -> RealSrcSpan -realSrcSpan f l1 c1 l2 c2 = mkRealSrcSpan loc1 loc2 +packRealSrcSpan :: FilePath -> Int -> Int -> Int -> Int -> RealSrcSpan +packRealSrcSpan f l1 c1 l2 c2 = mkRealSrcSpan loc1 loc2 where loc1 = mkRealSrcLoc (fsLit f) l1 c1 loc2 = mkRealSrcLoc (fsLit f) l2 c2 @@ -744,9 +747,7 @@ instance FromJSON (TError a) where parseJSON _ = mempty errSaved :: SrcSpan -> String -> TError a -errSaved sp body = ErrSaved sp (text n) (text $ unlines m) - where - n : m = lines body +errSaved sp body | n : m <- lines body = ErrSaved sp (text n) (text $ unlines m) totalityType :: PPrint a => Tidy -> a -> Bool totalityType td tE = pprintTidy td tE == text "{VV : Addr# | 5 < 4}" @@ -1082,10 +1083,9 @@ ppList d ls -- | Convert a GHC error into a list of our errors. sourceErrors :: String -> SourceError -> [TError t] -sourceErrors s = concatMap (errMsgErrors s) . bagToList . srcErrorMessages - -errMsgErrors :: String -> ErrMsg -> [TError t] -errMsgErrors s e = [ ErrGhc (errMsgSpan e) msg ] - where - msg = text s - $+$ nest 4 (text (show e)) +sourceErrors s = + concatMap errMsgErrors . bagToList . srcErrorMessages + where + errMsgErrors e = [ ErrGhc (errMsgSpan e) msg ] + where + msg = text s $+$ nest 4 (text (show e)) diff --git a/src/Language/Haskell/Liquid/Types/PredType.hs b/src/Language/Haskell/Liquid/Types/PredType.hs index b1d8b9e2c7..192be1f814 100644 --- a/src/Language/Haskell/Liquid/Types/PredType.hs +++ b/src/Language/Haskell/Liquid/Types/PredType.hs @@ -6,6 +6,7 @@ {-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Language.Haskell.Liquid.Types.PredType ( PrType @@ -193,7 +194,7 @@ dcWrapSpecType allowTC dc (DataConP _ _ vs ps cs yts rt _ _ _) ts' = map ("" , classRFInfo allowTC , , mempty) cs ++ yts' su = F.mkSubst [(x, F.EVar y) | (x, y) <- zip xs ys] rt' = F.subst su rt - makeVars = zipWith (\v a -> RTVar v (rTVarInfo a :: RTVInfo RSort)) vs (fst $ splitForAllTys $ dataConRepType dc) + makeVars = zipWith (\v a -> RTVar v (rTVarInfo a :: RTVInfo RSort)) vs (fst $ splitForAllTyCoVars $ dataConRepType dc) makeVars' = zip makeVars (repeat mempty) instance PPrint TyConP where diff --git a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs index 416661c6e3..ae16ed5165 100644 --- a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs +++ b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs @@ -58,7 +58,6 @@ import Liquid.GHC.API as Ghc ( Class , Type , Var , Name - , ErrMsg , SourceError , TyCon , topPrec @@ -73,6 +72,7 @@ import Language.Haskell.Liquid.Types.Types import Prelude hiding (error) import Text.PrettyPrint.HughesPJ hiding ((<>)) + -- | `Filter`s match errors. They are used to ignore classes of errors they -- match. `AnyFilter` matches all errors. `StringFilter` matches any error whose -- \"representation\" contains the given `String`. A \"representation\" is @@ -101,7 +101,7 @@ pprintSymbol x = char '‘' <-> pprint x <-> char '’' -------------------------------------------------------------------------------- -- | A whole bunch of PPrint instances follow ---------------------------------- -------------------------------------------------------------------------------- -instance PPrint ErrMsg where +instance PPrint (Ghc.MsgEnvelope Ghc.DecoratedSDoc) where pprintTidy _ = text . show instance PPrint SourceError where @@ -452,8 +452,8 @@ instance (PPrint r, F.Reftable r) => PPrint (UReft r) where -- | Pretty-printing errors ---------------------------------------------------- -------------------------------------------------------------------------------- -printError :: (Show e, F.PPrint e) => F.Tidy -> DynFlags -> TError e -> IO () -printError k dyn err = putErrMsg dyn (pos err) (ppError k empty err) +printError :: (Show e, F.PPrint e) => Ghc.Logger -> F.Tidy -> DynFlags -> TError e -> IO () +printError logger k dyn err = putErrMsg logger dyn (pos err) (ppError k empty err) -- | Similar in spirit to 'reportErrors' from the GHC API, but it uses our -- pretty-printer and shim functions under the hood. Also filters the errors diff --git a/src/Language/Haskell/Liquid/Types/RefType.hs b/src/Language/Haskell/Liquid/Types/RefType.hs index ec72c1baa9..7e30b4a89d 100644 --- a/src/Language/Haskell/Liquid/Types/RefType.hs +++ b/src/Language/Haskell/Liquid/Types/RefType.hs @@ -16,6 +16,7 @@ {-# OPTIONS_GHC -Wno-incomplete-patterns #-} -- TODO(#1918): Only needed for GHC <9.0.1. {-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wno-incomplete-record-updates #-} -- | Refinement Types. Mostly mirroring the GHC Type definition, but with -- room for refinements of various sorts. @@ -96,7 +97,6 @@ module Language.Haskell.Liquid.Types.RefType ( import Prelude hiding (error) -- import qualified Prelude import Data.Maybe (fromMaybe, isJust) -import Data.Bifunctor (first) import Data.Monoid (First(..)) import Data.Hashable import qualified Data.HashMap.Strict as M @@ -221,7 +221,6 @@ instance ( SubsTy tv (RType c tv ()) (RType c tv ()) ) => Monoid (RType c tv r) where mempty = panic Nothing "mempty: RType" - mappend = strengthenRefType -- MOVE TO TYPES instance ( SubsTy tv (RType c tv ()) c @@ -510,11 +509,11 @@ kindToRType_ ofType = ofType . go where go t | t == typeSymbolKind = stringTy - | t == typeNatKind = intTy + | t == naturalTy = intTy | otherwise = t isValKind :: Kind -> Bool -isValKind x = x == typeNatKind || x == typeSymbolKind +isValKind x = x == naturalTy || x == typeSymbolKind bTyVar :: Symbol -> BTyVar bTyVar = BTV @@ -1664,7 +1663,7 @@ typeSortForAll tce τ = F.notracepp ("typeSortForall " ++ showpp τ) $ genSort where sbody = typeSort tce tbody genSort t = foldl' (flip FAbs) (sortSubst su t) [i..n+i-1] - (as, tbody) = F.notracepp ("splitForallTys" ++ GM.showPpr τ) (splitForAllTys τ) + (as, tbody) = F.notracepp ("splitForallTys" ++ GM.showPpr τ) (splitForAllTyCoVars τ) su = M.fromList $ zip sas (FVar <$> [i..]) sas = symbol <$> as n = length as @@ -1705,24 +1704,53 @@ expandProductType x t | otherwise = fromRTypeRep $ trep {ty_binds = xs', ty_info=is', ty_args = ts', ty_refts = rs'} where isTrivial = ofType (varType x) == toRSort t - τs = map irrelevantMult $ fst $ splitFunTys $ snd $ splitForAllTys $ toType False t + τs = map irrelevantMult $ fst $ splitFunTys $ snd $ splitForAllTyCoVars $ toType False t trep = toRTypeRep t (xs',is',ts',rs') = unzip4 $ concatMap mkProductTy $ zip5 τs (ty_binds trep) (ty_info trep) (ty_args trep) (ty_refts trep) -- splitFunTys :: Type -> ([Type], Type) +data DataConAppContext + = DataConAppContext + { dcac_dc :: !DataCon + , dcac_tys :: ![Type] + , dcac_arg_tys :: ![(Type, StrictnessMark)] + , dcac_co :: !Coercion + } mkProductTy :: forall t r. (Monoid t, Monoid r) => (Type, Symbol, RFInfo, RType RTyCon RTyVar r, t) -> [(Symbol, RFInfo, RType RTyCon RTyVar r, t)] -mkProductTy (τ, x, i, t, r) = maybe [(x, i, t, r)] f $ do - DataConAppContext{..} <- deepSplitProductType_maybe menv τ - pure (dcac_dc, dcac_tys, map (first irrelevantMult) dcac_arg_tys, dcac_co) +mkProductTy (τ, x, i, t, r) = maybe [(x, i, t, r)] f (deepSplitProductType menv τ) where - f :: (DataCon, [Type], [(Type, StrictnessMark)], Coercion) -> [(Symbol, RFInfo, RType RTyCon RTyVar r, t)] - f = map ((dummySymbol, defRFInfo, , mempty) . ofType . fst) . third4 + f :: DataConAppContext -> [(Symbol, RFInfo, RType RTyCon RTyVar r, t)] + f DataConAppContext{..} = map ((dummySymbol, defRFInfo, , mempty) . ofType . fst) dcac_arg_tys menv = (emptyFamInstEnv, emptyFamInstEnv) +-- Copied from GHC 9.0.2. +orElse :: Maybe a -> a -> a +orElse = flip fromMaybe + +-- Copied from GHC 9.0.2. +deepSplitProductType :: FamInstEnvs -> Type -> Maybe DataConAppContext +-- If deepSplitProductType_maybe ty = Just (dc, tys, arg_tys, co) +-- then dc @ tys (args::arg_tys) :: rep_ty +-- co :: ty ~ rep_ty +-- Why do we return the strictness of the data-con arguments? +-- Answer: see Note [Record evaluated-ness in worker/wrapper] +deepSplitProductType fam_envs ty + | let (co, ty1) = topNormaliseType_maybe fam_envs ty + `orElse` (mkRepReflCo ty, ty) + , Just (tc, tc_args) <- splitTyConApp_maybe ty1 + , Just con <- tyConSingleDataCon_maybe tc + , let arg_tys = dataConInstArgTys con tc_args + strict_marks = dataConRepStrictness con + = Just DataConAppContext { dcac_dc = con + , dcac_tys = tc_args + , dcac_arg_tys = zipEqual "dspt" (map irrelevantMult arg_tys) strict_marks + , dcac_co = co } +deepSplitProductType _ _ = Nothing + ----------------------------------------------------------------------------------------- -- | Binders generated by class predicates, typically for constraining tyvars (e.g. FNum) ----------------------------------------------------------------------------------------- diff --git a/src/Language/Haskell/Liquid/Types/Types.hs b/src/Language/Haskell/Liquid/Types/Types.hs index 6294cb19e2..fcc5ccf8f0 100644 --- a/src/Language/Haskell/Liquid/Types/Types.hs +++ b/src/Language/Haskell/Liquid/Types/Types.hs @@ -248,7 +248,6 @@ module Language.Haskell.Liquid.Types.Types ( import Liquid.GHC.API as Ghc hiding ( Expr , Target , isFunTy - , LM , ($+$) , nest , text @@ -2071,8 +2070,8 @@ allErrors = dErrors -- | Printing Warnings --------------------------------------------------------- -------------------------------------------------------------------------------- -printWarning :: DynFlags -> Warning -> IO () -printWarning dyn (Warning span doc) = GHC.putWarnMsg dyn span doc +printWarning :: Logger -> DynFlags -> Warning -> IO () +printWarning logger dyn (Warning span doc) = GHC.putWarnMsg logger dyn span doc -------------------------------------------------------------------------------- -- | Error Data Type ----------------------------------------------------------- diff --git a/src/Language/Haskell/Liquid/Types/Visitors.hs b/src/Language/Haskell/Liquid/Types/Visitors.hs index ba6cf419ac..d2130651ff 100644 --- a/src/Language/Haskell/Liquid/Types/Visitors.hs +++ b/src/Language/Haskell/Liquid/Types/Visitors.hs @@ -123,16 +123,17 @@ exprLiterals = go go' _ = [] + tyLitToLit (CharTyLit c) = LitChar c tyLitToLit (StrTyLit fs) = LitString (bytesFS fs) tyLitToLit (NumTyLit i) = LitNumber LitNumInt (fromIntegral i) intPrimTy instance CBVisitable (Alt Var) where - freeVars env (a, xs, e) = freeVars env a ++ freeVars (extendEnv env xs) e - readVars (_,_, e) = readVars e - letVars (_,xs,e) = xs ++ letVars e - literals (c,_, e) = literals c ++ literals e + freeVars env (Alt a xs e) = freeVars env a ++ freeVars (extendEnv env xs) e + readVars (Alt _ _ e) = readVars e + letVars (Alt _ xs e) = xs ++ letVars e + literals (Alt c _ e) = literals c ++ literals e instance CBVisitable AltCon where freeVars _ (DataAlt dc) = [ x | AnId x <- dataConImplicitTyThings dc] @@ -189,7 +190,7 @@ coreVisitor vis env acc cbs = snd (foldl' step (env, acc) cbs) goE env acc (Case e _ _ cs) = foldl' (goC env) (stepE env acc e) cs goE _ acc _ = acc - goC env acc (_, xs, e) = stepE env' acc' e + goC env acc (Alt _ xs e) = stepE env' acc' e where env' = foldl' (envF vis) env xs acc' = foldl' (bindF vis env) acc xs diff --git a/src/Language/Haskell/Liquid/UX/ACSS.hs b/src/Language/Haskell/Liquid/UX/ACSS.hs index 000292644a..78c21e6858 100644 --- a/src/Language/Haskell/Liquid/UX/ACSS.hs +++ b/src/Language/Haskell/Liquid/UX/ACSS.hs @@ -1,4 +1,4 @@ -{-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wno-name-shadowing -Wno-incomplete-uni-patterns #-} -- | Formats Haskell source code as HTML with CSS and Mouseover Type Annotations module Language.Haskell.Liquid.UX.ACSS ( diff --git a/src/Language/Haskell/Liquid/UX/DiffCheck.hs b/src/Language/Haskell/Liquid/UX/DiffCheck.hs index 6a5c653d3c..9a4b75ca93 100644 --- a/src/Language/Haskell/Liquid/UX/DiffCheck.hs +++ b/src/Language/Haskell/Liquid/UX/DiffCheck.hs @@ -6,10 +6,11 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-orphans #-} {-# OPTIONS_GHC -Wno-name-shadowing #-} -{-# LANGUAGE TupleSections #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Language.Haskell.Liquid.UX.DiffCheck ( @@ -421,8 +422,8 @@ exprSpans (Cast e _) = exprSpans e exprSpans (Case e x _ cs) = getSrcSpan x : exprSpans e ++ concatMap altSpans cs exprSpans _ = [] -altSpans :: (NamedThing a, NamedThing a1) => (t, [a], Expr a1) -> [SrcSpan] -altSpans (_, xs, e) = map getSrcSpan xs ++ exprSpans e +altSpans :: (NamedThing b) => Alt b -> [SrcSpan] +altSpans (Alt _ xs e) = map getSrcSpan xs ++ exprSpans e isJunkSpan :: SrcSpan -> Bool isJunkSpan RealSrcSpan{} = False @@ -545,7 +546,7 @@ adjustSpan _ sp = Just sp adjustReal :: LMap -> RealSrcSpan -> Maybe RealSrcSpan adjustReal lm rsp - | Just δ <- sh = Just $ realSrcSpan f (l1 + δ) c1 (l2 + δ) c2 + | Just δ <- sh = Just $ packRealSrcSpan f (l1 + δ) c1 (l2 + δ) c2 | otherwise = Nothing where (f, l1, c1, l2, c2) = unpackRealSrcSpan rsp diff --git a/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs index 5ef1af4ca8..81b43916ef 100644 --- a/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs +++ b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs @@ -175,8 +175,6 @@ instance Applicative Simpl where FoundHole <*> _ = FoundHole instance Monad Simpl where - return = Simplified - Simplified x >>= f = f x FoundExprArg l >>= _ = FoundExprArg l FoundHole >>= _ = FoundHole diff --git a/src/Language/Haskell/Liquid/WiredIn.hs b/src/Language/Haskell/Liquid/WiredIn.hs index 696049a8d7..4ba5cfab6f 100644 --- a/src/Language/Haskell/Liquid/WiredIn.hs +++ b/src/Language/Haskell/Liquid/WiredIn.hs @@ -1,5 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} + module Language.Haskell.Liquid.WiredIn ( wiredTyCons , wiredDataCons diff --git a/stack.yaml b/stack.yaml index 865554838b..b23893b866 100644 --- a/stack.yaml +++ b/stack.yaml @@ -23,16 +23,15 @@ packages: - benchmark-timings - . extra-deps: -- blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 -- colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 - hashable-1.3.5.0 -- rest-rewrite-0.3.0 +- rest-rewrite-0.4.0 - git: https://github.com/qnikst/ghc-timings-report commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 # for tests - strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 -resolver: lts-19.33 +resolver: lts-20.1 +allow-newer: true nix: packages: [cacert, git, hostname, z3] diff --git a/stack.yaml.lock b/stack.yaml.lock index fc33be4d53..a3456d5945 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -5,54 +5,40 @@ packages: - completed: - pantry-tree: - sha256: e1a52f56ec0cab647ec7af0d75bfbb45f09cccea4a8127996cb7b132bd73bd2c - size: 279 - hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 - original: - hackage: blaze-colonnade-1.2.2.1@sha256:b27601f0366b006e86ee33297a722fe33c94ac058e61d4eace387d132e656a21,1394 -- completed: - pantry-tree: - sha256: 2010fda4c4af2dd9da64786d9e902f387b6a9cb034eb6573d678e752deecc319 - size: 327 - hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 - original: - hackage: colonnade-1.2.0.2@sha256:e0b43a1fe4f87072f3f7cd9eaccdb790f7df8ceff5f73c3a4e242aba9337485f,2099 -- completed: + hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 pantry-tree: sha256: 4df2f6b536a0fcc5f7d562cb29e373f27dc4a2747452ac5cc74c1599cab22fc5 size: 1248 - hackage: hashable-1.3.5.0@sha256:3a2beeafb220f9de706568a7e4a5b3c762cc4c9f25c94d7ef795b8c2d6a691d7,4240 original: hackage: hashable-1.3.5.0 - completed: + hackage: rest-rewrite-0.4.0@sha256:be93d899f7dece33f2a7613eb3dabd24d139f9cb2fc09f9efedfdce4ba6eb276,3923 pantry-tree: - sha256: 6e42cf85257cbc2abf50a9c8f3bac8777920f1b970e6f2cae9358690e1186e99 - size: 3943 - hackage: rest-rewrite-0.3.0@sha256:398f937a5faf6bd3329650ee9aed31bbfe7ed1c23252710908ad7295e3252c94,3890 + sha256: ad19ccb2185ac0b58ddfd2eede69e6444986e687232e1504eb04ce7bb6e39368 + size: 4018 original: - hackage: rest-rewrite-0.3.0 + hackage: rest-rewrite-0.4.0 - completed: + commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 + git: https://github.com/qnikst/ghc-timings-report name: ghc-timings pantry-tree: sha256: 72622264696c78cda23cf96382dee7a3d14e3eafdb8977486338f113681dcec4 size: 7544 - commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 - git: https://github.com/qnikst/ghc-timings-report version: '0.1' original: commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 git: https://github.com/qnikst/ghc-timings-report - completed: + hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 pantry-tree: sha256: cf7712453587e8ea69b96f33e2e8015c22d3b448259d4cace663cc15657309d7 size: 671 - hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 original: hackage: strip-ansi-escape-0.1.0.0@sha256:08f2ed93b16086a837ec46eab7ce8d27cf39d47783caaeb818878ea33c2ff75f,1628 snapshots: - completed: - sha256: 6d1532d40621957a25bad5195bfca7938e8a06d923c91bc52aa0f3c41181f2d4 - size: 619204 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/33.yaml - original: lts-19.33 + sha256: b73b2b116143aea728c70e65c3239188998bac5bc3be56465813dacd74215dc5 + size: 648424 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/20/1.yaml + original: lts-20.1 From be317e1a6479ce4a0a67bec50469ef0a50b112a4 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Mon, 26 Dec 2022 12:42:42 +0200 Subject: [PATCH 074/219] Add comment about disabling LH plugin when type checking Disabling the LH plugin before calling the type checker is already what was happening previously, but the reason why was not documented. This led to a long debugging session when I accidentally dropped this behaviour during the port to GHC 9.2. --- src/Language/Haskell/Liquid/GHC/Plugin.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Language/Haskell/Liquid/GHC/Plugin.hs b/src/Language/Haskell/Liquid/GHC/Plugin.hs index cb15a41497..466334f0fa 100644 --- a/src/Language/Haskell/Liquid/GHC/Plugin.hs +++ b/src/Language/Haskell/Liquid/GHC/Plugin.hs @@ -225,6 +225,9 @@ typecheckHook _ (unoptimise -> modSummary) tcGblEnv = do parsed <- GhcMonadLike.parseModule (LH.keepRawTokenStream modSummary) let comments = LH.extractSpecComments parsed + -- The LH plugin itself calls the type checker (see following line). This + -- would lead to a loop if we didn't remove the plugin when calling the type + -- checker. typechecked <- updTopEnv dropPlugins $ GhcMonadLike.typecheckModule (LH.ignoreInline parsed) env <- askHscEnv resolvedNames <- LH.lookupTyThings env modSummary tcGblEnv From 866e219bdb1c6d60f579d8a42b13371f495f3ca3 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Sun, 25 Dec 2022 23:53:49 +0200 Subject: [PATCH 075/219] Update liquid-ghc-prim to reexport ghc-prim-0.8 --- liquid-ghc-prim/liquid-ghc-prim.cabal | 10 +++++----- liquid-ghc-prim/src/GHC/IntWord64.hs | 3 --- liquid-ghc-prim/src/GHC/Prim/Exception.hs | 3 +++ liquid-ghc-prim/src/GHC/Prim/Panic.hs | 3 +++ liquid-ghc-prim/src/GHC/PrimopWrappers.hs | 3 --- 5 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 liquid-ghc-prim/src/GHC/IntWord64.hs create mode 100644 liquid-ghc-prim/src/GHC/Prim/Exception.hs create mode 100644 liquid-ghc-prim/src/GHC/Prim/Panic.hs delete mode 100644 liquid-ghc-prim/src/GHC/PrimopWrappers.hs diff --git a/liquid-ghc-prim/liquid-ghc-prim.cabal b/liquid-ghc-prim/liquid-ghc-prim.cabal index 7aa2a62ddf..d4c2fd21a1 100644 --- a/liquid-ghc-prim/liquid-ghc-prim.cabal +++ b/liquid-ghc-prim/liquid-ghc-prim.cabal @@ -1,4 +1,4 @@ -cabal-version: 1.24 +cabal-version: 2.0 name: liquid-ghc-prim version: 0.6.1 synopsis: Drop-in ghc-prim replacement for LiquidHaskell @@ -28,15 +28,15 @@ library GHC.CString GHC.Classes GHC.Debug - GHC.IntWord64 GHC.Magic + GHC.Prim.Exception GHC.Prim.Ext - GHC.PrimopWrappers + GHC.Prim.Panic GHC.Tuple GHC.Types hs-source-dirs: src - build-depends: ghc-prim >= 0.6.1 && < 0.9 + build-depends: ghc-prim ^>= 0.8 , liquidhaskell >= 0.8.10.1 default-language: Haskell2010 default-extensions: PackageImports @@ -44,4 +44,4 @@ library MagicHash if impl(ghc >= 8.10) ghc-options: -fplugin=LiquidHaskell - \ No newline at end of file + diff --git a/liquid-ghc-prim/src/GHC/IntWord64.hs b/liquid-ghc-prim/src/GHC/IntWord64.hs deleted file mode 100644 index 2084efbedc..0000000000 --- a/liquid-ghc-prim/src/GHC/IntWord64.hs +++ /dev/null @@ -1,3 +0,0 @@ -module GHC.IntWord64 (module Exports) where - -import "ghc-prim" GHC.IntWord64 as Exports diff --git a/liquid-ghc-prim/src/GHC/Prim/Exception.hs b/liquid-ghc-prim/src/GHC/Prim/Exception.hs new file mode 100644 index 0000000000..a4be753435 --- /dev/null +++ b/liquid-ghc-prim/src/GHC/Prim/Exception.hs @@ -0,0 +1,3 @@ +module GHC.Prim.Exception (module Exports) where + +import "ghc-prim" GHC.Prim.Exception as Exports diff --git a/liquid-ghc-prim/src/GHC/Prim/Panic.hs b/liquid-ghc-prim/src/GHC/Prim/Panic.hs new file mode 100644 index 0000000000..082676cb35 --- /dev/null +++ b/liquid-ghc-prim/src/GHC/Prim/Panic.hs @@ -0,0 +1,3 @@ +module GHC.Prim.Panic (module Exports) where + +import "ghc-prim" GHC.Prim.Panic as Exports diff --git a/liquid-ghc-prim/src/GHC/PrimopWrappers.hs b/liquid-ghc-prim/src/GHC/PrimopWrappers.hs deleted file mode 100644 index 86e0664bf7..0000000000 --- a/liquid-ghc-prim/src/GHC/PrimopWrappers.hs +++ /dev/null @@ -1,3 +0,0 @@ -module GHC.PrimopWrappers (module Exports) where - -import "ghc-prim" GHC.PrimopWrappers as Exports From ea224ee75aeb890a07f54b2aed818d4b92fe6c1d Mon Sep 17 00:00:00 2001 From: Quentin Aristote <62126931+qaristote@users.noreply.github.com> Date: Wed, 11 Jan 2023 11:48:27 +0000 Subject: [PATCH 076/219] README: fix typo in path to test scripts `scripts/tests/` -> `scripts/test/` --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cc0e7f49c3..a8bc804518 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ and you can list all the possible test options with or get a list of just the test groups, one per line, with - $ LIQUID_DEV_MODE=true ./scripts/tests/test_810_plugin.sh --show-all + $ LIQUID_DEV_MODE=true ./scripts/test/test_810_plugin.sh --show-all To pass in specific parameters and run a subset of the tests, you can invoke cabal directly with @@ -155,7 +155,7 @@ For details on adding tests, see note [Parallel_Tests] in `tests/test.hs`. When `liquidhaskell` tests run, we can collect timing information with - $ ./scripts/tests/test_810_plugin.sh --measure-timings + $ ./scripts/test/test_810_plugin.sh --measure-timings Measures will be collected in `.dump-timings` files. These can be converted to json data with From 48ce7a2e680cefe4fd133eff42d0ddd5c35f78b4 Mon Sep 17 00:00:00 2001 From: Quentin Aristote <62126931+qaristote@users.noreply.github.com> Date: Wed, 11 Jan 2023 14:15:30 +0000 Subject: [PATCH 077/219] README: performance charts: fix typos --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a8bc804518..cb4e146b4e 100644 --- a/README.md +++ b/README.md @@ -184,14 +184,14 @@ current directory. The current formatting is optimized for comparing the outputs of running the benchmarks alone. - $ scripts/test/test_810_plugin.sh + $ scripts/test/test_810_plugin.sh \ benchmark-stitch-lh \ benchmark-bytestring \ - benchmark-vector-algorithms + benchmark-vector-algorithms \ benchmark-cse230 \ benchmark-esop2013 \ benchmark-icfp15-pos \ - benchmark-icfp15-ne + benchmark-icfp15-neg ## How to Profile From 737cb53599dfa3e0ddf6f2f08745abd29f57c59c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 16 Jan 2023 09:33:20 -0300 Subject: [PATCH 078/219] Use ghc-9.2.5 in cabal job in CI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5a1e2dffcd..4ce7e38b32 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -159,7 +159,7 @@ jobs: image: ubuntu-2004:202107-02 steps: - cabal_build_and_test: - ghc_version: "9.0.2" + ghc_version: "9.2.5" liquid_runner: "--liquid-runner=cabal -v0 v2-exec liquidhaskell -- -v0 \ -package-env=$(./scripts/generate_testing_ghc_env) \ -package=liquidhaskell -package=Cabal " From b8163bd136f3dc1d9c30a9e3c72a2c8e203c17ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 16 Jan 2023 10:30:12 -0300 Subject: [PATCH 079/219] Don't infer LH type of partitions --- liquid-bytestring/src/Data/ByteString.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-bytestring/src/Data/ByteString.spec b/liquid-bytestring/src/Data/ByteString.spec index 89cc03fbec..e8266284d1 100644 --- a/liquid-bytestring/src/Data/ByteString.spec +++ b/liquid-bytestring/src/Data/ByteString.spec @@ -291,7 +291,7 @@ filter -> { o : Data.ByteString.ByteString | bslen o <= bslen i } partition - :: (_ -> GHC.Types.Bool) + :: (GHC.Types.Char -> GHC.Types.Bool) -> i : Data.ByteString.ByteString -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } , { r : Data.ByteString.ByteString | bslen r <= bslen i } From 3e3f9cb10929e02d965ff7c0da4edd58553f7082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 16 Jan 2023 10:31:08 -0300 Subject: [PATCH 080/219] Move embed directives to the spec file --- liquid-ghc-prim/src/GHC/Types.hs | 7 ------- liquid-ghc-prim/src/GHC/Types.spec | 6 ++++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/liquid-ghc-prim/src/GHC/Types.hs b/liquid-ghc-prim/src/GHC/Types.hs index ef2787f7e9..8ddd44ce81 100644 --- a/liquid-ghc-prim/src/GHC/Types.hs +++ b/liquid-ghc-prim/src/GHC/Types.hs @@ -1,10 +1,3 @@ module GHC.Types (module Exports) where import "ghc-prim" GHC.Types as Exports - -{-@ embed GHC.Prim.Int# as int @-} -{-@ embed GHC.Prim.Addr# as Str @-} -{-@ embed GHC.Prim.Char# as Char @-} -{-@ embed GHC.Prim.Double# as real @-} -{-@ embed GHC.Prim.Float# as real @-} -{-@ embed GHC.Prim.Word# as int @-} diff --git a/liquid-ghc-prim/src/GHC/Types.spec b/liquid-ghc-prim/src/GHC/Types.spec index 8cdd28bad9..e8dde2f98d 100644 --- a/liquid-ghc-prim/src/GHC/Types.spec +++ b/liquid-ghc-prim/src/GHC/Types.spec @@ -2,11 +2,17 @@ module spec GHC.Types where // Boxed types embed GHC.Types.Double as real +embed GHC.Prim.Double# as real embed GHC.Types.Float as real +embed GHC.Prim.Float# as real embed GHC.Types.Word as int +embed GHC.Prim.Word# as int embed GHC.Types.Int as int +embed GHC.Prim.Int# as int embed GHC.Types.Bool as bool embed GHC.Types.Char as Char +embed GHC.Prim.Char# as Char +embed GHC.Prim.Addr# as Str embed GHC.Integer.Type.Integer as int embed GHC.Num.Integer as int From fbbf074cb472bf6bcf88c54706085cd86c682b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 16 Jan 2023 10:31:50 -0300 Subject: [PATCH 081/219] Bring embed directives in scope to Prelude --- liquid-prelude/liquid-prelude.cabal | 1 + liquid-prelude/src/Language/Haskell/Liquid/Prelude.hs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/liquid-prelude/liquid-prelude.cabal b/liquid-prelude/liquid-prelude.cabal index c81001ab29..bc46fb6bfe 100644 --- a/liquid-prelude/liquid-prelude.cabal +++ b/liquid-prelude/liquid-prelude.cabal @@ -29,6 +29,7 @@ library KMeansHelper hs-source-dirs: src build-depends: liquid-base < 5 + , liquid-ghc-prim , bytestring >= 0.10.0.0 && < 0.12 , containers >= 0.6.0.0 && < 0.7 , liquidhaskell >= 0.8.10.2 diff --git a/liquid-prelude/src/Language/Haskell/Liquid/Prelude.hs b/liquid-prelude/src/Language/Haskell/Liquid/Prelude.hs index 7a4be44aaf..0a839374f9 100644 --- a/liquid-prelude/src/Language/Haskell/Liquid/Prelude.hs +++ b/liquid-prelude/src/Language/Haskell/Liquid/Prelude.hs @@ -2,6 +2,8 @@ module Language.Haskell.Liquid.Prelude where +import GHC.Types() -- import specs + ------------------------------------------------------------------- --------------------------- Arithmetic ---------------------------- ------------------------------------------------------------------- From 64f0992f7f38751502821187892915fba3cf2743 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 18 Jan 2023 11:43:53 +0100 Subject: [PATCH 082/219] make executable run again --- include/GHC/Num.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/GHC/Num.spec b/include/GHC/Num.spec index 984687e0e3..ac04f687e2 100644 --- a/include/GHC/Num.spec +++ b/include/GHC/Num.spec @@ -1,8 +1,8 @@ module spec GHC.Num where -embed GHC.Integer.Type.Integer as int +// embed GHC.Integer.Type.Integer as int -GHC.Num.fromInteger :: (GHC.Num.Num a) => x:GHC.Integer.Type.Integer -> {v:a | v = x } +GHC.Num.fromInteger :: (GHC.Num.Num a) => x:_ -> {v:a | v = x } GHC.Num.negate :: (GHC.Num.Num a) => x:a From 266a11c53c49cf85477c093f9fbad2c79ae02934 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 18 Jan 2023 11:44:12 +0100 Subject: [PATCH 083/219] fix name resolution error --- src/Language/Haskell/Liquid/Bare/DataType.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Bare/DataType.hs b/src/Language/Haskell/Liquid/Bare/DataType.hs index 49891c8157..f743558951 100644 --- a/src/Language/Haskell/Liquid/Bare/DataType.hs +++ b/src/Language/Haskell/Liquid/Bare/DataType.hs @@ -359,10 +359,11 @@ meetDataConSpec :: Bool -> F.TCEmb Ghc.TyCon -> [(Ghc.Var, SpecType)] -> [DataCo -------------------------------------------------------------------------------- meetDataConSpec allowTC emb xts dcs = M.toList $ snd <$> L.foldl' upd dcm0 xts where - dcm0 = M.fromList (dataConSpec' allowTC dcs) + dcm0 = M.fromListWith meetM (dataConSpec' allowTC dcs) upd dcm (x, t) = M.insert x (Ghc.getSrcSpan x, tx') dcm where tx' = maybe t (meetX x t) (M.lookup x dcm) + meetM (l,t) (_,t') = (l, t `F.meet` t') meetX x t (sp', t') = F.notracepp (_msg x t t') $ meetVarTypes emb (pprint x) (Ghc.getSrcSpan x, t) (sp', t') _msg x t t' = "MEET-VAR-TYPES: " ++ showpp (x, t, t') From 8b8648164b69fa188c126f863641d7395eeb6cc0 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 18 Jan 2023 11:48:58 +0100 Subject: [PATCH 084/219] add double import test --- tests/import/client/C.hs | 9 +++++++++ tests/import/lib/B.hs | 8 ++++++++ tests/import/lib/Language.hs | 10 ++++++++++ tests/tests.cabal | 3 +++ 4 files changed, 30 insertions(+) create mode 100644 tests/import/client/C.hs create mode 100644 tests/import/lib/B.hs create mode 100644 tests/import/lib/Language.hs diff --git a/tests/import/client/C.hs b/tests/import/client/C.hs new file mode 100644 index 0000000000..0e5fc50400 --- /dev/null +++ b/tests/import/client/C.hs @@ -0,0 +1,9 @@ +{-@ LIQUID "--reflection" @-} + +module C where +import Language +import B + +{-@ getVal :: {e:Expr l st r | isEFalse e } -> {v:Int | false} @-} +getVal :: Expr l st r -> Int +getVal (EFalse v) = v \ No newline at end of file diff --git a/tests/import/lib/B.hs b/tests/import/lib/B.hs new file mode 100644 index 0000000000..9257ed03ef --- /dev/null +++ b/tests/import/lib/B.hs @@ -0,0 +1,8 @@ +{-@ LIQUID "--reflection" @-} +module B where +import Language + +{-@ reflect subst @-} +subst :: Expr l st r -> Expr l st r +subst EUnit = EUnit +subst e = e \ No newline at end of file diff --git a/tests/import/lib/Language.hs b/tests/import/lib/Language.hs new file mode 100644 index 0000000000..c156334d39 --- /dev/null +++ b/tests/import/lib/Language.hs @@ -0,0 +1,10 @@ +module Language where + +data Expr l st r = EUnit | EFalse Int +{-@ data Expr l st r = EUnit | EFalse { elb1 :: {xxx:Int | false}} @-} + + +{-@ measure isEFalse @-} +isEFalse :: Expr l st r -> Bool +isEFalse (EFalse _ ) = True +isEFalse _ = False \ No newline at end of file diff --git a/tests/tests.cabal b/tests/tests.cabal index 1c83e5b380..24fbd37ac3 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2224,6 +2224,9 @@ executable import-cli , T1738Lib , WrapLib , WrapLibCode + , Language + , B + , C ghc-options: -fplugin=LiquidHaskell -fkeep-going From 8689f1a499a0041258f280bcb40f705f39224662 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Fri, 20 Jan 2023 14:12:22 +0100 Subject: [PATCH 085/219] allow not in spec --- include/CoreToLogic.lg | 1 + src/Language/Haskell/Liquid/Parse.hs | 2 +- tests/pos/LNot.hs | 30 ++++++++++++++++++++++++++++ tests/tests.cabal | 1 + 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/pos/LNot.hs diff --git a/include/CoreToLogic.lg b/include/CoreToLogic.lg index efb2e0d5aa..6fe3124087 100644 --- a/include/CoreToLogic.lg +++ b/include/CoreToLogic.lg @@ -23,6 +23,7 @@ define GHC.Real.fromIntegral x = (x) define GHC.Types.True = (true) define GHC.Real.div x y = (x / y) define GHC.Real.mod x y = (x mod y) +define GHC.Classes.not x = (~ x) define GHC.Base.$ f x = (f x) define Language.Haskell.Liquid.Bag.get k m = (Map_select m k) diff --git a/src/Language/Haskell/Liquid/Parse.hs b/src/Language/Haskell/Liquid/Parse.hs index cb655088a2..37babe3706 100644 --- a/src/Language/Haskell/Liquid/Parse.hs +++ b/src/Language/Haskell/Liquid/Parse.hs @@ -198,7 +198,7 @@ toLogicOneP = do reserved "define" (x:xs) <- some locSymbolP reservedOp "=" - e <- exprP + e <- (exprP <|> predP) return (x, val <$> xs, e) diff --git a/tests/pos/LNot.hs b/tests/pos/LNot.hs new file mode 100644 index 0000000000..729eff0a0f --- /dev/null +++ b/tests/pos/LNot.hs @@ -0,0 +1,30 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} +module LNot where +import Prelude hiding (any, all, filter, nub, foldr, flip) + + + +{-@ lemma_all_ex_not :: f:(a->Bool) -> ls:[a] -> { (bnot (any f ls)) == all (bnot . f) ls} @-} +lemma_all_ex_not :: (a->Bool) -> [a] -> () +lemma_all_ex_not f [] = () +lemma_all_ex_not f (x:xs) + | f x = lemma_all_ex_not f xs +lemma_all_ex_not f (x:xs) + | (bnot . f) x = lemma_all_ex_not f xs + +{-@ reflect any @-} +any :: (a -> Bool) -> [a] -> Bool +any _ [] = False +any p (x:xs) = if p x then True else any p xs + +{-@ reflect all @-} +all :: (a -> Bool) -> [a] -> Bool +all _ [] = True +all p (x:xs) = if p x then all p xs else False + +{-@ reflect bnot @-} +{-@ bnot :: x:Bool -> {v:Bool | v = not x} @-} +bnot :: Bool -> Bool +bnot True = False +bnot False = True \ No newline at end of file diff --git a/tests/tests.cabal b/tests/tests.cabal index 24fbd37ac3..909c9aa366 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -1925,6 +1925,7 @@ executable unit-pos-2 , Loo , LooLib , LooLibLib + , LNot ghc-options: -fplugin=LiquidHaskell -fkeep-going -O0 if flag(measure-timings) From 933d281e689ccd7a5ae7b8aa82ff3cc326250d55 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Fri, 20 Jan 2023 14:14:33 +0100 Subject: [PATCH 086/219] fine hlint --- src/Language/Haskell/Liquid/Parse.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Parse.hs b/src/Language/Haskell/Liquid/Parse.hs index 37babe3706..3384ac1265 100644 --- a/src/Language/Haskell/Liquid/Parse.hs +++ b/src/Language/Haskell/Liquid/Parse.hs @@ -198,7 +198,7 @@ toLogicOneP = do reserved "define" (x:xs) <- some locSymbolP reservedOp "=" - e <- (exprP <|> predP) + e <- exprP <|> predP return (x, val <$> xs, e) From 7e530f765003476cbd78784d85ab5794d566fb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 25 Jan 2023 16:34:33 -0300 Subject: [PATCH 087/219] Collect comments attached to declarations --- src-ghc/Liquid/GHC/GhcMonadLike.hs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index f97a61d85c..3c40f67368 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -300,11 +300,13 @@ data ApiComment -- | Extract top-level comments from a module. apiComments :: ParsedModule -> [Ghc.Located ApiComment] apiComments pm = - case pm_parsed_source pm of - L _ (HsModule { hsmodAnn = anns' }) -> - mapMaybe (tokComment . toRealSrc) $ - priorComments $ - epAnnComments anns' + let hs = unLoc (pm_parsed_source pm) + modComments = epAnnComments (hsmodAnn hs) + declComments = map (epAnnComments . ann . getLoc) (hsmodDecls hs) + in + mapMaybe (tokComment . toRealSrc) $ + concatMap priorComments $ + modComments : declComments where tokComment (L sp (EpaComment (EpaLineComment s) _)) = Just (L sp (ApiLineComment s)) tokComment (L sp (EpaComment (EpaBlockComment s) _)) = Just (L sp (ApiBlockComment s)) From d96b9691c0708a340e3c05335c4503c10d766f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Thu, 26 Jan 2023 23:21:13 -0300 Subject: [PATCH 088/219] Collect comments from import declarations --- src-ghc/Liquid/GHC/GhcMonadLike.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index 3c40f67368..93347c19fb 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -296,17 +296,19 @@ lookupModule mod_name Nothing = do data ApiComment = ApiLineComment String | ApiBlockComment String + deriving Show -- | Extract top-level comments from a module. apiComments :: ParsedModule -> [Ghc.Located ApiComment] apiComments pm = let hs = unLoc (pm_parsed_source pm) + importComments = map (epAnnComments . ann . getLoc) (hsmodImports hs) modComments = epAnnComments (hsmodAnn hs) declComments = map (epAnnComments . ann . getLoc) (hsmodDecls hs) in mapMaybe (tokComment . toRealSrc) $ concatMap priorComments $ - modComments : declComments + importComments ++ modComments : declComments where tokComment (L sp (EpaComment (EpaLineComment s) _)) = Just (L sp (ApiLineComment s)) tokComment (L sp (EpaComment (EpaBlockComment s) _)) = Just (L sp (ApiBlockComment s)) From b982fcf35519c80d68fae8094b14c6bfa6314bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Thu, 26 Jan 2023 23:33:17 -0300 Subject: [PATCH 089/219] Add missing antecedent to theorem of Bags --- liquid-prelude/src/Language/Haskell/Liquid/Bag.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-prelude/src/Language/Haskell/Liquid/Bag.hs b/liquid-prelude/src/Language/Haskell/Liquid/Bag.hs index 93f2da5197..5d7aa53a21 100644 --- a/liquid-prelude/src/Language/Haskell/Liquid/Bag.hs +++ b/liquid-prelude/src/Language/Haskell/Liquid/Bag.hs @@ -44,7 +44,7 @@ put k m = M.insert k (1 + get k m) m union :: (Ord k) => Bag k -> Bag k -> Bag k union m1 m2 = M.union m1 m2 -{-@ thm_emp :: x:k -> xs:Bag k -> { Language.Haskell.Liquid.Bag.empty /= put x xs } @-} +{-@ thm_emp :: x:k -> xs:Bag k -> { Map_select xs x >= 0 => Language.Haskell.Liquid.Bag.empty /= put x xs } @-} thm_emp :: (Ord k) => k -> Bag k -> () thm_emp x xs = const () (get x xs) From 3660b8cddaa4258ee355522dcb39e9a0af7f1fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Fri, 27 Jan 2023 10:45:33 -0300 Subject: [PATCH 090/219] Collect comments from match groups --- src-ghc/Liquid/GHC/GhcMonadLike.hs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index 93347c19fb..b691731c98 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -1,4 +1,5 @@ {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} -- | This module introduces a \"lighter\" "GhcMonad" typeclass which doesn't require an instance of @@ -304,7 +305,8 @@ apiComments pm = let hs = unLoc (pm_parsed_source pm) importComments = map (epAnnComments . ann . getLoc) (hsmodImports hs) modComments = epAnnComments (hsmodAnn hs) - declComments = map (epAnnComments . ann . getLoc) (hsmodDecls hs) + declComments = concat $ concat + [ [funBindMatchComments d, [ epAnnComments (ann sp)]] | L sp d <- hsmodDecls hs ] in mapMaybe (tokComment . toRealSrc) $ concatMap priorComments $ @@ -317,3 +319,7 @@ apiComments pm = -- TODO: take into account anchor_op, which only matters if the source was -- pre-processed by an exact-print-aware tool. toRealSrc (L a e) = L (RealSrcSpan (anchor a) Nothing) e + + funBindMatchComments (ValD _ fb@FunBind{}) = + map (epAnnComments . ann . getLoc) $ unLoc $ mg_alts $ fun_matches fb + funBindMatchComments _ = [] From fd0d37c601d7ea448ae9e07a0c47b02ae450d999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Fri, 27 Jan 2023 10:45:57 -0300 Subject: [PATCH 091/219] Adjust spec of ByteString.partition --- liquid-bytestring/src/Data/ByteString.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-bytestring/src/Data/ByteString.spec b/liquid-bytestring/src/Data/ByteString.spec index e8266284d1..e13a85dc0e 100644 --- a/liquid-bytestring/src/Data/ByteString.spec +++ b/liquid-bytestring/src/Data/ByteString.spec @@ -291,7 +291,7 @@ filter -> { o : Data.ByteString.ByteString | bslen o <= bslen i } partition - :: (GHC.Types.Char -> GHC.Types.Bool) + :: (Word8 -> GHC.Types.Bool) -> i : Data.ByteString.ByteString -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } , { r : Data.ByteString.ByteString | bslen r <= bslen i } From 6bb3904466ccc981853a5651ca9d98ccbfad10d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Fri, 27 Jan 2023 17:26:38 -0300 Subject: [PATCH 092/219] Implement generic traversal to collect comments in the AST --- src-ghc/Liquid/GHC/GhcMonadLike.hs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index b691731c98..4523f996a2 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -1,7 +1,9 @@ {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE RankNTypes #-} -- | This module introduces a \"lighter\" "GhcMonad" typeclass which doesn't require an instance of -- 'ExceptionMonad', and can therefore be used for both 'CoreM' and 'Ghc'. -- @@ -36,6 +38,8 @@ module Liquid.GHC.GhcMonadLike ( import Control.Monad.IO.Class import Control.Exception (throwIO) +import Data.Data (Data, gmapQr) +import Data.Generics (extQ) import qualified Liquid.GHC.API as Ghc import Liquid.GHC.API hiding ( ModuleInfo , findModule @@ -303,14 +307,9 @@ data ApiComment apiComments :: ParsedModule -> [Ghc.Located ApiComment] apiComments pm = let hs = unLoc (pm_parsed_source pm) - importComments = map (epAnnComments . ann . getLoc) (hsmodImports hs) - modComments = epAnnComments (hsmodAnn hs) - declComments = concat $ concat - [ [funBindMatchComments d, [ epAnnComments (ann sp)]] | L sp d <- hsmodDecls hs ] - in - mapMaybe (tokComment . toRealSrc) $ - concatMap priorComments $ - importComments ++ modComments : declComments + go :: forall a. Data a => a -> [LEpaComment] + go = gmapQr (++) [] go `extQ` (id @[LEpaComment]) + in mapMaybe (tokComment . toRealSrc) $ go hs where tokComment (L sp (EpaComment (EpaLineComment s) _)) = Just (L sp (ApiLineComment s)) tokComment (L sp (EpaComment (EpaBlockComment s) _)) = Just (L sp (ApiBlockComment s)) @@ -319,7 +318,3 @@ apiComments pm = -- TODO: take into account anchor_op, which only matters if the source was -- pre-processed by an exact-print-aware tool. toRealSrc (L a e) = L (RealSrcSpan (anchor a) Nothing) e - - funBindMatchComments (ValD _ fb@FunBind{}) = - map (epAnnComments . ann . getLoc) $ unLoc $ mg_alts $ fun_matches fb - funBindMatchComments _ = [] From 58133cc090ef500f577ee804ddabea6a7b7054e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Fri, 27 Jan 2023 17:36:39 -0300 Subject: [PATCH 093/219] Update liquid-bytestring to 0.11.3.1 --- liquid-bytestring/liquid-bytestring.cabal | 7 ++----- liquid-bytestring/src/Data/ByteString/Lazy/Builder.hs | 3 --- .../src/Data/ByteString/Lazy/Builder/ASCII.hs | 3 --- .../src/Data/ByteString/Lazy/Builder/Extras.hs | 3 --- liquid-platform/liquid-platform.cabal | 2 +- 5 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 liquid-bytestring/src/Data/ByteString/Lazy/Builder.hs delete mode 100644 liquid-bytestring/src/Data/ByteString/Lazy/Builder/ASCII.hs delete mode 100644 liquid-bytestring/src/Data/ByteString/Lazy/Builder/Extras.hs diff --git a/liquid-bytestring/liquid-bytestring.cabal b/liquid-bytestring/liquid-bytestring.cabal index 8f0c26c819..8841b459bd 100644 --- a/liquid-bytestring/liquid-bytestring.cabal +++ b/liquid-bytestring/liquid-bytestring.cabal @@ -1,6 +1,6 @@ cabal-version: 1.24 name: liquid-bytestring -version: 0.10.10.0 +version: 0.11.3.1 synopsis: LiquidHaskell specs for the bytestring package description: LiquidHaskell specs for the bytestring package. license: BSD3 @@ -38,9 +38,6 @@ library Data.ByteString.Builder.Internal Data.ByteString.Builder.Prim.Internal - Data.ByteString.Lazy.Builder - Data.ByteString.Lazy.Builder.Extras - Data.ByteString.Lazy.Builder.ASCII -- FIXME: This is commented out as unfortunately it doesn't refine -- correctly with modern versions of bytestring. @@ -48,7 +45,7 @@ library hs-source-dirs: src build-depends: liquid-base < 5 - , bytestring >= 0.10.10.0 && < 0.12 + , bytestring >= 0.11 && < 0.12 , liquidhaskell >= 0.8.10.1 default-language: Haskell2010 default-extensions: PackageImports diff --git a/liquid-bytestring/src/Data/ByteString/Lazy/Builder.hs b/liquid-bytestring/src/Data/ByteString/Lazy/Builder.hs deleted file mode 100644 index 451e224a33..0000000000 --- a/liquid-bytestring/src/Data/ByteString/Lazy/Builder.hs +++ /dev/null @@ -1,3 +0,0 @@ -module Data.ByteString.Lazy.Builder (module Exports) where - -import "bytestring" Data.ByteString.Lazy.Builder as Exports diff --git a/liquid-bytestring/src/Data/ByteString/Lazy/Builder/ASCII.hs b/liquid-bytestring/src/Data/ByteString/Lazy/Builder/ASCII.hs deleted file mode 100644 index ed271554e9..0000000000 --- a/liquid-bytestring/src/Data/ByteString/Lazy/Builder/ASCII.hs +++ /dev/null @@ -1,3 +0,0 @@ -module Data.ByteString.Lazy.Builder.ASCII (module Exports) where - -import "bytestring" Data.ByteString.Lazy.Builder.ASCII as Exports diff --git a/liquid-bytestring/src/Data/ByteString/Lazy/Builder/Extras.hs b/liquid-bytestring/src/Data/ByteString/Lazy/Builder/Extras.hs deleted file mode 100644 index 71b47ea203..0000000000 --- a/liquid-bytestring/src/Data/ByteString/Lazy/Builder/Extras.hs +++ /dev/null @@ -1,3 +0,0 @@ -module Data.ByteString.Lazy.Builder.Extras (module Exports) where - -import "bytestring" Data.ByteString.Lazy.Builder.Extras as Exports diff --git a/liquid-platform/liquid-platform.cabal b/liquid-platform/liquid-platform.cabal index 214facca6b..e2c691f781 100644 --- a/liquid-platform/liquid-platform.cabal +++ b/liquid-platform/liquid-platform.cabal @@ -29,7 +29,7 @@ executable liquidhaskell , liquid-containers >= 0.6.2.1 && < 0.7 , liquid-prelude >= 0.8.10.2 , liquid-vector >= 0.12.1.2 && < 0.13 - , liquid-bytestring >= 0.10.0.0 && < 0.11 + , liquid-bytestring >= 0.11 && < 0.12 , liquidhaskell >= 0.8.10.2 , filepath , process >= 1.6.0.0 && < 1.7 From 32aa8196fdb5d40d83529018b3ae8facf029c635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sun, 29 Jan 2023 23:31:52 -0300 Subject: [PATCH 094/219] Improve error message in casesToLg --- src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs index 7ee621eca8..bd181568d9 100644 --- a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs +++ b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs @@ -331,7 +331,7 @@ casesToLg allowTC v e alts = mapM (altToLg allowTC e) normAlts >>= go go ((d,p):dps) = do c <- checkDataAlt d e e' <- go dps return (EIte c p e' `subst1` su) - go [] = panic (Just (getSrcSpan v)) "Unexpected empty cases in casesToLg" + go [] = panic (Just (getSrcSpan v)) $ "Unexpected empty cases in casesToLg: " ++ show e su = (symbol v, e) checkDataAlt :: C.AltCon -> Expr -> LogicM Expr From 1eee4b839001e0c500250cd04586bedcd4b6567f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sun, 29 Jan 2023 23:33:23 -0300 Subject: [PATCH 095/219] Drop alternatives with empty cases when simplifying in CoreToLogic --- .../Haskell/Liquid/Transforms/CoreToLogic.hs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs index bd181568d9..f7e46e73a3 100644 --- a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs +++ b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs @@ -647,11 +647,18 @@ instance Simplify C.CoreExpr where inline _ (C.Coercion c) = C.Coercion c inline _ (C.Type t) = C.Type t -isUndefined :: Alt b -> Bool +isUndefined :: CoreAlt -> Bool isUndefined (Alt _ _ e) = isUndefinedExpr e where - -- auto generated undefined case: (\_ -> (patError @type "error message")) void - isUndefinedExpr (C.App (C.Var x) _) | show x `elem` perrors = True + isUndefinedExpr :: C.CoreExpr -> Bool + -- auto generated undefined case: (\_ -> (patError @levity @type "error message")) void + -- Type arguments are erased before calling isUndefined + isUndefinedExpr (C.App (C.Var x) _) + | show x `elem` perrors = True + -- another auto generated undefined case: + -- let lqanf_... = patError "error message") in case lqanf_... of {} + isUndefinedExpr (C.Let (C.NonRec x e) (C.Case (C.Var v) _ _ [])) + | x == v = isUndefinedExpr e isUndefinedExpr (C.Let _ e) = isUndefinedExpr e -- otherwise isUndefinedExpr _ = False From e3c3e5a0e6786d501c104314fb65ef1129933f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 30 Jan 2023 11:04:03 -0300 Subject: [PATCH 096/219] Don't reverse comments before parsing them --- src/Language/Haskell/Liquid/Parse.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Parse.hs b/src/Language/Haskell/Liquid/Parse.hs index cb655088a2..9bed5c5a94 100644 --- a/src/Language/Haskell/Liquid/Parse.hs +++ b/src/Language/Haskell/Liquid/Parse.hs @@ -57,7 +57,7 @@ hsSpecificationP :: ModuleName -> [BPspec] -> Either [Error] (ModName, Measure.BareSpec) hsSpecificationP modName specComments specQuotes = - case go ([], []) initPStateWithList $ reverse specComments of + case go ([], []) initPStateWithList specComments of ([], specs) -> Right $ mkSpec (ModName SrcImport modName) (specs ++ specQuotes) (errors, _) -> From bcf16dbfc8966015f18069515b20ad3eb1bc6235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 30 Jan 2023 11:54:52 -0300 Subject: [PATCH 097/219] Sort comments by location --- src-ghc/Liquid/GHC/GhcMonadLike.hs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src-ghc/Liquid/GHC/GhcMonadLike.hs b/src-ghc/Liquid/GHC/GhcMonadLike.hs index 4523f996a2..234850b9d9 100644 --- a/src-ghc/Liquid/GHC/GhcMonadLike.hs +++ b/src-ghc/Liquid/GHC/GhcMonadLike.hs @@ -40,6 +40,7 @@ import Control.Exception (throwIO) import Data.Data (Data, gmapQr) import Data.Generics (extQ) +import qualified Data.List import qualified Liquid.GHC.API as Ghc import Liquid.GHC.API hiding ( ModuleInfo , findModule @@ -309,7 +310,8 @@ apiComments pm = let hs = unLoc (pm_parsed_source pm) go :: forall a. Data a => a -> [LEpaComment] go = gmapQr (++) [] go `extQ` (id @[LEpaComment]) - in mapMaybe (tokComment . toRealSrc) $ go hs + in Data.List.sortOn (spanToLineColumn . getLoc) $ + mapMaybe (tokComment . toRealSrc) $ go hs where tokComment (L sp (EpaComment (EpaLineComment s) _)) = Just (L sp (ApiLineComment s)) tokComment (L sp (EpaComment (EpaBlockComment s) _)) = Just (L sp (ApiBlockComment s)) @@ -318,3 +320,6 @@ apiComments pm = -- TODO: take into account anchor_op, which only matters if the source was -- pre-processed by an exact-print-aware tool. toRealSrc (L a e) = L (RealSrcSpan (anchor a) Nothing) e + + spanToLineColumn = + fmap (\s -> (srcSpanStartLine s, srcSpanStartCol s)) . srcSpanToRealSrcSpan From 35e352f3367a08303212ce270de8d63d2d3e33be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 30 Jan 2023 11:55:56 -0300 Subject: [PATCH 098/219] Fix type mismatches in tests --- tests/pos/T716.hs | 4 ++-- tests/pos/UnboxedTuples.hs | 2 +- tests/pos/UnboxedTuplesAndTH.hs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/pos/T716.hs b/tests/pos/T716.hs index 1fcd6aa2c1..2a199151eb 100644 --- a/tests/pos/T716.hs +++ b/tests/pos/T716.hs @@ -24,8 +24,8 @@ import GHC.Word {-@ data Word = W# {w :: {v:Word# | undefinedOffset v >= 64}} @-} -grabWord16_SAFE (Ptr ip#) = let x = byteSwap16# (indexWord16OffAddr# ip# 0#) in W# (narrow16Word# x) +grabWord16_SAFE (Ptr ip#) = let x = byteSwap16# (indexWordOffAddr# ip# 0#) in W# (narrow16Word# x) -grabWord16_UNSAFE (Ptr ip#) = W# (narrow16Word# (byteSwap16# (indexWord16OffAddr# ip# 0#))) +grabWord16_UNSAFE (Ptr ip#) = W# (narrow16Word# (byteSwap16# (indexWordOffAddr# ip# 0#))) diff --git a/tests/pos/UnboxedTuples.hs b/tests/pos/UnboxedTuples.hs index 2ea0b7787e..d9afad484b 100644 --- a/tests/pos/UnboxedTuples.hs +++ b/tests/pos/UnboxedTuples.hs @@ -4,5 +4,5 @@ module UnboxedTuples where import GHC.Int -foo = let (# x, y #) = (# 1#, 1# #) in I8# x +foo = let (# x, y #) = (# 1#, 1# #) in I# x diff --git a/tests/pos/UnboxedTuplesAndTH.hs b/tests/pos/UnboxedTuplesAndTH.hs index 4c3a2a7013..07d82cfbd2 100644 --- a/tests/pos/UnboxedTuplesAndTH.hs +++ b/tests/pos/UnboxedTuplesAndTH.hs @@ -7,7 +7,7 @@ module UnboxedTuplesAndTH where import GHC.Int import Language.Haskell.TH.Syntax -foo = let (# x, y #) = (# 1#, 1# #) in I8# x +foo = let (# x, y #) = (# 1#, 1# #) in I# x bar :: Q Exp bar = [| 1 + 2|] From ef5e2f45bd897e5f6213db28b138cfebfc0bfe44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Tue, 31 Jan 2023 11:21:02 -0300 Subject: [PATCH 099/219] Expand type synonyms before comparing kinds --- src/Language/Haskell/Liquid/Types/RefType.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Types/RefType.hs b/src/Language/Haskell/Liquid/Types/RefType.hs index 7e30b4a89d..80e27a169a 100644 --- a/src/Language/Haskell/Liquid/Types/RefType.hs +++ b/src/Language/Haskell/Liquid/Types/RefType.hs @@ -513,7 +513,9 @@ kindToRType_ ofType = ofType . go | otherwise = t isValKind :: Kind -> Bool -isValKind x = x == naturalTy || x == typeSymbolKind +isValKind x0 = + let x = expandTypeSynonyms x0 + in x == naturalTy || x == typeSymbolKind bTyVar :: Symbol -> BTyVar bTyVar = BTV From f2554c756c9b73cfc268dae3e5ab59e388d60fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Tue, 31 Jan 2023 13:51:07 -0300 Subject: [PATCH 100/219] Include Fractional in the predefined unverified classes --- src/Language/Haskell/Liquid/WiredIn.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Language/Haskell/Liquid/WiredIn.hs b/src/Language/Haskell/Liquid/WiredIn.hs index 4ba5cfab6f..2f2ccde96d 100644 --- a/src/Language/Haskell/Liquid/WiredIn.hs +++ b/src/Language/Haskell/Liquid/WiredIn.hs @@ -215,6 +215,7 @@ derivingClasses = S.fromList , "GHC.Base.Functor" , "Data.Foldable.Foldable" , "Data.Traversable.Traversable" + , "GHC.Real.Fractional" -- , "GHC.Enum.Bounded" -- , "GHC.Base.Monoid" ] From cda9fc7b8e21f9cd4558a23558b6d1e71bf2d3f3 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Wed, 1 Feb 2023 12:45:19 +0100 Subject: [PATCH 101/219] dummy symbols after merge --- src/Language/Haskell/Liquid/Types/RefType.hs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Language/Haskell/Liquid/Types/RefType.hs b/src/Language/Haskell/Liquid/Types/RefType.hs index ec72c1baa9..006b69ed6c 100644 --- a/src/Language/Haskell/Liquid/Types/RefType.hs +++ b/src/Language/Haskell/Liquid/Types/RefType.hs @@ -701,11 +701,18 @@ strengthenRefType_ f (RImpF x1 i t1 t1' r1) (RImpF x2 _ t2 t2' r2) -- YL: Evidence that we need a Monoid instance for RFInfo? strengthenRefType_ f (RFun x1 i1 t1 t1' r1) (RFun x2 i2 t2 t2' r2) + | x2 /= F.dummySymbol = RFun x2 i1{permitTC = getFirst b} t t' (r1 `meet` r2) where t = strengthenRefType_ f t1 t2 t' = strengthenRefType_ f (subst1 t1' (x1, EVar x2)) t2' b = First (permitTC i1) <> First (permitTC i2) +strengthenRefType_ f (RFun x1 i1 t1 t1' r1) (RFun x2 i2 t2 t2' r2) + = RFun x1 i1{permitTC = getFirst b} t t' (r1 `meet` r2) + where t = strengthenRefType_ f t1 t2 + t' = strengthenRefType_ f t1' (subst1 t2' (x2, EVar x1)) + b = First (permitTC i1) <> First (permitTC i2) + strengthenRefType_ f (RApp tid t1s rs1 r1) (RApp _ t2s rs2 r2) = RApp tid ts rs (r1 `meet` r2) where ts = zipWith (strengthenRefType_ f) t1s t2s From 7961cec94b8b51931747a85e7a326523d45a6497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 1 Feb 2023 18:01:40 -0300 Subject: [PATCH 102/219] Fix bytestring benchmarks --- tests/benchmarks/bytestring-0.9.2.1/Data/ByteString.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/bytestring-0.9.2.1/Data/ByteString.hs b/tests/benchmarks/bytestring-0.9.2.1/Data/ByteString.hs index 0779c2ef12..a59d5f78a4 100644 --- a/tests/benchmarks/bytestring-0.9.2.1/Data/ByteString.hs +++ b/tests/benchmarks/bytestring-0.9.2.1/Data/ByteString.hs @@ -271,7 +271,7 @@ import System.IO (hGetBufNonBlocking) import System.IO.Error (isEOFError) -- import GHC.Handle -import GHC.Exts (Word#, (+#), writeWord8OffAddr#) +import GHC.Exts (Word8#, (+#), writeWord8OffAddr#) import GHC.Base (build) import GHC.Word hiding (Word8) import GHC.Ptr (Ptr(..)) @@ -1225,7 +1225,7 @@ splitWith pred_ (PS fp off lenAAA) = splitWith0 pred# off lenAAA fp splitWith0 pred' off' len' fp' = withPtr fp $ \p -> splitLoop pred' p 0 off' len' fp' - splitLoop :: (Word# -> Bool) + splitLoop :: (Word8# -> Bool) -> Ptr Word8 -> Int -> Int -> Int -> ForeignPtr Word8 From 72d9a7fd1661c9a152abe8d1cd39130c0719abb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 1 Feb 2023 19:02:25 -0300 Subject: [PATCH 103/219] Comment a bit more explicitly the handling of Crash --- src/Language/Haskell/Liquid/GHC/Plugin.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Language/Haskell/Liquid/GHC/Plugin.hs b/src/Language/Haskell/Liquid/GHC/Plugin.hs index 466334f0fa..a1078d424d 100644 --- a/src/Language/Haskell/Liquid/GHC/Plugin.hs +++ b/src/Language/Haskell/Liquid/GHC/Plugin.hs @@ -369,6 +369,8 @@ checkLiquidHaskellContext lhContext = do -- If there are unmatched filters or errors, and we are not reporting with -- json, we don't make it to this part of the code because errorLogger -- will throw an exception. + -- + -- F.Crash is also handled by reportResult and errorLogger case o_result out of F.Safe _ -> return $ Right pmrClientLib _ | json moduleCfg -> failM From c5cacab03b567a3ae29af1bbb46f09b83a05753e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 1 Feb 2023 19:05:42 -0300 Subject: [PATCH 104/219] Replace undefined with a message pointing to #2129 --- src/Language/Haskell/Liquid/Synthesize/Check.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Synthesize/Check.hs b/src/Language/Haskell/Liquid/Synthesize/Check.hs index f38aca4dad..fa918aaf9c 100644 --- a/src/Language/Haskell/Liquid/Synthesize/Check.hs +++ b/src/Language/Haskell/Liquid/Synthesize/Check.hs @@ -79,7 +79,7 @@ checkError :: SpecType -> SM (Maybe CoreExpr) checkError t = do errVar <- varError let errorExpr = App (App (Var errVar) (Type (toType False t))) errorInt - globalFlags = undefined + globalFlags = error "broken in https://github.com/ucsd-progsys/liquidhaskell/pull/2129" platform = targetPlatform globalFlags errorInt = mkIntExprInt platform 42 b <- hasType t errorExpr From 7543799039ad9cfebcfab4a0dd6a2ad855e7f8b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Thu, 2 Feb 2023 10:15:40 -0300 Subject: [PATCH 105/219] Bump version of liquidhaskell --- liquidhaskell.cabal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 55d96afd06..f246712ce4 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: liquidhaskell -version: 0.8.10.7.1 +version: 0.9.2.5.0 synopsis: Liquid Types for Haskell description: Liquid Types for Haskell. license: BSD-3-Clause @@ -11,7 +11,7 @@ maintainer: Ranjit Jhala category: Language homepage: https://github.com/ucsd-progsys/liquidhaskell build-type: Simple -tested-with: GHC == 9.0.2 +tested-with: GHC == 9.2.5 extra-source-files: CHANGES.md README.md devel/Paths_liquidhaskell.hs From 10f450e1515bea28c4281cef88f3c36404bc9a93 Mon Sep 17 00:00:00 2001 From: Niki Vazou Date: Fri, 3 Feb 2023 10:01:23 +0100 Subject: [PATCH 106/219] Update liquidhaskell.cabal --- liquidhaskell.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 06356a6779..a20ea56743 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: liquidhaskell -version: 0.8.10.7.1 +version: 0.9.0.2.1 synopsis: Liquid Types for Haskell description: Liquid Types for Haskell. license: BSD-3-Clause From e091969fc259e9bf7a42778ff6d20c876bb54413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Fri, 3 Feb 2023 07:48:25 -0300 Subject: [PATCH 107/219] Fix cabal checks --- cabal.project | 3 +++ liquidhaskell.cabal | 3 ++- stack.yaml | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cabal.project b/cabal.project index 978ece7fc8..068e322a0f 100644 --- a/cabal.project +++ b/cabal.project @@ -22,5 +22,8 @@ source-repository-package package liquid-fixpoint flags: +devel +package liquidhaskell + ghc-options: -j + package liquid-platform flags: +devel diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index a20ea56743..6b6bdca662 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -67,6 +67,7 @@ source-repository head flag devel default: False + manual: True description: Enable more warnings and fail compilation when warnings occur. Turn this flag on in CI. @@ -235,7 +236,7 @@ library , extra default-language: Haskell98 default-extensions: PatternGuards, RecordWildCards, DoAndIfThenElse - ghc-options: -W -fwarn-missing-signatures -j + ghc-options: -W -fwarn-missing-signatures if flag(devel) ghc-options: -Wall -Werror diff --git a/stack.yaml b/stack.yaml index 865554838b..af7fe81d0e 100644 --- a/stack.yaml +++ b/stack.yaml @@ -8,6 +8,7 @@ flags: extra-package-dbs: [] ghc-options: hscolour: -w + liquidhaskell: -j packages: - liquid-fixpoint - liquid-ghc-prim From 797f27d191b82bb3aa55e686ebc15481ebc6bee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 18:41:03 -0300 Subject: [PATCH 108/219] Adjust bounds of liquid-fixpoint --- liquidhaskell.cabal | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 6b6bdca662..141f98e4f5 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -213,7 +213,7 @@ library , gitrev , hashable >= 1.3 && < 1.4 , hscolour >= 1.22 - , liquid-fixpoint >= 0.8.10.2.1 && < 0.9 + , liquid-fixpoint == 0.9.0.2.1 , mtl >= 2.1 , optics >= 0.2 , optparse-applicative < 0.17 @@ -269,7 +269,7 @@ test-suite liquidhaskell-parser build-depends: base >= 4.8.1.0 && < 5 , directory >= 1.2.5 && < 1.4 , filepath - , liquid-fixpoint >= 0.8.10.1 + , liquid-fixpoint , liquidhaskell , megaparsec , syb @@ -288,7 +288,7 @@ test-suite synthesis other-modules: Paths_liquidhaskell hs-source-dirs: tests build-depends: base >= 4.8.1.0 && < 5 - , liquid-fixpoint >= 0.8.10.1 + , liquid-fixpoint , liquidhaskell , tasty >= 0.7 , tasty-hunit From cbacdfc1da0d347ce8bf69c2b51ee6df2dacfc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 19:10:55 -0300 Subject: [PATCH 109/219] Update reference to liquid-fixpoint --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 11a773a08e..dd58da1edd 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 11a773a08e66cea13d8ddbf203ca32bd5cea97b2 +Subproject commit dd58da1edd9560ed24d65ea1497248e207e7ee0c From 28d8f21301a1f6c427ed4ce56c07d400e7a79030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 13:00:25 -0300 Subject: [PATCH 110/219] Remove the legacy executable --- .circleci/config.yml | 2 +- README.md | 6 +- appveyor.yml | 23 +- docs/mkDocs/docs/install.md | 2 - docs/mkDocs/docs/legacy.md | 65 --- docs/mkDocs/docs/specifications.md | 29 -- exe/Liquid.hs | 6 - include/710/Data/Traversable.spec | 3 - include/Bot.hquals | 8 - include/Control/Exception.spec | 5 - include/Control/Parallel/Strategies.spec | 3 - include/Data/Bits.spec | 6 - include/Data/ByteString.spec | 375 --------------- include/Data/ByteString/Char8.spec | 402 ---------------- include/Data/ByteString/Lazy.spec | 338 -------------- include/Data/ByteString/Lazy/Char8.spec | 417 ----------------- include/Data/ByteString/Short.spec | 25 - include/Data/ByteString/Unsafe.spec | 29 -- include/Data/Char.spec | 1 - include/Data/Either.spec | 5 - include/Data/Foldable.spec | 6 - include/Data/Int.spec | 8 - include/Data/Map.hiddenspec | 27 -- include/Data/Maybe.spec | 7 - include/Data/OldList.spec | 11 - include/Data/Set.spec | 59 --- include/Data/String.spec | 8 - include/Data/Text.spec | 289 ------------ include/Data/Text/Fusion.spec | 25 - include/Data/Text/Fusion/Common.spec | 52 --- include/Data/Text/Lazy/Fusion.spec | 8 - include/Data/Time.spec | 3 - include/Data/Time/Calendar.spec | 11 - include/Data/Tuple.spec | 4 - include/Data/Vector.hquals | 13 - include/Data/Vector.spec | 26 -- include/Data/Word.spec | 10 - include/Data/Word8.spec | 5 - include/Foreign/C/String.spec | 11 - include/Foreign/C/Types.spec | 7 - include/Foreign/ForeignPtr.spec | 16 - include/Foreign/Marshal/Alloc.spec | 3 - include/Foreign/Marshal/Array.spec | 3 - include/Foreign/Ptr.spec | 5 - include/Foreign/Storable.spec | 30 -- include/GHC/Base.hquals | 30 -- include/GHC/Base.spec | 79 ---- include/GHC/CString.spec | 11 - include/GHC/Classes.spec | 29 -- include/GHC/Exts.spec | 10 - include/GHC/ForeignPtr.spec | 9 - include/GHC/IO/Handle.spec | 10 - include/GHC/Int.spec | 8 - include/GHC/List.spec | 60 --- include/GHC/Num.spec | 9 - include/GHC/Prim.spec | 8 - include/GHC/Ptr.spec | 24 - include/GHC/Read.spec | 5 - include/GHC/Real.spec | 37 -- include/GHC/Types.spec | 41 -- include/GHC/Word.spec | 7 - include/KMeansHelper.hs | 78 ---- include/Language/Haskell/Liquid/Bag.hs | 53 --- include/Language/Haskell/Liquid/Equational.hs | 55 --- include/Language/Haskell/Liquid/Foreign.hs | 64 --- include/Language/Haskell/Liquid/List.hs | 7 - include/Language/Haskell/Liquid/Prelude.hs | 142 ------ include/Language/Haskell/Liquid/Prelude.pred | 22 - .../Haskell/Liquid/ProofCombinators.hs | 183 -------- include/Language/Haskell/Liquid/RTick.hs | 440 ------------------ .../Haskell/Liquid/RTick/Combinators.hs | 366 --------------- include/Language/Haskell/Liquid/String.hs | 62 --- .../Haskell/Liquid/Synthesize/Error.hs | 5 - include/NotReal.spec | 11 - include/PatErr.spec | 15 - include/Prelude.hquals | 44 -- include/Prelude.spec | 88 ---- include/Real.spec | 9 - include/System/IO.spec | 3 - include/len.hquals | 7 - liquidhaskell.cabal | 61 +-- src/Language/Haskell/Liquid/Liquid.hs | 15 +- 82 files changed, 10 insertions(+), 4494 deletions(-) delete mode 100644 docs/mkDocs/docs/legacy.md delete mode 100644 exe/Liquid.hs delete mode 100644 include/710/Data/Traversable.spec delete mode 100644 include/Bot.hquals delete mode 100644 include/Control/Exception.spec delete mode 100644 include/Control/Parallel/Strategies.spec delete mode 100644 include/Data/Bits.spec delete mode 100644 include/Data/ByteString.spec delete mode 100644 include/Data/ByteString/Char8.spec delete mode 100644 include/Data/ByteString/Lazy.spec delete mode 100644 include/Data/ByteString/Lazy/Char8.spec delete mode 100644 include/Data/ByteString/Short.spec delete mode 100644 include/Data/ByteString/Unsafe.spec delete mode 100644 include/Data/Char.spec delete mode 100644 include/Data/Either.spec delete mode 100644 include/Data/Foldable.spec delete mode 100644 include/Data/Int.spec delete mode 100644 include/Data/Map.hiddenspec delete mode 100644 include/Data/Maybe.spec delete mode 100644 include/Data/OldList.spec delete mode 100644 include/Data/Set.spec delete mode 100644 include/Data/String.spec delete mode 100644 include/Data/Text.spec delete mode 100644 include/Data/Text/Fusion.spec delete mode 100644 include/Data/Text/Fusion/Common.spec delete mode 100644 include/Data/Text/Lazy/Fusion.spec delete mode 100644 include/Data/Time.spec delete mode 100644 include/Data/Time/Calendar.spec delete mode 100644 include/Data/Tuple.spec delete mode 100644 include/Data/Vector.hquals delete mode 100644 include/Data/Vector.spec delete mode 100644 include/Data/Word.spec delete mode 100644 include/Data/Word8.spec delete mode 100644 include/Foreign/C/String.spec delete mode 100644 include/Foreign/C/Types.spec delete mode 100644 include/Foreign/ForeignPtr.spec delete mode 100644 include/Foreign/Marshal/Alloc.spec delete mode 100644 include/Foreign/Marshal/Array.spec delete mode 100644 include/Foreign/Ptr.spec delete mode 100644 include/Foreign/Storable.spec delete mode 100644 include/GHC/Base.hquals delete mode 100644 include/GHC/Base.spec delete mode 100644 include/GHC/CString.spec delete mode 100644 include/GHC/Classes.spec delete mode 100644 include/GHC/Exts.spec delete mode 100644 include/GHC/ForeignPtr.spec delete mode 100644 include/GHC/IO/Handle.spec delete mode 100644 include/GHC/Int.spec delete mode 100644 include/GHC/List.spec delete mode 100644 include/GHC/Num.spec delete mode 100644 include/GHC/Prim.spec delete mode 100644 include/GHC/Ptr.spec delete mode 100644 include/GHC/Read.spec delete mode 100644 include/GHC/Real.spec delete mode 100644 include/GHC/Types.spec delete mode 100644 include/GHC/Word.spec delete mode 100644 include/KMeansHelper.hs delete mode 100644 include/Language/Haskell/Liquid/Bag.hs delete mode 100644 include/Language/Haskell/Liquid/Equational.hs delete mode 100644 include/Language/Haskell/Liquid/Foreign.hs delete mode 100644 include/Language/Haskell/Liquid/List.hs delete mode 100644 include/Language/Haskell/Liquid/Prelude.hs delete mode 100644 include/Language/Haskell/Liquid/Prelude.pred delete mode 100644 include/Language/Haskell/Liquid/ProofCombinators.hs delete mode 100644 include/Language/Haskell/Liquid/RTick.hs delete mode 100644 include/Language/Haskell/Liquid/RTick/Combinators.hs delete mode 100644 include/Language/Haskell/Liquid/String.hs delete mode 100644 include/Language/Haskell/Liquid/Synthesize/Error.hs delete mode 100644 include/NotReal.spec delete mode 100644 include/PatErr.spec delete mode 100644 include/Prelude.hquals delete mode 100644 include/Prelude.spec delete mode 100644 include/Real.spec delete mode 100644 include/System/IO.spec delete mode 100644 include/len.hquals diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ce7e38b32..8ced71f19e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,7 +68,7 @@ commands: echo 'export PATH=~/.ghcup/bin:$PATH' >> $BASH_ENV << parameters.cabal_update_command >> cabal v2-clean - cabal v2-build --project-file << parameters.project_file >> --flag include --flag devel -j --enable-tests liquid liquidhaskell-parser synthesis liquid-base liquid-prelude liquid-bytestring liquid-containers liquid-ghc-prim liquid-parallel liquid-vector liquid-platform test-driver + cabal v2-build --project-file << parameters.project_file >> --flag include --flag devel -j --enable-tests liquidhaskell-parser synthesis liquid-base liquid-prelude liquid-bytestring liquid-containers liquid-ghc-prim liquid-parallel liquid-vector liquid-platform test-driver - save_cache: key: cabal-cache-v3-{{ checksum "liquidhaskell.cabal" }}-{{ checksum "<< parameters.project_file >>" }}-{{ checksum "liquid-fixpoint-commit" }} paths: diff --git a/README.md b/README.md index cb4e146b4e..ebc9a2854e 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,7 @@ to let us know. If possible, try to: * State as clearly as possible what is the problem you are facing; * Provide a small Haskell file producing the issue; * Write down the expected behaviour vs the actual behaviour; -* If possible, let us know if you have used the [plugin](install.md) or the [executable](legacy.md) and - which _GHC version_ you are using. +* Please, let us know which liquidhaskell version you are using. ## Your first Pull Request @@ -356,8 +355,7 @@ the code provided as part of the `release/0.8.10.2` branch, commit `9a2f8284c5fe The module [GHC.Plugin][] is the main entrypoint for all the plugin functionalities. Whenever possible, this module is reusing common functionalities from the [GHC.Interface][], which is the original module used to interface LH with the old executable. Generally speaking, the [GHC.Interface][] module is considered "legacy" -and it's rarely what one wants to modify. It will probably be removed once the old executable stops being -supported, with the functions now in use by the [GHC.Plugin][] being moved into the latter. +and it's rarely what one wants to modify. It will probably be removed at some point. ## The GhcMonadLike shim diff --git a/appveyor.yml b/appveyor.yml index 5d1ffd3632..265e0b3254 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -31,28 +31,15 @@ install: build_script: -# Build LiquidHaskell (the legacy executable) -# until https://gitlab.haskell.org/ghc/ghc/issues/17236 is fixed. - echo "" | rm -rf .stack-work -- echo "" | stack --no-terminal build --ghc-options="-fexternal-interpreter" liquidhaskell:lib --flag liquidhaskell:no-plugin --copy-bins --local-bin-path . -- echo "" | stack --no-terminal build liquid-fixpoint:exe:fixpoint liquidhaskell:exe:liquid --flag liquidhaskell:no-plugin --copy-bins --local-bin-path . +- echo "" | stack --no-terminal build --flag liquidhaskell:devel liquidhaskell # Copy runtime DLLs - call appveyor-copy.bat -# Test if they are working -- fixpoint --version -- liquid --version +# ZIP executable +# - 7z a liquidhaskell.zip liquid.exe fixpoint.exe .\include\CoreToLogic.lg LICENSE LICENSE_Z3 libstdc++-6.dll libgcc_s_seh-1.dll libwinpthread-1.dll -# ZIP execturable -- 7z a liquidhaskell.zip liquid.exe fixpoint.exe .\include\CoreToLogic.lg LICENSE LICENSE_Z3 libstdc++-6.dll libgcc_s_seh-1.dll libwinpthread-1.dll - -# Run the tests (using the legacy executable) +# Run the tests test_script: -- echo "" | stack --no-terminal test liquidhaskell:liquidhaskell-parser --fast --flag liquidhaskell:no-plugin -# XXX(matt.walker): Can this whole file be removed? -# - echo "" | stack --no-terminal test liquidhaskell:test --fast --flag liquidhaskell:no-plugin --ta="--liquid-runner \"stack --compiler=ghc-8.10.7 --silent exec -- liquid\"" --test-arguments "-p Micro" - -artifacts: -- path: liquidhaskell.zip - name: LiquidHaskell +- echo "" | stack --no-terminal test --flag liquidhaskell:devel liquidhaskell:liquidhaskell-parser diff --git a/docs/mkDocs/docs/install.md b/docs/mkDocs/docs/install.md index df2d4608dd..133412aa38 100644 --- a/docs/mkDocs/docs/install.md +++ b/docs/mkDocs/docs/install.md @@ -54,5 +54,3 @@ You may also want to delete the `.liquid` directories placed alongside your sour ## Other Options **Online Demo**: For small projects without a `.cabal` file, you can paste your code into the [online demo](http://goto.ucsd.edu:8090/index.html). - -**Legacy Executable**: A [stanadalone executable](legacy.md) is also provided, although it is **deprecated** and will be removed in the future. diff --git a/docs/mkDocs/docs/legacy.md b/docs/mkDocs/docs/legacy.md deleted file mode 100644 index cd5f819b3c..0000000000 --- a/docs/mkDocs/docs/legacy.md +++ /dev/null @@ -1,65 +0,0 @@ -# Installing the Legacy LiquidHaskell Executable - -**We strongly recommend** that you use the [GHC Plugin](install.md) -available in version 0.8.10 onwards, as the legacy executable is deprecated and has been -kept around for backwards compatibility. It will eventually be removed from future LH releases. - -## External software requirements - -Make sure all the required [external software](install.md) software is installed before proceeding. - -## Installation options - -You can install the `liquid` binary via package manager *or* source. - -### Via Package Manager - -Simply do: - - cabal install liquidhaskell - -We are working to put `liquid` on `stackage`. - -You can designate a specific version of LiquidHaskell to -ensure that the correct GHC version is in the environment. -For example: - - cabal install liquidhaskell-0.8.10.1 - -### Build from Source - -If you want the most recent version, you can build from source as follows, -either using `stack` (recommended) or `cabal`. In either case: - -1. *recursively* `clone` the repo: - - ```git clone --recursive https://github.com/ucsd-progsys/liquidhaskell.git``` - -2. Go inside the `liquidhaskell` directory: - - ``` - cd liquidhaskell - ``` - -3. Build the package: - - a. with [stack][stack]: - - stack install liquidhaskell - - b. or with [cabal][cabal]: - - cabal v2-build liquidhaskell - -## Running in GHCi - -To run inside `ghci` e.g. when developing do: - -```bash -$ stack ghci liquidhaskell -ghci> :m +Language.Haskell.Liquid.Liquid -ghci> liquid ["tests/pos/Abs.hs"] -``` - -[stack]: https://github.com/commercialhaskell/stack/blob/master/doc/install_and_upgrade.md -[cabal]: https://www.haskell.org/cabal/ diff --git a/docs/mkDocs/docs/specifications.md b/docs/mkDocs/docs/specifications.md index e27dc3c0f2..57ecf936b4 100644 --- a/docs/mkDocs/docs/specifications.md +++ b/docs/mkDocs/docs/specifications.md @@ -44,38 +44,9 @@ The following sections detail more variety for the uses of the above annotations ## Modules WITHOUT code -The following section is slightly different depending on whether you are using the plugin (which you should!) -or the legacy executable. - -### (Plugin) Adding refinements for external modules - See the [installation](install.md) section, which cointains a link to a walkthrough document that describes how to add refinements for external packages (cfr. **"Providing Specifications for Existing Packages"**) -### (Legacy executable) Adding refinements for external modules - -When checking a file `target.hs`, you can specify an _include_ directory by - - liquid -i /path/to/include/ target.hs - -Now, to write specifications for some **external module** `Foo.Bar.Baz` for which -you **do not have the code**, you can create a `.spec` file at: - - /path/to/include/Foo/Bar/Baz.spec - -See, for example, the contents of: - -+ [include/Prelude.spec](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Prelude.spec) -+ [include/Data/List.spec](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/List.spec) -+ [include/Data/Vector.spec](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Data/Vector.spec) - -**Note**: - -+ The above directories are part of the LH prelude, and included by - default when running `liquid`. -+ The `.spec` mechanism is *only for external modules** without code, - see below for standalone specifications for **internal** or **home** modules. - ## Modules WITH code: Data Write the specification directly into the .hs or .lhs file, diff --git a/exe/Liquid.hs b/exe/Liquid.hs deleted file mode 100644 index b6c4c39755..0000000000 --- a/exe/Liquid.hs +++ /dev/null @@ -1,6 +0,0 @@ -import Language.Haskell.Liquid.Liquid (liquid) -import System.Environment (getArgs) --- import GhcTest - -main :: IO a -main = liquid =<< getArgs diff --git a/include/710/Data/Traversable.spec b/include/710/Data/Traversable.spec deleted file mode 100644 index c47696d147..0000000000 --- a/include/710/Data/Traversable.spec +++ /dev/null @@ -1,3 +0,0 @@ -module spec Data.Traversable where - -Data.Traversable.sequence :: Data.Traversable.Traversable t => forall m a. GHC.Base.Monad m => xs:t (m a) -> m ({v:t a | len v = len xs}) diff --git a/include/Bot.hquals b/include/Bot.hquals deleted file mode 100644 index 0382d0c64e..0000000000 --- a/include/Bot.hquals +++ /dev/null @@ -1,8 +0,0 @@ -//BOT: Do not delete EVER! - -qualif Bot(v:@(0)) : 0 = 1 -qualif Bot(v:obj) : 0 = 1 -qualif Bot(v:a) : 0 = 1 -qualif Bot(v:bool) : 0 = 1 -qualif Bot(v:int) : 0 = 1 - diff --git a/include/Control/Exception.spec b/include/Control/Exception.spec deleted file mode 100644 index 5e68bf44ca..0000000000 --- a/include/Control/Exception.spec +++ /dev/null @@ -1,5 +0,0 @@ -module spec Control.Exception where - -// Useless as compiled into GHC primitive, which is ignored -assume assert :: {v:Bool | v } -> a -> a - diff --git a/include/Control/Parallel/Strategies.spec b/include/Control/Parallel/Strategies.spec deleted file mode 100644 index a0fd3a197c..0000000000 --- a/include/Control/Parallel/Strategies.spec +++ /dev/null @@ -1,3 +0,0 @@ -module spec Control.Parallel.Strategies where - -assume withStrategy :: Control.Parallel.Strategies.Strategy a -> x:a -> {v:a | v == x} diff --git a/include/Data/Bits.spec b/include/Data/Bits.spec deleted file mode 100644 index 2ab553b565..0000000000 --- a/include/Data/Bits.spec +++ /dev/null @@ -1,6 +0,0 @@ -module spec Data.Bits where - -// TODO: cannot use this because `Bits` is not a `Num` -// Data.Bits.shiftR :: (Data.Bits.Bits a) => x:a -> d:Nat -// -> {v:a | ((d=1) => (x <= 2*v + 1 && 2*v <= x)) } - diff --git a/include/Data/ByteString.spec b/include/Data/ByteString.spec deleted file mode 100644 index 89cc03fbec..0000000000 --- a/include/Data/ByteString.spec +++ /dev/null @@ -1,375 +0,0 @@ -module spec Data.ByteString where - -import Data.String - -measure bslen :: Data.ByteString.ByteString -> { n : Int | 0 <= n } - -invariant { bs : Data.ByteString.ByteString | 0 <= bslen bs } - -invariant { bs : Data.ByteString.ByteString | bslen bs == stringlen bs } - -empty :: { bs : Data.ByteString.ByteString | bslen bs == 0 } - -singleton :: _ -> { bs : Data.ByteString.ByteString | bslen bs == 1 } - -pack :: w8s : [_] - -> { bs : Data.ByteString.ByteString | bslen bs == len w8s } - -unpack :: bs : Data.ByteString.ByteString - -> { w8s : [_] | len w8s == bslen bs } - -cons :: _ - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 } - -snoc :: i : Data.ByteString.ByteString - -> _ - -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 } - -append :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen l + bslen r } - -head :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -unsnoc :: i:Data.ByteString.ByteString - -> (Maybe ({ o : Data.ByteString.ByteString | bslen o == bslen i - 1 }, _)) - -last :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -tail :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -init - :: {i:Data.ByteString.ByteString | 1 <= bslen i } - -> {o:Data.ByteString.ByteString | bslen o == bslen i - 1 } - -null - :: bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | b <=> bslen bs == 0 } - -length :: bs : Data.ByteString.ByteString -> { n : Int | bslen bs == n } - -map - :: (_ -> _) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -reverse - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -intersperse - :: _ - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | (bslen i == 0 <=> bslen o == 0) && (1 <= bslen i <=> bslen o == 2 * bslen i - 1) } - -intercalate - :: l : Data.ByteString.ByteString - -> rs : [Data.ByteString.ByteString] - -> { o : Data.ByteString.ByteString | len rs == 0 ==> bslen o == 0 } - -transpose - :: is : [Data.ByteString.ByteString] - -> { os : [{ bs : Data.ByteString.ByteString | bslen bs <= len is }] | len is == 0 ==> len os == 0} - -foldl1 - :: (_ -> _ -> _) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> _ - -foldl1' - :: (_ -> _ -> _) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> _ - -foldr1 - :: (_ -> _ -> _) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> _ - -foldr1' - :: (_ -> _ -> _) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> _ - -concat - :: is : [Data.ByteString.ByteString] - -> { o : Data.ByteString.ByteString | (len is == 0) ==> (bslen o == 0) } - -concatMap - :: (_ -> Data.ByteString.ByteString) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen i == 0 ==> bslen o == 0 } - -any - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> not b } - -all - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> b } - -maximum :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -minimum :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -scanl :: (_ -> _ -> _) - -> _ - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -scanl1 :: (_ -> _ -> _) - -> i : { i : Data.ByteString.ByteString | 1 <= bslen i } - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -scanr - :: (_ -> _ -> _) - -> _ - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -scanr1 - :: (_ -> _ -> _) - -> i : { i : Data.ByteString.ByteString | 1 <= bslen i } - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -mapAccumL - :: (acc -> _ -> (acc, _)) - -> acc - -> i : Data.ByteString.ByteString - -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i }) - -mapAccumR - :: (acc -> _ -> (acc, _)) - -> acc - -> i : Data.ByteString.ByteString - -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i }) - -replicate - :: n : Int - -> _ - -> { bs : Data.ByteString.ByteString | bslen bs == n } - -unfoldrN - :: n : Int - -> (a -> Maybe (_, a)) - -> a - -> ({ bs : Data.ByteString.ByteString | bslen bs <= n }, Maybe a) - -take - :: n : Int - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == 0) && - ((0 <= n && n <= bslen i) <=> bslen o == n) && - (bslen i <= n <=> bslen o = bslen i) } - -drop - :: n : Int - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == bslen i) && - ((0 <= n && n <= bslen i) <=> bslen o == bslen i - n) && - (bslen i <= n <=> bslen o == 0) } - -splitAt - :: n : Int - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | (n <= 0 <=> bslen l == 0) && - ((0 <= n && n <= bslen i) <=> bslen l == n) && - (bslen i <= n <=> bslen l == bslen i) } - , { r : Data.ByteString.ByteString | (n <= 0 <=> bslen r == bslen i) && - ((0 <= n && n <= bslen i) <=> bslen r == bslen i - n) && - (bslen i <= n <=> bslen r == 0) } - ) - -takeWhile - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o <= bslen i } - -dropWhile - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o <= bslen i } - -span - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -spanEnd - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -break - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -breakEnd - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -group - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }] - -groupBy - :: (_ -> _ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }] - -inits - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -tails - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -split - :: _ - -> i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -splitWith - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -isPrefixOf - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen l >= bslen r ==> not b } - -isSuffixOf - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen l > bslen r ==> not b } - -isInfixOf - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen l > bslen r ==> not b } - -breakSubstring - :: il : Data.ByteString.ByteString - -> ir : Data.ByteString.ByteString - -> ( { ol : Data.ByteString.ByteString | bslen ol <= bslen ir && (bslen il > bslen ir ==> bslen ol == bslen ir)} - , { or : Data.ByteString.ByteString | bslen or <= bslen ir && (bslen il > bslen ir ==> bslen or == 0) } - ) - -elem - :: _ - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> not b } - -notElem - :: _ - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> b } - -find - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> (Maybe { w8 : _ | bslen bs /= 0 }) - -filter - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o <= bslen i } - -partition - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -index :: bs : Data.ByteString.ByteString -> { n : Int | 0 <= n && n < bslen bs } -> _ - -elemIndex - :: _ - -> bs : Data.ByteString.ByteString - -> (Maybe { n : Int | 0 <= n && n < bslen bs }) - -elemIndices - :: _ - -> bs : Data.ByteString.ByteString - -> [{ n : Int | 0 <= n && n < bslen bs }] - -elemIndexEnd - :: _ - -> bs : Data.ByteString.ByteString - -> (Maybe { n : Int | 0 <= n && n < bslen bs }) - -findIndex - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> (Maybe { n : Int | 0 <= n && n < bslen bs }) - -findIndices - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> [{ n : Int | 0 <= n && n < bslen bs }] - -count - :: _ - -> bs : Data.ByteString.ByteString - -> { n : Int | 0 <= n && n < bslen bs } - -zip - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { o : [(_, _)] | len o <= bslen l && len o <= bslen r } - -zipWith - :: (_ -> _ -> a) - -> l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { o : [a] | len o <= bslen l && len o <= bslen r } - -unzip - :: i : [(_, _)] - -> ( { l : Data.ByteString.ByteString | bslen l == len i } - , { r : Data.ByteString.ByteString | bslen r == len i } - ) - -sort - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -copy - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -hGet - :: _ - -> n : { n : Int | 0 <= n } - -> (IO { bs : Data.ByteString.ByteString | bslen bs == n || bslen bs == 0 }) - -hGetSome - :: _ - -> n : { n : Int | 0 <= n } - -> (IO { bs : Data.ByteString.ByteString | bslen bs <= n }) - -hGetNonBlocking - :: _ - -> n : { n : Int | 0 <= n } - -> (IO { bs : Data.ByteString.ByteString | bslen bs <= n }) - -uncons - :: i : Data.ByteString.ByteString - -> (Maybe (_, { o : Data.ByteString.ByteString | bslen o == bslen i - 1 })) - diff --git a/include/Data/ByteString/Char8.spec b/include/Data/ByteString/Char8.spec deleted file mode 100644 index a9c96565fc..0000000000 --- a/include/Data/ByteString/Char8.spec +++ /dev/null @@ -1,402 +0,0 @@ -module spec Data.ByteString.Char8 where - -import Data.ByteString - -assume empty :: { bs : Data.ByteString.ByteString | bslen bs == 0 } - -assume singleton - :: Char -> { bs : Data.ByteString.ByteString | bslen bs == 1 } - -assume pack - :: w8s : [Char] - -> { bs : Data.ByteString.ByteString | bslen bs == len w8s } - -assume unpack - :: bs : Data.ByteString.ByteString - -> { w8s : [Char] | len w8s == bslen bs } - -assume cons - :: Char - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 } - -assume snoc - :: i : Data.ByteString.ByteString - -> Char - -> { o : Data.ByteString.ByteString | bslen o == bslen i + 1 } - -assume append - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen l + bslen r } - -head :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char - -assume uncons - :: i : Data.ByteString.ByteString - -> Maybe (Char, { o : Data.ByteString.ByteString | bslen o == bslen i - 1 }) - -assume unsnoc - :: i : Data.ByteString.ByteString - -> Maybe ({ o : Data.ByteString.ByteString | bslen o == bslen i - 1 }, Char) - -assume last :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char - -assume tail :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char - -assume init :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char - -assume null - :: bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | b <=> bslen bs == 0 } - -assume length :: bs : Data.ByteString.ByteString -> { n : Int | bslen bs == n } - -assume map - :: (Char -> Char) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume reverse - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume intersperse - :: Char - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | (bslen i == 0 <=> bslen o == 0) && (1 <= bslen i <=> bslen o == 2 * bslen i - 1) } - -assume intercalate - :: l : Data.ByteString.ByteString - -> rs : [Data.ByteString.ByteString] - -> { o : Data.ByteString.ByteString | len rs == 0 ==> bslen o == 0 } - -assume transpose - :: is : [Data.ByteString.ByteString] - -> { os : [{ bs : Data.ByteString.ByteString | bslen bs <= len is }] | len is == 0 ==> len os == 0} - -foldl1 - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> Char - -foldl1' - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> Char - -foldr1 - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> Char - -foldr1' - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.ByteString | 1 <= bslen bs } - -> Char - -assume concat - :: is : [Data.ByteString.ByteString] - -> { o : Data.ByteString.ByteString | len is == 0 ==> bslen o } - -assume concatMap - :: (Char -> Data.ByteString.ByteString) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen i == 0 ==> bslen o == 0 } - -assume any :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> not b } - -assume all :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> b } - -maximum - :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char - -minimum - :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> Char - -assume scanl - :: (Char -> Char -> Char) - -> Char - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume scanl1 - :: (Char -> Char -> Char) - -> i : { i : Data.ByteString.ByteString | 1 <= bslen i } - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume scanr - :: (Char -> Char -> Char) - -> Char - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume scanr1 - :: (Char -> Char -> Char) - -> i : { i : Data.ByteString.ByteString | 1 <= bslen i } - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume mapAccumL - :: (acc -> Char -> (acc, Char)) - -> acc - -> i : Data.ByteString.ByteString - -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i }) - -assume mapAccumR - :: (acc -> Char -> (acc, Char)) - -> acc - -> i : Data.ByteString.ByteString - -> (acc, { o : Data.ByteString.ByteString | bslen o == bslen i }) - -assume replicate - :: n : Int - -> Char - -> { bs : Data.ByteString.ByteString | bslen bs == n } - -assume unfoldrN - :: n : Int - -> (a -> Maybe (Char, a)) - -> a - -> ({ bs : Data.ByteString.ByteString | bslen bs <= n }, Maybe a) - -assume take - :: n : Int - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == 0) && - ((0 <= n && n <= bslen i) <=> bslen o == n) && - (bslen i <= n <=> bslen o = bslen i) } - -assume drop - :: n : Int - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | (n <= 0 <=> bslen o == bslen i) && - ((0 <= n && n <= bslen i) <=> bslen o == bslen i - n) && - (bslen i <= n <=> bslen o == 0) } - -assume splitAt - :: n : Int - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | (n <= 0 <=> bslen l == 0) && - ((0 <= n && n <= bslen i) <=> bslen l == n) && - (bslen i <= n <=> bslen l == bslen i) } - , { r : Data.ByteString.ByteString | (n <= 0 <=> bslen r == bslen i) && - ((0 <= n && n <= bslen i) <=> bslen r == bslen i - n) && - (bslen i <= n <=> bslen r == 0) } - ) - -assume takeWhile - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o <= bslen i } - -assume dropWhile - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o <= bslen i } - -assume span - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -assume spanEnd - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -assume break - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -assume breakEnd - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - , { r : Data.ByteString.ByteString | bslen r <= bslen i } - ) - -assume group - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }] - -assume groupBy - :: (Char -> Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | 1 <= bslen o && bslen o <= bslen i }] - -assume inits - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -assume tails - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -assume split - :: Char - -> i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -assume splitWith - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -assume lines - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -assume words - :: i : Data.ByteString.ByteString - -> [{ o : Data.ByteString.ByteString | bslen o <= bslen i }] - -assume unlines - :: is : [Data.ByteString.ByteString] - -> { o : Data.ByteString.ByteString | (len is == 0 <=> bslen o == 0) && bslen o >= len is } - -assume unwords - :: is : [Data.ByteString.ByteString] - -> { o : Data.ByteString.ByteString | (len is == 0 ==> bslen o == 0) && (1 <= len is ==> bslen o >= len is - 1) } - -assume isPrefixOf - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen l >= bslen r ==> not b } - -assume isSuffixOf - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen l > bslen r ==> not b } - -assume isInfixOf - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen l > bslen r ==> not b } - -assume breakSubstring - :: il : Data.ByteString.ByteString - -> ir : Data.ByteString.ByteString - -> ( { ol : Data.ByteString.ByteString | bslen ol <= bslen ir && (bslen il > bslen ir ==> bslen ol == bslen ir)} - , { or : Data.ByteString.ByteString | bslen or <= bslen ir && (bslen il > bslen ir ==> bslen or == 0) } - ) - -assume elem - :: Char - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> not b } - -assume notElem - :: Char - -> bs : Data.ByteString.ByteString - -> { b : GHC.Types.Bool | bslen bs == 0 ==> b } - -assume find - :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> Maybe { w8 : Char | bslen bs /= 0 } - -assume filter - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o <= bslen i } - -index - :: bs : Data.ByteString.ByteString - -> { n : Int | 0 <= n && n < bslen bs } - -> Char - -assume elemIndex - :: Char - -> bs : Data.ByteString.ByteString - -> Maybe { n : Int | 0 <= n && n < bslen bs } - -assume elemIndices - :: Char - -> bs : Data.ByteString.ByteString - -> [{ n : Int | 0 <= n && n < bslen bs }] - -assume elemIndexEnd - :: Char - -> bs : Data.ByteString.ByteString - -> Maybe { n : Int | 0 <= n && n < bslen bs } - -assume findIndex - :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> Maybe { n : Int | 0 <= n && n < bslen bs } - -assume findIndices - :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.ByteString - -> [{ n : Int | 0 <= n && n < bslen bs }] - -assume count - :: Char - -> bs : Data.ByteString.ByteString - -> { n : Int | 0 <= n && n < bslen bs } - -assume zip - :: l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { o : [(Char, Char)] | len o <= bslen l && len o <= bslen r } - -assume zipWith - :: (Char -> Char -> a) - -> l : Data.ByteString.ByteString - -> r : Data.ByteString.ByteString - -> { o : [a] | len o <= bslen l && len o <= bslen r } - -assume unzip - :: i : [(Char, Char)] - -> ( { l : Data.ByteString.ByteString | bslen l == len i } - , { r : Data.ByteString.ByteString | bslen r == len i } - ) - -assume sort - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume readInt - :: i : Data.ByteString.ByteString - -> Maybe { p : (Int, { o : Data.ByteString.ByteString | bslen o < bslen i}) | bslen i /= 0 } - -assume readInteger - :: i : Data.ByteString.ByteString - -> Maybe { p : (Integer, { o : Data.ByteString.ByteString | bslen o < bslen i}) | bslen i /= 0 } - -assume copy - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bslen i } - -assume hGet - :: System.IO.Handle - -> n : { n : Int | 0 <= n } - -> IO { bs : Data.ByteString.ByteString | bslen bs == n || bslen bs == 0 } - -assume hGetSome - :: System.IO.Handle - -> n : { n : Int | 0 <= n } - -> IO { bs : Data.ByteString.ByteString | bslen bs <= n } - -assume hGetNonBlocking - :: System.IO.Handle - -> n : { n : Int | 0 <= n } - -> IO { bs : Data.ByteString.ByteString | bslen bs <= n } - -// assume partition - // :: (Char -> GHC.Types.Bool) - // -> i : Data.ByteString.ByteString - // -> ( { l : Data.ByteString.ByteString | bslen l <= bslen i } - // , { r : Data.ByteString.ByteString | bslen r <= bslen i } - // ) diff --git a/include/Data/ByteString/Lazy.spec b/include/Data/ByteString/Lazy.spec deleted file mode 100644 index 63b2b3da1c..0000000000 --- a/include/Data/ByteString/Lazy.spec +++ /dev/null @@ -1,338 +0,0 @@ -module spec Data.ByteString.Lazy where - -import Data.String -import Data.ByteString - -measure bllen :: Data.ByteString.Lazy.ByteString -> { n : GHC.Int.Int64 | 0 <= n } - -invariant { bs : Data.ByteString.Lazy.ByteString | 0 <= bllen bs } - -invariant { bs : Data.ByteString.Lazy.ByteString | bllen bs == stringlen bs } - -assume empty :: { bs : Data.ByteString.Lazy.ByteString | bllen bs == 0 } - -assume singleton - :: _ -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == 1 } - -assume pack - :: w8s : [_] - -> { bs : _ | bllen bs == len w8s } - -assume unpack - :: bs : Data.ByteString.Lazy.ByteString - -> { w8s : [_] | len w8s == bllen bs } - -assume fromStrict - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bslen i } - -assume toStrict - :: i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bllen i } - -assume fromChunks - :: i : [Data.ByteString.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | len i == 0 <=> bllen o == 0 } - -assume toChunks - :: i : Data.ByteString.Lazy.ByteString - -> { os : [{ o : Data.ByteString.ByteString | bslen o <= bllen i}] | len os == 0 <=> bllen i == 0 } - -assume cons - :: _ - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 } - -assume snoc - :: i : Data.ByteString.Lazy.ByteString - -> _ - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 } - -assume append - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen l + bllen r } - -assume head - :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> _ - -assume uncons - :: i : Data.ByteString.Lazy.ByteString - -> Maybe (_, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 }) - -assume unsnoc - :: i : Data.ByteString.Lazy.ByteString - -> Maybe ({ o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 }, _) - -assume last :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> _ - -assume tail :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> _ - -assume init :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> _ - -assume null :: bs : Data.ByteString.Lazy.ByteString -> { b : GHC.Types.Bool | b <=> bllen bs == 0 } - -assume length - :: bs : Data.ByteString.Lazy.ByteString -> { n : GHC.Int.Int64 | bllen bs == n } - -assume map - :: (_ -> _) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume reverse - :: i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume intersperse - :: _ - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | (bllen i == 0 <=> bllen o == 0) && (1 <= bllen i <=> bllen o == 2 * bllen i - 1) } - -assume intercalate - :: l : Data.ByteString.Lazy.ByteString - -> rs : [Data.ByteString.Lazy.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | len rs == 0 ==> bllen o == 0 } - -assume transpose - :: is : [Data.ByteString.Lazy.ByteString] - -> { os : [{ bs : Data.ByteString.Lazy.ByteString | bllen bs <= len is }] | len is == 0 ==> len os == 0} - -assume foldl1 - :: (_ -> _ -> _) - -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> _ - -assume foldl1' - :: (_ -> _ -> _) - -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> _ - -assume foldr1 - :: (_ -> _ -> _) - -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> _ - -assume concat - :: is : [Data.ByteString.Lazy.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | (len is == 0) ==> (bllen o == 0) } - -assume concatMap - :: (_ -> Data.ByteString.Lazy.ByteString) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen i == 0 ==> bllen o == 0 } - -assume any :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen bs == 0 ==> not b } - -assume all :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen bs == 0 ==> b } - -assume maximum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> _ - -assume minimum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> _ - -assume scanl - :: (_ -> _ -> _) - -> _ - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume mapAccumL - :: (acc -> _ -> (acc, _)) - -> acc - -> i : Data.ByteString.Lazy.ByteString - -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }) - -assume mapAccumR - :: (acc -> _ -> (acc, _)) - -> acc - -> i : Data.ByteString.Lazy.ByteString - -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }) - -assume replicate - :: n : GHC.Int.Int64 - -> _ - -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == n } - -assume take - :: n : GHC.Int.Int64 - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 ==> bllen o == 0) && - ((0 <= n && n <= bllen i) <=> bllen o == n) && - (bllen i <= n <=> bllen o = bllen i) } - -assume drop - :: n : GHC.Int.Int64 - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen o == bllen i) && - ((0 <= n && n <= bllen i) <=> bllen o == bllen i - n) && - (bllen i <= n <=> bllen o == 0) } - -assume splitAt - :: n : GHC.Int.Int64 - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen l == 0) && - ((0 <= n && n <= bllen i) <=> bllen l == n) && - (bllen i <= n <=> bllen l == bllen i) } - , { r : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen r == bllen i) && - ((0 <= n && n <= bllen i) <=> bllen r == bllen i - n) && - (bllen i <= n <=> bllen r == 0) } - ) - -assume takeWhile - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i } - -assume dropWhile - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i } - -assume span - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) - -assume break - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) - -assume group - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }] - -assume groupBy - :: (_ -> _ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }] - -assume inits - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume tails - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume split - :: _ - -> i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume splitWith - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume isPrefixOf - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen l >= bllen r ==> not b } - -assume isSuffixOf - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen l >= bllen r ==> not b } - -assume elem - :: _ - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | (bllen bs == 0) ==> not b } - -assume notElem - :: _ - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | (bllen bs == 0) ==> b } - -assume find - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { w8 : _ | bllen bs /= 0 } - -assume filter - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i } - -assume partition - :: (_ -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) - -assume index - :: bs : Data.ByteString.Lazy.ByteString - -> { n : GHC.Int.Int64 | 0 <= n && n < bllen bs } - -> _ - -assume elemIndex - :: _ - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { n : GHC.Int.Int64 | 0 <= n && n < bllen bs } - -assume elemIndices - :: _ - -> bs : Data.ByteString.Lazy.ByteString - -> [{ n : GHC.Int.Int64 | 0 <= n && n < bllen bs }] - -assume elemIndexEnd - :: _ - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { n : GHC.Int.Int64 | 0 <= n && n < bllen bs } - -assume findIndex - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { n : GHC.Int.Int64 | 0 <= n && n < bllen bs } - -assume findIndices - :: (_ -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> [{ n : GHC.Int.Int64 | 0 <= n && n < bllen bs }] - -assume count - :: _ - -> bs : Data.ByteString.Lazy.ByteString - -> { n : GHC.Int.Int64 | 0 <= n && n < bllen bs } - -assume zip - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { o : [(_, _)] | len o <= bllen l && len o <= bllen r } - -assume zipWith - :: (_ -> _ -> a) - -> l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { o : [a] | len o <= bllen l && len o <= bllen r } - -assume unzip - :: i : [(_, _)] - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l == len i } - , { r : Data.ByteString.Lazy.ByteString | bllen r == len i } - ) - -assume copy - :: i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume hGet - :: _ - -> n : { n : Int | 0 <= n } - -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs == n || bllen bs == 0 } - -assume hGetNonBlocking - :: _ - -> n : { n : Int | 0 <= n } - -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs <= n } diff --git a/include/Data/ByteString/Lazy/Char8.spec b/include/Data/ByteString/Lazy/Char8.spec deleted file mode 100644 index 7207795496..0000000000 --- a/include/Data/ByteString/Lazy/Char8.spec +++ /dev/null @@ -1,417 +0,0 @@ -module spec Data.ByteString.Lazy where - -assume empty :: { bs : Data.ByteString.Lazy.ByteString | bllen bs == 0 } - -assume singleton - :: Char -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == 1 } - -assume pack - :: w8s : [Char] - -> { bs : Data.ByteString.ByteString | bllen bs == len w8s } - -assume unpack - :: bs : Data.ByteString.Lazy.ByteString - -> { w8s : [Char] | len w8s == bllen bs } - -assume fromStrict - :: i : Data.ByteString.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bslen i } - -assume toStrict - :: i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.ByteString | bslen o == bllen i } - -assume fromChunks - :: i : [Data.ByteString.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | len i == 0 <=> bllen o == 0 } - -assume toChunks - :: i : Data.ByteString.Lazy.ByteString - -> { os : [{ o : Data.ByteString.ByteString | bslen o <= bllen i}] | len os == 0 <=> bllen i == 0 } - -assume cons - :: Char - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 } - -assume snoc - :: i : Data.ByteString.Lazy.ByteString - -> Char - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i + 1 } - -assume append - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen l + bllen r } - -head - :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -assume uncons - :: i : Data.ByteString.Lazy.ByteString - -> Maybe (Char, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 }) - -assume unsnoc - :: i : Data.ByteString.Lazy.ByteString - -> Maybe ({ o : Data.ByteString.Lazy.ByteString | bllen o == bllen i - 1 }, Char) - -last - :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -tail - :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -init - :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -assume null - :: bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | b <=> bllen bs == 0 } - -assume length - :: bs : Data.ByteString.Lazy.ByteString -> { n : Data.Int.Int64 | bllen bs == n } - -assume map - :: (Char -> Char) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume reverse - :: i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume intersperse - :: Char - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | (bllen i == 0 <=> bllen o == 0) && (1 <= bllen i <=> bllen o == 2 * bllen i - 1) } - -assume intercalate - :: l : Data.ByteString.Lazy.ByteString - -> rs : [Data.ByteString.Lazy.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | len rs == 0 ==> bllen o == 0 } - -assume transpose - :: is : [Data.ByteString.Lazy.ByteString] - -> { os : [{ bs : Data.ByteString.Lazy.ByteString | bllen bs <= len is }] | len is == 0 ==> len os == 0} - -foldl1 - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -foldl1' - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -foldr1 - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -foldr1' - :: (Char -> Char -> Char) - -> { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } - -> Char - -assume concat - :: is : [Data.ByteString.Lazy.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | len is == 0 ==> bllen o } - -assume concatMap - :: (Char -> Data.ByteString.Lazy.ByteString) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen i == 0 ==> bllen o == 0 } - -assume any :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen bs == 0 ==> not b } - -assume all :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen bs == 0 ==> b } - -maximum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> Char - -minimum :: { bs : Data.ByteString.Lazy.ByteString | 1 <= bllen bs } -> Char - -assume scanl - :: (Char -> Char -> Char) - -> Char - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume scanl1 - :: (Char -> Char -> Char) - -> i : { i : Data.ByteString.Lazy.ByteString | 1 <= bllen i } - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume scanr - :: (Char -> Char -> Char) - -> Char - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume scanr1 - :: (Char -> Char -> Char) - -> i : { i : Data.ByteString.Lazy.ByteString | 1 <= bllen i } - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume mapAccumL - :: (acc -> Char -> (acc, Char)) - -> acc - -> i : Data.ByteString.Lazy.ByteString - -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }) - -assume mapAccumR - :: (acc -> Char -> (acc, Char)) - -> acc - -> i : Data.ByteString.Lazy.ByteString - -> (acc, { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i }) - -assume replicate - :: n : Data.Int.Int64 - -> Char - -> { bs : Data.ByteString.Lazy.ByteString | bllen bs == n } - -assume unfoldrN - :: n : Int - -> (a -> Maybe (Char, a)) - -> a - -> ({ bs : Data.ByteString.Lazy.ByteString | bllen bs <= n }, Maybe a) - -assume take - :: n : Data.Int.Int64 - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 ==> bllen o == 0) && - ((0 <= n && n <= bllen i) <=> bllen o == n) && - (bllen i <= n <=> bllen o = bllen i) } - -assume drop - :: n : Data.Int.Int64 - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen o == bllen i) && - ((0 <= n && n <= bllen i) <=> bllen o == bllen i - n) && - (bllen i <= n <=> bllen o == 0) } - -assume splitAt - :: n : Data.Int.Int64 - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen l == 0) && - ((0 <= n && n <= bllen i) <=> bllen l == n) && - (bllen i <= n <=> bllen l == bllen i) } - , { r : Data.ByteString.Lazy.ByteString | (n <= 0 <=> bllen r == bllen i) && - ((0 <= n && n <= bllen i) <=> bllen r == bllen i - n) && - (bllen i <= n <=> bllen r == 0) } - ) - -assume takeWhile - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i } - -assume dropWhile - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i } - -assume span - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) - -assume spanEnd - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) - -assume break - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) - -assume breakEnd - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) -assume group - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }] - -assume groupBy - :: (Char -> Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | 1 <= bllen o && bllen o <= bllen i }] - -assume inits - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume tails - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume split - :: Char - -> i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume splitWith - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume lines - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume words - :: i : Data.ByteString.Lazy.ByteString - -> [{ o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i }] - -assume unlines - :: is : [Data.ByteString.Lazy.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | (len is == 0 <=> bllen o == 0) && bllen o >= len is } - -assume unwords - :: is : [Data.ByteString.Lazy.ByteString] - -> { o : Data.ByteString.Lazy.ByteString | (len is == 0 ==> bllen o == 0) && (1 <= len is ==> bllen o >= len is - 1) } - -assume isPrefixOf - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen l >= bllen r ==> not b } - -assume isSuffixOf - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen l >= bllen r ==> not b } - -assume isInfixOf - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen l >= bllen r ==> not b } - -assume breakSubstring - :: il : Data.ByteString.Lazy.ByteString - -> ir : Data.ByteString.Lazy.ByteString - -> ( { ol : Data.ByteString.Lazy.ByteString | bllen ol <= bllen ir && (bllen il > bllen ir ==> bllen ol == bllen ir)} - , { or : Data.ByteString.Lazy.ByteString | bllen or <= bllen ir && (bllen il > bllen ir ==> bllen or == 0) } - ) - -assume elem - :: Char - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen b == 0 ==> not b } - -assume notElem - :: Char - -> bs : Data.ByteString.Lazy.ByteString - -> { b : GHC.Types.Bool | bllen b == 0 ==> b } - -assume find - :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { w8 : Char | bllen bs /= 0 } - -assume filter - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o <= bllen i } - -assume partition - :: (Char -> GHC.Types.Bool) - -> i : Data.ByteString.Lazy.ByteString - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l <= bllen i } - , { r : Data.ByteString.Lazy.ByteString | bllen r <= bllen i } - ) - -index - :: bs : Data.ByteString.Lazy.ByteString - -> { n : Data.Int.Int64 | 0 <= n && n < bllen bs } - -> Char - -assume elemIndex - :: Char - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs } - -assume elemIndices - :: Char - -> bs : Data.ByteString.Lazy.ByteString - -> [{ n : Data.Int.Int64 | 0 <= n && n < bllen bs }] - -assume elemIndexEnd - :: Char - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs } - -assume findIndex - :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> Maybe { n : Data.Int.Int64 | 0 <= n && n < bllen bs } - -assume findIndices - :: (Char -> GHC.Types.Bool) - -> bs : Data.ByteString.Lazy.ByteString - -> [{ n : Data.Int.Int64 | 0 <= n && n < bllen bs }] - -assume count - :: Char - -> bs : Data.ByteString.Lazy.ByteString - -> { n : Data.Int.Int64 | 0 <= n && n < bllen bs } - -assume zip - :: l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { o : [(Char, Char)] | len o <= bllen l && len o <= bllen r } - -assume zipWith - :: (Char -> Char -> a) - -> l : Data.ByteString.Lazy.ByteString - -> r : Data.ByteString.Lazy.ByteString - -> { o : [a] | len o <= bllen l && len o <= bllen r } - -assume unzip - :: i : [(Char, Char)] - -> ( { l : Data.ByteString.Lazy.ByteString | bllen l == len i } - , { r : Data.ByteString.Lazy.ByteString | bllen r == len i } - ) - -assume sort - :: i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume readInt - :: i : Data.ByteString.Lazy.ByteString - -> Maybe { p : (Int, { o : Data.ByteString.Lazy.ByteString | bllen o < bllen i}) | bllen i /= 0 } - -assume readInteger - :: i : Data.ByteString.Lazy.ByteString - -> Maybe { p : (Integer, { o : Data.ByteString.Lazy.ByteString | bllen o < bllen i}) | bllen i /= 0 } - -assume copy - :: i : Data.ByteString.Lazy.ByteString - -> { o : Data.ByteString.Lazy.ByteString | bllen o == bllen i } - -assume hGet - :: System.IO.Handle - -> n : { n : Int | 0 <= n } - -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs == n || bllen bs == 0 } - -assume hGetNonBlocking - :: System.IO.Handle - -> n : { n : Int | 0 <= n } - -> IO { bs : Data.ByteString.Lazy.ByteString | bllen bs <= n } diff --git a/include/Data/ByteString/Short.spec b/include/Data/ByteString/Short.spec deleted file mode 100644 index 3b254a3aa9..0000000000 --- a/include/Data/ByteString/Short.spec +++ /dev/null @@ -1,25 +0,0 @@ -module spec Data.ByteString.Short where - -import Data.String - -measure sbslen :: Data.ByteString.Short.ShortByteString -> { n : Int | 0 <= n } - -invariant { bs : Data.ByteString.Short.ShortByteString | 0 <= sbslen bs } - -invariant { bs : Data.ByteString.Short.ShortByteString | sbslen bs == stringlen bs } - -toShort :: i : Data.ByteString.ByteString -> { o : Data.ByteString.Short.ShortByteString | sbslen o == bslen i } - -fromShort :: o : Data.ByteString.Short.ShortByteString -> { i : Data.ByteString.ByteString | bslen i == sbslen o } - -pack :: w8s : [Data.Word.Word8] -> { bs : Data.ByteString.Short.ShortByteString | sbslen bs == len w8s } - -unpack :: bs : Data.ByteString.Short.ShortByteString -> { w8s : [Data.Word.Word8] | len w8s == sbslen bs } - -empty :: { bs : Data.ByteString.Short.ShortByteString | sbslen bs == 0 } - -null :: bs : Data.ByteString.Short.ShortByteString -> { b : GHC.Types.Bool | b <=> sbslen bs == 0 } - -length :: bs : Data.ByteString.Short.ShortByteString -> { n : Int | sbslen bs == n } - -index :: bs : Data.ByteString.Short.ShortByteString -> { n : Int | 0 <= n && n < sbslen bs } -> Data.Word.Word8 diff --git a/include/Data/ByteString/Unsafe.spec b/include/Data/ByteString/Unsafe.spec deleted file mode 100644 index 775a4bb913..0000000000 --- a/include/Data/ByteString/Unsafe.spec +++ /dev/null @@ -1,29 +0,0 @@ -module spec Data.ByteString.Unsafe where - -unsafeHead - :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -unsafeTail - :: bs : { v : Data.ByteString.ByteString | bslen v > 0 } - -> { v : Data.ByteString.ByteString | bslen v = bslen bs - 1 } - -unsafeInit - :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -unsafeLast - :: { bs : Data.ByteString.ByteString | 1 <= bslen bs } -> _ - -unsafeIndex - :: bs : Data.ByteString.ByteString - -> { n : Int | 0 <= n && n < bslen bs } - -> _ - -unsafeTake - :: n : { n : Int | 0 <= n } - -> i : { i : Data.ByteString.ByteString | n <= bslen i } - -> { o : Data.ByteString.ByteString | bslen o == n } - -unsafeDrop - :: n : { n : Int | 0 <= n } - -> i : { i : Data.ByteString.ByteString | n <= bslen i } - -> { o : Data.ByteString.ByteString | bslen o == bslen i - n } diff --git a/include/Data/Char.spec b/include/Data/Char.spec deleted file mode 100644 index 2c53389917..0000000000 --- a/include/Data/Char.spec +++ /dev/null @@ -1 +0,0 @@ -module spec Data.Chare where diff --git a/include/Data/Either.spec b/include/Data/Either.spec deleted file mode 100644 index 607b58eecf..0000000000 --- a/include/Data/Either.spec +++ /dev/null @@ -1,5 +0,0 @@ -module spec Data.Either where - -measure isLeft :: Data.Either.Either a b -> Bool - isLeft (Left x) = true - isLeft (Right x) = false diff --git a/include/Data/Foldable.spec b/include/Data/Foldable.spec deleted file mode 100644 index c4d72d09d9..0000000000 --- a/include/Data/Foldable.spec +++ /dev/null @@ -1,6 +0,0 @@ -module spec Data.Foldable where - -import GHC.Base - -length :: Data.Foldable.Foldable f => forall a. xs:f a -> {v:Nat | v = len xs} -null :: v:_ -> {b:Bool | (b <=> len v = 0) && (not b <=> len v > 0)} diff --git a/include/Data/Int.spec b/include/Data/Int.spec deleted file mode 100644 index 7b418181e5..0000000000 --- a/include/Data/Int.spec +++ /dev/null @@ -1,8 +0,0 @@ -module spec Data.Int where - -embed Data.Int.Int8 as int -embed Data.Int.Int16 as int -embed Data.Int.Int32 as int -embed Data.Int.Int64 as int - -// type Nat64 = {v:Data.Int.Int64 | v >= 0} diff --git a/include/Data/Map.hiddenspec b/include/Data/Map.hiddenspec deleted file mode 100644 index 5e98059389..0000000000 --- a/include/Data/Map.hiddenspec +++ /dev/null @@ -1,27 +0,0 @@ -module spec Data.Map where - -embed Data.Map.Map as Map_t - ---------------------------------------------------------------------------------------- --- | Logical Map Operators: Interpreted "natively" by the SMT solver ------------------ ---------------------------------------------------------------------------------------- - -measure Map_select :: forall k v. Data.Map.Map k v -> k -> v - -measure Map_store :: forall k v. Data.Map.Map k v -> k -> v -> Data.Map.Map k v - - -insert :: Ord k => k:k -> v:v -> m:Data.Map.Map k v -> {n:Data.Map.Map k v | n = Map_store m k v} - -lookup :: Ord k => k:k -> m:Data.Map.Map k v -> Maybe {v:v | v = Map_select m k} - -(!) :: Ord k => m:Data.Map.Map k v -> k:k -> {v:v | v = Map_select m k} - - - - - - - - - diff --git a/include/Data/Maybe.spec b/include/Data/Maybe.spec deleted file mode 100644 index 4f40670a82..0000000000 --- a/include/Data/Maybe.spec +++ /dev/null @@ -1,7 +0,0 @@ -module spec Data.Maybe where - -maybe :: v:b -> (a -> b) -> u:(Maybe a) -> {w:b | not (isJust u) => w == v} -isJust :: v:(Maybe a) -> {b:Bool | b == isJust v} -isNothing :: v:(Maybe a) -> {b:Bool | not (isJust v) == b} -fromJust :: {v:(Maybe a) | isJust v} -> a -fromMaybe :: v:a -> u:(Maybe a) -> {x:a | not (isJust u) => x == v} diff --git a/include/Data/OldList.spec b/include/Data/OldList.spec deleted file mode 100644 index b82274ecce..0000000000 --- a/include/Data/OldList.spec +++ /dev/null @@ -1,11 +0,0 @@ -module spec Data.OldList where - -import GHC.Base -import GHC.List -import GHC.Types - -assume groupBy :: (a -> a -> GHC.Types.Bool) -> [a] -> [{v:[a] | len(v) > 0}] - -assume transpose :: [[a]] -> [{v:[a] | (len v) > 0}] - - diff --git a/include/Data/Set.spec b/include/Data/Set.spec deleted file mode 100644 index 2ea2f18ef6..0000000000 --- a/include/Data/Set.spec +++ /dev/null @@ -1,59 +0,0 @@ -module spec Data.Set where - -embed Data.Set.Internal.Set as Set_Set - -// ---------------------------------------------------------------------------------------------- -// -- | Logical Set Operators: Interpreted "natively" by the SMT solver ------------------------- -// ---------------------------------------------------------------------------------------------- - - -// union -measure Set_cup :: (Data.Set.Internal.Set a) -> (Data.Set.Internal.Set a) -> (Data.Set.Internal.Set a) - -// intersection -measure Set_cap :: (Data.Set.Internal.Set a) -> (Data.Set.Internal.Set a) -> (Data.Set.Internal.Set a) - -// difference -measure Set_dif :: (Data.Set.Internal.Set a) -> (Data.Set.Internal.Set a) -> (Data.Set.Internal.Set a) - -// singleton -measure Set_sng :: a -> (Data.Set.Internal.Set a) - -// emptiness test -measure Set_emp :: (Data.Set.Internal.Set a) -> GHC.Types.Bool - -// empty set -measure Set_empty :: forall a. GHC.Types.Int -> (Data.Set.Internal.Set a) - -// membership test -measure Set_mem :: a -> (Data.Set.Internal.Set a) -> GHC.Types.Bool - -// inclusion test -measure Set_sub :: (Data.Set.Internal.Set a) -> (Data.Set.Internal.Set a) -> GHC.Types.Bool - -// --------------------------------------------------------------------------------------------- -// -- | Refined Types for Data.Set Operations -------------------------------------------------- -// --------------------------------------------------------------------------------------------- - -isSubsetOf :: (GHC.Classes.Ord a) => x:(Data.Set.Internal.Set a) -> y:(Data.Set.Internal.Set a) -> {v:GHC.Types.Bool | v <=> Set_sub x y} -member :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Internal.Set a) -> {v:GHC.Types.Bool | v <=> Set_mem x xs} -null :: xs:(Data.Set.Internal.Set a) -> {v:GHC.Types.Bool | v <=> Set_emp xs} - -empty :: {v:(Data.Set.Internal.Set a) | Set_emp v} -singleton :: x:a -> {v:(Data.Set.Internal.Set a) | v = (Set_sng x)} -insert :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Internal.Set a) -> {v:(Data.Set.Internal.Set a) | v = Set_cup xs (Set_sng x)} -delete :: (GHC.Classes.Ord a) => x:a -> xs:(Data.Set.Internal.Set a) -> {v:(Data.Set.Internal.Set a) | v = Set_dif xs (Set_sng x)} - -union :: GHC.Classes.Ord a => xs:(Data.Set.Internal.Set a) -> ys:(Data.Set.Internal.Set a) -> {v:(Data.Set.Internal.Set a) | v = Set_cup xs ys} -intersection :: GHC.Classes.Ord a => xs:(Data.Set.Internal.Set a) -> ys:(Data.Set.Internal.Set a) -> {v:(Data.Set.Internal.Set a) | v = Set_cap xs ys} -difference :: GHC.Classes.Ord a => xs:(Data.Set.Internal.Set a) -> ys:(Data.Set.Internal.Set a) -> {v:(Data.Set.Internal.Set a) | v = Set_dif xs ys} - -fromList :: GHC.Classes.Ord a => xs:[a] -> {v:Data.Set.Internal.Set a | v = listElts xs} - -// --------------------------------------------------------------------------------------------- -// -- | The set of elements in a list ---------------------------------------------------------- -// --------------------------------------------------------------------------------------------- - -measure listElts :: [a] -> (Data.Set.Internal.Set a) - listElts [] = {v | (Set_emp v)} - listElts (x:xs) = {v | v = Set_cup (Set_sng x) (listElts xs) } diff --git a/include/Data/String.spec b/include/Data/String.spec deleted file mode 100644 index 48da15f724..0000000000 --- a/include/Data/String.spec +++ /dev/null @@ -1,8 +0,0 @@ -module spec Data.String where - -measure stringlen :: a -> GHC.Types.Int - -Data.String.fromString - :: forall a. Data.String.IsString a - => i : [GHC.Types.Char] - -> { o : a | i ~~ o && len i == stringlen o } diff --git a/include/Data/Text.spec b/include/Data/Text.spec deleted file mode 100644 index 16716a3de4..0000000000 --- a/include/Data/Text.spec +++ /dev/null @@ -1,289 +0,0 @@ -module spec Data.Text where - -import Data.String - -measure tlen :: Data.Text.Text -> { n : Int | 0 <= n } - -invariant { t : Data.Text.Text | 0 <= tlen t } - -invariant { t : Data.Text.Text | tlen t == stringlen t } - -empty :: { t : Data.Text.Text | tlen t == 0 } - -singleton :: _ -> { t : Data.Text.Text | tlen t == 1 } - -pack :: str : [_] - -> { t : Data.Text.Text | tlen t == len str } - -unpack :: t : Data.Text.Text - -> { str : [_] | len str == tlen t } - -cons :: _ - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen o == tlen i + 1 } - -snoc :: i : Data.Text.Text - -> _ - -> { o : Data.Text.Text | tlen o == tlen i + 1 } - -append :: l : Data.Text.Text - -> r : Data.Text.Text - -> { o : Data.Text.Text | tlen o == tlen l + tlen r } - -head :: { t : Data.Text.Text | 1 <= tlen t } -> _ - -unsnoc :: i:Data.Text.Text - -> (Maybe ({ o : Data.Text.Text | tlen o == tlen i - 1 }, _)) - -last :: { t : Data.Text.Text | 1 <= tlen t } -> _ - -tail :: { t : Data.Text.Text | 1 <= tlen t } -> _ - -init - :: {i:Data.Text.Text | 1 <= tlen i } - -> {o:Data.Text.Text | tlen o == tlen i - 1 } - -null - :: t : Data.Text.Text - -> { b : GHC.Types.Bool | b <=> tlen t == 0 } - -length :: t : Data.Text.Text -> { n : Int | tlen t == n } - -map - :: (_ -> _) - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen o == tlen i } - -reverse - :: i : Data.Text.Text - -> { o : Data.Text.Text | tlen o == tlen i } - -intersperse - :: _ - -> i : Data.Text.Text - -> { o : Data.Text.Text | (tlen i == 0 <=> tlen o == 0) && (1 <= tlen i <=> tlen o == 2 * tlen i - 1) } - -intercalate - :: l : Data.Text.Text - -> rs : [Data.Text.Text] - -> { o : Data.Text.Text | len rs == 0 ==> tlen o == 0 } - -transpose - :: is : [Data.Text.Text] - -> { os : [{ t : Data.Text.Text | tlen t <= len is }] | len is == 0 ==> len os == 0} - -foldl1 - :: (_ -> _ -> _) - -> { t : Data.Text.Text | 1 <= tlen t } - -> _ - -foldl1' - :: (_ -> _ -> _) - -> { t : Data.Text.Text | 1 <= tlen t } - -> _ - -foldr1 - :: (_ -> _ -> _) - -> { t : Data.Text.Text | 1 <= tlen t } - -> _ - -concat - :: is : [Data.Text.Text] - -> { o : Data.Text.Text | (len is == 0) ==> (tlen o == 0) } - -concatMap - :: (_ -> Data.Text.Text) - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen i == 0 ==> tlen o == 0 } - -any - :: (_ -> GHC.Types.Bool) - -> t : Data.Text.Text - -> { b : GHC.Types.Bool | tlen t == 0 ==> not b } - -all - :: (_ -> GHC.Types.Bool) - -> t : Data.Text.Text - -> { b : GHC.Types.Bool | tlen t == 0 ==> b } - -maximum :: { t : Data.Text.Text | 1 <= tlen t } -> _ - -minimum :: { t : Data.Text.Text | 1 <= tlen t } -> _ - -scanl :: (_ -> _ -> _) - -> _ - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen o == tlen i } - -scanl1 :: (_ -> _ -> _) - -> i : { i : Data.Text.Text | 1 <= tlen i } - -> { o : Data.Text.Text | tlen o == tlen i } - -scanr - :: (_ -> _ -> _) - -> _ - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen o == tlen i } - -scanr1 - :: (_ -> _ -> _) - -> i : { i : Data.Text.Text | 1 <= tlen i } - -> { o : Data.Text.Text | tlen o == tlen i } - -mapAccumL - :: (acc -> _ -> (acc, _)) - -> acc - -> i : Data.Text.Text - -> (acc, { o : Data.Text.Text | tlen o == tlen i }) - -mapAccumR - :: (acc -> _ -> (acc, _)) - -> acc - -> i : Data.Text.Text - -> (acc, { o : Data.Text.Text | tlen o == tlen i }) - -replicate - :: n : Int - -> _ - -> { t : Data.Text.Text | tlen t == n } - -unfoldrN - :: n : Int - -> (a -> Maybe (_, a)) - -> a - -> { t : Data.Text.Text | tlen t <= n } - -take - :: n : Int - -> i : Data.Text.Text - -> { o : Data.Text.Text | (n <= 0 <=> tlen o == 0) && - ((0 <= n && n <= tlen i) <=> tlen o == n) && - (tlen i <= n <=> tlen o = tlen i) } - -drop - :: n : Int - -> i : Data.Text.Text - -> { o : Data.Text.Text | (n <= 0 <=> tlen o == tlen i) && - ((0 <= n && n <= tlen i) <=> tlen o == tlen i - n) && - (tlen i <= n <=> tlen o == 0) } - -splitAt - :: n : Int - -> i : Data.Text.Text - -> ( { l : Data.Text.Text | (n <= 0 <=> tlen l == 0) && - ((0 <= n && n <= tlen i) <=> tlen l == n) && - (tlen i <= n <=> tlen l == tlen i) } - , { r : Data.Text.Text | (n <= 0 <=> tlen r == tlen i) && - ((0 <= n && n <= tlen i) <=> tlen r == tlen i - n) && - (tlen i <= n <=> tlen r == 0) } - ) - -takeWhile - :: (_ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen o <= tlen i } - -dropWhile - :: (_ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen o <= tlen i } - -span - :: (_ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> ( { l : Data.Text.Text | tlen l <= tlen i } - , { r : Data.Text.Text | tlen r <= tlen i } - ) - -break - :: (_ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> ( { l : Data.Text.Text | tlen l <= tlen i } - , { r : Data.Text.Text | tlen r <= tlen i } - ) - -group - :: i : Data.Text.Text - -> [{ o : Data.Text.Text | 1 <= tlen o && tlen o <= tlen i }] - -groupBy - :: (_ -> _ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> [{ o : Data.Text.Text | 1 <= tlen o && tlen o <= tlen i }] - -inits - :: i : Data.Text.Text - -> [{ o : Data.Text.Text | tlen o <= tlen i }] - -tails - :: i : Data.Text.Text - -> [{ o : Data.Text.Text | tlen o <= tlen i }] - -split - :: (_ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> [{ o : Data.Text.Text | tlen o <= tlen i }] - -isPrefixOf - :: l : Data.Text.Text - -> r : Data.Text.Text - -> { b : GHC.Types.Bool | tlen l >= tlen r ==> not b } - -isSuffixOf - :: l : Data.Text.Text - -> r : Data.Text.Text - -> { b : GHC.Types.Bool | tlen l > tlen r ==> not b } - -isInfixOf - :: l : Data.Text.Text - -> r : Data.Text.Text - -> { b : GHC.Types.Bool | tlen l > tlen r ==> not b } - -find - :: (_ -> GHC.Types.Bool) - -> t : Data.Text.Text - -> (Maybe { char : _ | tlen t /= 0 }) - -filter - :: (_ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> { o : Data.Text.Text | tlen o <= tlen i } - -partition - :: (_ -> GHC.Types.Bool) - -> i : Data.Text.Text - -> ( { l : Data.Text.Text | tlen l <= tlen i } - , { r : Data.Text.Text | tlen r <= tlen i } - ) - -index :: t : Data.Text.Text -> { n : Int | 0 <= n && n < tlen t } -> _ - -findIndex - :: (_ -> GHC.Types.Bool) - -> t : Data.Text.Text - -> (Maybe { n : Int | 0 <= n && n < tlen t }) - -count - :: _ - -> t : Data.Text.Text - -> { n : Int | 0 <= n && n < tlen t } - -zip - :: l : Data.Text.Text - -> r : Data.Text.Text - -> { o : [(_, _)] | len o <= tlen l && len o <= tlen r } - -zipWith - :: (_ -> _ -> Char) - -> l : Data.Text.Text - -> r : Data.Text.Text - -> { o : Text | tlen o <= tlen l && tlen o <= tlen r } - -copy - :: i : Data.Text.Text - -> { o : Data.Text.Text | tlen o == tlen i } - -uncons - :: i : Data.Text.Text - -> (Maybe (_, { o : Data.Text.Text | tlen o == tlen i - 1 })) - diff --git a/include/Data/Text/Fusion.spec b/include/Data/Text/Fusion.spec deleted file mode 100644 index 7655e1a55d..0000000000 --- a/include/Data/Text/Fusion.spec +++ /dev/null @@ -1,25 +0,0 @@ -module spec Data.Text.Fusion where - -import Data.Text.Fusion.Common - -stream :: t:Data.Text.Internal.Text - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (tlength t)} -reverseStream :: t:Data.Text.Internal.Text - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (tlength t)} -unstream :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Internal.Text | (tlength v) = (slen s)} - -findIndex :: (GHC.Types.Char -> GHC.Types.Bool) - -> s:Data.Text.Fusion.Internal.Stream Char - -> (Data.Maybe.Maybe {v:Nat | v < (slen s)}) - -mapAccumL :: (a -> GHC.Types.Char -> (a,GHC.Types.Char)) - -> a - -> s:Data.Text.Fusion.Internal.Stream Char - -> (a, {v:Data.Text.Internal.Text | (tlength v) = (slen s)}) - - -length :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:GHC.Types.Int | v = (slen s)} -reverse :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Internal.Text | (tlength v) = (slen s)} diff --git a/include/Data/Text/Fusion/Common.spec b/include/Data/Text/Fusion/Common.spec deleted file mode 100644 index 17037b50cc..0000000000 --- a/include/Data/Text/Fusion/Common.spec +++ /dev/null @@ -1,52 +0,0 @@ -module spec Data.Text.Fusion.Common where - -measure slen :: Data.Text.Fusion.Internal.Stream a - -> GHC.Types.Int - -cons :: GHC.Types.Char - -> s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (1 + (slen s))} - -snoc :: s:Data.Text.Fusion.Internal.Stream Char - -> GHC.Types.Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (1 + (slen s))} - -compareLengthI :: s:Data.Text.Fusion.Internal.Stream Char - -> l:GHC.Types.Int - -> {v:GHC.Types.Ordering | ((v = GHC.Types.EQ) <=> ((slen s) = l))} - -isSingleton :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:GHC.Types.Bool | (v <=> ((slen s) = 1))} - -singleton :: GHC.Types.Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = 1} - -streamList :: l:[a] - -> {v:Data.Text.Fusion.Internal.Stream a | (slen v) = (len l)} - -unstreamList :: s:Data.Text.Fusion.Internal.Stream a - -> {v:[a] | (len v) = (slen s)} - -map :: (GHC.Types.Char -> GHC.Types.Char) - -> s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (slen s)} - -filter :: (GHC.Types.Char -> GHC.Types.Bool) - -> s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) <= (slen s)} - -intersperse :: GHC.Types.Char - -> s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) > (slen s)} - -replicateCharI :: l:GHC.Types.Int - -> GHC.Types.Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = l} - -toCaseFold :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) >= (slen s)} - -toUpper :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) >= (slen s)} -toLower :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) >= (slen s)} diff --git a/include/Data/Text/Lazy/Fusion.spec b/include/Data/Text/Lazy/Fusion.spec deleted file mode 100644 index a4525a1ec7..0000000000 --- a/include/Data/Text/Lazy/Fusion.spec +++ /dev/null @@ -1,8 +0,0 @@ -module spec Data.Text.Lazy.Fusion where - -stream :: t:Data.Text.Lazy.Internal.Text - -> {v:Data.Text.Fusion.Internal.Stream Char | (slen v) = (ltlength t)} -unstream :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:Data.Text.Lazy.Internal.Text | (ltlength v) = (slen s)} -length :: s:Data.Text.Fusion.Internal.Stream Char - -> {v:GHC.Int.Int64 | v = (slen s)} diff --git a/include/Data/Time.spec b/include/Data/Time.spec deleted file mode 100644 index 2fdd747a08..0000000000 --- a/include/Data/Time.spec +++ /dev/null @@ -1,3 +0,0 @@ -module spec Data.Time where - -import Data.Time.Calendar diff --git a/include/Data/Time/Calendar.spec b/include/Data/Time/Calendar.spec deleted file mode 100644 index 8cb3fe3bcc..0000000000 --- a/include/Data/Time/Calendar.spec +++ /dev/null @@ -1,11 +0,0 @@ -module spec Data.Time.Calendar where - -type NumericMonth = { x:Nat | 0 < x && x <= 12 } - -type NumericDayOfMonth = { x:Nat | 0 < x && x <= 31 } - -fromGregorian :: Integer -> NumericMonth -> NumericDayOfMonth -> Day - -toGregorian :: Day -> (Integer,NumericMonth,NumericDayOfMonth) - -gregorianMonthLength :: Integer -> NumericMonth -> { x:Nat | 28 <= x && x <= 31 } diff --git a/include/Data/Tuple.spec b/include/Data/Tuple.spec deleted file mode 100644 index 030c794b0d..0000000000 --- a/include/Data/Tuple.spec +++ /dev/null @@ -1,4 +0,0 @@ -module spec Data.Tuple where - -fst :: {f:(x:(a,b) -> {v:a | v = (fst x)}) | f == fst } -snd :: {f:(x:(a,b) -> {v:b | v = (snd x)}) | f == snd } \ No newline at end of file diff --git a/include/Data/Vector.hquals b/include/Data/Vector.hquals deleted file mode 100644 index 11cd038798..0000000000 --- a/include/Data/Vector.hquals +++ /dev/null @@ -1,13 +0,0 @@ -qualif VecEmpty(v: Data.Vector.Vector a) : (vlen v) = 0 -qualif VecEmpty(v: Data.Vector.Vector a) : (vlen v) > 0 -qualif VecEmpty(v: Data.Vector.Vector a) : (vlen v) >= 0 - -qualif Vlen(v:int, x: Data.Vector.Vector a) : (v = vlen x) -qualif Vlen(v:int, x: Data.Vector.Vector a) : (v <= vlen x) -qualif Vlen(v:int, x: Data.Vector.Vector a) : (v < vlen x) - -qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v < vlen x) -qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v <= vlen x) -qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v > vlen x) -qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v >= vlen x) -qualif CmpVlen(v:Data.Vector.Vector a, x:Data.Vector.Vector b) : (vlen v = vlen x) \ No newline at end of file diff --git a/include/Data/Vector.spec b/include/Data/Vector.spec deleted file mode 100644 index 78faf38b70..0000000000 --- a/include/Data/Vector.spec +++ /dev/null @@ -1,26 +0,0 @@ -module spec Data.Vector where - -import GHC.Base - -data variance Data.Vector.Vector covariant - - -measure vlen :: forall a. (Data.Vector.Vector a) -> Int - -invariant {v: Data.Vector.Vector a | 0 <= vlen v } - -! :: forall a. x:(Data.Vector.Vector a) -> vec:{v:Nat | v < vlen x } -> a - -unsafeIndex :: forall a. x:(Data.Vector.Vector a) -> vec:{v:Nat | v < vlen x } -> a - -fromList :: forall a. x:[a] -> {v: Data.Vector.Vector a | vlen v = len x } - -length :: forall a. x:(Data.Vector.Vector a) -> {v : Nat | v = vlen x } - -replicate :: n:Nat -> a -> {v:Data.Vector.Vector a | vlen v = n} - -imap :: (Nat -> a -> b) -> x:(Data.Vector.Vector a) -> {y:Data.Vector.Vector b | vlen y = vlen x } - -map :: (a -> b) -> x:(Data.Vector.Vector a) -> {y:Data.Vector.Vector b | vlen y = vlen x } - -head :: forall a. {xs: Data.Vector.Vector a | vlen xs > 0} -> a diff --git a/include/Data/Word.spec b/include/Data/Word.spec deleted file mode 100644 index dc7d3bce01..0000000000 --- a/include/Data/Word.spec +++ /dev/null @@ -1,10 +0,0 @@ -module spec Data.Word where - -embed Data.Word.Word as int -embed Data.Word.Word8 as int -embed Data.Word.Word16 as int -embed Data.Word.Word32 as int -embed Data.Word.Word64 as int - -invariant {v : Data.Word.Word32 | 0 <= v } -invariant {v : Data.Word.Word16 | 0 <= v } diff --git a/include/Data/Word8.spec b/include/Data/Word8.spec deleted file mode 100644 index 76bf4190fb..0000000000 --- a/include/Data/Word8.spec +++ /dev/null @@ -1,5 +0,0 @@ -module spec Data.Word8 where - -import GHC.Word - -invariant {v:GHC.Word.Word8 | 0 <= v } \ No newline at end of file diff --git a/include/Foreign/C/String.spec b/include/Foreign/C/String.spec deleted file mode 100644 index 607c436d46..0000000000 --- a/include/Foreign/C/String.spec +++ /dev/null @@ -1,11 +0,0 @@ -module spec Foreign.C.String where - -import Foreign.Ptr - -type CStringLen = ((GHC.Ptr.Ptr Foreign.C.Types.CChar), Nat)<{\p v -> (v <= (plen p))}> -type CStringLenN N = ((GHC.Ptr.Ptr Foreign.C.Types.CChar), {v:Nat | v = N})<{\p v -> (v <= (plen p))}> - -// measure cStringLen :: Foreign.C.String.CStringLen -> GHC.Types.Int - -measure cStringLen :: ((GHC.Ptr.Ptr Foreign.C.Types.CChar), GHC.Types.Int) -> GHC.Types.Int - cStringLen (c, n) = n diff --git a/include/Foreign/C/Types.spec b/include/Foreign/C/Types.spec deleted file mode 100644 index f77f5868fd..0000000000 --- a/include/Foreign/C/Types.spec +++ /dev/null @@ -1,7 +0,0 @@ -module spec Foreign.C.Types where - -import GHC.Word - -embed Foreign.C.Types.CInt as int -embed Foreign.C.Types.CSize as int -embed Foreign.C.Types.CULong as int diff --git a/include/Foreign/ForeignPtr.spec b/include/Foreign/ForeignPtr.spec deleted file mode 100644 index 5c1bd76ba9..0000000000 --- a/include/Foreign/ForeignPtr.spec +++ /dev/null @@ -1,16 +0,0 @@ -module spec Foreign.ForeignPtr where - -import GHC.ForeignPtr -import Foreign.Ptr - -Foreign.ForeignPtr.withForeignPtr :: forall a b. fp:(GHC.ForeignPtr.ForeignPtr a) - -> ((PtrN a (fplen fp)) -> GHC.Types.IO b) - -> (GHC.Types.IO b) - -GHC.ForeignPtr.newForeignPtr_ :: p:(GHC.Ptr.Ptr a) -> (GHC.Types.IO (ForeignPtrN a (plen p))) -Foreign.Concurrent.newForeignPtr :: p:(PtrV a) -> GHC.Types.IO () -> (GHC.Types.IO (ForeignPtrN a (plen p))) -Foreign.ForeignPtr.newForeignPtr :: _ -> p:(PtrV a) -> (GHC.Types.IO (ForeignPtrN a (plen p))) - - -// this uses `sizeOf (undefined :: a)`, so the ForeignPtr does not necessarily have length `n` -// Foreign.ForeignPtr.Imp.mallocForeignPtrArray :: (Foreign.Storable.Storable a) => n:Nat -> IO (ForeignPtrN a n) diff --git a/include/Foreign/Marshal/Alloc.spec b/include/Foreign/Marshal/Alloc.spec deleted file mode 100644 index c7d8a31e82..0000000000 --- a/include/Foreign/Marshal/Alloc.spec +++ /dev/null @@ -1,3 +0,0 @@ -module spec Foreign.Marshal.Alloc where - -Foreign.Marshal.Alloc.allocaBytes :: n:Nat -> (PtrN a n -> IO b) -> IO b diff --git a/include/Foreign/Marshal/Array.spec b/include/Foreign/Marshal/Array.spec deleted file mode 100644 index a492f87da0..0000000000 --- a/include/Foreign/Marshal/Array.spec +++ /dev/null @@ -1,3 +0,0 @@ -module spec Foreign.Marshal.Array where - -Foreign.Marshal.Array.allocaArray :: Foreign.Storable.Storable a => n:Int -> ((PtrN a n) -> IO b) -> IO b diff --git a/include/Foreign/Ptr.spec b/include/Foreign/Ptr.spec deleted file mode 100644 index 0fe190159a..0000000000 --- a/include/Foreign/Ptr.spec +++ /dev/null @@ -1,5 +0,0 @@ -module spec Foreign.Ptr where - -import GHC.Ptr - - diff --git a/include/Foreign/Storable.spec b/include/Foreign/Storable.spec deleted file mode 100644 index ed85c4a7d3..0000000000 --- a/include/Foreign/Storable.spec +++ /dev/null @@ -1,30 +0,0 @@ -module spec Foreign.Storable where - -import Foreign.Ptr - -// DON'T do this, we can't import HS files from SPEC files -// import Language.Haskell.Liquid.Foreign - -predicate PValid P N = ((0 <= N) && (N < (plen P))) - -Foreign.Storable.poke :: (Foreign.Storable.Storable a) - => {v: (GHC.Ptr.Ptr a) | 0 < (plen v)} - -> a - -> (GHC.Types.IO ()) - -Foreign.Storable.peek :: (Foreign.Storable.Storable a) - => p:{v: (GHC.Ptr.Ptr a) | 0 < (plen v)} - -> (GHC.Types.IO {v:a | v = (deref p)}) - -Foreign.Storable.peekByteOff :: (Foreign.Storable.Storable a) - => forall b. p:(GHC.Ptr.Ptr b) - -> {v:GHC.Types.Int | (PValid p v)} - -> (GHC.Types.IO a) - -Foreign.Storable.pokeByteOff :: (Foreign.Storable.Storable a) - => forall b. p:(GHC.Ptr.Ptr b) - -> {v:GHC.Types.Int | (PValid p v)} - -> a - -> GHC.Types.IO () - - diff --git a/include/GHC/Base.hquals b/include/GHC/Base.hquals deleted file mode 100644 index 4a282c6773..0000000000 --- a/include/GHC/Base.hquals +++ /dev/null @@ -1,30 +0,0 @@ -//qualif NonNull(v: [a]) : (? (nonnull([v]))) -//qualif Null(v: [a]) : (~ (? (nonnull([v])))) -//qualif EqNull(v:Bool, ~A: [a]): (v <=> (? (nonnull([~A])))) - -// qualif IsEmp(v:GHC.Types.Bool, ~A: [a]) : ((v) <=> len([~A]) [ > ; = ] 0) -// qualif ListZ(v: [a]) : len([v]) [ = ; >= ; > ] 0 -// qualif CmpLen(v:[a], ~A:[b]) : len([v]) [= ; >=; >; <=; <] len([~A]) -// qualif EqLen(v:int, ~A: [a]) : v = len([~A]) -// qualif LenEq(v:[a], ~A: int) : ~A = len([v]) -// qualif LenAcc(v:int, ~A:[a], ~B: int): v = len([~A]) + ~B -// qualif LenDiff(v:[a], ~A:int): len([v]) = (~A [ +; - ] 1) - -qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (v <=> (len xs > 0)) -qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (v <=> (len xs = 0)) - -qualif ListZ(v: [a]) : (len([v]) = 0) -qualif ListZ(v: [a]) : (len([v]) >= 0) -qualif ListZ(v: [a]) : (len([v]) > 0) - -qualif CmpLen(v:[a], xs:[b]) : (len([v]) = len([xs])) -qualif CmpLen(v:[a], xs:[b]) : (len([v]) >= len([xs])) -qualif CmpLen(v:[a], xs:[b]) : (len([v]) > len([xs])) -qualif CmpLen(v:[a], xs:[b]) : (len([v]) <= len([xs])) -qualif CmpLen(v:[a], xs:[b]) : (len([v]) < len([xs])) - -qualif EqLen(v:int, xs: [a]) : (v = len([xs])) -qualif LenEq(v:[a], x: int) : (x = len([v])) -qualif LenDiff(v:[a], x:int) : (len([v]) = x + 1) -qualif LenDiff(v:[a], x:int) : (len([v]) = x - 1) -qualif LenAcc(v:int, xs:[a], n: int): (v = len([xs]) + n) diff --git a/include/GHC/Base.spec b/include/GHC/Base.spec deleted file mode 100644 index 438850d12c..0000000000 --- a/include/GHC/Base.spec +++ /dev/null @@ -1,79 +0,0 @@ -module spec GHC.Base where - -import GHC.CString -import GHC.Prim -import GHC.Classes -import GHC.Types - -embed GHC.Types.Int as int -embed GHC.Types.Bool as bool - -measure autolen :: forall a. a -> GHC.Types.Int -class measure len :: forall f a. f a -> GHC.Types.Int -instance measure len :: forall a. [a] -> GHC.Types.Int - len [] = 0 - len (y:ys) = 1 + len ys - -// measure null :: [a] -> Bool -// null [] = true -// null (y:ys) = false - -measure fst :: (a, b) -> a - fst (a, b) = a - -measure snd :: (a, b) -> b - snd (a, b) = b - -qualif Fst(__v:a, __y:b): (__v = (fst __y)) -qualif Snd(__v:a, __y:b): (__v = (snd __y)) - -measure isJust :: Maybe a -> Bool - isJust (Just x) = true - isJust (Nothing) = false - -measure fromJust :: Maybe a -> a - fromJust (Just x) = x - - -invariant {v: [a] | len v >= 0 } -map :: (a -> b) -> xs:[a] -> {v: [b] | len v == len xs} -(++) :: xs:[a] -> ys:[a] -> {v:[a] | len v == len xs + len ys} - -($) :: (a -> b) -> a -> b -id :: x:a -> {v:a | v = x} - -// data variance Text.ParserCombinators.ReadPrec.ReadPrec contravariant - -// qualif NonNull(v: [a]) : (? (nonnull v )) -// qualif Null(v: [a]) : (~ (? (nonnull v ))) -// qualif EqNull(v:Bool, ~A: [a]): (v <=> (? (nonnull([~A])))) - -// qualif IsEmp(v:GHC.Types.Bool, ~A: [a]) : ((v) <=> len([~A]) [ > ; = ] 0) -// qualif ListZ(v: [a]) : len v [ = ; >= ; > ] 0 -// qualif CmpLen(v:[a], ~A:[b]) : len v [= ; >=; >; <=; <] len([~A]) -// qualif EqLen(v:int, ~A: [a]) : v = len([~A]) -// qualif LenEq(v:[a], ~A: int) : ~A = len v -// qualif LenAcc(v:int, ~A:[a], ~B: int): v = len([~A]) + ~B -// qualif LenDiff(v:[a], ~A:int): len v = (~A [ +; - ] 1) - -qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (v <=> (len xs > 0)) -qualif IsEmp(v:GHC.Types.Bool, xs: [a]) : (v <=> (len xs = 0)) - -qualif ListZ(v: [a]) : (len v = 0) -qualif ListZ(v: [a]) : (len v >= 0) -qualif ListZ(v: [a]) : (len v > 0) - -qualif CmpLen(v:[a], xs:[b]) : (len v = len xs ) -qualif CmpLen(v:[a], xs:[b]) : (len v >= len xs ) -qualif CmpLen(v:[a], xs:[b]) : (len v > len xs ) -qualif CmpLen(v:[a], xs:[b]) : (len v <= len xs ) -qualif CmpLen(v:[a], xs:[b]) : (len v < len xs ) - -qualif EqLen(v:int, xs: [a]) : (v = len xs ) -qualif LenEq(v:[a], x: int) : (x = len v ) - -qualif LenDiff(v:[a], x:int) : (len v = x + 1) -qualif LenDiff(v:[a], x:int) : (len v = x - 1) -qualif LenAcc(v:int, xs:[a], n: int): (v = len xs + n) - - diff --git a/include/GHC/CString.spec b/include/GHC/CString.spec deleted file mode 100644 index 1f903d319d..0000000000 --- a/include/GHC/CString.spec +++ /dev/null @@ -1,11 +0,0 @@ -module spec GHC.CString where - -import GHC.Prim - -measure strLen :: GHC.Base.String -> GHC.Types.Int - -embed GHC.Types.Char as Char - -GHC.CString.unpackCString# - :: x:GHC.Prim.Addr# - -> {v:[Char] | v ~~ x && len v == strLen x} diff --git a/include/GHC/Classes.spec b/include/GHC/Classes.spec deleted file mode 100644 index 4031995e06..0000000000 --- a/include/GHC/Classes.spec +++ /dev/null @@ -1,29 +0,0 @@ -module spec GHC.Classes where - -import GHC.Types - -not :: x:GHC.Types.Bool -> {v:GHC.Types.Bool | ((v) <=> ~(x))} -(&&) :: x:GHC.Types.Bool -> y:GHC.Types.Bool - -> {v:GHC.Types.Bool | ((v) <=> ((x) && (y)))} -(||) :: x:GHC.Types.Bool -> y:GHC.Types.Bool - -> {v:GHC.Types.Bool | ((v) <=> ((x) || (y)))} -(==) :: (GHC.Classes.Eq a) => x:a -> y:a - -> {v:GHC.Types.Bool | ((v) <=> x = y)} -(/=) :: (GHC.Classes.Eq a) => x:a -> y:a - -> {v:GHC.Types.Bool | ((v) <=> x != y)} -(>) :: (GHC.Classes.Ord a) => x:a -> y:a - -> {v:GHC.Types.Bool | ((v) <=> x > y)} -(>=) :: (GHC.Classes.Ord a) => x:a -> y:a - -> {v:GHC.Types.Bool | ((v) <=> x >= y)} -(<) :: (GHC.Classes.Ord a) => x:a -> y:a - -> {v:GHC.Types.Bool | ((v) <=> x < y)} -(<=) :: (GHC.Classes.Ord a) => x:a -> y:a - -> {v:GHC.Types.Bool | ((v) <=> x <= y)} - -compare :: (GHC.Classes.Ord a) => x:a -> y:a - -> {v:GHC.Types.Ordering | (((v = GHC.Types.EQ) <=> (x = y)) && - ((v = GHC.Types.LT) <=> (x < y)) && - ((v = GHC.Types.GT) <=> (x > y))) } - -max :: (GHC.Classes.Ord a) => x:a -> y:a -> {v:a | v = (if x > y then x else y) } -min :: (GHC.Classes.Ord a) => x:a -> y:a -> {v:a | v = (if x < y then x else y) } diff --git a/include/GHC/Exts.spec b/include/GHC/Exts.spec deleted file mode 100644 index 538ef92706..0000000000 --- a/include/GHC/Exts.spec +++ /dev/null @@ -1,10 +0,0 @@ -module spec GHC.Exts where - -// embed GHC.Exts.Int# as int -// embed GHC.Exts.Word# as int -// embed GHC.Exts.Addr# as Str -// embed GHC.Exts.Double# as real -// embed GHC.Exts.Char# as Char - - - diff --git a/include/GHC/ForeignPtr.spec b/include/GHC/ForeignPtr.spec deleted file mode 100644 index 794cd0338b..0000000000 --- a/include/GHC/ForeignPtr.spec +++ /dev/null @@ -1,9 +0,0 @@ -module spec GHC.ForeignPtr where - -measure fplen :: GHC.ForeignPtr.ForeignPtr a -> GHC.Types.Int - -type ForeignPtrV a = {v: GHC.ForeignPtr.ForeignPtr a | 0 <= fplen v} -type ForeignPtrN a N = {v: GHC.ForeignPtr.ForeignPtr a | 0 <= fplen v && fplen v == N } - -mallocPlainForeignPtrBytes :: n:{v:GHC.Types.Int | v >= 0 } -> (GHC.Types.IO (ForeignPtrN a n)) - diff --git a/include/GHC/IO/Handle.spec b/include/GHC/IO/Handle.spec deleted file mode 100644 index dac988eb77..0000000000 --- a/include/GHC/IO/Handle.spec +++ /dev/null @@ -1,10 +0,0 @@ -module spec GHC.IO.Handle where - -hGetBuf :: GHC.IO.Handle.Handle -> GHC.Ptr.Ptr a -> n:Nat - -> (GHC.Types.IO {v:Nat | v <= n}) - -hGetBufNonBlocking :: GHC.IO.Handle.Handle -> GHC.Ptr.Ptr a -> n:Nat - -> (GHC.Types.IO {v:Nat | v <= n}) - -hFileSize :: GHC.IO.Handle.Handle - -> (GHC.Types.IO {v:GHC.Integer.Type.Integer | v >= 0}) diff --git a/include/GHC/Int.spec b/include/GHC/Int.spec deleted file mode 100644 index e7a8cd5578..0000000000 --- a/include/GHC/Int.spec +++ /dev/null @@ -1,8 +0,0 @@ -module spec GHC.Int where - -embed GHC.Int.Int8 as int -embed GHC.Int.Int16 as int -embed GHC.Int.Int32 as int -embed GHC.Int.Int64 as int - -type Nat64 = {v:GHC.Int.Int64 | v >= 0} diff --git a/include/GHC/List.spec b/include/GHC/List.spec deleted file mode 100644 index 9e62f65a0b..0000000000 --- a/include/GHC/List.spec +++ /dev/null @@ -1,60 +0,0 @@ -module spec GHC.List where - -head :: xs:{v: [a] | len v > 0} -> {v:a | v = head xs} -tail :: xs:{v: [a] | len v > 0} -> {v: [a] | len(v) = (len(xs) - 1) && v = tail xs} - -last :: xs:{v: [a] | len v > 0} -> a -init :: xs:{v: [a] | len v > 0} -> {v: [a] | len(v) = len(xs) - 1} -null :: xs:[a] -> {v: GHC.Types.Bool | ((v) <=> len(xs) = 0) } -length :: xs:[a] -> {v: GHC.Types.Int | v = len(xs)} -filter :: (a -> GHC.Types.Bool) -> xs:[a] -> {v: [a] | len(v) <= len(xs)} -scanl :: (a -> b -> a) -> a -> xs:[b] -> {v: [a] | len(v) = 1 + len(xs) } -scanl1 :: (a -> a -> a) -> xs:{v: [a] | len(v) > 0} -> {v: [a] | len(v) = len(xs) } -foldr1 :: (a -> a -> a) -> xs:{v: [a] | len(v) > 0} -> a -scanr :: (a -> b -> b) -> b -> xs:[a] -> {v: [b] | len(v) = 1 + len(xs) } -scanr1 :: (a -> a -> a) -> xs:{v: [a] | len(v) > 0} -> {v: [a] | len(v) = len(xs) } - -lazy GHC.List.iterate -iterate :: (a -> a) -> a -> [a] - -repeat :: a -> [a] -lazy GHC.List.repeat - -replicate :: n:Nat -> x:a -> {v: [{v:a | v = x}] | len(v) = n} - -cycle :: {v: [a] | len(v) > 0 } -> [a] -lazy cycle - -takeWhile :: (a -> GHC.Types.Bool) -> xs:[a] -> {v: [a] | len(v) <= len(xs)} -dropWhile :: (a -> GHC.Types.Bool) -> xs:[a] -> {v: [a] | len(v) <= len(xs)} - -take :: n:GHC.Types.Int - -> xs:[a] - -> {v:[a] | if n >= 0 then (len v = (if (len xs) < n then (len xs) else n)) else (len v = 0)} -drop :: n:GHC.Types.Int - -> xs:[a] - -> {v:[a] | (if (n >= 0) then (len(v) = (if (len(xs) < n) then 0 else len(xs) - n)) else ((len v) = (len xs)))} - -splitAt :: n:_ -> x:[a] -> ({v:[a] | (if (n >= 0) then (if (len x) < n then (len v) = (len x) else (len v) = n) else ((len v) = 0))},[a])<{\x1 x2 -> (len x2) = (len x) - (len x1)}> -span :: (a -> GHC.Types.Bool) - -> xs:[a] - -> ({v:[a]|((len v)<=(len xs))}, {v:[a]|((len v)<=(len xs))}) - -break :: (a -> GHC.Types.Bool) -> xs:[a] -> ([a],[a])<{\x y -> (len xs) = (len x) + (len y)}> - -reverse :: xs:[a] -> {v: [a] | len(v) = len(xs)} - -include - -GHC.List.!! :: xs:[a] -> {v: _ | ((0 <= v) && (v < len(xs)))} -> a - - -zip :: xs : [a] -> ys:[b] - -> {v : [(a, b)] | ((((len v) <= (len xs)) && ((len v) <= (len ys))) - && (((len xs) = (len ys)) => ((len v) = (len xs))) )} - -zipWith :: (a -> b -> c) - -> xs : [a] -> ys:[b] - -> {v : [c] | (((len v) <= (len xs)) && ((len v) <= (len ys)))} - -errorEmptyList :: {v: _ | false} -> a diff --git a/include/GHC/Num.spec b/include/GHC/Num.spec deleted file mode 100644 index ac04f687e2..0000000000 --- a/include/GHC/Num.spec +++ /dev/null @@ -1,9 +0,0 @@ -module spec GHC.Num where - -// embed GHC.Integer.Type.Integer as int - -GHC.Num.fromInteger :: (GHC.Num.Num a) => x:_ -> {v:a | v = x } - -GHC.Num.negate :: (GHC.Num.Num a) - => x:a - -> {v:a | v = -x} diff --git a/include/GHC/Prim.spec b/include/GHC/Prim.spec deleted file mode 100644 index ab672c9589..0000000000 --- a/include/GHC/Prim.spec +++ /dev/null @@ -1,8 +0,0 @@ -module spec GHC.Prim where - -embed GHC.Prim.Int# as int -embed GHC.Prim.Addr# as Str -embed GHC.Prim.Char# as Char -embed GHC.Prim.Double# as real -embed GHC.Prim.Float# as real -embed GHC.Prim.Word# as int diff --git a/include/GHC/Ptr.spec b/include/GHC/Ptr.spec deleted file mode 100644 index ce0d796043..0000000000 --- a/include/GHC/Ptr.spec +++ /dev/null @@ -1,24 +0,0 @@ -module spec GHC.Ptr where - -measure pbase :: GHC.Ptr.Ptr a -> GHC.Types.Int -measure plen :: GHC.Ptr.Ptr a -> GHC.Types.Int -measure isNullPtr :: GHC.Ptr.Ptr a -> Bool - -invariant {v:Foreign.Ptr.Ptr a | 0 <= plen v } -invariant {v:Foreign.Ptr.Ptr a | 0 <= pbase v } - -type PtrN a N = {v: PtrV a | plen v == N } -type PtrV a = {v: GHC.Ptr.Ptr a | 0 <= plen v } - -GHC.Ptr.castPtr :: p:(PtrV a) -> (PtrN b (plen p)) - -GHC.Ptr.plusPtr :: base:(PtrV a) - -> off:{v:GHC.Types.Int | v <= plen base } - -> {v:(PtrV b) | pbase v = pbase base && plen v = plen base - off} - -GHC.Ptr.minusPtr :: q:(PtrV a) - -> p:{v:(PtrV b) | pbase v == pbase q && plen v >= plen q} - -> {v:Nat | v == plen p - plen q} - -measure deref :: GHC.Ptr.Ptr a -> a - diff --git a/include/GHC/Read.spec b/include/GHC/Read.spec deleted file mode 100644 index 8314ac74b6..0000000000 --- a/include/GHC/Read.spec +++ /dev/null @@ -1,5 +0,0 @@ -module spec GHC.Read where - -type ParsedString XS = {v:_ | (if ((len XS) > 0) then ((len v) < (len XS)) else ((len v) = 0))} - -GHC.Read.lex :: xs:_ -> [((ParsedString xs), (ParsedString xs))] diff --git a/include/GHC/Real.spec b/include/GHC/Real.spec deleted file mode 100644 index edf1b10f3a..0000000000 --- a/include/GHC/Real.spec +++ /dev/null @@ -1,37 +0,0 @@ -module spec GHC.Real where - -(GHC.Real.^) :: (GHC.Num.Num a, GHC.Real.Integral b) => a:a -> n:b -> {v:a | v == 0 <=> a == 0 } - -GHC.Real.fromIntegral :: (GHC.Real.Integral a, GHC.Num.Num b) => x:a -> {v:b|v=x} - -class (GHC.Num.Num a) => GHC.Real.Fractional a where - (GHC.Real./) :: x:a -> y:{v:a | v /= 0} -> {v:a | v == x / y} - GHC.Real.recip :: a -> a - GHC.Real.fromRational :: GHC.Real.Ratio Integer -> a - -class (GHC.Real.Real a, GHC.Enum.Enum a) => GHC.Real.Integral a where - GHC.Real.quot :: x:a -> y:{v:a | v /= 0} -> {v:a | (v = (x / y)) && - ((x >= 0 && y >= 0) => v >= 0) && - ((x >= 0 && y >= 1) => v <= x) } - GHC.Real.rem :: x:a -> y:{v:a | v /= 0} -> {v:a | ((v >= 0) && (v < y))} - GHC.Real.mod :: x:a -> y:{v:a | v /= 0} -> {v:a | v = x mod y && ((0 <= x && 0 < y) => (0 <= v && v < y))} - - GHC.Real.div :: x:a -> y:{v:a | v /= 0} -> {v:a | (v = (x / y)) && - ((x >= 0 && y >= 0) => v >= 0) && - ((x >= 0 && y >= 1) => v <= x) && - ((1 < y) => v < x ) && - ((y >= 1) => v <= x) - } - GHC.Real.quotRem :: x:a -> y:{v:a | v /= 0} -> ( {v:a | (v = (x / y)) && - ((x >= 0 && y >= 0) => v >= 0) && - ((x >= 0 && y >= 1) => v <= x)} - , {v:a | ((v >= 0) && (v < y))}) - GHC.Real.divMod :: x:a -> y:{v:a | v /= 0} -> ( {v:a | (v = (x / y)) && - ((x >= 0 && y >= 0) => v >= 0) && - ((x >= 0 && y >= 1) => v <= x) } - , {v:a | v = x mod y && ((0 <= x && 0 < y) => (0 <= v && v < y))} - ) - GHC.Real.toInteger :: x:a -> {v:GHC.Integer.Type.Integer | v = x} - -// fixpoint can't handle (x mod y), only (x mod c) so we need to be more clever here -// mod :: x:a -> y:a -> {v:a | v = (x mod y) } diff --git a/include/GHC/Types.spec b/include/GHC/Types.spec deleted file mode 100644 index fe1278fda4..0000000000 --- a/include/GHC/Types.spec +++ /dev/null @@ -1,41 +0,0 @@ -module spec GHC.Types where - -embed GHC.Prim.Int# as int -embed GHC.Prim.Addr# as Str -embed GHC.Prim.Char# as Char -embed GHC.Types.Double# as real -embed GHC.Types.Float# as real -embed GHC.Types.Word as int - -// TODO: Drop prefix below -// GHC.Types.EQ :: {v:GHC.Types.Ordering | v = (cmp v) } -// GHC.Types.LT :: {v:GHC.Types.Ordering | v = (cmp v) } -// GHC.Types.GT :: {v:GHC.Types.Ordering | v = (cmp v) } - -// measure cmp :: GHC.Types.Ordering -> GHC.Types.Ordering -// cmp GHC.Types.EQ = { v | v = GHC.Types.EQ } -// cmp GHC.Types.LT = { v | v = GHC.Types.LT } -// cmp GHC.Types.GT = { v | v = GHC.Types.GT } - - -GHC.Types.True :: {v:GHC.Types.Bool | v } -GHC.Types.False :: {v:GHC.Types.Bool | (~ v) } - -GHC.Types.isTrue# :: n:_ -> {v:GHC.Types.Bool | (n = 1 <=> v)} - -GHC.Types.W# :: w:_ -> {v:GHC.Types.Word | v == w } - -assume GHC.Types.D# :: x:GHC.Prim.Double# -> {v: GHC.Types.Double | v = (x :: real) } -assume GHC.Types.F# :: x:GHC.Prim.Float# -> {v: GHC.Types.Float | v = (x :: real) } -assume GHC.Types.I# :: x:GHC.Prim.Int# -> {v: GHC.Types.Int | v = (x :: int) } -assume GHC.Types.C# :: x:GHC.Prim.Char# -> {v: GHC.Types.Char | v = (x :: Char) } - -assume GHC.Prim.+# :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v: GHC.Prim.Int# | v = x + y} -assume GHC.Prim.-# :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v: GHC.Prim.Int# | v = x - y} -assume GHC.Prim.==# :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v:GHC.Prim.Int# | v = 1 <=> x = y} -assume GHC.Prim.>=# :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v:GHC.Prim.Int# | v = 1 <=> x >= y} -assume GHC.Prim.<=# :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v:GHC.Prim.Int# | v = 1 <=> x <= y} -assume GHC.Prim.<# :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v:GHC.Prim.Int# | v = 1 <=> x < y} -assume GHC.Prim.># :: x:GHC.Prim.Int# -> y:GHC.Prim.Int# -> {v:GHC.Prim.Int# | v = 1 <=> x > y} - -measure addrLen :: GHC.Prim.Addr# -> GHC.Types.Int diff --git a/include/GHC/Word.spec b/include/GHC/Word.spec deleted file mode 100644 index ff48403fe5..0000000000 --- a/include/GHC/Word.spec +++ /dev/null @@ -1,7 +0,0 @@ -module spec GHC.Word where - -embed GHC.Word.Word as int -embed GHC.Word.Word8 as int -embed GHC.Word.Word16 as int -embed GHC.Word.Word32 as int -embed GHC.Word.Word64 as int diff --git a/include/KMeansHelper.hs b/include/KMeansHelper.hs deleted file mode 100644 index e531ad4bff..0000000000 --- a/include/KMeansHelper.hs +++ /dev/null @@ -1,78 +0,0 @@ -module KMeansHelper where - -import Prelude hiding (zipWith) -import Data.List (sort, span, minimumBy) -import Data.Function (on) -import Data.Ord (comparing) -import Language.Haskell.Liquid.Prelude (liquidAssert, liquidError) - - --- | Fixed-Length Lists - -{-@ type List a N = {v : [a] | (len v) = N} @-} - - --- | N Dimensional Points - -{-@ type Point N = List Double N @-} - -{-@ type NonEmptyList a = {v : [a] | (len v) > 0} @-} - --- | Clustering - -{-@ type Clustering a = [(NonEmptyList a)] @-} - ------------------------------------------------------------------- --- | Grouping By a Predicate ------------------------------------- ------------------------------------------------------------------- - -{-@ groupBy :: (a -> a -> Bool) -> [a] -> (Clustering a) @-} -groupBy _ [] = [] -groupBy eq (x:xs) = (x:ys) : groupBy eq zs - where (ys,zs) = span (eq x) xs - ------------------------------------------------------------------- --- | Partitioning By a Size -------------------------------------- ------------------------------------------------------------------- - -{-@ type PosInt = {v: Int | v > 0 } @-} - -{-@ partition :: size:PosInt -> xs:[a] -> (Clustering a) / [len xs] @-} - -partition size [] = [] -partition size ys@(_:_) = zs : partition size zs' - where - zs = take size ys - zs' = drop size ys - ------------------------------------------------------------------------ --- | Safe Zipping ----------------------------------------------------- ------------------------------------------------------------------------ - -{-@ zipWith :: (a -> b -> c) -> xs:[a] -> (List b (len xs)) -> (List c (len xs)) @-} -zipWith f (a:as) (b:bs) = f a b : zipWith f as bs -zipWith _ [] [] = [] - --- Other cases only for exposition -zipWith _ (_:_) [] = liquidError "Dead Code" -zipWith _ [] (_:_) = liquidError "Dead Code" - ------------------------------------------------------------------------ --- | "Matrix" Transposition ------------------------------------------- ------------------------------------------------------------------------ - -{-@ type Matrix a Rows Cols = (List (List a Cols) Rows) @-} - -{-@ transpose :: c:Int -> r:PosInt -> Matrix a r c -> Matrix a c r @-} - -transpose :: Int -> Int -> [[a]] -> [[a]] -transpose 0 _ _ = [] -transpose c r ((x:xs) : xss) = (x : map head xss) : transpose (c-1) r (xs : map tail xss) - --- Or, with comprehensions --- transpose c r ((x:xs):xss) = (x : [ xs' | (x':_) <- xss ]) : transpose (c-1) r (xs : [xs' | (_ : xs') <- xss]) - --- Not needed, just for exposition -transpose c r ([] : _) = liquidError "dead code" -transpose c r [] = liquidError "dead code" - diff --git a/include/Language/Haskell/Liquid/Bag.hs b/include/Language/Haskell/Liquid/Bag.hs deleted file mode 100644 index a2fe10cd34..0000000000 --- a/include/Language/Haskell/Liquid/Bag.hs +++ /dev/null @@ -1,53 +0,0 @@ -module Language.Haskell.Liquid.Bag where - -import qualified Data.Map as M - -{-@ embed Data.Map.Map as Map_t @-} - -{-@ measure Map_default :: Int -> Bag a @-} -{-@ measure Map_union :: Bag a -> Bag a -> Bag a @-} -{-@ measure Map_select :: Data.Map.Map k v -> k -> v @-} -{-@ measure Map_store :: Data.Map.Map k v -> k -> v -> Data.Map.Map k v @-} -{-@ measure bagSize :: Bag k -> Int @-} - --- if I just write measure fromList the measure definition is not imported -{-@ measure fromList :: [k] -> Bag k - fromList [] = Map_default 0 - fromList (x:xs) = Map_store (fromList xs) x (1 + (Map_select (fromList xs) x)) - @-} - - -type Bag a = M.Map a Int - -{-@ assume empty :: {v:Bag k | v = Map_default 0} @-} -empty :: Bag k -empty = M.empty - -{-@ assume bagSize :: b:Bag k -> {i:Nat | i == bagSize b} @-} -bagSize :: Bag k -> Int -bagSize b = sum (M.elems b) - -{-@ fromList :: (Ord k) => xs:[k] -> {v:Bag k | v == fromList xs } @-} -fromList :: (Ord k) => [k] -> Bag k -fromList [] = empty -fromList (x:xs) = put x (fromList xs) - -{-@ assume get :: (Ord k) => k:k -> b:Bag k -> {v:Nat | v = Map_select b k} @-} -get :: (Ord k) => k -> Bag k -> Int -get k m = M.findWithDefault 0 k m - -{-@ assume put :: (Ord k) => k:k -> b:Bag k -> {v:Bag k | v = Map_store b k (1 + (Map_select b k))} @-} -put :: (Ord k) => k -> Bag k -> Bag k -put k m = M.insert k (1 + get k m) m - -{-@ assume union :: (Ord k) => m1:Bag k -> m2:Bag k -> {v:Bag k | v = Map_union m1 m2} @-} -union :: (Ord k) => Bag k -> Bag k -> Bag k -union m1 m2 = M.union m1 m2 - -{-@ thm_emp :: x:k -> xs:Bag k -> { Language.Haskell.Liquid.Bag.empty /= put x xs } @-} -thm_emp :: (Ord k) => k -> Bag k -> () -thm_emp x xs = const () (get x xs) - -{-@ assume thm_size :: xs:[k] -> { bagSize (fromList xs) == len xs } @-} -thm_size :: (Ord k) => [k] -> () -thm_size _ = () diff --git a/include/Language/Haskell/Liquid/Equational.hs b/include/Language/Haskell/Liquid/Equational.hs deleted file mode 100644 index 11ba1aad7e..0000000000 --- a/include/Language/Haskell/Liquid/Equational.hs +++ /dev/null @@ -1,55 +0,0 @@ -module Language.Haskell.Liquid.Equational where - -------------------------------------------------------------------------------- --- | Proof is just unit -------------------------------------------------------------------------------- - -type Proof = () - -------------------------------------------------------------------------------- --- | Casting expressions to Proof using the "postfix" `*** QED` -------------------------------------------------------------------------------- - -data QED = QED - -infixl 2 *** -(***) :: a -> QED -> Proof -_ *** QED = () - -------------------------------------------------------------------------------- --- | Equational Reasoning operators --- | The `eq` operator is inlined in the logic, so can be used in reflected --- | functions while ignoring the equality steps. -------------------------------------------------------------------------------- - -infixl 3 ==., `eq` - - -{-@ (==.) :: x:a -> y:{a | x == y} -> {v:a | v == y && v == x} @-} -(==.) :: a -> a -> a -_ ==. x = x -{-# INLINE (==.) #-} - - -{-@ eq :: x:a -> y:{a | x == y} -> {v:a | v == y && v == x} @-} -eq :: a -> a -> a -_ `eq` x = x -{-# INLINE eq #-} - -------------------------------------------------------------------------------- --- | Explanations -------------------------------------------------------------------------------- - -infixl 3 ? - -{-@ (?) :: forall a b Bool>. a -> b -> a @-} -(?) :: a -> b -> a -x ? _ = x -{-# INLINE (?) #-} - -------------------------------------------------------------------------------- --- | Using proofs as theorems -------------------------------------------------------------------------------- - -withTheorem :: a -> Proof -> a -withTheorem z _ = z diff --git a/include/Language/Haskell/Liquid/Foreign.hs b/include/Language/Haskell/Liquid/Foreign.hs deleted file mode 100644 index c89a59e34d..0000000000 --- a/include/Language/Haskell/Liquid/Foreign.hs +++ /dev/null @@ -1,64 +0,0 @@ -{-# OPTIONS_GHC -fno-warn-unused-imports #-} -{-# LANGUAGE MagicHash #-} - -{- OPTIONS_GHC -cpp #-} -{- OPTIONS_GHC -cpp -fglasgow-exts -} - -module Language.Haskell.Liquid.Foreign where - -import Foreign.C.Types (CSize(..)) -import Foreign.Ptr -import Foreign.ForeignPtr -import GHC.Base - -import Data.Word (Word64) -- Necessary to bring in scope the evidence that Word64 = int - --- TODO: shouldn't have to re-import these (tests/pos/imp0.hs) -{- import Foreign.C.Types -} -{- import Foreign.Ptr -} -{- import Foreign.ForeignPtr -} -{- import GHC.Base -} - - - ------------------------------------------------------------------------------------------------ - -{-# NOINLINE intCSize #-} -{-@ assume intCSize :: x:Int -> {v: CSize | v = x } @-} -intCSize :: Int -> CSize -intCSize = fromIntegral - -{-# NOINLINE cSizeInt #-} -{-@ assume cSizeInt :: x:CSize -> {v: Int | v = x } @-} -cSizeInt :: CSize -> Int -cSizeInt = fromIntegral - - -{-@ assume mkPtr :: x:GHC.Prim.Addr# -> {v: (Ptr b) | ((plen v) = (addrLen x) && ((plen v) >= 0)) } @-} -mkPtr :: Addr# -> Ptr b -mkPtr = undefined -- Ptr x - - -{-@ assume isNullPtr :: p:(Ptr a) -> {v:Bool | (v <=> (isNullPtr p)) } @-} -isNullPtr :: Ptr a -> Bool -isNullPtr p = (p == nullPtr) -{-# INLINE isNullPtr #-} - -{-@ fpLen :: p:(ForeignPtr a) -> {v:Int | v = (fplen p) } @-} -fpLen :: ForeignPtr a -> Int -fpLen = undefined - -{-@ pLen :: p:(Ptr a) -> {v:Int | v = (plen p) } @-} -pLen :: Ptr a -> Int -pLen = undefined - -{-@ deref :: p:Ptr a -> {v:a | v = (deref p)} @-} -deref :: Ptr a -> a -deref = undefined - -{-@ eqPtr :: p:PtrV a - -> q:{v:PtrV a | (((pbase v) = (pbase p)) && ((plen v) <= (plen p)))} - -> {v:Bool | (v <=> ((plen p) = (plen q)))} - @-} -eqPtr :: Ptr a -> Ptr a -> Bool -eqPtr = undefined diff --git a/include/Language/Haskell/Liquid/List.hs b/include/Language/Haskell/Liquid/List.hs deleted file mode 100644 index b111ba693e..0000000000 --- a/include/Language/Haskell/Liquid/List.hs +++ /dev/null @@ -1,7 +0,0 @@ -module Language.Haskell.Liquid.List (transpose) where - -{-@ lazy transpose @-} -transpose :: Int -> [[a]] -> [[a]] -transpose _ [] = [] -transpose n ([] : xss) = transpose n xss -transpose n ((x:xs) : xss) = (x : [h | (h:_) <- xss]) : transpose (n - 1) (xs : [ t | (_:t) <- xss]) diff --git a/include/Language/Haskell/Liquid/Prelude.hs b/include/Language/Haskell/Liquid/Prelude.hs deleted file mode 100644 index 7a4be44aaf..0000000000 --- a/include/Language/Haskell/Liquid/Prelude.hs +++ /dev/null @@ -1,142 +0,0 @@ -{-# LANGUAGE MagicHash #-} - -module Language.Haskell.Liquid.Prelude where - -------------------------------------------------------------------- ---------------------------- Arithmetic ---------------------------- -------------------------------------------------------------------- - -{-@ assume plus :: x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x + y} @-} -{-@ assume minus :: x:{v:Int | true } -> y:{v:Int | true} -> {v:Int | v = x - y} @-} -{-@ assume times :: x:Int -> y:Int -> Int @-} -{-@ assume eq :: x:Int -> y:Int -> {v:Bool | ((v) <=> x = y)} @-} -{-@ assume neq :: x:Int -> y:Int -> {v:Bool | ((v) <=> x != y)} @-} -{-@ assume leq :: x:Int -> y:Int -> {v:Bool | ((v) <=> x <= y)} @-} -{-@ assume geq :: x:Int -> y:Int -> {v:Bool | ((v) <=> x >= y)} @-} -{-@ assume lt :: x:Int -> y:Int -> {v:Bool | ((v) <=> x < y)} @-} -{-@ assume gt :: x:Int -> y:Int -> {v:Bool | ((v) <=> x > y)} @-} - -{-# NOINLINE plus #-} -plus :: Int -> Int -> Int -plus x y = x + y - -{-# NOINLINE minus #-} -minus :: Int -> Int -> Int -minus x y = x - y - -{-# NOINLINE times #-} -times :: Int -> Int -> Int -times x y = x * y - -------------------------------------------------------------------- ---------------------------- Comparisons --------------------------- -------------------------------------------------------------------- - -{-# NOINLINE eq #-} -eq :: Int -> Int -> Bool -eq x y = x == y - -{-# NOINLINE neq #-} -neq :: Int -> Int -> Bool -neq x y = not (x == y) - -{-# NOINLINE leq #-} -leq :: Int -> Int -> Bool -leq x y = x <= y - -{-# NOINLINE geq #-} -geq :: Int -> Int -> Bool -geq x y = x >= y - -{-# NOINLINE lt #-} -lt :: Int -> Int -> Bool -lt x y = x < y - -{-# NOINLINE gt #-} -gt :: Int -> Int -> Bool -gt x y = x > y - -------------------------------------------------------------------- ------------------------- Specifications --------------------------- -------------------------------------------------------------------- - - -{-@ ignore liquidAssertB @-} -{-@ assume liquidAssertB :: x:{v:Bool | v} -> {v: Bool | v} @-} -{-# NOINLINE liquidAssertB #-} -liquidAssertB :: Bool -> Bool -liquidAssertB b = b - -{-@ assume liquidAssert :: {v:Bool | v} -> a -> a @-} -{-# NOINLINE liquidAssert #-} -liquidAssert :: Bool -> a -> a -liquidAssert _ x = x - -{-@ ignore liquidAssume @-} -{-@ assume liquidAssume :: b:Bool -> a -> {v: a | b} @-} -{-# NOINLINE liquidAssume #-} -liquidAssume :: Bool -> a -> a -liquidAssume b x = if b then x else error "liquidAssume fails" - -{-@ ignore liquidAssumeB @-} -{-@ assume liquidAssumeB :: forall

Bool>. (a

-> {v:Bool| v}) -> a -> a

@-} -liquidAssumeB :: (a -> Bool) -> a -> a -liquidAssumeB p x | p x = x - | otherwise = error "liquidAssumeB fails" - - -{-@ ignore unsafeError @-} -{-# NOINLINE unsafeError #-} -unsafeError :: String -> a -unsafeError = error - - -{-@ liquidError :: {v:String | 0 = 1} -> a @-} -{-# NOINLINE liquidError #-} -liquidError :: String -> a -liquidError = error - -{-@ assume crash :: forall a . x:{v:Bool | v} -> a @-} -{-# NOINLINE crash #-} -crash :: Bool -> a -crash = undefined - -{-# NOINLINE force #-} -force :: Bool -force = True - -{-# NOINLINE choose #-} -choose :: Int -> Int -choose = undefined - -------------------------------------------------------------------- ------------ Modular Arithmetic Wrappers --------------------------- -------------------------------------------------------------------- - --- tedium because fixpoint doesn't want to deal with (x mod y) only (x mod c) -{-@ assume isEven :: x:Int -> {v:Bool | ((v) <=> ((x mod 2) = 0))} @-} -{-# NOINLINE isEven #-} -isEven :: Int -> Bool -isEven x = x `mod` 2 == 0 - -{-@ assume isOdd :: x:Int -> {v:Bool | ((v) <=> ((x mod 2) = 1))} @-} -{-# NOINLINE isOdd #-} -isOdd :: Int -> Bool -isOdd x = x `mod` 2 == 1 - ------------------------------------------------------------------------------------------------ - -{-@ safeZipWith :: (a -> b -> c) -> xs : [a] -> ys:{v:[b] | len v = len xs} - -> {v : [c] | len v = len xs } @-} -safeZipWith :: (a->b->c) -> [a]->[b]->[c] -safeZipWith f (a:as) (b:bs) = f a b : safeZipWith f as bs -safeZipWith _ [] [] = [] -safeZipWith _ _ _ = error "safeZipWith: cannot happen!" - -{-@ (==>) :: p:Bool -> q:Bool -> {v:Bool | v <=> (p => q)} @-} -infixr 8 ==> -(==>) :: Bool -> Bool -> Bool -False ==> False = True -False ==> True = True -True ==> True = True -True ==> False = False diff --git a/include/Language/Haskell/Liquid/Prelude.pred b/include/Language/Haskell/Liquid/Prelude.pred deleted file mode 100644 index a6c5c9663a..0000000000 --- a/include/Language/Haskell/Liquid/Prelude.pred +++ /dev/null @@ -1,22 +0,0 @@ -assume (>) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> Bool -assume (<) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> Bool -assume (>=) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> Bool -assume (<=) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> Bool -assume (==) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> Bool -assume (+) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> a^True -assume (*) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> a^True -assume (-) :: forall a. forAll p1:a p2:a. (Ord a^True) => a^p1 -> a^p2 -> a^True -assume ($) :: forall a b. forAll q1:a q2:b. (a^q1 -> b^q2) -> a^q1 -> b^q2 -assume (.) :: forall b c a. forAll q1:a q2:b q3:c. (b^q2 -> c^q3) -> (a^q1 -> b^q2) -> a^q1 -> c^q3 -assume filter :: forall a. forAll p1:a. (a^p1 -> Bool) -> [a^p1]-> [a^p1] -assume snd :: forall a b. forAll p1:a p2:b. (a^p1, b^p2)-> b^p2 -assume map :: forall a b. forAll q1:a q2:b. (a^q1 -> b^q2) -> [a^q1]-> [b^q2] -assume (++) :: forall a. forAll q:a. [a^q]-> [a^q]-> [a^q] -assume concat :: forall a. forAll q:a. [[a^q]]-> [a^q] -assume foldl :: forall a b. forAll q1:a q2:b. (a^q1 -> b^q2 -> a^q1) -> a^q1 -> [b^q2]-> a^q1 -assume foldr :: forall a b. forAll q1:a q2:b. (a^q1 -> b^q2 -> b^q2) -> b^q2 -> [a^q1]-> b^q2 -assume (,) :: forall a b. forAll q1:a q2:b. a^q1 -> b^q2 ->(a^q1, b^q2) -assume Prelude.error :: forall a. forAll q2:a. [Char]-> a^q2 -assume Prelude.head :: forall a. forAll q:a. [a^q]-> a^q -assume Prelude.tail :: forall a. forAll q:a. [a^q]-> [a^q] -assume Prelude.enumFromTo :: forall a. forAll q:a. (Enum a^ True) => a^q -> a^q -> [a^q] diff --git a/include/Language/Haskell/Liquid/ProofCombinators.hs b/include/Language/Haskell/Liquid/ProofCombinators.hs deleted file mode 100644 index 3360eb7ad5..0000000000 --- a/include/Language/Haskell/Liquid/ProofCombinators.hs +++ /dev/null @@ -1,183 +0,0 @@ -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE IncoherentInstances #-} - -module Language.Haskell.Liquid.ProofCombinators ( - - -- ATTENTION! `Admit` and `(==!)` are UNSAFE: they should not belong the final proof term - - -- * Proof is just a () alias - Proof - , toProof - - -- * Proof constructors - , trivial, unreachable, (***), QED(..) - - -- * Proof certificate constructors - , (?) - - -- * These two operators check all intermediate equalities - , (===) -- proof of equality is implicit eg. x === y - , (=<=) -- proof of equality is implicit eg. x <= y - , (=>=) -- proof of equality is implicit eg. x =>= y - - -- * This operator does not check intermediate equalities - , (==.) - - -- Uncheck operator used only for proof debugging - , (==!) -- x ==! y always succeeds - - -- * Combining Proofs - , (&&&) - , withProof - , impossible - - -) where - -------------------------------------------------------------------------------- --- | Proof is just a () alias ------------------------------------------------- -------------------------------------------------------------------------------- - -type Proof = () - -toProof :: a -> Proof -toProof _ = () - -------------------------------------------------------------------------------- --- | Proof Construction ------------------------------------------------------- -------------------------------------------------------------------------------- - --- | trivial is proof by SMT - -trivial :: Proof -trivial = () - --- {-@ unreachable :: {v : Proof | False } @-} -unreachable :: Proof -unreachable = () - --- All proof terms are deleted at runtime. -{- RULE "proofs are irrelevant" forall (p :: Proof). p = () #-} - --- | proof casting --- | `x *** QED`: x is a proof certificate* strong enough for SMT to prove your theorem --- | `x *** Admit`: x is an unfinished proof - -infixl 3 *** -{-@ assume (***) :: a -> p:QED -> { if (isAdmit p) then false else true } @-} -(***) :: a -> QED -> Proof -_ *** _ = () - -data QED = Admit | QED - -{-@ measure isAdmit :: QED -> Bool @-} -{-@ Admit :: {v:QED | isAdmit v } @-} - - -------------------------------------------------------------------------------- --- | * Checked Proof Certificates --------------------------------------------- -------------------------------------------------------------------------------- - --- Any (refined) carries proof certificates. --- For example 42 :: {v:Int | v == 42} is a certificate that --- the value 42 is equal to 42. --- But, this certificate will not really be used to proof any fancy theorems. - --- Below we provide a number of equational operations --- that constuct proof certificates. - --- | Implicit equality - --- x === y returns the proof certificate that --- result value is equal to both x and y --- when y == x (as assumed by the operator's precondition) - -infixl 3 === -{-@ (===) :: x:a -> y:{a | y == x} -> {v:a | v == x && v == y} @-} -(===) :: a -> a -> a -_ === y = y - -infixl 3 =<= -{-@ (=<=) :: x:a -> y:{a | x <= y} -> {v:a | v == y} @-} -(=<=) :: a -> a -> a -_ =<= y = y - -infixl 3 =>= -{-@ (=>=) :: x:a -> y:{a | x >= y} -> {v:a | v == y} @-} -(=>=) :: a -> a -> a -_ =>= y = y - -------------------------------------------------------------------------------- --- | `?` is basically Haskell's $ and is used for the right precedence --- | `?` lets you "add" some fact into a proof term -------------------------------------------------------------------------------- - -infixl 3 ? - -{-@ (?) :: forall a b Bool, pb :: b -> Bool>. a -> b -> a @-} -(?) :: a -> b -> a -x ? _ = x -{-# INLINE (?) #-} - -------------------------------------------------------------------------------- --- | Assumed equality --- `x ==! y ` --- returns the admitted proof certificate that result value is equals x and y -------------------------------------------------------------------------------- - -infixl 3 ==! -{-@ assume (==!) :: x:a -> y:a -> {v:a | v == x && v == y} @-} -(==!) :: a -> a -> a -(==!) _ y = y - - --- | To summarize: --- --- - (==!) is *only* for proof debugging --- - (===) does not require explicit proof term --- - (?) lets you insert "lemmas" as other `Proof` values - -------------------------------------------------------------------------------- --- | * Unchecked Proof Certificates ------------------------------------------- -------------------------------------------------------------------------------- - --- | The above operators check each intermediate proof step. --- The operator `==.` below accepts an optional proof term --- argument, but does not check intermediate steps. --- TODO: What is it USEFUL FOR? - -infixl 3 ==. - -{-# DEPRECATED (==.) "Use (===) instead" #-} - -{-# INLINE (==.) #-} -(==.) :: a -> a -> a -_ ==. x = x - -------------------------------------------------------------------------------- --- | * Combining Proof Certificates ------------------------------------------- -------------------------------------------------------------------------------- - -(&&&) :: Proof -> Proof -> Proof -x &&& _ = x - - -{-@ withProof :: x:a -> b -> {v:a | v = x} @-} -withProof :: a -> b -> a -withProof x _ = x - -{-@ impossible :: {v:a | false} -> b @-} -impossible :: a -> b -impossible _ = undefined - -------------------------------------------------------------------------------- --- | Convenient Syntax for Inductive Propositions -------------------------------------------------------------------------------- - -{-@ measure prop :: a -> b @-} -{-@ type Prop E = {v:_ | prop v = E} @-} - - - diff --git a/include/Language/Haskell/Liquid/RTick.hs b/include/Language/Haskell/Liquid/RTick.hs deleted file mode 100644 index 5e70ed0ec5..0000000000 --- a/include/Language/Haskell/Liquid/RTick.hs +++ /dev/null @@ -1,440 +0,0 @@ - --- --- Liquidate your assets: reasoning about resource usage in Liquid Haskell. --- Martin A.T. Handley, Niki Vazou, and Graham Hutton. --- - -{-@ LIQUID "--reflection" @-} - -module Language.Haskell.Liquid.RTick - ( - - -- Tick datatype: - Tick(..) - -- Primitive resource operators: - , fmap - , pure - , (<*>) - , liftA2 - , return - , (>>=) - , (=<<) - , eqBind - , leqBind - , geqBind - , ap - , liftM - , liftM2 - -- Resource modifiers: - , step - , wait -- step 1 . return - , waitN -- step (n > 0) . return - , go -- step (-1) . return - , goN -- step (n < 0) . return - , wmap -- step 1 . fmap f - , wmapN -- step (n > 0) . fmap f - , gmap -- step (-1) . fmap f - , gmapN -- step (n < 0) . fmap f - , () -- step 1 . (f <*>) - , () -- step 2 . (f <*>) - , (<\>) -- step (-1) . (f <*>) - , (<\\>) -- step (-2) . (f <*>) - , (>/=) -- step 1 . (>>= f) - , (=/<) -- step 1 . (>>= f) - , (>//=) -- step 2 . (>>= f) - , (=//<) -- step 2 . (>>= f) - , (>\=) -- step (-1) . (>>= f) - , (=\<) -- step (-1) . (>>= f) - , (>\\=) -- step (-2) . (>>= f) - , (=\\<) -- step (-2) . (>>= f) - -- Memoisation: - , pay - , zipWithM - - - ) where - -import Prelude hiding ( Functor(..), Applicative(..), Monad(..), (=<<) ) - -import qualified Control.Applicative as A -import qualified Control.Monad as M -import qualified Data.Functor as F - --- --- The 'Tick' datatype and its corresponding resource modifiers. --- --- See 'ResourceModifiers.hs' for proofs that all resource modifiers --- can be defined using 'return', '(>>=) 'and 'step'. --- - -------------------------------------------------------------------------------- --- | 'Tick' datatype for recording resource usage: -------------------------------------------------------------------------------- - -{-@ data Tick a = Tick { tcost :: Int, tval :: a } @-} -data Tick a = Tick { tcost :: Int, tval :: a } - -------------------------------------------------------------------------------- --- | Primitive resource operators: -------------------------------------------------------------------------------- - -instance F.Functor Tick where - fmap = fmap - -{-@ reflect fmap @-} -{-@ fmap :: f:(a -> b) -> t1:Tick a - -> { t:Tick b | Tick (tcost t1) (f (tval t1)) == t } -@-} -fmap :: (a -> b) -> Tick a -> Tick b -fmap f (Tick m x) = Tick m (f x) - -instance A.Applicative Tick where - pure = pure - (<*>) = (<*>) - -{-@ reflect pure @-} -{-@ pure :: x:a -> { t:Tick a | x == tval t && 0 == tcost t } @-} -pure :: a -> Tick a -pure x = Tick 0 x - -{-@ reflect <*> @-} -{-@ (<*>) :: t1:Tick (a -> b) -> t2:Tick a - -> { t:Tick b | (tval t1) (tval t2) == tval t && - tcost t1 + tcost t2 == tcost t } -@-} -infixl 4 <*> -(<*>) :: Tick (a -> b) -> Tick a -> Tick b -Tick m f <*> Tick n x = Tick (m + n) (f x) - -{-@ reflect liftA2 @-} -{-@ liftA2 :: f:(a -> b -> c) -> t1:Tick a -> t2:Tick b - -> { t:Tick c | f (tval t1) (tval t2) == tval t && - tcost t1 + tcost t2 == tcost t } -@-} -liftA2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c -liftA2 f (Tick m x) (Tick n y) = Tick (m + n) (f x y) - -instance M.Monad Tick where - return = return - (>>=) = (>>=) - -{-@ reflect return @-} -{-@ return :: x:a -> { t:Tick a | x == tval t && 0 == tcost t } @-} -return :: a -> Tick a -return x = Tick 0 x - -{-@ reflect >>= @-} -{-@ (>>=) :: t1:Tick a -> f:(a -> Tick b) - -> { t:Tick b | tval (f (tval t1)) == tval t && - tcost t1 + tcost (f (tval t1)) == tcost t } -@-} -infixl 4 >>= -(>>=) :: Tick a -> (a -> Tick b) -> Tick b -Tick m x >>= f = let Tick n y = f x in Tick (m + n) y - -{-@ reflect =<< @-} -{-@ (=<<) :: f:(a -> Tick b) -> t1:Tick a - -> { t:Tick b | tval (f (tval t1)) == tval t && - tcost t1 + tcost (f (tval t1)) == tcost t } -@-} -infixl 4 =<< -(=<<) :: (a -> Tick b) -> Tick a -> Tick b -f =<< Tick m x = let Tick n y = f x in Tick (m + n) y - -{-@ reflect ap @-} -{-@ ap :: t1:(Tick (a -> b)) -> t2:Tick a - -> { t:Tick b | (tval t1) (tval t2) == tval t && - tcost t1 + tcost t2 == tcost t } -@-} -ap :: Tick (a -> b) -> Tick a -> Tick b -ap (Tick m f) (Tick n x) = Tick (m + n) (f x) - -{-@ reflect liftM @-} -{-@ liftM :: f:(a -> b) -> t1:Tick a -> { t:Tick b | tcost t1 == tcost t } @-} -liftM :: (a -> b) -> Tick a -> Tick b -liftM f (Tick m x) = Tick m (f x) - -{-@ reflect liftM2 @-} -{-@ liftM2 :: f:(a -> b -> c) -> t1:Tick a -> t2:Tick b - -> { t:Tick c | f (tval t1) (tval t2) == tval t && - tcost t1 + tcost t2 == tcost t } -@-} -liftM2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c -liftM2 f (Tick m x) (Tick n y) = Tick (m + n) (f x y) - -------------------------------------------------------------------------------- - -{-@ reflect eqBind @-} -{-@ eqBind :: n:Int -> t1:Tick a - -> f:(a -> { tf:Tick b | n == tcost tf }) - -> { t:Tick b | tval (f (tval t1)) == tval t && - tcost t1 + n == tcost t } -@-} -eqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b -eqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y - -{-@ reflect leqBind @-} -{-@ leqBind :: n:Int -> t1:Tick a - -> f:(a -> { tf:Tick b | n >= tcost tf }) - -> { t:Tick b | tcost t1 + n >= tcost t } -@-} -leqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b -leqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y - -{-@ reflect geqBind @-} -{-@ geqBind :: n:Int -> t1:Tick a - -> f:(a -> { tf:Tick b | n <= tcost tf }) - -> { t2:Tick b | tcost t1 + n <= tcost t2 } -@-} -geqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b -geqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y - -------------------------------------------------------------------------------- --- | Resource modifiers: -------------------------------------------------------------------------------- - -{-@ reflect step @-} -{-@ step :: m:Int -> t1:Tick a - -> { t:Tick a | tval t1 == tval t && m + tcost t1 == tcost t } -@-} -step :: Int -> Tick a -> Tick a -step m (Tick n x) = Tick (m + n) x - --- --- @wait := step 1 . return@. --- -{-@ reflect wait @-} -{-@ wait :: x:a -> { t:Tick a | x == tval t && 1 == tcost t } @-} -wait :: a -> Tick a -wait x = Tick 1 x - --- --- @waitN (n > 0) := step n . return@. --- -{-@ reflect waitN @-} -{-@ waitN :: n:Nat -> x:a - -> { t:Tick a | x == tval t && n == tcost t } -@-} -waitN :: Int -> a -> Tick a -waitN n x = Tick n x - --- --- @go := step (-1) . return@. --- -{-@ reflect go @-} -{-@ go :: x:a -> { t:Tick a | x == tval t && (-1) == tcost t } @-} -go :: a -> Tick a -go x = Tick (-1) x - --- --- @goN (n > 0) := step (-n) . return@. --- -{-@ reflect goN @-} -{-@ goN :: { n:Nat | n > 0 } -> x:a - -> { t:Tick a | x == tval t && (-n) == tcost t } -@-} -goN :: Int -> a -> Tick a -goN n x = Tick (-n) x - --- --- @wmap f := step 1 . fmap f@. --- -{-@ reflect wmap @-} -{-@ wmap :: f:(a -> b) -> t1:Tick a - -> { t:Tick b | Tick (1 + tcost t1) (f (tval t1)) == t } -@-} -wmap :: (a -> b) -> Tick a -> Tick b -wmap f (Tick m x) = Tick (1 + m) (f x) - --- --- @wmapN (n > 0) f := step n . fmap f@. --- -{-@ reflect wmapN @-} -{-@ wmapN :: { m:Nat | m > 0 } -> f:(a -> b) -> t1:Tick a - -> { t:Tick b | Tick (m + tcost t1) (f (tval t1)) == t } -@-} -wmapN :: Int -> (a -> b) -> Tick a -> Tick b -wmapN m f (Tick n x) = Tick (m + n) (f x) - --- --- @gmap f := step (-1) . fmap f@. --- -{-@ reflect gmap @-} -{-@ gmap :: f:(a -> b) -> t1:Tick a - -> { t:Tick b | Tick (tcost t1 - 1) (f (tval t1)) == t } -@-} -gmap :: (a -> b) -> Tick a -> Tick b -gmap f (Tick m x) = Tick (m - 1) (f x) - --- --- @gmapN (n > 0) f := step (-n) . fmap f@. --- -{-@ reflect gmapN @-} -{-@ gmapN :: { m:Nat | m > 0 } -> f:(a -> b) -> t1:Tick a - -> { t:Tick b | Tick (tcost t1 - m) (f (tval t1)) == t } -@-} -gmapN :: Int -> (a -> b) -> Tick a -> Tick b -gmapN m f (Tick n x) = Tick (n - m) (f x) - --- --- \"wapp\": @(f ) := step 1 . (f <*>)@. --- -{-@ reflect @-} -{-@ () :: t1:(Tick (a -> b)) -> t2:Tick a - -> { t:Tick b | (tval t1) (tval t2) == tval t && - 1 + tcost t1 + tcost t2 == tcost t } -@-} -infixl 4 -() :: Tick (a -> b) -> Tick a -> Tick b -Tick m f Tick n x = Tick (1 + m + n) (f x) - --- --- \"wwapp\": @(f ) := step 2 . (f <*>)@. --- -{-@ reflect @-} -{-@ () :: t1:(Tick (a -> b)) -> t2:Tick a - -> { t:Tick b | (tval t1) (tval t2) == tval t && - 2 + tcost t1 + tcost t2 == tcost t } -@-} -infixl 4 -() :: Tick (a -> b) -> Tick a -> Tick b -Tick m f Tick n x = Tick (2 + m + n) (f x) - --- --- \"gapp\": @(f <\>) := step (-1) . (f <*>)@. --- -{-@ reflect <\> @-} -{-@ (<\>) :: t1:(Tick (a -> b)) -> t2:Tick a - -> { t:Tick b | (tval t1) (tval t2) == tval t && - tcost t1 + tcost t2 - 1 == tcost t } -@-} -infixl 4 <\> -(<\>) :: Tick (a -> b) -> Tick a -> Tick b -Tick m f <\> Tick n x = Tick (m + n - 1) (f x) - --- --- \"ggapp\": @(f <\\>) := step (-2) . (f <*>)@. --- -{-@ reflect <\\> @-} -{-@ (<\\>) :: t1:(Tick (a -> b)) -> t2:Tick a - -> { t:Tick b | (tval t1) (tval t2) == tval t && - tcost t1 + tcost t2 - 2 == tcost t } -@-} -infixl 4 <\\> -(<\\>) :: Tick (a -> b) -> Tick a -> Tick b -Tick m f <\\> Tick n x = Tick (m + n - 2) (f x) - --- --- \"wbind\": @(>/= f) := step 1 . (>>= f)@. --- -{-@ reflect >/= @-} -{-@ (>/=) :: t1:Tick a -> f:(a -> Tick b) - -> { t:Tick b | (tval (f (tval t1)) == tval t) && - (1 + tcost t1 + tcost (f (tval t1))) == tcost t } -@-} -infixl 4 >/= -(>/=) :: Tick a -> (a -> Tick b) -> Tick b -Tick m x >/= f = let Tick n y = f x in Tick (1 + m + n) y - --- --- \"wbind\": @(f =/<) := step 1 . (f =<<)@. --- -{-@ reflect =/< @-} -{-@ (=/<) :: f:(a -> Tick b) -> t1:Tick a - -> { t:Tick b | tval (f (tval t1)) == tval t && - 1 + tcost t1 + tcost (f (tval t1)) == tcost t } -@-} -infixl 4 =/< -(=/<) :: (a -> Tick b) -> Tick a -> Tick b -f =/< Tick m x = let Tick n y = f x in Tick (1 + m + n) y - --- --- \"wwbind\": @(>//= f) := step 2 . (>>= f)@. --- -{-@ reflect >//= @-} -{-@ (>//=) :: t1:Tick a -> f:(a -> Tick b) - -> { t:Tick b | tval (f (tval t1)) == tval t && - 2 + tcost t1 + tcost (f (tval t1)) == tcost t } -@-} -infixl 4 >//= -(>//=) :: Tick a -> (a -> Tick b) -> Tick b -Tick m x >//= f = let Tick n y = f x in Tick (2 + m + n) y - --- --- \"wwbind\": @(f =//<) := step 2 . (f =<<)@. --- -{-@ reflect =//< @-} -{-@ (=//<) :: f:(a -> Tick b) -> t1:Tick a - -> { t:Tick b | tval (f (tval t1)) == tval t && - 2 + tcost t1 + tcost (f (tval t1)) == tcost t } -@-} -infixl 4 =//< -(=//<) :: (a -> Tick b) -> Tick a -> Tick b -f =//< Tick m x = let Tick n y = f x in Tick (2 + m + n) y - --- --- \"gbind\": @(>\= f) := step (-1) . (>>= f)@. --- -{-@ reflect >\= @-} -{-@ (>\=) :: t1:Tick a -> f:(a -> Tick b) - -> { t:Tick b | tval (f (tval t1)) == tval t && - tcost t1 + tcost (f (tval t1)) - 1 == tcost t } -@-} -infixl 4 >\= -(>\=) :: Tick a -> (a -> Tick b) -> Tick b -Tick m x >\= f = let Tick n y = f x in Tick (m + n - 1) y - --- --- \"gbind\": @(f =\<) := step (-1) . (f =<<)@. --- -{-@ reflect =\< @-} -{-@ (=\<) :: f:(a -> Tick b) -> t1:Tick a - -> { t:Tick b | tval (f (tval t1)) == tval t && - tcost t1 + tcost (f (tval t1)) - 1 == tcost t } -@-} -infixl 4 =\< -(=\<) :: (a -> Tick b) -> Tick a -> Tick b -f =\< Tick m x = let Tick n y = f x in Tick (m + n - 1) y - --- --- \"ggbind\": @(>\= f) := step (-2) . (>>= f)@. --- -{-@ reflect >\\= @-} -{-@ (>\\=) :: t1:Tick a -> f:(a -> Tick b) - -> { t:Tick b | tval (f (tval t1)) == tval t && - tcost t1 + tcost (f (tval t1)) - 2 == tcost t } -@-} -infixl 4 >\\= -(>\\=) :: Tick a -> (a -> Tick b) -> Tick b -Tick m x >\\= f = let Tick n y = f x in Tick (m + n - 2) y - --- --- \"ggbind\": @(f =\\<) := step (-2) . (f =<<)@. --- -{-@ reflect =\\< @-} -{-@ (=\\<) :: f:(a -> Tick b) -> t1:Tick a - -> { t:Tick b | tval (f (tval t1)) == tval t && - tcost t1 + tcost (f (tval t1)) - 2 == tcost t } -@-} -infixl 4 =\\< -(=\\<) :: (a -> Tick b) -> Tick a -> Tick b -f =\\< Tick m x = let Tick n y = f x in Tick (m + n - 2) y - -------------------------------------------------------------------------------- --- | Memoisation: -------------------------------------------------------------------------------- - -{-@ reflect pay @-} -{-@ pay :: m:Int - -> { t1:Tick a | m <= tcost t1 } - -> { t:Tick ({ t2 : Tick a | tcost t1 - m == tcost t2 }) | m == tcost t } -@-} -pay :: Int -> Tick a -> Tick (Tick a) -pay m (Tick n x) = Tick m (Tick (n - m) x) - - -{-@ reflect zipWithM @-} -{-@ zipWithM :: f:(a -> b -> Tick c) -> x:Tick a -> y:Tick b --> {t:Tick c | tcost t == tcost x + tcost y + tcost (f (tval x) (tval y))} @-} -zipWithM :: (a -> b -> Tick c) -> Tick a -> Tick b -> Tick c -zipWithM f (Tick c1 x1) (Tick c2 x2) = let Tick c x = f x1 x2 in Tick (c + c1 + c2) x diff --git a/include/Language/Haskell/Liquid/RTick/Combinators.hs b/include/Language/Haskell/Liquid/RTick/Combinators.hs deleted file mode 100644 index 00da9a0c4c..0000000000 --- a/include/Language/Haskell/Liquid/RTick/Combinators.hs +++ /dev/null @@ -1,366 +0,0 @@ - --- --- Liquidate your assets: reasoning about resource usage in Liquid Haskell. --- - -{-@ LIQUID "--reflection" @-} - -module Language.Haskell.Liquid.RTick.Combinators - ( - - -- Basic: - Proof -- Simply the unit type. - , QED(..) -- 'ASS': Signify the end of an /unfinished/ proof. - -- 'QED': Signify the end of a /complete/ proof. - , (&&&) -- Combine proofs. - , (***) -- Discard final result at the end of a proof. - , (?) -- Appeal to an external theorem. - , isAss -- Check whether a proof is complete. - , toProof -- Cast to proof. - , trivial -- Trivial proof. - , withTheorem -- Appeal to an external theorem. - -- Equational: - , (==.) -- Equality. - , (==?) -- Equality (assumption). - , eq -- Equality. Note: 'eq' is inlined in the logic. - -- Inequational: - , (<.) -- Less than. - , (.) -- Greater than. - , (>?) -- Greater than (assumption). - , (>=.) -- Greater than or equal. - , (>=?) -- Greater than or equal (assumption). - , (<=>.) -- Cost equivalence. - , (<=>?) -- Cost equivalence (assumption) - , (>~>.) -- Improvement. - , (>~>?) -- Improvement (assumption). - , (.>==) -- Quantified improvement. - , (?>==) -- Quantified improvement (assumption). - , (<~<.) -- Diminishment. - , (<~.) -- Quantified improvement. - , (==>?) -- Quantified improvement (assumption). - , (==<.) -- Quantified diminishment. - , (== {b} @-} -assert :: Bool -> Proof -assert _ = () - --- unchecked -(==!) :: a -> a -> a -_ ==! x = x - - -type Proof = () -data QED = QED | ASS - -{-@ toProof :: a -> Proof @-} -toProof :: a -> Proof -toProof _ = () -{-# INLINE toProof #-} - -{-@ trivial :: Proof @-} -trivial :: Proof -trivial = () -{-# INLINE trivial #-} - -{-@ measure isAss @-} -isAss :: QED -> Bool -isAss ASS = True -isAss QED = False - -{-@ assume (***) :: a -> qed:QED -> { if (isAss qed) then false else true } @-} -infixl 1 *** -(***) :: a -> QED -> Proof -_ *** _ = () -{-# INLINE (***) #-} - -{-@ (?) :: x:a -> Proof -> { v:a | x == v } @-} -infixl 3 ? -(?) :: a -> Proof -> a -x ? _ = x -{-# INLINE (?) #-} - -{-@ (&&&) :: Proof -> Proof -> Proof @-} -infixl 3 &&& -(&&&) :: Proof -> Proof -> Proof -x &&& _ = x -{-# INLINE (&&&) #-} - -{-@ withTheorem :: x:a -> Proof -> { v:a | x == v } @-} -withTheorem :: a -> Proof -> a -withTheorem x _ = x -{-# INLINE withTheorem #-} - -------------------------------------------------------------------------------- --- | Equational: -------------------------------------------------------------------------------- - --- --- Equality. --- -{-@ (==.) :: x:a -> { y:a | x == y } -> { v:a | x == v && y == v } @-} -infixl 3 ==. -(==.) :: a -> a -> a -_ ==. x = x -{-# INLINE (==.) #-} - -{-@ assume (==?) :: x:a -> y:a -> { v:a | x == v && y == v } @-} -infixl 3 ==? -(==?) :: a -> a -> a -_ ==? x = x -{-# INLINE (==?) #-} - --- --- Equality. Note: 'eq' is inlined in the logic, so can be used in --- reflected functions. --- -{-@ eq :: x:a -> { y:a | x == y } -> { v:a | x == v && y == v } @-} -eq :: a -> a -> a -_ `eq` x = x -{-# INLINE eq #-} - -------------------------------------------------------------------------------- --- | Inequational: -------------------------------------------------------------------------------- - --- --- Less than. --- -{-@ (<.) :: m:a -> { n:a | m < n } -> { o:a | o == n } @-} -infixl 3 <. -(<.) :: a -> a -> a -_ <. n = n -{-# INLINE (<.) #-} - -{-@ assume ( n:a -> { o:a | o == n && m < n } @-} -infixl 3 a -> a -_ { n:a | m <= n } -> { o:a | o == n } @-} -infixl 3 <=. -(<=.) :: a -> a -> a -_ <=. n = n -{-# INLINE (<=.) #-} - -{-@ assume (<=?) :: m:a -> n:a -> { o:a | o == n && m <= n } @-} -infixl 3 <=? -(<=?) :: a -> a -> a -_ <=? n = n -{-# INLINE (<=?) #-} - --- --- Greater than. --- -{-@ (>.) :: m:a -> { n:a | m > n } -> { o:a | o == n } @-} -infixl 3 >. -(>.) :: a -> a -> a -_ >. y = y -{-# INLINE (>.) #-} - -{-@ assume (>?) :: m:a -> n:a -> { o:a | o == n && m > n } @-} -infixl 3 >? -(>?) :: a -> a -> a -_ >? y = y -{-# INLINE (>?) #-} - --- --- Greater than or equal. --- -{-@ (>=.) :: m:a -> { n:a | m >= n } -> { o:a | o == n } @-} -infixl 3 >=. -(>=.) :: a -> a -> a -_ >=. n = n -{-# INLINE (>=.) #-} - -{-@ assume (>=?) :: m:a -> n:a -> { o:a | o == n && m >= n } @-} -infixl 3 >=? -(>=?) :: a -> a -> a -_ >=? n = n -{-# INLINE (>=?) #-} - --- --- Cost equivalence. --- -{-@ predicate COSTEQ T1 T2 = tval T1 == tval T2 && tcost T1 == tcost T2 @-} - -{-@ (<=>.) - :: t1:Tick a - -> { t2:Tick a | COSTEQ t1 t2 } - -> { t3:Tick a | COSTEQ t1 t2 && COSTEQ t1 t3 && COSTEQ t2 t3 } -@-} -infixl 3 <=>. -(<=>.) :: Tick a -> Tick a -> Tick a -(<=>.) _ t2 = t2 -{-# INLINE (<=>.) #-} - -{-@ assume (<=>?) - :: t1:Tick a -> t2:Tick a - -> { t3:Tick a | COSTEQ t1 t2 && COSTEQ t1 t3 && t2 == t3 } -@-} -infixl 3 <=>? -(<=>?) :: Tick a -> Tick a -> Tick a -(<=>?) _ t2 = t2 -{-# INLINE (<=>?) #-} - --- --- Improvement. --- -{-@ predicate IMP T1 T2 = tval T1 == tval T2 && tcost T1 >= tcost T2 @-} - -{-@ (>~>.) - :: t1:Tick a - -> { t2:Tick a | IMP t1 t2 } - -> { t3:Tick a | IMP t1 t2 && IMP t1 t3 && t2 == t3 } -@-} -infixl 3 >~>. -(>~>.) :: Tick a -> Tick a -> Tick a -(>~>.) _ t2 = t2 -{-# INLINE (>~>.) #-} - -{-@ assume (>~>?) - :: t1:Tick a -> t2:Tick a - -> { t3:Tick a | IMP t1 t2 && IMP t1 t3 && t2 == t3 } -@-} -infixl 3 >~>? -(>~>?) :: Tick a -> Tick a -> Tick a -(>~>?) _ t2 = t2 -{-# INLINE (>~>?) #-} - --- --- Quantified improvement. --- -{-@ predicate QIMP T1 N T2 = tval T1 == tval T2 && tcost T1 == tcost T2 + N @-} - -{-@ (.>==) - :: t1:Tick a - -> n:Int - -> { t2:Tick a | QIMP t1 n t2 } - -> { t3:Tick a | QIMP t1 n t2 && QIMP t1 n t3 && t2 == t3 } -@-} -infixl 3 .>== -(.>==) :: Tick a -> Int -> Tick a -> Tick a -(.>==) _ _ t2 = t2 -{-# INLINE (.>==) #-} - -{-@ assume (?>==) - :: t1:Tick a -> n:Nat -> t2:Tick a - -> { t3:Tick a | QIMP t1 n t2 && QIMP t1 n t3 && t2 == t3 } -@-} -infixl 3 ?>== -(?>==) :: Tick a -> Int -> Tick a -> Tick a -(?>==) _ _ t2 = t2 -{-# INLINE (?>==) #-} - --- --- Diminishment. --- -{-@ predicate DIM T1 T2 = tval T1 == tval T2 && tcost T1 <= tcost T2 @-} - -{-@ (<~<.) - :: t1:Tick a - -> { t2:Tick a | DIM t1 t2 } - -> { t3:Tick a | DIM t1 t2 && DIM t1 t3 && t2 == t3 } -@-} -infixl 3 <~<. -(<~<.) :: Tick a -> Tick a -> Tick a -(<~<.) _ t2 = t2 -{-# INLINE (<~<.) #-} - -{-@ assume (<~ t2:Tick a - -> { t3:Tick a | DIM t1 t2 && DIM t1 t3 && t2 == t3 } -@-} -infixl 3 <~ Tick a -> Tick a -(<~ n:Nat - -> { t2:Tick a | QDIM t1 n t2 } - -> { t3:Tick a | QDIM t1 n t2 && QDIM t1 n t3 && t2 == t3 } -@-} -infixl 3 .<== -(.<==) :: Tick a -> Int -> Tick a -> Tick a -(.<==) _ _ t2 = t2 -{-# INLINE (.<==) #-} - -{-@ assume (?<==) - :: t1:Tick a -> n:Nat -> t2:Tick a - -> { t3:Tick a | QDIM t1 n t2 && QDIM t1 n t3 && t2 == t3 } -@-} -infixl 3 ?<== -(?<==) :: Tick a -> Int -> Tick a -> Tick a -(?<==) _ _ t2 = t2 -{-# INLINE (?<==) #-} - -------------------------------------------------------------------------------- --- | Cost separators: -------------------------------------------------------------------------------- - --- --- Quantified improvement. --- -{-@ (==>.) :: (a -> b) -> a -> b @-} -infixl 3 ==>. -(==>.) :: (a -> b) -> a -> b -f ==>. a = f a -{-# INLINE (==>.) #-} - --- --- Quantified improvement (assumption). --- -{-@ (==>?) :: (a -> b) -> a -> b @-} -infixl 3 ==>? -(==>?) :: (a -> b) -> a -> b -f ==>? a = f a -{-# INLINE (==>?) #-} - --- --- Quantified diminishment. --- -{-@ (==<.) :: (a -> b) -> a -> b @-} -infixl 3 ==<. -(==<.) :: (a -> b) -> a -> b -f ==<. a = f a -{-# INLINE (==<.) #-} - --- --- Quantified diminishment (assumption). --- -{-@ (== b) -> a -> b @-} -infixl 3 == b) -> a -> b -f == Int @-} -{-@ measure subString :: SMTString -> Int -> Int -> SMTString @-} -{-@ measure concatString :: SMTString -> SMTString -> SMTString @-} -{-@ measure fromString :: String -> SMTString @-} -{-@ measure takeString :: Int -> SMTString -> SMTString @-} -{-@ measure dropString :: Int -> SMTString -> SMTString @-} - ----------------------------------- - -{-@ assume concatString :: x:SMTString -> y:SMTString - -> {v:SMTString | v == concatString x y && stringLen v == stringLen x + stringLen y } @-} -concatString :: SMTString -> SMTString -> SMTString -concatString (S s1) (S s2) = S (s1 `BS.append` s2) - -{-@ assume stringEmp :: {v:SMTString | v == stringEmp && stringLen v == 0 } @-} -stringEmp :: SMTString -stringEmp = S (BS.empty) - -stringLen :: SMTString -> Int -{-@ assume stringLen :: x:SMTString -> {v:Nat | v == stringLen x} @-} -stringLen (S s) = BS.length s - - -{-@ assume subString :: s:SMTString -> offset:Int -> ln:Int -> {v:SMTString | v == subString s offset ln } @-} -subString :: SMTString -> Int -> Int -> SMTString -subString (S s) o l = S (BS.take l $ BS.drop o s) - - -{-@ assume takeString :: i:Nat -> xs:{SMTString | i <= stringLen xs } -> {v:SMTString | stringLen v == i && v == takeString i xs } @-} -takeString :: Int -> SMTString -> SMTString -takeString i (S s) = S (BS.take i s) - -{-@ assume dropString :: i:Nat -> xs:{SMTString | i <= stringLen xs } -> {v:SMTString | stringLen v == stringLen xs - i && v == dropString i xs } @-} -dropString :: Int -> SMTString -> SMTString -dropString i (S s) = S (BS.drop i s) - - -{-@ assume fromString :: i:String -> {o:SMTString | i == o && o == fromString i} @-} -fromString :: String -> SMTString -fromString = S . ST.fromString - - -{-@ assume isNullString :: i:SMTString -> {b:Bool | b <=> stringLen i == 0 } @-} -isNullString :: SMTString -> Bool -isNullString (S s) = BS.length s == 0 diff --git a/include/Language/Haskell/Liquid/Synthesize/Error.hs b/include/Language/Haskell/Liquid/Synthesize/Error.hs deleted file mode 100644 index 41af9bf08d..0000000000 --- a/include/Language/Haskell/Liquid/Synthesize/Error.hs +++ /dev/null @@ -1,5 +0,0 @@ -module Language.Haskell.Liquid.Synthesize.Error where - -{-@ err :: { v: Int | false } -> a @-} -err :: Int -> a -err s = undefined \ No newline at end of file diff --git a/include/NotReal.spec b/include/NotReal.spec deleted file mode 100644 index fd347cb3d3..0000000000 --- a/include/NotReal.spec +++ /dev/null @@ -1,11 +0,0 @@ -module spec Prelude where - -import GHC.Num -assume GHC.Num.* :: (GHC.Num.Num a) => x:a -> y:a - -> {v:a | ((((((x = 0) || (y = 0)) => (v = 0))) - && (((x > 0) && (y > 0)) => ((v >= x) && (v >= y)))) - && (((x > 1) && (y > 1)) => ((v > x) && (v > y)))) - } - - -GHC.Real./ :: (GHC.Real.Fractional a) => x:a -> y:{v:a | v != 0.0} -> a diff --git a/include/PatErr.spec b/include/PatErr.spec deleted file mode 100644 index 14d4f69b25..0000000000 --- a/include/PatErr.spec +++ /dev/null @@ -1,15 +0,0 @@ -module spec Prelude where - - -measure totalityError :: a -> Bool - - -assume Control.Exception.Base.patError :: {v:GHC.Prim.Addr# | totalityError "Pattern match(es) are non-exhaustive"} -> a - -assume Control.Exception.Base.recSelError :: {v:GHC.Prim.Addr# | totalityError "Use of partial record field selector"} -> a - -assume Control.Exception.Base.nonExhaustiveGuardsError :: {v:GHC.Prim.Addr# | totalityError "Guards are non-exhaustive"} -> a - -assume Control.Exception.Base.noMethodBindingError :: {v:GHC.Prim.Addr# | totalityError "Missing method(s) on instance declaration"} -> a - -assume Control.Exception.Base.recConError :: {v:GHC.Prim.Addr# | totalityError "Missing field in record construction"} -> a \ No newline at end of file diff --git a/include/Prelude.hquals b/include/Prelude.hquals deleted file mode 100644 index 66d1337c30..0000000000 --- a/include/Prelude.hquals +++ /dev/null @@ -1,44 +0,0 @@ -//BOT: Do not delete EVER! - -qualif Bot(v:@(0)) : (0 = 1) -qualif Bot(v:obj) : (0 = 1) -qualif Bot(v:a) : (0 = 1) -qualif Bot(v:bool) : (0 = 1) -qualif Bot(v:int) : (0 = 1) - -qualif CmpZ(v:a) : (v < 0) -qualif CmpZ(v:a) : (v <= 0) -qualif CmpZ(v:a) : (v > 0) -qualif CmpZ(v:a) : (v >= 0) -qualif CmpZ(v:a) : (v = 0) -qualif CmpZ(v:a) : (v != 0) - -qualif Cmp(v:a, x:a) : (v < x) -qualif Cmp(v:a, x:a) : (v <= x) -qualif Cmp(v:a, x:a) : (v > x) -qualif Cmp(v:a, x:a) : (v >= x) -qualif Cmp(v:a, x:a) : (v = x) -qualif Cmp(v:a, x:a) : (v != x) - -// qualif CmpZ(v:a) : v [ < ; <= ; > ; >= ; = ; != ] 0 -// qualif Cmp(v:a,x:a) : v [ < ; <= ; > ; >= ; = ; != ] x -// qualif Cmp(v:int,x:int) : v [ < ; <= ; > ; >= ; = ; != ] x - - -qualif One(v:int) : v = 1 -qualif True1(v:GHC.Types.Bool) : (v) -qualif False1(v:GHC.Types.Bool) : (~ v) - -constant papp1 : func(1, [Pred @(0); @(0); bool]) -qualif Papp(v:a,p:Pred a) : (papp1(p, v)) - -constant papp2 : func(4, [Pred @(0) @(1); @(2); @(3); bool]) -qualif Papp2(v:a,x:b,p:Pred a b) : (papp2(p, v, x)) - -qualif Papp3(v:a,x:b, y:c, p:Pred a b c) : (papp3(p, v, x, y)) -constant papp3 : func(6, [Pred @(0) @(1) @(2); @(3); @(4); @(5); bool]) - -// qualif Papp4(v:a,x:b, y:c, z:d, p:Pred a b c d) : papp4(p, v, x, y, z) -constant papp4 : func(8, [Pred @(0) @(1) @(2) @(6); @(3); @(4); @(5); @(7); bool]) - -constant runFun : func(2, [Arrow @(0) @(1); @(0); @(1)]) diff --git a/include/Prelude.spec b/include/Prelude.spec deleted file mode 100644 index bffeaa9f5f..0000000000 --- a/include/Prelude.spec +++ /dev/null @@ -1,88 +0,0 @@ -module spec Prelude where - -import GHC.Base -import GHC.Int -import GHC.List -import GHC.Num -import GHC.Real -import GHC.Word - -import Data.Foldable -import Data.Maybe -import Data.Tuple -import GHC.Exts -import GHC.Err - - -// GHC.Types.D# :: x:_ -> {v:_ | v = x} - -GHC.Err.error :: {v:_ | false} -> a - -assume GHC.Base.. :: forall

c -> Bool, q :: a -> b -> Bool, r :: a -> c -> Bool>. - {xcmp::a, wcmp::b |- c

<: c} - (ycmp:b -> c

) - -> (zcmp:a -> b) - -> xcmp:a -> c -assume GHC.Integer.smallInteger :: x:GHC.Prim.Int# -> { v:GHC.Integer.Type | v = (x :: int) } - -assume GHC.Num.+ :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x + y } -assume GHC.Num.- :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x - y } - -embed GHC.Types.Double as real -embed GHC.Types.Float as real -embed Integer as int - -type GeInt N = {v: GHC.Types.Int | v >= N } -type LeInt N = {v: GHC.Types.Int | v <= N } -type Nat = {v: GHC.Types.Int | v >= 0 } -type Even = {v: GHC.Types.Int | (v mod 2) = 0 } -type Odd = {v: GHC.Types.Int | (v mod 2) = 1 } -type BNat N = {v: Nat | v <= N } -type TT = {v: GHC.Types.Bool | v} -type FF = {v: GHC.Types.Bool | not v} -type String = [GHC.Types.Char] - -predicate Max V X Y = if X > Y then V = X else V = Y -predicate Min V X Y = if X < Y then V = X else V = Y - -type IncrListD a = [a]<{\x y -> (x+D) <= y}> - -// BOT: Do not delete EVER! - -qualif Bot(v:@(0)) : (0 = 1) -qualif Bot(v:obj) : (0 = 1) -qualif Bot(v:a) : (0 = 1) -qualif Bot(v:bool) : (0 = 1) -qualif Bot(v:int) : (0 = 1) - -qualif CmpZ(v:a) : (v < 0) -qualif CmpZ(v:a) : (v <= 0) -qualif CmpZ(v:a) : (v > 0) -qualif CmpZ(v:a) : (v >= 0) -qualif CmpZ(v:a) : (v = 0) -qualif CmpZ(v:a) : (v != 0) - -qualif Cmp(v:a, x:a) : (v < x) -qualif Cmp(v:a, x:a) : (v <= x) -qualif Cmp(v:a, x:a) : (v > x) -qualif Cmp(v:a, x:a) : (v >= x) -qualif Cmp(v:a, x:a) : (v = x) -qualif Cmp(v:a, x:a) : (v != x) - -qualif One(v:int) : v = 1 -qualif True1(v:GHC.Types.Bool) : (v) -qualif False1(v:GHC.Types.Bool) : (~ v) - -// REBARE constant papp1 : func(1, [Pred @(0); @(0); bool]) -qualif Papp(v:a, p:Pred a) : (papp1 p v) - -// REBARE constant papp2 : func(4, [Pred @(0) @(1); @(2); @(3); bool]) -qualif Papp2(v:a, x:b, p:Pred a b) : (papp2 p v x) - -// REBARE constant papp3 : func(6, [Pred @(0) @(1) @(2); @(3); @(4); @(5); bool]) -qualif Papp3(v:a, x:b, y:c, p:Pred a b c) : (papp3 p v x y) - -// qualif Papp4(v:a,x:b, y:c, z:d, p:Pred a b c d) : papp4(p, v, x, y, z) -// REBARE constant papp4 : func(8, [Pred @(0) @(1) @(2) @(6); @(3); @(4); @(5); @(7); bool]) - -// REBARE constant runFun : func(2, [Arrow @(0) @(1); @(0); @(1)]) diff --git a/include/Real.spec b/include/Real.spec deleted file mode 100644 index 978c83533d..0000000000 --- a/include/Real.spec +++ /dev/null @@ -1,9 +0,0 @@ -module spec Prelude where - -import GHC.Num - -assume GHC.Num.* :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x * y} - - - -// GHC.Real./ :: forall a. (GHC.Real.Fractional a) => x:a -> y:{v:a | v != 0.0} -> {v: a | v = (x / y) } diff --git a/include/System/IO.spec b/include/System/IO.spec deleted file mode 100644 index d044ab3c62..0000000000 --- a/include/System/IO.spec +++ /dev/null @@ -1,3 +0,0 @@ -module spec System.IO where - -import GHC.IO.Handle diff --git a/include/len.hquals b/include/len.hquals deleted file mode 100644 index dd7ecc6724..0000000000 --- a/include/len.hquals +++ /dev/null @@ -1,7 +0,0 @@ - -// Qualifiers about complex length relationships -// qualif LenSum(v:[a], ~A:[b], ~B:[c]): len([v]) = (len([~A]) [ +; - ] len([~B])) - -qualif LenSum(v:[a], xs:[b], ys:[c]): len([v]) = (len([xs]) + len([ys])) -qualif LenSum(v:[a], xs:[b], ys:[c]): len([v]) = (len([xs]) - len([ys])) - diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 96363a745f..cd26b7b0bb 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -14,48 +14,8 @@ build-type: Simple tested-with: GHC == 9.2.5 extra-source-files: CHANGES.md README.md - devel/Paths_liquidhaskell.hs - tests/pos/*.hs - tests/neg/*.hs - tests/import/lib/*.hs - tests/import/client/*.hs - tests/errors/*.hs - tests/pos/*.hquals - tests/ffi-include/foo.c - tests/ffi-include/foo.h - --- The legacy executable requires a set of hardcoded specifications --- provided by the files in the 'include' directory. This --- directory is now deprecated and you should never edit it, unless you --- are specifically fixing a bug in the legacy executable. --- Remove these lines below once we stop supporting the legacy plugin. -data-files: include/*.hquals - include/*.hs - include/*.spec - include/CoreToLogic.lg - include/Control/*.spec - include/Control/Parallel/*.spec - include/Data/*.hquals - include/Data/*.spec - include/Data/Text/*.spec - include/Data/Text/Fusion/*.spec - include/Data/Text/Lazy/*.spec - include/Data/ByteString/*.spec - include/Foreign/*.spec - include/Foreign/C/*.spec - include/Foreign/Marshal/*.spec - include/GHC/*.hquals - include/GHC/*.spec - include/GHC/IO/*.spec - include/Language/Haskell/Liquid/*.hs - include/Language/Haskell/Liquid/Synthesize/*.hs - include/Language/Haskell/Liquid/*.pred - include/System/*.spec - include/710/Data/*.spec - include/*.hs - include/Language/Haskell/Liquid/*.hs - include/Language/Haskell/Liquid/*.pred +data-files: include/CoreToLogic.lg syntax/liquid.css -- Needed for the mirror-modules helper @@ -80,11 +40,6 @@ flag deterministic-profiling description: Support building against GHC with backported -flag no-plugin - default: False - manual: True - description: Use the legacy executable for testing. - flag mirror-modules-helper default: False manual: True @@ -247,20 +202,6 @@ library if flag(deterministic-profiling) cpp-options: -DDETERMINISTIC_PROFILING - if flag(no-plugin) - cpp-options: -DLIQUID_NO_PLUGIN - --- This is the (legacy) 'liquid' executable which uses the old GHC Interface. -executable liquid - main-is: exe/Liquid.hs - build-depends: base >= 4.9.1.0 && < 5, liquidhaskell - default-language: Haskell98 - default-extensions: PatternGuards - ghc-options: -W -threaded - - if flag(devel) - ghc-options: -Wall -Wno-name-shadowing -Werror - test-suite liquidhaskell-parser type: exitcode-stdio-1.0 main-is: Parser.hs diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index 003b6f6124..c6c9175ff1 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -3,11 +3,8 @@ {-@ LIQUID "--diff" @-} module Language.Haskell.Liquid.Liquid ( - -- * Executable command - liquid - -- * Single query - , runLiquid + runLiquid -- * Ghci State , MbEnv @@ -51,16 +48,6 @@ import Liquid.GHC.API as GHC hiding (text, vcat, ($+$), getOpts, (<+>) type MbEnv = Maybe HscEnv - --------------------------------------------------------------------------------- -liquid :: [String] -> IO b --------------------------------------------------------------------------------- -liquid args = do - cfg <- getOpts args - printLiquidHaskellBanner - (ec, _) <- runLiquid Nothing cfg - exitWith ec - -------------------------------------------------------------------------------- liquidConstraints :: Config -> IO (Either [CGInfo] ExitCode) -------------------------------------------------------------------------------- From e4a3331f7c7fc7303e14cf879a40be44cefab3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 13:06:41 -0300 Subject: [PATCH 111/219] Remove the include flag --- .circleci/config.yml | 4 ++-- devel/Paths_liquidhaskell.hs | 18 ------------------ liquidhaskell.cabal | 7 ------- 3 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 devel/Paths_liquidhaskell.hs diff --git a/.circleci/config.yml b/.circleci/config.yml index 8ced71f19e..2540d972b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,7 +68,7 @@ commands: echo 'export PATH=~/.ghcup/bin:$PATH' >> $BASH_ENV << parameters.cabal_update_command >> cabal v2-clean - cabal v2-build --project-file << parameters.project_file >> --flag include --flag devel -j --enable-tests liquidhaskell-parser synthesis liquid-base liquid-prelude liquid-bytestring liquid-containers liquid-ghc-prim liquid-parallel liquid-vector liquid-platform test-driver + cabal v2-build --project-file << parameters.project_file >> --flag devel -j --enable-tests liquidhaskell-parser synthesis liquid-base liquid-prelude liquid-bytestring liquid-containers liquid-ghc-prim liquid-parallel liquid-vector liquid-platform test-driver - save_cache: key: cabal-cache-v3-{{ checksum "liquidhaskell.cabal" }}-{{ checksum "<< parameters.project_file >>" }}-{{ checksum "liquid-fixpoint-commit" }} paths: @@ -85,7 +85,7 @@ commands: command: | LIQUID_CABAL_PROJECT_FILE=<> cabal v2-run --project-file << parameters.project_file >> test-driver || (<>) cabal v2-test --project-file << parameters.project_file >> tests:tasty || (<>) - (liquidhaskell_datadir=$PWD cabal v2-test -j1 --project-file << parameters.project_file >> liquidhaskell:liquidhaskell-parser --flag include --flag devel --test-show-details=streaming --test-options="--xml=/tmp/junit/cabal/parser-test-results.xml") || (<>) + (liquidhaskell_datadir=$PWD cabal v2-test -j1 --project-file << parameters.project_file >> liquidhaskell:liquidhaskell-parser --flag devel --test-show-details=streaming --test-options="--xml=/tmp/junit/cabal/parser-test-results.xml") || (<>) no_output_timeout: 30m stack_build_and_test: diff --git a/devel/Paths_liquidhaskell.hs b/devel/Paths_liquidhaskell.hs deleted file mode 100644 index d00d95ffbd..0000000000 --- a/devel/Paths_liquidhaskell.hs +++ /dev/null @@ -1,18 +0,0 @@ -{-# LANGUAGE TemplateHaskell #-} - -module Paths_liquidhaskell where - -import Language.Haskell.TH -import System.Directory -import System.FilePath -import Data.Version (Version, makeVersion) - -getDataFileName :: FilePath -> IO FilePath -getDataFileName fp = do - let loc' = $(do { loc <- location; f <- runIO (canonicalizePath (loc_filename loc)); litE (stringL f); }) - let root = takeDirectory (takeDirectory loc') - return (root fp) - --- | dummy version (devel only) -version :: Version -version = makeVersion [0,0,0,0] diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index cd26b7b0bb..2287803d0a 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -31,10 +31,6 @@ flag devel description: Enable more warnings and fail compilation when warnings occur. Turn this flag on in CI. -flag include - default: False - description: use in-tree include directory - flag deterministic-profiling default: False description: Support building against GHC with @@ -196,9 +192,6 @@ library if flag(devel) ghc-options: -Wall -Werror - if flag(include) - hs-source-dirs: devel - if flag(deterministic-profiling) cpp-options: -DDETERMINISTIC_PROFILING From fedd1718845e7f4ed30db7a3c45f45de35820857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sun, 5 Feb 2023 21:55:37 -0300 Subject: [PATCH 112/219] Add a driver for profiling the lh plugin --- .circleci/config.yml | 5 +++++ README.md | 28 +------------------------- scripts/ProfilingDriver.hs | 41 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 27 deletions(-) create mode 100644 scripts/ProfilingDriver.hs diff --git a/.circleci/config.yml b/.circleci/config.yml index 2540d972b1..81bc77429e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -88,6 +88,11 @@ commands: (liquidhaskell_datadir=$PWD cabal v2-test -j1 --project-file << parameters.project_file >> liquidhaskell:liquidhaskell-parser --flag devel --test-show-details=streaming --test-options="--xml=/tmp/junit/cabal/parser-test-results.xml") || (<>) no_output_timeout: 30m + - run: + name: Test building the profiling driver + command: | + cabal exec -- ghc scripts/ProfilingDriver.hs + stack_build_and_test: description: "Build and test the project using Stack" parameters: diff --git a/README.md b/README.md index ebc9a2854e..4bd530c9a4 100644 --- a/README.md +++ b/README.md @@ -194,33 +194,7 @@ the benchmarks alone. ## How to Profile -1. Build with profiling on - - ``` - $ stack build liquidhaskell --fast --profile - ``` - -2. Run with profiling - - ``` - $ stack exec -- liquid range.hs +RTS -hc -p - $ stack exec -- liquid range.hs +RTS -hy -p - ``` - - Followed by this which shows the stats file - - ``` - $ more liquid.prof - ``` - - or by this to see the graph - - ``` - $ hp2ps -e8in -c liquid.hp - $ gv liquid.ps - ``` - - etc. +See the instructions in [scripts/ProfilingDriver.hs][] ## How to Get Stack Traces On Exceptions diff --git a/scripts/ProfilingDriver.hs b/scripts/ProfilingDriver.hs new file mode 100644 index 0000000000..a92e642eba --- /dev/null +++ b/scripts/ProfilingDriver.hs @@ -0,0 +1,41 @@ +-- | This programs calls ghc using the provided command line arguments +-- +-- Use it to profile the liquidhaskell plugin. +-- +-- Build liquid-platform first with profiling enabled. +-- +-- > cabal build --enable-profiling liquid-platform +-- +-- Then build this program. +-- +-- > cabal exec --enable-profiling -- ghc -prof scripts/ProfilingDriver.hs +-- +-- Then run the liquidhaskell executable pointing it to this driver with +-- the LIQUID_GHC_PATH env var. +-- +-- > LIQUID_GHC_PATH=scripts/ProfilingDriver liquidhaskell_datadir=$PWD \ +-- > cabal exec -- liquidhaskell +RTS -p -RTS tests/pos/Bag.hs +-- +module Main where + +import GHC as G +import GHC.Driver.Session as G + +import Control.Monad +import Control.Monad.IO.Class +import System.Environment +import GHC.Paths (libdir) +import GHC.Utils.Logger as G + +main :: IO () +main = do + xs <- getArgs + runGhc (Just libdir) $ do + df1 <- getSessionDynFlags + let cmdOpts = ["-fforce-recomp"] ++ filter ("--make" /=) xs + logger <- liftIO G.initLogger + (df2, leftovers, warns) <- G.parseDynamicFlags logger df1 (map G.noLoc cmdOpts) + setSessionDynFlags df2 + ts <- mapM (flip G.guessTarget Nothing) $ map unLoc leftovers + setTargets ts + void $ G.load LoadAllTargets From 6060bac307e6b618f067fd3035757563e4b55dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 18:02:57 -0300 Subject: [PATCH 113/219] Remove getIncludeDir --- scripts/CountBinders.hs | 93 ------------------- src-ghc/Liquid/GHC/Interface.hs | 8 +- src/Language/Haskell/Liquid/Bare/Resolve.hs | 3 +- src/Language/Haskell/Liquid/GHC/Plugin.hs | 3 +- src/Language/Haskell/Liquid/Misc.hs | 13 +-- .../Haskell/Liquid/Synthesize/Monad.hs | 3 +- src/Language/Haskell/Liquid/Types/Specs.hs | 12 +-- src/Language/Haskell/Liquid/UX/CmdLine.hs | 4 - 8 files changed, 10 insertions(+), 129 deletions(-) delete mode 100755 scripts/CountBinders.hs diff --git a/scripts/CountBinders.hs b/scripts/CountBinders.hs deleted file mode 100755 index 3bc7292e12..0000000000 --- a/scripts/CountBinders.hs +++ /dev/null @@ -1,93 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TypeSynonymInstances #-} -module Main where - - -import Control.Applicative -import Data.Function -import Data.Generics -import Data.List -import System.Environment -import Text.Printf - -import CoreMonad -import CoreSyn -import DynFlags -import GHC -import GHC.Paths -import HscTypes -import qualified Outputable as Out -import Type -import Var - -import Language.Haskell.Liquid.GhcMisc -import Language.Haskell.Liquid.Misc - -getCoreBinds :: FilePath -> IO [CoreBind] -getCoreBinds target = runGhc (Just libdir) $ do - addTarget =<< guessTarget target Nothing - flags <- getSessionDynFlags - inc <- liftIO getIncludeDir - setSessionDynFlags $ updateDynFlags flags [inc] - load LoadAllTargets - modGraph <- getModuleGraph - case find ((== target) . msHsFilePath) modGraph of - Just modSummary -> do - mod_guts <- coreModule <$> (desugarModule =<< typecheckModule =<< parseModule modSummary) - return $! mg_binds mod_guts - Nothing -> error "Ghc Interface: Unable to get GhcModGuts" - - -updateDynFlags :: DynFlags -> [FilePath] -> DynFlags -updateDynFlags df ps - = df { importPaths = ps ++ importPaths df - , libraryPaths = ps ++ libraryPaths df - , profAuto = ProfAutoCalls - , ghcLink = NoLink - , hscTarget = HscInterpreted - , ghcMode = CompManager - } `xopt_set` Opt_MagicHash - `dopt_set` Opt_ImplicitImportQualified - - -allBinders :: [CoreBind] -> [CoreBind] -allBinders cbs = cbs ++ map bind (concatMap (listify isBinder) cbs) - where - bind (Let x _) = x - isBinder (Let _ _) = True - isBinder _ = False - - -recsAndFuns :: [CoreBind] -> ([Var],[Var],[Var]) -recsAndFuns binds = (recs,recfuns,funs) - where - recs = [v | Rec bs <- binds, (v,_) <- bs] - recfuns = filter isFun recs - -- GHC does transforms recursive functions (at least with tyvars) - -- into a let binding that quantifies over the tyvar followed by a - -- letrec that defines the function, e.g. - -- let foo = \ @a -> { letrec foo = ... in foo } - -- but we don't want to count foo as rec and nonrec - funs = nubBy ((==) `on` getOccName) - $ [v | NonRec v _ <- binds, isFun v] - ++ recfuns - isFun = isFunTy . snd . splitForAllTys . varType - - -main :: IO () -main = do - target <- head <$> getArgs - binds <- allBinders <$> getCoreBinds target - - let (recs,recfuns,funs) = recsAndFuns binds - - printf "funs: %d\n" (length funs) - printf "recs: %d\n" (length recs) - printf "recsFuns: %d\n" (length recfuns) - - -instance Show CoreBind where - show = showPpr - -instance Show (Expr CoreBndr) where - show = showPpr diff --git a/src-ghc/Liquid/GHC/Interface.hs b/src-ghc/Liquid/GHC/Interface.hs index 25ec16efb3..3ec177d3c5 100644 --- a/src-ghc/Liquid/GHC/Interface.hs +++ b/src-ghc/Liquid/GHC/Interface.hs @@ -138,9 +138,7 @@ realTargets :: Maybe HscEnv -> Config -> [FilePath] -> IO [FilePath] realTargets mbEnv cfg tgtFs | noCheckImports cfg = return tgtFs | otherwise = do - incDir <- Misc.getIncludeDir - allFs <- orderTargets mbEnv cfg tgtFs - let srcFs = filter (not . Misc.isIncludeFile incDir) allFs + srcFs <- orderTargets mbEnv cfg tgtFs realFs <- filterM check srcFs dir <- getCurrentDirectory return (makeRelative dir <$> realFs) @@ -586,7 +584,6 @@ makeGhcSrc cfg file typechecked modSum = do availableTcs <- availableTyCons hscEnv modSum (fst $ tm_internals_ typechecked) (mg_exports modGuts') let impVars = importVars coreBinds ++ classCons (mgi_cls_inst modGuts) - incDir <- liftIO Misc.getIncludeDir --liftIO $ do -- print $ "_gsTcs => " ++ show (nub $ (mgi_tcs modGuts) ++ availableTcs) @@ -596,8 +593,7 @@ makeGhcSrc cfg file typechecked modSum = do -- print $ "defVars => " ++ show (dataCons ++ (letVars coreBinds)) return $ Src - { _giIncDir = incDir - , _giTarget = file + { _giTarget = file , _giTargetMod = ModName Target (moduleName (ms_mod modSum)) , _giCbs = coreBinds , _giImpVars = impVars diff --git a/src/Language/Haskell/Liquid/Bare/Resolve.hs b/src/Language/Haskell/Liquid/Bare/Resolve.hs index f06368613d..7b932f2858 100644 --- a/src/Language/Haskell/Liquid/Bare/Resolve.hs +++ b/src/Language/Haskell/Liquid/Bare/Resolve.hs @@ -664,10 +664,9 @@ allowExtResolution :: Env -> LocSymbol -> Bool allowExtResolution env lx = case fileMb of Nothing -> True Just f -> myTracepp ("allowExt: " ++ show (f, tgtFile)) - $ f == tgtFile || Misc.isIncludeFile incDir f || F.isExtFile F.Spec f + $ f == tgtFile || F.isExtFile F.Spec f where tgtFile = _giTarget (reSrc env) - incDir = _giIncDir (reSrc env) fileMb = Errors.srcSpanFileMb (GM.fSrcSpan lx) lookupThings :: Env -> F.Symbol -> [(F.Symbol, Ghc.TyThing)] diff --git a/src/Language/Haskell/Liquid/GHC/Plugin.hs b/src/Language/Haskell/Liquid/GHC/Plugin.hs index a1078d424d..8c486c9cef 100644 --- a/src/Language/Haskell/Liquid/GHC/Plugin.hs +++ b/src/Language/Haskell/Liquid/GHC/Plugin.hs @@ -620,8 +620,7 @@ makeTargetSrc cfg file tcData modGuts hscEnv = do debugLog $ "qualImports => " ++ show (tcQualifiedImports tcData) return $ TargetSrc - { giIncDir = mempty - , giTarget = file + { giTarget = file , giTargetMod = ModName Target (moduleName (mg_module modGuts)) , giCbs = coreBinds , giImpVars = impVars diff --git a/src/Language/Haskell/Liquid/Misc.hs b/src/Language/Haskell/Liquid/Misc.hs index c31c8d3442..81bddb27e9 100644 --- a/src/Language/Haskell/Liquid/Misc.hs +++ b/src/Language/Haskell/Liquid/Misc.hs @@ -159,16 +159,6 @@ unzip4 = go [] [] [] [] go a1 a2 a3 a4 [] = (reverse a1, reverse a2, reverse a3, reverse a4) -isIncludeFile :: FilePath -> FilePath -> Bool -isIncludeFile incDir src = -- do - -- incDir <- getIncludeDir - -- return - incDir `L.isPrefixOf` src - -getIncludeDir :: IO FilePath -getIncludeDir = dropFileName <$> getDataFileName ("include" "Prelude.spec") -{-# DEPRECATED getIncludeDir "getIncludeDir is deprecated. The hardcoded include folder will be removed in the future." #-} - getCssPath :: IO FilePath getCssPath = getDataFileName $ "syntax" "liquid.css" @@ -184,8 +174,7 @@ getCoreToLogicPath = do if exists then return atExe else - fmap ( fileName) getIncludeDir - + getDataFileName ("include" fileName) {-@ type ListN a N = {v:[a] | len v = N} @-} {-@ type ListL a L = ListN a (len L) @-} diff --git a/src/Language/Haskell/Liquid/Synthesize/Monad.hs b/src/Language/Haskell/Liquid/Synthesize/Monad.hs index dedd46d0dd..8dcee2d2c7 100644 --- a/src/Language/Haskell/Liquid/Synthesize/Monad.hs +++ b/src/Language/Haskell/Liquid/Synthesize/Monad.hs @@ -403,8 +403,7 @@ varError = do toGhcSrc :: TargetSrc -> GhcSrc toGhcSrc a = Src - { _giIncDir = giIncDir a - , _giTarget = giTarget a + { _giTarget = giTarget a , _giTargetMod = giTargetMod a , _giCbs = giCbs a , _gsTcs = gsTcs a diff --git a/src/Language/Haskell/Liquid/Types/Specs.hs b/src/Language/Haskell/Liquid/Types/Specs.hs index 9ca12b19af..8c7f0ae698 100644 --- a/src/Language/Haskell/Liquid/Types/Specs.hs +++ b/src/Language/Haskell/Liquid/Types/Specs.hs @@ -155,8 +155,7 @@ instance HasConfig TargetInfo where -- information (for example, 'giDefVars' are populated with datacons from the module plus the -- let vars derived from the A-normalisation). data TargetSrc = TargetSrc - { giIncDir :: !FilePath -- ^ Path for LH include/prelude directory - , giTarget :: !FilePath -- ^ Source file for module + { giTarget :: !FilePath -- ^ Source file for module , giTargetMod :: !ModName -- ^ Name for module , giCbs :: ![CoreBind] -- ^ Source Code , gsTcs :: ![TyCon] -- ^ All used Type constructors @@ -694,8 +693,7 @@ data GhcInfo = GI -} data GhcSrc = Src - { _giIncDir :: !FilePath -- ^ Path for LH include/prelude directory - , _giTarget :: !FilePath -- ^ Source file for module + { _giTarget :: !FilePath -- ^ Source file for module , _giTargetMod :: !ModName -- ^ Name for module , _giCbs :: ![CoreBind] -- ^ Source Code , _gsTcs :: ![TyCon] -- ^ All used Type constructors @@ -741,8 +739,7 @@ targetSrcIso :: Iso' GhcSrc TargetSrc targetSrcIso = iso toTargetSrc fromTargetSrc where toTargetSrc a = TargetSrc - { giIncDir = _giIncDir a - , giTarget = _giTarget a + { giTarget = _giTarget a , giTargetMod = _giTargetMod a , giCbs = _giCbs a , gsTcs = _gsTcs a @@ -761,8 +758,7 @@ targetSrcIso = iso toTargetSrc fromTargetSrc } fromTargetSrc a = Src - { _giIncDir = giIncDir a - , _giTarget = giTarget a + { _giTarget = giTarget a , _giTargetMod = giTargetMod a , _giCbs = giCbs a , _gsTcs = gsTcs a diff --git a/src/Language/Haskell/Liquid/UX/CmdLine.hs b/src/Language/Haskell/Liquid/UX/CmdLine.hs index 8cacbc58ab..54e7215bca 100644 --- a/src/Language/Haskell/Liquid/UX/CmdLine.hs +++ b/src/Language/Haskell/Liquid/UX/CmdLine.hs @@ -79,7 +79,6 @@ import Language.Haskell.Liquid.UX.Annotate import Language.Haskell.Liquid.UX.Config import Language.Haskell.Liquid.UX.SimpleVersion (simpleVersion) import Liquid.GHC.Misc -import Language.Haskell.Liquid.Misc import Language.Haskell.Liquid.Types.PrettyPrint () import Language.Haskell.Liquid.Types hiding (typ) import qualified Language.Haskell.Liquid.UX.ACSS as ACSS @@ -619,11 +618,8 @@ gitMsg gi = concat mkOpts :: Config -> IO Config mkOpts cfg = do let files' = sortNub $ files cfg - id0 <- getIncludeDir return $ cfg { files = files' -- See NOTE [searchpath] - , idirs = [id0 gHC_VERSION, id0] - ++ idirs cfg } -------------------------------------------------------------------------------- From 4242c8a4baee76654e941a29b6cbf712f7f7bb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sun, 5 Feb 2023 23:09:23 -0300 Subject: [PATCH 114/219] Remove allowExtResolution which always returns True in the plugin --- src/Language/Haskell/Liquid/Bare/Resolve.hs | 30 ++++----------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/Language/Haskell/Liquid/Bare/Resolve.hs b/src/Language/Haskell/Liquid/Bare/Resolve.hs index 7b932f2858..03d4c5d853 100644 --- a/src/Language/Haskell/Liquid/Bare/Resolve.hs +++ b/src/Language/Haskell/Liquid/Bare/Resolve.hs @@ -61,7 +61,6 @@ import qualified Data.HashMap.Strict as M import qualified Data.Text as T import qualified Text.PrettyPrint.HughesPJ as PJ -import qualified Language.Fixpoint.Utils.Files as F import qualified Language.Fixpoint.Types as F import qualified Language.Fixpoint.Types.Visitor as F import qualified Language.Fixpoint.Misc as Misc @@ -69,7 +68,6 @@ import qualified Liquid.GHC.API as Ghc import qualified Liquid.GHC.Misc as GM import qualified Language.Haskell.Liquid.Misc as Misc import qualified Language.Haskell.Liquid.Types.RefType as RT -import qualified Language.Haskell.Liquid.Types.Errors as Errors import Language.Haskell.Liquid.Types.Types import Language.Haskell.Liquid.Measure (BareSpec) import Language.Haskell.Liquid.Types.Specs hiding (BareSpec) @@ -648,26 +646,8 @@ lookupTyThing env mdname lsym = [ (k, t) | (k, ts) <- ordMatches, t <- ts] msg = "lookupTyThing: " ++ F.showpp (lsym, x, mds) (x, mds) = symbolModules env (F.val lsym) nameSym = F.symbol mdname - allowExt = allowExtResolution env lsym - mm name m mods = myTracepp ("matchMod: " ++ F.showpp (lsym, name, m, mods, allowExt)) $ - matchMod env name m allowExt mods - --- | [NOTE:External-Resolution] @allowExtResolution@ determines whether a @LocSymbol@ --- can be resolved by a @TyThing@ that is _outside_ the module corresponding to @LocSymbol@. --- We need to allow this, e.g. to resolve names like @Data.Set.Set@ with @Data.Set.Internal.Set@, --- but should do so ONLY when the LocSymbol comes from a "hand-written" .spec file or --- something from the LH prelude. Other names, e.g. from "machine-generated" .bspec files --- should already be FULLY-qualified to to their actual definition (e.g. Data.Set.Internal.Set) --- and so we should DISALLOW external-resolution in such cases. - -allowExtResolution :: Env -> LocSymbol -> Bool -allowExtResolution env lx = case fileMb of - Nothing -> True - Just f -> myTracepp ("allowExt: " ++ show (f, tgtFile)) - $ f == tgtFile || F.isExtFile F.Spec f - where - tgtFile = _giTarget (reSrc env) - fileMb = Errors.srcSpanFileMb (GM.fSrcSpan lx) + mm name m mods = myTracepp ("matchMod: " ++ F.showpp (lsym, name, m, mods)) $ + matchMod env name m mods lookupThings :: Env -> F.Symbol -> [(F.Symbol, Ghc.TyThing)] lookupThings env x = myTracepp ("lookupThings: " ++ F.showpp x) @@ -675,8 +655,8 @@ lookupThings env x = myTracepp ("lookupThings: " ++ F.showpp x) where get z = M.lookup z (_reTyThings env) -matchMod :: Env -> F.Symbol -> F.Symbol -> Bool -> Maybe [F.Symbol] -> [Int] -matchMod env tgtName defName allowExt = go +matchMod :: Env -> F.Symbol -> F.Symbol -> Maybe [F.Symbol] -> [Int] +matchMod env tgtName defName = go where go Nothing -- Score UNQUALIFIED names | defName == tgtName = [0] -- prioritize names defined in *this* module @@ -687,7 +667,7 @@ matchMod env tgtName defName allowExt = go | isEmptySymbol defName && ms == [tgtName] = [0] -- local variable, see tests-names-pos-local00.hs | ms == [defName] = [1] - | allowExt && isExt = [matchImp env defName 2] -- to allow matching re-exported names e.g. Data.Set.union for Data.Set.Internal.union + | isExt = [matchImp env defName 2] -- to allow matching re-exported names e.g. Data.Set.union for Data.Set.Internal.union | otherwise = [] where isExt = any (`isParentModuleOf` defName) ms From 43ba8a844f2fa8ff6ce676933c2c749dece07643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sun, 5 Feb 2023 23:44:52 -0300 Subject: [PATCH 115/219] Documentation typos --- scripts/ProfilingDriver.hs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/ProfilingDriver.hs b/scripts/ProfilingDriver.hs index a92e642eba..557d95a96d 100644 --- a/scripts/ProfilingDriver.hs +++ b/scripts/ProfilingDriver.hs @@ -1,5 +1,4 @@ --- | This programs calls ghc using the provided command line arguments --- +-- | This program calls ghc using the provided command line arguments. -- Use it to profile the liquidhaskell plugin. -- -- Build liquid-platform first with profiling enabled. From 8010d279dd0faa19ad1813f8aeb6a082c731644e Mon Sep 17 00:00:00 2001 From: Gabriel Hondet <7418676+gabrielhdt@users.noreply.github.com> Date: Mon, 6 Feb 2023 08:55:11 +0100 Subject: [PATCH 116/219] Removed solved issues from TODO.EASY.md --- TODO.EASY.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/TODO.EASY.md b/TODO.EASY.md index b3f5c6516c..3051e92b83 100644 --- a/TODO.EASY.md +++ b/TODO.EASY.md @@ -1,22 +1,15 @@ -- Verification of Libraries +- Verification of Libraries - [zlib](https://hackage.haskell.org/package/zlib) - [probability](https://github.com/nikivazou/probability) - + - fix parser error message - - Parse Errors [#241](https://github.com/ucsd-progsys/liquidhaskell/issues/241) - - Liquid Haskell doesn't accept Haskell names containing ' (single-quote) [#273](https://github.com/ucsd-progsys/liquidhaskell/issues/273) - - Error messages [#400](https://github.com/ucsd-progsys/liquidhaskell/issues/400) - Add list of reserved tokens -- Parse Propositional Variables in Refinements [#338](https://github.com/ucsd-progsys/liquidhaskell/issues/338) - -- Combine GHC and Liquid Type Aliases [#381](https://github.com/ucsd-progsys/liquidhaskell/issues/381) - - Applying data type with wrong number of abstract refinement params could give better errors [#297](https://github.com/ucsd-progsys/liquidhaskell/issues/297) - Export qualifiers from measure types [#302](https://github.com/ucsd-progsys/liquidhaskell/issues/302) -- systematically remove all error calls +- systematically remove all error calls NV: Not sure how easy this is, as it requires deep understanding of the code to distinguish dead code from our errors. From 858f90f20b6a80798b2bae6f658501c4cffb6434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 19:19:18 -0300 Subject: [PATCH 117/219] Rename test_plugin script --- README.md | 22 +++++++++---------- scripts/test/test_901_plugin.sh | 5 ----- .../{test_810_plugin.sh => test_plugin.sh} | 0 3 files changed, 10 insertions(+), 17 deletions(-) delete mode 100755 scripts/test/test_901_plugin.sh rename scripts/test/{test_810_plugin.sh => test_plugin.sh} (100%) diff --git a/README.md b/README.md index 4bd530c9a4..8d4df5dbbf 100644 --- a/README.md +++ b/README.md @@ -107,28 +107,26 @@ For documentation on the `test-driver` executable itself, please refer to the `README.md` in `tests/` or run `cabal run tests:test-driver -- --help` or `stack run test-driver -- --help` -_For a way of running the test suite for multiple GHC versions, consult the General Development FAQs. below_ - There are particular scripts for running LH in the different modes, e.g. for different compiler versions. These scripts are in: $ ./scripts/test -So you can run *all* the tests for say the ghc-8.10 version by +So you can run *all* the tests by - $ ./scripts/test/test_810_plugin.sh + $ ./scripts/test/test_plugin.sh You can run a bunch of particular test-groups instead by - $ LIQUID_DEV_MODE=true ./scripts/test/test_810_plugin.sh ... + $ LIQUID_DEV_MODE=true ./scripts/test/test_plugin.sh ... and you can list all the possible test options with - $ LIQUID_DEV_MODE=true ./scripts/test/test_810_plugin.sh --help + $ LIQUID_DEV_MODE=true ./scripts/test/test_plugin.sh --help or get a list of just the test groups, one per line, with - $ LIQUID_DEV_MODE=true ./scripts/test/test_810_plugin.sh --show-all + $ LIQUID_DEV_MODE=true ./scripts/test/test_plugin.sh --show-all To pass in specific parameters and run a subset of the tests, you can invoke cabal directly with @@ -154,7 +152,7 @@ For details on adding tests, see note [Parallel_Tests] in `tests/test.hs`. When `liquidhaskell` tests run, we can collect timing information with - $ ./scripts/test/test_810_plugin.sh --measure-timings + $ ./scripts/test/test_plugin.sh --measure-timings Measures will be collected in `.dump-timings` files. These can be converted to json data with @@ -183,7 +181,7 @@ current directory. The current formatting is optimized for comparing the outputs of running the benchmarks alone. - $ scripts/test/test_810_plugin.sh \ + $ scripts/test/test_plugin.sh \ benchmark-stitch-lh \ benchmark-bytestring \ benchmark-vector-algorithms \ @@ -418,18 +416,18 @@ action by looking at the pattern synonym for [FunTy][]. Yes. The easiest way is to run one of the scripts inside the `scripts/test` directory. We provide scripts to run the testsuite for a variety of GHC versions, mostly using `stack` but also with `cabal` (e.g. -`test_810_plugin.sh`). If run without arguments, the script will run the _full_ testsuite. If an argument +`test_plugin.sh`). If run without arguments, the script will run the _full_ testsuite. If an argument is given, only a particular pattern/test will be run. Running ``` -./scripts/test/test_810_plugin.sh BST +./scripts/test/test_plugin.sh BST ``` will run all the tests which name matches "BST". In case the "fast recompilation" is desired, it's totally possibly to pass `LIQUID_DEV_MODE` to the script, for example: ``` -LIQUID_DEV_MODE=true ./scripts/test/test_810_plugin.sh +LIQUID_DEV_MODE=true ./scripts/test/test_plugin.sh ``` [GHC.API]: https://github.com/ucsd-progsys/liquidhaskell/blob/develop/src/Language/Haskell/Liquid/GHC/API.hs diff --git a/scripts/test/test_901_plugin.sh b/scripts/test/test_901_plugin.sh deleted file mode 100755 index 8dd029ccb8..0000000000 --- a/scripts/test/test_901_plugin.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -TEST_GROUPS="$@" - -LIQUID_CABAL_PROJECT_FILE=cabal.ghc9.project liquidhaskell_datadir=$PWD cabal v2-run --project-file cabal.ghc9.project tests:test-driver -- "$TEST_GROUPS" diff --git a/scripts/test/test_810_plugin.sh b/scripts/test/test_plugin.sh similarity index 100% rename from scripts/test/test_810_plugin.sh rename to scripts/test/test_plugin.sh From 4424052700c3cf30a9cdb5342b6fccfa706ca400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 19:26:27 -0300 Subject: [PATCH 118/219] Replace sections for stack traces and submodules with pointers to official documentation. --- README.md | 73 +++++-------------------------------------------------- 1 file changed, 6 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 8d4df5dbbf..880e529ba6 100644 --- a/README.md +++ b/README.md @@ -190,75 +190,14 @@ the benchmarks alone. benchmark-icfp15-pos \ benchmark-icfp15-neg -## How to Profile +## Miscelaneous tasks -See the instructions in [scripts/ProfilingDriver.hs][] +* **Profiling** See the instructions in [scripts/ProfilingDriver.hs][]. +* **Getting stack traces on exceptions** See `-xc` flag in the [GHC user's guide][ghc-users-guide]. +* **Working with submodules** See `man gitsubmodules` or the [git documentation site][git-documentation]. -## How to Get Stack Traces On Exceptions - -1. Build with profiling on - - ``` - $ stack build liquidhaskell --fast --profile - ``` - -2. Run with backtraces - - ``` - $ liquid +RTS -xc -RTS foo.hs - ``` - - ``` - stack exec -- liquid List00.hs +RTS -p -xc -RTS - ``` - -## Working With Submodules - -To update the `liquid-fixpoint` submodule, run: - -``` -cd ./liquid-fixpoint -git fetch --all -git checkout / -cd .. -``` - -This will update `liquid-fixpoint` to the latest version on `` (usually `master`) -from `` (usually `origin`). After updating `liquid-fixpoint`, make sure to include this change in a -commit! Running: - -``` -git add ./liquid-fixpoint -``` - -will save the current commit hash of `liquid-fixpoint` in your next commit to the `liquidhaskell` repository. -For the best experience, **don't** make changes directly to the `./liquid-fixpoint` submodule, or else git -may get confused. Do any `liquid-fixpoint` development inside a separate clone/copy elsewhere. If something -goes wrong, run: - -``` -rm -r ./liquid-fixpoint -git submodule update --init -``` - -to blow away your copy of the `liquid-fixpoint` submodule and revert to the last saved commit hash. - -Want to work fully offline? `git` lets you add a local directory as a remote. Run: - -``` -cd ./liquid-fixpoint -git remote add local /path/to/your/fixpoint/clone -cd .. -``` - -Then to update the submodule from your local clone, you can run: - -``` -cd ./liquid-fixpoint -git fetch local -git checkout local/ -cd .. -``` +[ghc-users-guide]: https://downloads.haskell.org/ghc/latest/docs/users_guide/ +[git-documentation]: https://git-scm.com/doc ## Releasing on Hackage From bbb2dd171de1063ca6db0ffce4ae54c62c48c5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sat, 4 Feb 2023 19:32:17 -0300 Subject: [PATCH 119/219] Point to the main README in scripts/plot-performance/README.md --- scripts/plot-performance/README.md | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/scripts/plot-performance/README.md b/scripts/plot-performance/README.md index 5356ae8743..b2967190c9 100644 --- a/scripts/plot-performance/README.md +++ b/scripts/plot-performance/README.md @@ -5,27 +5,4 @@ produced by LH's testuite. It will produce something like this: ![perf-min](https://user-images.githubusercontent.com/442035/78143687-e3f4a480-742e-11ea-9a47-6b1800914a15.png) -### Usage - -In order to measure, say, regression between two LH branches, it's first necessary to acquire two `.csv` -files to compare. For example, suppose you want to measure the performance changes between `develop` and -a `new-feature` branch. The easiest way is to do something like this: - -``` -git checkout develop -stack build -stack test -j1 liquidhaskell:test --flag liquidhaskell:include --flag liquidhaskell:devel --test-arguments="-p Micro" -git checkout new-feature -stack build -stack test -j1 liquidhaskell:test --flag liquidhaskell:include --flag liquidhaskell:devel --test-arguments="-p Micro" -``` - -After doing so, inside `tests/logs` you will find a bunch of folders named after your hostname, with some -timestamps. At that point you can simply do: - -``` -./chart_perf.sh ../path/to/develop.csv ../path/to/new_feature.csv -``` - -The order is _chronological_, i.e. the first csv should be the "before" and the second the "after". After -you do that, you should hopefully have a `perf.png` image on your filesystem to inspect. +See the main [README](../../README.md#how-to-create-performance-comparison-charts) for usage information. From 851cd8bfa939574c93659ea3d632188362d5af25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Mon, 6 Feb 2023 21:50:21 -0300 Subject: [PATCH 120/219] Update papers talks and other articles --- docs/mkDocs/docs/papers.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/mkDocs/docs/papers.md b/docs/mkDocs/docs/papers.md index 437fc846d5..9877e85652 100644 --- a/docs/mkDocs/docs/papers.md +++ b/docs/mkDocs/docs/papers.md @@ -12,11 +12,14 @@ you could curl up with: ### Haskell +- [REST: Integrating Term Rewriting with Program Verification, ECOOP 2022](https://drops.dagstuhl.de/opus/volltexte/2022/16210/) +- [Refinement Reflection: Complete Verification with SMT, POPL 2018](https://ranjitjhala.github.io/static/refinement_reflection.pdf) +- [Local Refinement Typing, ICFP 2017](https://ranjitjhala.github.io/static/local_refinement_typing.pdf) +- [Bounded Refinement Types, ICFP 2015](http://goto.ucsd.edu/~nvazou/icfp15/main.pdf) - [Refinement Types For Haskell, ICFP 2014](http://goto.ucsd.edu/~rjhala/papers/refinement_types_for_haskell.pdf) - [LiquidHaskell in the Real World, Haskell 2014](http://goto.ucsd.edu/~rjhala/papers/real_world_liquid.pdf) - [Abstract Refinement Types, ESOP 2013](http://goto.ucsd.edu/~rjhala/papers/abstract_refinement_types.pdf) - ### ML - [Liquid Types, PLDI 2008](http://goto.ucsd.edu/~rjhala/liquid/liquid_types.pdf) @@ -33,11 +36,21 @@ you could curl up with: ## Talks +- [Resource Analysis with Refinement Types, YOW! Lambda Jam 2021](https://skillsmatter.com/skillscasts/16729-resource-analysis-with-refinement-types) +- [Liquid Haskell: Theorem Proving for All, Haskell Exchange 2018](https://skillsmatter.com/skillscasts/11068-keynote-looking-forward-to-niki-vazou-s-keynote-at-haskellx-2018) +- [Scrap your Bounds Checks with Liquid Haskell, Haskell Exchange 2017](https://skillsmatter.com/skillscasts/10690-keynote-scrap-your-bounds-checks-with-liquid-haskell) [(slides)](https://github.com/Gabriella439/slides/blob/main/liquidhaskell/slides.md) + The following talks are good tutorial introductions to the techniques. - [Tutorial at VMCAI](http://goto.ucsd.edu/~rjhala/talks/liquid_types_VMCAI.pptx) - [Tutorial at CAV](http://goto.ucsd.edu/~rjhala/talks/liquid_types_CAV2011.pptx) +## Other articles + +- [A Dialog with Liquid Haskell, Tweag blog 2022](https://www.tweag.io/blog/2022-07-21-lh-introspection/) +- [Why Liquid Haskell Matters, Tweag blog 2022](https://www.tweag.io/blog/2022-01-19-why-liquid-haskell/) +- [Compile-time memory safety using Liquid Haskell, Haskell for all blog 2015](https://www.haskellforall.com/2015/12/compile-time-memory-safety-using-liquid.html) + ## People Liquid Types have been developed in the UCSD Programming Systems group by From 4b1afd6bf3d1bf0d1b2847c581c0482757e080df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Sun, 5 Feb 2023 10:01:51 -0300 Subject: [PATCH 121/219] Remove Synthesize modules --- .circleci/config.yml | 2 +- docs/mkDocs/docs/specifications.md | 51 --- liquid-prelude/liquid-prelude.cabal | 1 - .../Haskell/Liquid/Synthesize/Error.hs | 5 - liquidhaskell.cabal | 30 -- src-ghc/Liquid/GHC/Play.hs | 3 - .../Haskell/Liquid/Constraint/Generate.hs | 8 - .../Haskell/Liquid/Constraint/Init.hs | 1 - .../Haskell/Liquid/Constraint/Monad.hs | 18 +- .../Haskell/Liquid/Constraint/Types.hs | 1 - src/Language/Haskell/Liquid/Liquid.hs | 6 +- src/Language/Haskell/Liquid/Synthesize.hs | 179 -------- .../Haskell/Liquid/Synthesize/Check.hs | 98 ---- src/Language/Haskell/Liquid/Synthesize/Env.hs | 47 -- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 414 ----------------- .../Haskell/Liquid/Synthesize/Generate.hs | 252 ----------- .../Haskell/Liquid/Synthesize/Misc.hs | 94 ---- .../Haskell/Liquid/Synthesize/Monad.hs | 422 ------------------ .../Haskell/Liquid/Synthesize/Termination.hs | 24 - src/Language/Haskell/Liquid/UX/CmdLine.hs | 18 - src/Language/Haskell/Liquid/UX/Config.hs | 4 - tests/Synthesis.hs | 153 ------- tests/synthesis/TODO/ListConcat.hs | 30 -- tests/synthesis/TODO/ListToBST.hs | 44 -- tests/synthesis/TODO/TreeToList.hs | 42 -- tests/synthesis/TODO/User.hs | 48 -- tests/synthesis/logs/.gitkeep | 0 tests/synthesis/static/Append.hs | 12 - tests/synthesis/static/BSTFlatten.hs | 74 --- tests/synthesis/static/BSTSort.hs | 82 ---- tests/synthesis/static/BinHeapSingleton.hs | 24 - tests/synthesis/static/Data.hs | 17 - tests/synthesis/static/Data2.hs | 23 - tests/synthesis/static/Data3.hs | 27 -- tests/synthesis/static/IntSimple.hs | 27 -- tests/synthesis/static/ListId.hs | 7 - tests/synthesis/static/ListInsertSort.hs | 36 -- tests/synthesis/static/ListNull.hs | 20 - tests/synthesis/static/ListZip.hs | 15 - tests/synthesis/static/ListZipWith.hs | 19 - tests/synthesis/static/NestedListSimple.hs | 9 - tests/synthesis/static/Stutter.hs | 11 - tests/synthesis/static/TreeOne.hs | 21 - tests/synthesis/static/TupleListSimple.hs | 9 - tests/synthesis/static/map.hs | 12 - tests/synthesis/static/single-elem-list.hs | 8 - tests/synthesis/tests/Append.hs | 9 - tests/synthesis/tests/BSTFlatten.hs | 71 --- tests/synthesis/tests/BSTSort.hs | 83 ---- tests/synthesis/tests/BinHeapSingleton.hs | 25 -- tests/synthesis/tests/Data.hs | 17 - tests/synthesis/tests/Data2.hs | 23 - tests/synthesis/tests/Data3.hs | 27 -- tests/synthesis/tests/IntSimple.hs | 27 -- tests/synthesis/tests/ListId.hs | 7 - tests/synthesis/tests/ListInsertSort.hs | 38 -- tests/synthesis/tests/ListNull.hs | 19 - tests/synthesis/tests/ListZip.hs | 18 - tests/synthesis/tests/ListZipWith.hs | 20 - tests/synthesis/tests/NestedListSimple.hs | 9 - tests/synthesis/tests/Stutter.hs | 11 - tests/synthesis/tests/TreeOne.hs | 21 - tests/synthesis/tests/TupleListSimple.hs | 9 - tests/synthesis/tests/map.hs | 11 - tests/synthesis/tests/single-elem-list.hs | 8 - 65 files changed, 3 insertions(+), 2898 deletions(-) delete mode 100644 liquid-prelude/src/Language/Haskell/Liquid/Synthesize/Error.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize/Check.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize/Env.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize/GHC.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize/Generate.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize/Misc.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize/Monad.hs delete mode 100644 src/Language/Haskell/Liquid/Synthesize/Termination.hs delete mode 100644 tests/Synthesis.hs delete mode 100644 tests/synthesis/TODO/ListConcat.hs delete mode 100644 tests/synthesis/TODO/ListToBST.hs delete mode 100644 tests/synthesis/TODO/TreeToList.hs delete mode 100644 tests/synthesis/TODO/User.hs delete mode 100644 tests/synthesis/logs/.gitkeep delete mode 100644 tests/synthesis/static/Append.hs delete mode 100644 tests/synthesis/static/BSTFlatten.hs delete mode 100644 tests/synthesis/static/BSTSort.hs delete mode 100644 tests/synthesis/static/BinHeapSingleton.hs delete mode 100644 tests/synthesis/static/Data.hs delete mode 100644 tests/synthesis/static/Data2.hs delete mode 100644 tests/synthesis/static/Data3.hs delete mode 100644 tests/synthesis/static/IntSimple.hs delete mode 100644 tests/synthesis/static/ListId.hs delete mode 100644 tests/synthesis/static/ListInsertSort.hs delete mode 100644 tests/synthesis/static/ListNull.hs delete mode 100644 tests/synthesis/static/ListZip.hs delete mode 100644 tests/synthesis/static/ListZipWith.hs delete mode 100644 tests/synthesis/static/NestedListSimple.hs delete mode 100644 tests/synthesis/static/Stutter.hs delete mode 100644 tests/synthesis/static/TreeOne.hs delete mode 100644 tests/synthesis/static/TupleListSimple.hs delete mode 100644 tests/synthesis/static/map.hs delete mode 100644 tests/synthesis/static/single-elem-list.hs delete mode 100644 tests/synthesis/tests/Append.hs delete mode 100644 tests/synthesis/tests/BSTFlatten.hs delete mode 100644 tests/synthesis/tests/BSTSort.hs delete mode 100644 tests/synthesis/tests/BinHeapSingleton.hs delete mode 100644 tests/synthesis/tests/Data.hs delete mode 100644 tests/synthesis/tests/Data2.hs delete mode 100644 tests/synthesis/tests/Data3.hs delete mode 100644 tests/synthesis/tests/IntSimple.hs delete mode 100644 tests/synthesis/tests/ListId.hs delete mode 100644 tests/synthesis/tests/ListInsertSort.hs delete mode 100644 tests/synthesis/tests/ListNull.hs delete mode 100644 tests/synthesis/tests/ListZip.hs delete mode 100644 tests/synthesis/tests/ListZipWith.hs delete mode 100644 tests/synthesis/tests/NestedListSimple.hs delete mode 100644 tests/synthesis/tests/Stutter.hs delete mode 100644 tests/synthesis/tests/TreeOne.hs delete mode 100644 tests/synthesis/tests/TupleListSimple.hs delete mode 100644 tests/synthesis/tests/map.hs delete mode 100644 tests/synthesis/tests/single-elem-list.hs diff --git a/.circleci/config.yml b/.circleci/config.yml index 81bc77429e..984a6ad96f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,7 +68,7 @@ commands: echo 'export PATH=~/.ghcup/bin:$PATH' >> $BASH_ENV << parameters.cabal_update_command >> cabal v2-clean - cabal v2-build --project-file << parameters.project_file >> --flag devel -j --enable-tests liquidhaskell-parser synthesis liquid-base liquid-prelude liquid-bytestring liquid-containers liquid-ghc-prim liquid-parallel liquid-vector liquid-platform test-driver + cabal v2-build --project-file << parameters.project_file >> --flag devel -j --enable-tests liquidhaskell-parser liquid-base liquid-prelude liquid-bytestring liquid-containers liquid-ghc-prim liquid-parallel liquid-vector liquid-platform test-driver - save_cache: key: cabal-cache-v3-{{ checksum "liquidhaskell.cabal" }}-{{ checksum "<< parameters.project_file >>" }}-{{ checksum "liquid-fixpoint-commit" }} paths: diff --git a/docs/mkDocs/docs/specifications.md b/docs/mkDocs/docs/specifications.md index 57ecf936b4..31f15d3927 100644 --- a/docs/mkDocs/docs/specifications.md +++ b/docs/mkDocs/docs/specifications.md @@ -916,57 +916,6 @@ you can write {-@ lazy foo @-} ``` -# Synthesis - -**Status:** `experimental` - -LH has some very preliminary support for program synthesis. - -### How to use it - -Activate the flag for typed holes in LiquidHaskell. E.g. -from command line: - - liquid --typedholes - -In a Haskell source file: - - {-@ LIQUID --typed-holes @-} - -Using the flag for typed holes, two more flags can be used: - -- **max-match-depth**: Maximum number of pattern match expressions used during synthesis (default value: 4). - -- **max-app-depth**: Maximum number of same function applications used during synthesis (default value: 2). - -Having the program specified in a Haskell source file, use -GHC' s hole variables, e.g.: - -```haskell -{-@ myMap :: (a -> b) -> xs:[a] -> {v:[b] | len v == len xs} @-} -myMap :: (a -> b) -> [a] -> [b] -myMap = _goal -``` - -## Limitations - -This is an experimental feature, so potential users could only -expect to synthesize programs, like [these](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/synthesis). - -Current limitations include: - -- No boolean conditionals are synthesized. -- Holes can only appear at top level, e.g.: - - {-@ f :: x: [a] -> { v: [a] | v == x } @-} - f :: [a] -> [a] - -- This works - f = _hole - -- This does not work - f x = _hole - -- Only one hole can appear in each module. - # Relational Types **Status:** `experimental` diff --git a/liquid-prelude/liquid-prelude.cabal b/liquid-prelude/liquid-prelude.cabal index bc46fb6bfe..90b8f433d5 100644 --- a/liquid-prelude/liquid-prelude.cabal +++ b/liquid-prelude/liquid-prelude.cabal @@ -25,7 +25,6 @@ library Language.Haskell.Liquid.Equational Language.Haskell.Liquid.Bag Language.Haskell.Liquid.ProofCombinators - Language.Haskell.Liquid.Synthesize.Error KMeansHelper hs-source-dirs: src build-depends: liquid-base < 5 diff --git a/liquid-prelude/src/Language/Haskell/Liquid/Synthesize/Error.hs b/liquid-prelude/src/Language/Haskell/Liquid/Synthesize/Error.hs deleted file mode 100644 index 41af9bf08d..0000000000 --- a/liquid-prelude/src/Language/Haskell/Liquid/Synthesize/Error.hs +++ /dev/null @@ -1,5 +0,0 @@ -module Language.Haskell.Liquid.Synthesize.Error where - -{-@ err :: { v: Int | false } -> a @-} -err :: Int -> a -err s = undefined \ No newline at end of file diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 2287803d0a..d29d178fcd 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -91,13 +91,6 @@ library Language.Haskell.Liquid.Measure Language.Haskell.Liquid.Misc Language.Haskell.Liquid.Parse - Language.Haskell.Liquid.Synthesize.GHC - Language.Haskell.Liquid.Synthesize.Termination - Language.Haskell.Liquid.Synthesize.Monad - Language.Haskell.Liquid.Synthesize.Misc - Language.Haskell.Liquid.Synthesize.Generate - Language.Haskell.Liquid.Synthesize.Check - Language.Haskell.Liquid.Synthesize.Env Language.Haskell.Liquid.Termination.Structural Language.Haskell.Liquid.Transforms.ANF Language.Haskell.Liquid.Transforms.CoreToLogic @@ -123,7 +116,6 @@ library Language.Haskell.Liquid.Types.Types Language.Haskell.Liquid.Types.Variance Language.Haskell.Liquid.Types.Visitors - Language.Haskell.Liquid.Synthesize Language.Haskell.Liquid.UX.ACSS Language.Haskell.Liquid.UX.Annotate Language.Haskell.Liquid.UX.CTags @@ -216,28 +208,6 @@ test-suite liquidhaskell-parser if flag(devel) ghc-options: -Wall -Wno-name-shadowing -Werror -test-suite synthesis - type: exitcode-stdio-1.0 - main-is: Synthesis.hs - other-modules: Paths_liquidhaskell - hs-source-dirs: tests - build-depends: base >= 4.8.1.0 && < 5 - , liquid-fixpoint - , liquidhaskell - , tasty >= 0.7 - , tasty-hunit - , process - , filepath - , text - , directory - , ghc - , extra - default-language: Haskell2010 - ghc-options: -W - - if flag(devel) - ghc-options: -Wall -Wno-name-shadowing -Werror - -- This executable can be used to generate modules for mirror-packages. executable mirror-modules main-is: Main.hs diff --git a/src-ghc/Liquid/GHC/Play.hs b/src-ghc/Liquid/GHC/Play.hs index 7dced56c34..747a1e0861 100644 --- a/src-ghc/Liquid/GHC/Play.hs +++ b/src-ghc/Liquid/GHC/Play.hs @@ -144,9 +144,6 @@ isRecursivenewTyCon c go _ = False -isHoleVar :: Var -> Bool -isHoleVar x = L.isPrefixOf "_" (show x) - dataConImplicitIds :: DataCon -> [Id] dataConImplicitIds dc = [ x | AnId x <- dataConImplicitTyThings dc] diff --git a/src/Language/Haskell/Liquid/Constraint/Generate.hs b/src/Language/Haskell/Liquid/Constraint/Generate.hs index 64417c570e..623fcf0852 100644 --- a/src/Language/Haskell/Liquid/Constraint/Generate.hs +++ b/src/Language/Haskell/Liquid/Constraint/Generate.hs @@ -49,7 +49,6 @@ import Language.Haskell.Liquid.Constraint.Monad import Language.Haskell.Liquid.Constraint.Split import Language.Haskell.Liquid.Constraint.Relational (consAssmRel, consRelTop) import Language.Haskell.Liquid.Types.Dictionaries -import Liquid.GHC.Play (isHoleVar) import qualified Liquid.GHC.Resugar as Rs import qualified Liquid.GHC.SpanStack as Sp import qualified Liquid.GHC.Misc as GM -- ( isInternal, collectArguments, tickSrcSpan, showPpr ) @@ -423,10 +422,6 @@ consCB _ _ γ (NonRec x _) | isDictionary x where isDictionary = isJust . dlookup (denv γ) - -consCB _ _ γ (NonRec x _ ) | isHoleVar x && typedHoles (getConfig γ) - = return γ - consCB _ _ γ (NonRec x def) | Just (w, τ) <- grepDictionary def , Just d <- dlookup (denv γ) w @@ -676,9 +671,6 @@ cconsE' γ e@(Cast e' c) t = do t' <- castTy γ (exprType e) e' c addC (SubC γ (F.notracepp ("Casted Type for " ++ GM.showPpr e ++ "\n init type " ++ showpp t) t') t) ("cconsE Cast: " ++ GM.showPpr e) -cconsE' γ (Var x) t | isHoleVar x && typedHoles (getConfig γ) - = addHole x t γ - cconsE' γ e t = do te <- consE γ e te' <- instantiatePreds γ e te >>= addPost γ diff --git a/src/Language/Haskell/Liquid/Constraint/Init.hs b/src/Language/Haskell/Liquid/Constraint/Init.hs index 11f0d105f7..dc746ca53b 100644 --- a/src/Language/Haskell/Liquid/Constraint/Init.hs +++ b/src/Language/Haskell/Liquid/Constraint/Init.hs @@ -256,7 +256,6 @@ initCGI cfg info = CGInfo { , binds = F.emptyBindEnv , ebinds = [] , annotMap = AI M.empty - , holesMap = M.empty , newTyEnv = M.fromList (mapSnd val <$> gsNewTypes (gsSig spc)) , tyConInfo = tyi , tyConEmbed = tce diff --git a/src/Language/Haskell/Liquid/Constraint/Monad.hs b/src/Language/Haskell/Liquid/Constraint/Monad.hs index eeafc7db5a..f5e4d0930f 100644 --- a/src/Language/Haskell/Liquid/Constraint/Monad.hs +++ b/src/Language/Haskell/Liquid/Constraint/Monad.hs @@ -10,13 +10,12 @@ import qualified Data.HashMap.Strict as M import qualified Data.Text as T import Control.Monad -import Control.Monad.State (get, gets, modify) +import Control.Monad.State (gets, modify) import Language.Haskell.Liquid.Types hiding (loc) import Language.Haskell.Liquid.Constraint.Types import Language.Haskell.Liquid.Constraint.Env import Language.Fixpoint.Misc hiding (errorstar) import Liquid.GHC.Misc -- (concatMapM) -import Liquid.GHC.SpanStack (srcSpan) import Liquid.GHC.API as Ghc hiding (panic, showPpr) -------------------------------------------------------------------------------- @@ -87,21 +86,6 @@ addLocA :: Maybe Var -> SrcSpan -> Annot SpecType -> CG () addLocA !xo !l !t = modify $ \s -> s { annotMap = addA l xo t $ annotMap s } - --- | Used for annotating holes - -addHole :: Var -> SpecType -> CGEnv -> CG () -addHole x t γ - | typedHoles (getConfig γ) = - do st <- get - modify $ \s -> s {holesMap = M.insert x (hinfo (st, γ)) $ holesMap s} - -- addWarning $ ErrHole loc ("hole found") (reGlobal env <> reLocal env) x' t - | otherwise = return () - where - hinfo = HoleInfo t loc env - loc = srcSpan $ cgLoc γ - env = mconcat [renv γ, grtys γ, assms γ, intys γ] - -------------------------------------------------------------------------------- -- | Update annotations for a location, due to (ghost) predicate applications -------------------------------------------------------------------------------- diff --git a/src/Language/Haskell/Liquid/Constraint/Types.hs b/src/Language/Haskell/Liquid/Constraint/Types.hs index 91c4aeb637..4b1f03159f 100644 --- a/src/Language/Haskell/Liquid/Constraint/Types.hs +++ b/src/Language/Haskell/Liquid/Constraint/Types.hs @@ -212,7 +212,6 @@ data CGInfo = CGInfo , binds :: !FixBindEnv -- ^ set of environment binders , ebinds :: ![F.BindId] -- ^ existentials , annotMap :: !(AnnInfo (Annot SpecType)) -- ^ source-position annotation map - , holesMap :: !(M.HashMap Var (HoleInfo (CGInfo, CGEnv) SpecType)) -- ^ information for ghc hole expressions , tyConInfo :: !TyConMap -- ^ information about type-constructors , specDecr :: ![(Var, [Int])] -- ^ ^ Lexicographic order of decreasing args (DEPRECATED) , newTyEnv :: !(M.HashMap Ghc.TyCon SpecType) -- ^ Mapping of new type type constructors with their refined types. diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index c6c9175ff1..384ea3adf0 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -32,7 +32,6 @@ import Language.Fixpoint.Misc import Language.Fixpoint.Solver import qualified Language.Fixpoint.Types as F import Language.Haskell.Liquid.Types -import Language.Haskell.Liquid.Synthesize (synthesize) import Language.Haskell.Liquid.UX.Errors import Language.Haskell.Liquid.UX.CmdLine import Language.Haskell.Liquid.UX.Tidy @@ -253,10 +252,7 @@ solveCs cfg tgt cgi info names = do `addErrors` makeFailErrors (S.toList failBs) rf `addErrors` makeFailUseErrors (S.toList failBs) (giCbs $ giSrc info) let lErrors = applySolution sol <$> logErrors cgi - hErrors <- if typedHoles cfg - then synthesize tgt fcfg (cgi{holesMap = applySolution sol <$> holesMap cgi}) - else return [] - let resModel = resModel' `addErrors` (e2u cfg sol <$> (lErrors ++ hErrors)) + let resModel = resModel' `addErrors` (e2u cfg sol <$> lErrors) let out0 = mkOutput cfg resModel sol (annotMap cgi) return $ out0 { o_vars = names } { o_result = resModel } diff --git a/src/Language/Haskell/Liquid/Synthesize.hs b/src/Language/Haskell/Liquid/Synthesize.hs deleted file mode 100644 index c54ee0091c..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize.hs +++ /dev/null @@ -1,179 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FlexibleContexts #-} - -module Language.Haskell.Liquid.Synthesize ( - synthesize - ) where - -import Language.Haskell.Liquid.Types -import Language.Haskell.Liquid.Constraint.Types -import Language.Haskell.Liquid.Constraint.Generate -import qualified Language.Haskell.Liquid.Types.RefType as R -import Language.Haskell.Liquid.Synthesize.Termination -import Language.Haskell.Liquid.Synthesize.Generate -import Language.Haskell.Liquid.Synthesize.GHC hiding (SSEnv) -import Language.Haskell.Liquid.Synthesize.Monad -import Language.Haskell.Liquid.Synthesize.Misc hiding (notrace) -import Language.Haskell.Liquid.Constraint.Fresh (trueTy) -import qualified Language.Fixpoint.Smt.Interface as SMT -import Language.Fixpoint.Types hiding (SEnv, SVar, Error) -import qualified Language.Fixpoint.Types as F -import qualified Language.Fixpoint.Types.Config as F -import Language.Haskell.Liquid.Synthesize.Env -import Liquid.GHC.API as GHC hiding (text, ($+$)) - -import Text.PrettyPrint.HughesPJ (text, ($+$)) -import Control.Monad.State.Lazy -import qualified Data.HashMap.Strict as M -import Data.Maybe - -synthesize :: FilePath -> F.Config -> CGInfo -> IO [Error] -synthesize tgt fcfg cginfo = - mapM go (M.toList $ holesMap cginfo) - where - measures = map (val . msName) ((gsMeasures . gsData . giSpec . ghcI) cginfo) - go (x, HoleInfo _ loc env (cgi,cge)) = do - let topLvlBndr = fromMaybe (error "Top-level binder not found") (cgVar cge) - typeOfTopLvlBnd = fromMaybe (error "Type: Top-level symbol not found") (M.lookup (symbol topLvlBndr) (reGlobal env)) - coreProgram = giCbs $ giSrc $ ghcI cgi - (uniVars, _) = getUniVars coreProgram topLvlBndr - fromREnv' = filterREnv (reLocal env) - fromREnv'' = M.fromList (filter (rmClassVars . toType False . snd) (M.toList fromREnv')) - rmClassVars t = case t of { TyConApp c _ -> not . isClassTyCon $ c; _ -> True } - fromREnv = M.fromList (rmMeasures measures (M.toList fromREnv'')) - isForall t = case t of { ForAllTy{} -> True; _ -> False} - rEnvForalls = M.fromList (filter (isForall . toType False . snd) (M.toList fromREnv)) - fs = map (snd . snd) $ M.toList (symbolToVar coreProgram topLvlBndr rEnvForalls) - - ssenv0 = symbolToVar coreProgram topLvlBndr fromREnv - (senv1, foralls') = initSSEnv typeOfTopLvlBnd cginfo ssenv0 - - ctx <- SMT.makeContext fcfg tgt - state0 <- initState ctx fcfg cgi cge env topLvlBndr (reverse uniVars) M.empty - let foralls = foralls' ++ fs - fills <- synthesize' ctx cgi senv1 typeOfTopLvlBnd topLvlBndr typeOfTopLvlBnd foralls state0 - - return $ ErrHole loc ( - if not (null fills) - then text "\n Hole Fills:" $+$ pprintMany (map (coreToHs typeOfTopLvlBnd topLvlBndr . fromAnf) fills) - else mempty) mempty (symbol x) typeOfTopLvlBnd - - -synthesize' :: SMT.Context -> CGInfo -> SSEnv -> SpecType -> Var -> SpecType -> [Var] -> SState -> IO [CoreExpr] -synthesize' ctx cgi ssenv tx xtop ttop foralls st2 - = evalSM (go tx) ctx ssenv st2 - where - - go :: SpecType -> SM [CoreExpr] - - -- Type Abstraction - go (RAllT a t _x) = GHC.Lam (tyVarVar a) <$$> go t - - go t@(RApp c _ts _ _r) = do - let coreProgram = giCbs $ giSrc $ ghcI cgi - args = drop 1 (argsP coreProgram xtop) - (_, (xs, _, txs, _), _) = bkArrow ttop - addEnv xtop $ decrType xtop ttop args (zip xs txs) - - if R.isNumeric (tyConEmbed cgi) c - then error " [ Numeric in synthesize ] Update liquid fixpoint. " - else do let ts = unifyWith (toType False t) - if null ts then modify (\s -> s { sUGoalTy = Nothing } ) - else modify (\s -> s { sUGoalTy = Just ts } ) - modify (\s -> s {sForalls = (foralls, [])}) - emem0 <- insEMem0 ssenv - modify (\s -> s { sExprMem = emem0 }) - synthesizeBasic t - - go (RAllP _ t) = go t - - go (RRTy _env _ref _obl t) = go t - - go t@RFun{} - = do ys <- mapM freshVar txs - let su = F.mkSubst $ zip xs (EVar . symbol <$> ys) - mapM_ (uncurry addEnv) (zip ys (subst su<$> txs)) - let dt = decrType xtop ttop ys (zip xs txs) - addEnv xtop dt - mapM_ (uncurry addEmem) (zip ys (subst su <$> txs)) - addEmem xtop dt - senv1 <- getSEnv - let goalType' = subst su to - hsGoalTy = toType False goalType' - ts = unifyWith hsGoalTy - if null ts then modify (\s -> s { sUGoalTy = Nothing } ) - else modify (\s -> s { sUGoalTy = Just ts } ) - modify (\s -> s { sForalls = (foralls, []) } ) - emem0 <- insEMem0 senv1 - modify (\s -> s { sExprMem = emem0 }) - mapM_ (`addDecrTerm` []) ys - scruts <- synthesizeScrut ys - modify (\s -> s { scrutinees = scruts }) - GHC.mkLams ys <$$> synthesizeBasic goalType' - where (_, (xs, _,txs, _), to) = bkArrow t - - go t = error (" Unmatched t = " ++ show t) - -synthesizeBasic :: SpecType -> SM [CoreExpr] -synthesizeBasic t = do - let ts = unifyWith (toType False t) -- All the types that are used for instantiation. - if null ts then modify (\s -> s { sUGoalTy = Nothing } ) - else modify (\s -> s { sUGoalTy = Just ts } ) - modify (\s -> s { sGoalTys = [] }) - fixEMem t - es <- genTerms t - if null es then synthesizeMatch t - else return es - -synthesizeMatch :: SpecType -> SM [CoreExpr] -synthesizeMatch t = do - scruts <- scrutinees <$> get - i <- incrCase - case safeIxScruts i scruts of - Nothing -> return [] - Just id' -> if null scruts - then return [] - else withIncrDepth (matchOnExpr t (scruts !! id')) - -synthesizeScrut :: [Var] -> SM [(CoreExpr, Type, TyCon)] -synthesizeScrut vs = do - exprs <- synthesizeScrutinee vs - let exprs' = map (\e -> (exprType e, e)) exprs - isDataCon v = case varType v of { TyConApp c _ -> not . isClassTyCon $ c; _ -> False } - vs0 = filter isDataCon vs - es0 = map GHC.Var vs0 - es1 = map (\e -> (exprType e, e)) es0 - es2 = [(e, t, c) | (t@(TyConApp c _), e) <- es1] - return (es2 ++ [(e, t, c) | (t@(TyConApp c _), e) <- exprs']) - -matchOnExpr :: SpecType -> (CoreExpr, Type, TyCon) -> SM [CoreExpr] -matchOnExpr t (GHC.Var v, tx, c) - = matchOn t (v, tx, c) -matchOnExpr t (e, tx, c) - = do freshV <- freshVarType tx - freshSpecTy <- liftCG $ trueTy False tx - -- use consE - addEnv freshV freshSpecTy - es <- matchOn t (freshV, tx, c) - return $ GHC.Let (GHC.NonRec freshV e) <$> es - -matchOn :: SpecType -> (Var, Type, TyCon) -> SM [CoreExpr] -matchOn t (v, tx, c) = - (GHC.Case (GHC.Var v) v tx <$$> sequence) <$> mapM (makeAlt t (v, tx)) (tyConDataCons c) - - -makeAlt :: SpecType -> (Var, Type) -> DataCon -> SM [GHC.CoreAlt] -makeAlt t (x, TyConApp _ kts) c = locally $ do - ts <- liftCG $ mapM (trueTy False) τs - xs <- mapM freshVar ts - newScruts <- synthesizeScrut xs - modify (\s -> s { scrutinees = scrutinees s ++ newScruts } ) - addsEnv $ zip xs ts - addsEmem $ zip xs ts - addDecrTerm x xs - liftCG0 (\γ -> caseEnv γ x mempty (GHC.DataAlt c) xs Nothing) - es <- synthesizeBasic t - return $ Alt (GHC.DataAlt c) xs <$> es - where - (_, _, τs) = dataConInstSig c kts -makeAlt _ _ _ = error "makeAlt.bad argument " diff --git a/src/Language/Haskell/Liquid/Synthesize/Check.hs b/src/Language/Haskell/Liquid/Synthesize/Check.hs deleted file mode 100644 index fa918aaf9c..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize/Check.hs +++ /dev/null @@ -1,98 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE BangPatterns #-} - -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -module Language.Haskell.Liquid.Synthesize.Check (check, hasType, isWellTyped, checkError) where - - -import Language.Fixpoint.Types.Constraints -import qualified Language.Fixpoint.Types.Config - as F -import qualified Language.Fixpoint.Types as F -import Language.Fixpoint.Solver -import Language.Haskell.Liquid.Types.Types -import Language.Haskell.Liquid.Types.Specs -import Language.Haskell.Liquid.Constraint.Env -import Language.Haskell.Liquid.Constraint.Generate -import Language.Haskell.Liquid.Constraint.Types -import Language.Haskell.Liquid.Constraint.Fresh - ( trueTy ) -import Language.Haskell.Liquid.Constraint.ToFixpoint -import Language.Haskell.Liquid.Synthesize.Monad -import Language.Haskell.Liquid.Synthesize.GHC -import Liquid.GHC.API as Ghc -import Control.Monad.State.Lazy -import System.Console.CmdArgs.Verbosity -import Liquid.GHC.TypeRep -import Language.Haskell.Liquid.Types - -hasType :: SpecType -> CoreExpr -> SM Bool -hasType t !e' = notrace (" [ Check ] " ++ show e') $ do - x <- freshVar t - st <- get - let tpOfE = exprType e' - ht = toType False t - if tpOfE == ht - then liftIO $ quietly $ check (sCGI st) (sCGEnv st) (sFCfg st) x e (Just t) - else error $ " [ hasType ] Expression = " ++ show e' ++ " with type " ++ showTy tpOfE ++ " , specType = " ++ show t - where e = tx e' - --- Returns true if the expression is well-typed. -isWellTyped :: CoreExpr -> SM Bool -isWellTyped e = do - t <- liftCG $ trueTy False $ exprType e - hasType t e - - -tx :: CoreExpr -> CoreExpr -tx (Case e b t alts) = Case e b t ((\(Alt c bs e) -> Alt c bs (tx e)) <$> alts) -tx e@(Let _ _) = let (bs,e') = unbind e in foldr Let e' bs -tx e = e - -unbind :: CoreExpr -> ([CoreBind], CoreExpr) -unbind (Let (NonRec x ex) e) = let (bs,e') = unbind ex in (bs ++ [NonRec x e'],e) -unbind e = ([], e) - - -check :: CGInfo -> CGEnv -> F.Config -> Var -> CoreExpr -> Maybe SpecType -> IO Bool -check cgi γ cfg x e t = do - finfo <- cgInfoFInfo info' cs - isSafe <$> solve cfg{F.srcFile = "SCheck" <> F.srcFile cfg} finfo - where - cs = generateConstraintsWithEnv info' (cgi{hsCs = []}) (γ{grtys = insertREnv' (F.symbol x) t (grtys γ)}) - info' = info {giSrc = giSrc', giSpec = giSpec'} - giSrc' = (giSrc info) {giCbs = [Rec [(x, e)]]} - giSpec' = giSpecOld{gsSig = gsSig'} - giSpecOld = giSpec info - gsSigOld = gsSig giSpecOld - gsSig' = gsSigOld {gsTySigs = addTySig x t (gsTySigs gsSigOld)} - info = ghcI cgi - - insertREnv' _ Nothing g = g - insertREnv' x (Just t) g = insertREnv x t g - - addTySig _ Nothing ts = ts - addTySig x (Just t) ts = (x,dummyLoc t):ts - -checkError :: SpecType -> SM (Maybe CoreExpr) -checkError t = do - errVar <- varError - let errorExpr = App (App (Var errVar) (Type (toType False t))) errorInt - globalFlags = error "broken in https://github.com/ucsd-progsys/liquidhaskell/pull/2129" - platform = targetPlatform globalFlags - errorInt = mkIntExprInt platform 42 - b <- hasType t errorExpr - if b - then return $ Just errorExpr - else return Nothing - -quietly :: IO a -> IO a -quietly act = do - vb <- getVerbosity - setVerbosity Quiet - r <- act - setVerbosity vb - return r - - diff --git a/src/Language/Haskell/Liquid/Synthesize/Env.hs b/src/Language/Haskell/Liquid/Synthesize/Env.hs deleted file mode 100644 index c51ed7c04c..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize/Env.hs +++ /dev/null @@ -1,47 +0,0 @@ -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -module Language.Haskell.Liquid.Synthesize.Env where - -import Language.Fixpoint.Types -import Liquid.GHC.API as GHC -import Language.Haskell.Liquid.Constraint.Types -import Language.Haskell.Liquid.Types -import Language.Haskell.Liquid.Synthesize.Monad -import qualified Data.HashMap.Strict as M -import qualified Data.HashSet as S -import Data.List - -initSSEnv :: SpecType -> CGInfo -> SSEnv -> (SSEnv, [Var]) -initSSEnv rt info senv = (M.union senv (M.fromList foralls), vs) - where foralls = filter iNeedIt (mkElem <$> prims) - vs = map (snd . snd) foralls - dataCons = typeToCons rt - mkElem (v, lt) = (symbol v, (val lt, v)) - prims = gsCtors $ gsData $ giSpec $ ghcI info - iNeedIt (_, (_, v)) = v `elem` (dataConWorkId <$> dataCons) - --- | For algebraic datatypes: Find (in the refinement type) --- all the datatypes that are used and --- get their constructors. -tpToCons :: SpecType -> [DataCon] -tpToCons (RAllT _a t _x) - = tpToCons t -tpToCons (RApp c args _ _r) - = tyConDataCons (rtc_tc c) ++ concatMap tpToCons args -tpToCons (RFun _sym _ rt0 rt1 _reft) - = tpToCons rt0 ++ tpToCons rt1 -tpToCons RVar{} - = [] -tpToCons (RAllP _ t) - = tpToCons t -tpToCons (RRTy _ _ _ t) - = tpToCons t -tpToCons _ - = [] - -typeToCons :: SpecType -> [DataCon] -typeToCons rt = S.toList $ S.fromList (tpToCons rt) - -rmMeasures :: [Symbol] -> [(Symbol, SpecType)] -> [(Symbol, SpecType)] -rmMeasures meas = filter (\(s,_) -> case find (== s) meas of Nothing -> True - Just _ -> False) diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs deleted file mode 100644 index 83c7d02112..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ /dev/null @@ -1,414 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE LambdaCase #-} - -{-# OPTIONS_GHC -Wno-orphans #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -module Language.Haskell.Liquid.Synthesize.GHC where - -import qualified Language.Fixpoint.Types as F -import Language.Haskell.Liquid.Types -import Data.Default -import Data.Maybe ( fromMaybe ) -import Liquid.GHC.TypeRep -import Liquid.GHC.API as GHC -import Language.Fixpoint.Types -import qualified Data.HashMap.Strict as M - -import Data.List -import Data.List.Split - -instance Default Type where - def = TyVarTy alphaTyVar - -mkVar :: Maybe String -> Int -> Type -> Var -mkVar x i t = mkGlobalVar VanillaId name t vanillaIdInfo - where - name = mkSystemName (mkUnique 'S' i) (mkVarOcc x') - x' = fromMaybe (freshName i) x - -freshName :: Int -> String -freshName i = "lSyn$" ++ show i - --- | Assuming that the functions are instantiated when this function is called. -goalType :: Type -> -- This is the goal type. It is used for basic types. - Type -> -- This type comes from the environment. - Bool -- True if the 2nd arg produces expression - -- of type equal to 1st argument. -goalType τ FunTy{ ft_res = t'' } - | t'' == τ = True - | otherwise = goalType τ t'' -goalType τ t - | τ == t = True - | otherwise = False - --- Subgoals are function's arguments. -createSubgoals :: Type -> [Type] -createSubgoals (ForAllTy _ htype) = createSubgoals htype -createSubgoals (FunTy { ft_arg = t1, ft_res = t2 }) = t1 : createSubgoals t2 -createSubgoals t = [t] - -subgoals :: Type -> -- Given a function type, - Maybe (Type, [Type]) -- separate the result type from the input types. -subgoals t = if null gTys then Nothing else Just (resTy, inpTys) - where gTys = createSubgoals t - (resTy, inpTys) = (last gTys, take (length gTys - 1) gTys) - - --- @withSubgoal@ :: Takes a subgoal type, and --- returns all expressions in @ExprMemory@ that have the same type. -withSubgoal :: [(Type, CoreExpr, Int)] -> Type -> [(CoreExpr, Int)] -withSubgoal [] _ = [] -withSubgoal ((t, e, i) : exprs) τ = - if τ == t - then (e, i) : withSubgoal exprs τ - else withSubgoal exprs τ - --- | Assuming that goals are type variables or constructors. --- Note: We maintain ordering from the goal type. --- Not handled (compared to @varsInType): function types, type applications -unifyWith :: Type -> [Type] -unifyWith v@(TyVarTy _) = [v] -unifyWith (TyConApp _ ts) = ts -unifyWith t = error $ " [ unifyWith ] " ++ showTy t - -fromAnf :: CoreExpr -> CoreExpr -fromAnf e = fst $ fromAnf' e [] - --- | Replace let bindings in applications. --- > If you find a binding add it to the second argument. --- | (lhs, rhs) | -fromAnf' :: CoreExpr -> [(Var, CoreExpr)] -> (CoreExpr, [(Var, CoreExpr)]) -fromAnf' (Lam b e) bnds - = let (e', bnds') = fromAnf' e bnds - in (Lam b e', bnds') -fromAnf' (Let bnd e) bnds - = case bnd of Rec {} -> error " By construction, no recursive bindings in let expression. " - NonRec rb lb -> let (lb', bnds') = fromAnf' lb bnds - in fromAnf' e ((rb, lb') : bnds') -fromAnf' (Var var) bnds - = (fromMaybe (Var var) (lookup var bnds), bnds) -fromAnf' (Case scr bnd tp alts) bnds - = (Case scr bnd tp (map (\(Alt altc xs e) -> Alt altc xs (fst $ fromAnf' e bnds)) alts), bnds) -fromAnf' (App e1 e2) bnds - = let (e1', bnds') = fromAnf' e1 bnds - (e2', bnds'') = fromAnf' e2 bnds' - in (App e1' e2', bnds'') -fromAnf' t@Type{} bnds - = (t, bnds) -fromAnf' l@Lit{} bnds - = (l, bnds) -fromAnf' _ _ - = error " Should not reach this point. " - --- | Function used for pretty printing core as Haskell source. --- Input does not contain let bindings. -coreToHs :: SpecType -> Var -> CoreExpr -> String -coreToHs t v e = pprintSymbols (discardModName v ++ pprintFormals caseIndent v e (tracepp " cnt " cnt) []) - where cnt = countTcConstraints t - -symbols :: String -symbols = [':'] - -pprintSymbols :: String -> String -pprintSymbols txt = foldr (\x xs -> pprintSym symbols x ++ xs) [] txt - -pprintSym :: String -> Char -> String -pprintSym symbols s - = case find (== s) symbols of - Nothing -> [s] - Just s' -> ['(', s', ')'] - -discardModName :: Var -> String -discardModName v = last (splitOn "." (show v)) - -rmModName :: String -> String -rmModName s = - let ts = splitOn "." s - in maintainLParen ts ++ last ts ++ maintainRParen ts - -maintainLParen :: [String] -> String -maintainLParen ts - = if length ts > 1 && head (head ts) == '(' - then "(" - else "" - -maintainRParen :: [String] -> String -maintainRParen ts - = if last (last ts) == '(' - then ")" - else "" - -pprintFormals :: Int -> Var -> CoreExpr -> Int -> [Var] -> String -pprintFormals i v (Lam b e) cnt vs - | isTyVar b = pprintFormals i v e cnt vs - | cnt > 0 = pprintFormals i v e (cnt - 1) (b:vs) - | otherwise = " " ++ show b ++ pprintFormals i v e cnt vs -pprintFormals i _ e _ vs - = " =" ++ pprintBody vs i e - -caseIndent :: Int -caseIndent = 4 - -indent :: Int -> String -indent i = replicate i ' ' - -errorExprPp :: CoreExpr -> Bool -errorExprPp (GHC.App (GHC.App err@(GHC.Var _) (GHC.Type _)) _) - = show err == "Language.Haskell.Liquid.Synthesize.Error.err" -errorExprPp _ - = False - -pprintVar :: Var -> String -pprintVar v = if isTyVar v then "" else " " ++ discardModName v - -pprintBody :: [Var] -> Int -> CoreExpr -> String -pprintBody vs i (Lam b e) - = pprintFormals i b e 0 vs -pprintBody vs _ (Var v) - = case find (== v) vs of - Nothing -> pprintVar v - Just _ -> "" -pprintBody vs _ e@App{} - = let pprintApp = fixApplication (show e) - noTcVars = filter (\x -> case find (== x) (map show vs) of - Nothing -> True - Just _ -> False) (words pprintApp) - in if errorExprPp e - then " error \" Dead code! \" " - else " " ++ unwords noTcVars -pprintBody _ _ l@Lit{} - = " " ++ show l -pprintBody vs i (Case scr _ _ alts) - = "\n" ++ indent i ++ - "case" ++ pprintBody vs i scr ++ " of\n" ++ - concatMap (pprintAlts vs (i + caseIndent)) alts -pprintBody _ _ Type{} - = "" -pprintBody _ _ e - = error (" Not yet implemented for e = " ++ show e) - -fixApplication :: String -> String -fixApplication e = - let ws' = words (replaceNewLine e) - ws = handleCommas ws' - cleanWs = rmTypeAppl ws - in unwords (fixCommas $ fixParen (map rmModName cleanWs)) - -handleCommas :: [String] -> [String] -handleCommas [] = [] -handleCommas (c:cs) - = if last c == ',' - then init c : "," : handleCommas cs - else c : handleCommas cs - -fixCommas :: [String] -> [String] -fixCommas [] = [] -fixCommas [x] = [x] -fixCommas (x:y:xs) - = if y == "," - then (x++y) : fixCommas xs - else x : fixCommas (y:xs) - -fixParen :: [String] -> [String] -fixParen [] = [] -fixParen [x] = [x] -fixParen (x:y:xs) - = if replicate (length y) ')' == y - then let w0 = x ++ y - w = if head w0 == '(' && last w0 == ')' - then tail (init w0) - else w0 - in w : fixParen xs - else x : fixParen (y:xs) - -rmTypeAppl :: [String] -> [String] -rmTypeAppl [] - = [] -rmTypeAppl (c:cs) - = if c == "@" - then case cs of - [] -> error " Type application: Badly formatted string. " - (c': cs') -> - let p = paren c' - in if null p then rmTypeAppl cs' else p : rmTypeAppl cs' - else c:rmTypeAppl cs - -paren :: String -> String -paren [] - = [] -paren (c:cs) - = if c == ')' then c : paren cs else paren cs - -replaceNewLine :: String -> String -replaceNewLine [] - = [] -replaceNewLine (c:cs) - = if c == '\n' - then ' ' : replaceNewLine cs - else c : replaceNewLine cs - -pprintAlts :: [Var] -> Int -> Alt Var -> String -pprintAlts vars i (Alt (DataAlt dataCon) vs e) - = indent i ++ show dataCon ++ concatMap (\v -> " " ++ show v) vs ++ " ->" ++ - pprintBody vars (i+caseIndent) e ++ "\n" -pprintAlts _ _ _ - = error " Pretty printing for pattern match on datatypes. " - --- TODO Remove variables generated for type class constraints -countTcConstraints :: SpecType -> Int -countTcConstraints t = - let ws = words (show t) - - countCommas :: [String] -> Int - countCommas [] = 0 - countCommas (x:xs) = - case find (== ',') x of - Nothing -> countCommas xs - Just _ -> 1 + countCommas xs - - in case find (== "=>") ws of - Nothing -> 0 - Just _ -> 1 + countCommas (takeWhile (/= "=>") ws) - - - ------------------------------------------------------------------------------------ --- | Prune trivial expressions | -- ------------------------------------------------------------------------------------ -nonTrivial :: GHC.CoreExpr -> Bool -nonTrivial (GHC.App _ (GHC.Type _)) = False -nonTrivial _ = True - -nonTrivials :: [GHC.CoreExpr] -> Bool -nonTrivials = foldr (\x b -> nonTrivial x || b) False - -trivial :: GHC.CoreExpr -> Bool -trivial (GHC.App (GHC.Var _) (GHC.Type _)) = True -- Is this a nullary constructor? -trivial _ = False - -hasTrivial :: [GHC.CoreExpr] -> Bool -hasTrivial es = foldr (\x b -> trivial x || b) False es - -allTrivial :: [[GHC.CoreExpr]] -> Bool -allTrivial es = foldr (\x b -> hasTrivial x && b) True es - -rmTrivials :: [(GHC.CoreExpr, Int)] -> [(GHC.CoreExpr, Int)] -rmTrivials = filter (not . trivial . fst) - ----------------------------------------------------------------------------------- --- | Scrutinee filtering | -- ----------------------------------------------------------------------------------- - -isVar :: GHC.CoreExpr -> Bool -isVar (GHC.Var _) = True -isVar _ = False - -returnsTuple :: Var -> Bool -returnsTuple v = - case subgoals (varType v) of - Nothing -> False - Just (t, _) -> - case t of - TyConApp c _ts -> c == pairTyCon - _ -> False - ------------------------------------------------------------------------------------------------- --------------------------------------- Handle REnv --------------------------------------------- ------------------------------------------------------------------------------------------------- --- Duplicate from Monad due to dependencies between modules. -type SSEnv = M.HashMap Symbol (SpecType, Var) - -filterREnv :: M.HashMap Symbol SpecType -> M.HashMap Symbol SpecType -filterREnv renv = - let renv_lst = M.toList renv - renv_lst' = filter (\(_, specT) -> let ht = toType False specT - in showTy ht /= "(RApp GHC.Prim.Addr# )") renv_lst - in M.fromList renv_lst' - -getTopLvlBndrs :: GHC.CoreProgram -> [Var] -getTopLvlBndrs = concatMap (\case GHC.NonRec b _ -> [b] - GHC.Rec recs -> map fst recs) - --- | That' s a hack to get the type variables we need for instantiation. -getUniVars :: GHC.CoreProgram -> Var -> ([Var], [Var]) -getUniVars cp tlVar = - case filter (`isInCB` tlVar) cp of - [cb] -> getUniVars0 (getBody cb tlVar) ([], []) - _ -> error " Every top-level corebind must be unique! " - -getUniVars0 :: GHC.CoreExpr -> ([Var], [Var]) -> ([Var], [Var]) -getUniVars0 (Lam b e) (uvs, tcDicts) - = case varType b of - TyConApp c _ -> - if isClassTyCon c - then getUniVars0 e (uvs, b : tcDicts) - else getUniVars0 e (b:uvs, tcDicts) - _ -> getUniVars0 e (b:uvs, tcDicts) -getUniVars0 _ vs - = vs - -getBody :: GHC.CoreBind -> Var -> GHC.CoreExpr -getBody (GHC.NonRec b e) tlVar = if b == tlVar then e else error " [ getBody ] " -getBody (GHC.Rec _) _ = error "Assuming our top-level binder is non-recursive (only contains a hole)" - --- | Current top-level binder | -varsP :: GHC.CoreProgram -> Var -> (GHC.CoreExpr -> [Var]) -> [Var] -varsP cp tlVar f = - case filter (`isInCB` tlVar) cp of - [cb] -> varsCB cb f - _ -> error " Every top-level corebind must be unique! " - -isInCB :: GHC.CoreBind -> Var -> Bool -isInCB (GHC.NonRec b _) tlVar = b == tlVar -isInCB (GHC.Rec recs) tlVar = foldr ((\v b -> v == tlVar && b) . fst) True recs - -varsCB :: GHC.CoreBind -> (GHC.CoreExpr -> [Var]) -> [Var] -varsCB (GHC.NonRec _ e) f = f e -varsCB (GHC.Rec _) _ = notrace " [ symbolToVarCB ] Rec " [] - -varsE :: GHC.CoreExpr -> [Var] -varsE (GHC.Lam a e) = a : varsE e -varsE (GHC.Let (GHC.NonRec b _) e) = b : varsE e -varsE (GHC.Case _ b _ alts) = foldr (\(Alt _ vars e) res -> vars ++ varsE e ++ res) [b] alts -varsE (GHC.Tick _ e) = varsE e -varsE _ = [] - -caseVarsE :: GHC.CoreExpr -> [Var] -caseVarsE (GHC.Lam _ e) = caseVarsE e -caseVarsE (GHC.Let (GHC.NonRec _ _) e) = caseVarsE e -caseVarsE (GHC.Case _ b _ alts) = foldr (\(Alt _ _ e) res -> caseVarsE e ++ res) [b] alts -caseVarsE (GHC.Tick _ e) = caseVarsE e -caseVarsE _ = [] - -instance Default Var where - def = alphaTyVar - -symbolToVar :: GHC.CoreProgram -> Var -> M.HashMap Symbol SpecType -> SSEnv -symbolToVar cp tlBndr renv = - let vars = [(F.symbol x, x) | x <- varsP cp tlBndr varsE] - casevars = [F.symbol x | x <- varsP cp tlBndr caseVarsE] - tlVars = [(F.symbol x, x) | x <- getTopLvlBndrs cp] - lookupErrorMsg x = " [ symbolToVar ] impossible lookup for x = " ++ show x - symbolVar x = fromMaybe (fromMaybe (error (lookupErrorMsg x)) $ lookup x tlVars) $ lookup x vars - renv' = foldr M.delete renv casevars - in M.fromList [ (s, (t, symbolVar s)) | (s, t) <- M.toList renv'] - -argsP :: GHC.CoreProgram -> Var -> [Var] -argsP [] tlVar = error $ " [ argsP ] " ++ show tlVar -argsP (cb : cbs) tlVar - | isInCB cb tlVar = argsCB cb - | otherwise = argsP cbs tlVar - -argsCB :: GHC.CoreBind -> [Var] -argsCB (GHC.NonRec _ e) = argsE e -argsCB _ = error " [ argsCB ] " - -argsE :: GHC.CoreExpr -> [Var] -argsE (GHC.Lam a e) = a : argsE e -argsE (GHC.Let (GHC.NonRec _ _) e) = argsE e -argsE _ = [] - -notrace :: String -> a -> a -notrace _ a = a - diff --git a/src/Language/Haskell/Liquid/Synthesize/Generate.hs b/src/Language/Haskell/Liquid/Synthesize/Generate.hs deleted file mode 100644 index d62ba7fef5..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize/Generate.hs +++ /dev/null @@ -1,252 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE BangPatterns #-} - -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -module Language.Haskell.Liquid.Synthesize.Generate where - -import Liquid.GHC.API as GHC hiding (Depth) -import Language.Haskell.Liquid.Types -import Language.Haskell.Liquid.Synthesize.GHC - hiding ( SSEnv ) -import Language.Haskell.Liquid.Synthesize.Monad -import Language.Haskell.Liquid.Synthesize.Misc - hiding ( notrace ) -import Language.Haskell.Liquid.Synthesize.Check -import Data.Maybe -import Control.Monad.State.Lazy -import Language.Haskell.Liquid.Constraint.Fresh - ( trueTy ) -import Data.List -import Data.Tuple.Extra -import Language.Fixpoint.Types.PrettyPrint (tracepp) - --- Generate terms that have type t: This changes the @ExprMemory@ in @SM@ state. --- Return expressions type checked against type @specTy@. -genTerms :: SpecType -> SM [CoreExpr] -genTerms = genTerms' ResultMode - - -data SearchMode - = ArgsMode -- ^ searching for arguments of functions that can eventually - -- produce the top level hole fill - | ResultMode -- ^ searching for the hole fill - deriving (Eq, Show) - -genTerms' :: SearchMode -> SpecType -> SM [CoreExpr] -genTerms' i specTy = - do goalTys <- sGoalTys <$> get - case find (== toType False specTy) goalTys of - Nothing -> modify (\s -> s { sGoalTys = toType False specTy : sGoalTys s }) - Just _ -> return () - fixEMem specTy - fnTys <- functionCands (toType False specTy) - es <- withTypeEs specTy - es0 <- structuralCheck es - - err <- checkError specTy - case err of - Nothing -> - filterElseM (hasType specTy) es0 $ - withDepthFill i specTy 0 fnTys - Just e -> return [e] - -genArgs :: SpecType -> SM [CoreExpr] -genArgs t = - do goalTys <- sGoalTys <$> get - case find (== toType False t) goalTys of - Nothing -> do modify (\s -> s { sGoalTys = toType False t : sGoalTys s }) - fixEMem t - fnTys <- functionCands (toType False t) - es <- withDepthFillArgs t 0 fnTys - if null es - then return [] - else do -- modify (\s -> s {sExprId = sExprId s + 1}) - return es - Just _ -> return [] - -withDepthFillArgs :: SpecType -> Int -> [(Type, CoreExpr, Int)] -> SM [CoreExpr] -withDepthFillArgs t depth cs = do - thisEm <- sExprMem <$> get - es <- argsFill thisEm cs [] - argsDepth <- localMaxArgsDepth - - filterElseM (hasType t) es $ - if depth < argsDepth - then trace (" [ withDepthFillArgs ] argsDepth = " ++ show argsDepth) $ withDepthFillArgs t (depth + 1) cs - else return [] - -argsFill :: ExprMemory -> [(Type, CoreExpr, Int)] -> [CoreExpr] -> SM [CoreExpr] -argsFill _ [] es0 = return es0 -argsFill em0 (c:cs) es0 = - case subgoals (fst3 c) of - Nothing -> return [] - Just (resTy, subGs) -> - do let argCands = map (withSubgoal em0) subGs - toGen = foldr (\x b -> (not . null) x && b) True (tracepp (" [ argsFill ] for c = " ++ show (snd3 c) ++ " argCands ") argCands) - es <- do curExprId <- sExprId <$> get - if toGen then - prune curExprId c argCands - else return [] - curExprId <- sExprId <$> get - let nextEm = map (resTy, , curExprId + 1) es - modify (\s -> s {sExprMem = nextEm ++ sExprMem s }) - argsFill em0 cs (es ++ es0) - -withDepthFill :: SearchMode -> SpecType -> Int -> [(Type, GHC.CoreExpr, Int)] -> SM [CoreExpr] -withDepthFill i t depth tmp = do - exprs <- fill i depth tmp [] - appDepth <- localMaxAppDepth - - filterElseM (hasType t) exprs $ - if depth < appDepth - then do modify (\s -> s { sExprId = sExprId s + 1 }) - withDepthFill i t (depth + 1) tmp - else return [] - -fill :: SearchMode -> Int -> [(Type, GHC.CoreExpr, Int)] -> [CoreExpr] -> SM [CoreExpr] -fill _ _ [] accExprs - = return accExprs -fill i depth (c : cs) accExprs - = case subgoals (fst3 c) of - Nothing -> return [] -- Not a function type - Just (resTy, subGs) -> - do specSubGs <- liftCG $ mapM (trueTy False) (filter (not . isFunction) subGs) - mapM_ genArgs specSubGs - em <- sExprMem <$> get - let argCands = map (withSubgoal em) subGs - toGen = foldr (\x b -> (not . null) x && b) True argCands - newExprs <- do curExprId <- sExprId <$> get - if toGen - then prune curExprId c (tracepp (" [ fill " ++ show curExprId ++ " ] For c = " ++ show (snd3 c) ++ " argCands ") argCands) - else return [] - curExprId <- sExprId <$> get - let nextEm = map (resTy, , curExprId + 1) newExprs - modify (\s -> s {sExprMem = nextEm ++ sExprMem s }) - let accExprs' = newExprs ++ accExprs - fill i depth cs accExprs' - -------------------------------------------------------------------------------------------- --- | Pruning terms for function application | -- -------------------------------------------------------------------------------------------- -type Depth = Int - -feasible :: Depth -> (CoreExpr, Int) -> Bool -feasible d c = snd c >= d - -feasibles :: Depth -> Int -> [(CoreExpr, Int)] -> [Int] -feasibles _ _ [] - = [] -feasibles d i (c:cs) - = if feasible d c - then i : feasibles d (i+1) cs - else feasibles d (i+1) cs - -isFeasible :: Depth -> [[(CoreExpr, Int)]] -> [[Int]] -isFeasible d = map (feasibles d 0) - -findFeasibles :: Depth -> [[(CoreExpr, Int)]] -> ([[Int]], [Int]) -findFeasibles d cs = (fs, ixs) - where fs = isFeasible d cs - ixs = [i | (i, f) <- zip [0..] fs, not (null f)] - -toExpr :: [Int] -> -- Produced from @isFeasible@. - -- Assumed in increasing order. - [(GHC.CoreExpr, Int)] -> -- The candidate expressions. - ([(GHC.CoreExpr, Int)], -- Expressions from 2nd argument. - [(GHC.CoreExpr, Int)]) -- The rest of the expressions -toExpr ixs args = ( [ args !! i | (ix, i) <- is, ix == i ], - [ args !! i | (ix, i) <- is, ix /= i ]) - where is = zip [0..] ixs - -fixCands :: Int -> [Int] -> [[(CoreExpr, Int)]] -> ([[(CoreExpr, Int)]], [[(CoreExpr, Int)]]) -fixCands i ixs args - = let cs = args !! i - (cur, next) = toExpr ixs cs - (args0, args1) = (replace (i+1) cur args, replace (i+1) next args) - in (args0, args1) - --- | The first argument should be an 1-based index. -replace :: Int -> a -> [a] -> [a] -replace i x l - = left ++ [x] ++ right - where left = take (i-1) l - right = drop i l - -repeatFix :: [Int] -> [[Int]] -> (Type, CoreExpr, Int) -> [[(CoreExpr, Int)]] -> [CoreExpr] -> SM [CoreExpr] -repeatFix [ ] _ _ _ es - = return es -repeatFix (i:is) ixs toFill args es - = do let (args0, args1) = fixCands i (ixs !! i) args - es0 <- fillOne toFill args0 - es1 <- structuralCheck es0 - es2 <- (++ es) <$> filterM isWellTyped es1 - repeatFix is ixs toFill args1 es2 - -prune :: Depth -> (Type, CoreExpr, Int) -> [[(CoreExpr, Int)]] -> SM [CoreExpr] -prune d toFill args - = do let (ixs, is) = findFeasibles d args - repeatFix is ixs toFill args [] - - ----------------------------------------------------------------------------- --- | Term generation: Perform type and term application for functions. | -- ----------------------------------------------------------------------------- - -fillOne :: (Type, GHC.CoreExpr, Int) -> [[(CoreExpr, Int)]] -> SM [CoreExpr] -fillOne _ [] - = return [] -fillOne (t, e, _) cs - = applyTerms [e] cs ((snd . fromJust . subgoals) t) - -applyTerm :: [GHC.CoreExpr] -> [(CoreExpr, Int)] -> Type -> SM [CoreExpr] -applyTerm es args t = do - es1 <- mapM (\x -> applyArg es x t) args - return (concat es1) - -applyArg :: [GHC.CoreExpr] -> (CoreExpr, Int) -> Type -> SM [CoreExpr] -applyArg es (arg, _) t - = do !idx <- incrSM - return [ case arg of GHC.Var _ -> GHC.App e arg - _ -> let letv = mkVar (Just ("x" ++ show idx)) idx t - in GHC.Let (GHC.NonRec letv arg) (GHC.App e (GHC.Var letv)) - | e <- es - ] - -applyTerms :: [GHC.CoreExpr] -> [[(CoreExpr, Int)]] -> [Type] -> SM [CoreExpr] -applyTerms es [] [] - = return es -applyTerms es0 (c:cs) (t:ts) - = do es1 <- applyTerm es0 c t - applyTerms es1 cs ts -applyTerms _es _cs _ts - = error "[ applyTerms ] Wildcard. " - --------------------------------------------------------------------------------------- -prodScrutinees :: [(Type, CoreExpr, Int)] -> [[[(CoreExpr, Int)]]] -> SM [CoreExpr] -prodScrutinees [] [] = return [] -prodScrutinees (c:cs) (a:as) = do - es <- fillOne c a - (++ es) <$> prodScrutinees cs as -prodScrutinees _ _ = error " prodScrutinees " - -synthesizeScrutinee :: [Var] -> SM [CoreExpr] -synthesizeScrutinee vars = do - s <- get - let foralls = (fst . sForalls) s - insVs = sUniVars s - fix = sFix s - -- Assign higher priority to function candidates that return tuples - fnCs0 = filter returnsTuple foralls - fnCs = if returnsTuple fix then fix : fnCs0 else fnCs0 - - fnEs = map GHC.Var fnCs - fnCs' = map (\e -> instantiate e (Just insVs)) fnEs - sGs = map ((snd . fromJust) . subgoals . exprType) fnCs' - argCands = map (map (withSubgoal vs)) sGs - fnCs'' = map (\e -> (exprType e, e, 0)) fnCs' - - vs' = filter ((not . isFunction) . varType) vars - vs = map (\v -> (varType v, GHC.Var v, 0)) vs' - prodScrutinees fnCs'' argCands diff --git a/src/Language/Haskell/Liquid/Synthesize/Misc.hs b/src/Language/Haskell/Liquid/Synthesize/Misc.hs deleted file mode 100644 index 2c16fa05a2..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize/Misc.hs +++ /dev/null @@ -1,94 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} - -{-# OPTIONS_GHC -Wno-orphans #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -module Language.Haskell.Liquid.Synthesize.Misc where - -import qualified Language.Fixpoint.Types as F -import Control.Monad.State.Lazy -import Text.PrettyPrint.HughesPJ (text, Doc, vcat, ($+$)) -import Language.Haskell.Liquid.Synthesize.GHC -import Liquid.GHC.TypeRep -import Liquid.GHC.API hiding (text, ($+$), vcat) -import Language.Fixpoint.Types - - -isFunction :: Type -> Bool -isFunction FunTy{} = True -isFunction ForAllTy{} = True -isFunction _ = False - -(<$$>) :: (Functor m, Functor n) => (a -> b) -> m (n a) -> m (n b) -(<$$>) = fmap . fmap - -filterElseM :: Monad m => (a -> m Bool) -> [a] -> m [a] -> m [a] -filterElseM f as ms = do - rs <- filterM f as - if null rs then - ms - else - return rs - --- Replaces | old w | new | symbol name in expr. -substInFExpr :: F.Symbol -> F.Symbol -> F.Expr -> F.Expr -substInFExpr pn nn e = F.subst1 e (pn, F.EVar nn) - - -findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a) -findM _ [] = return Nothing -findM p (x:xs) = do b <- p x ; if b then return (Just x) else findM p xs - - -composeM :: Monad m => (a -> m b) -> (b -> c) -> a -> m c -composeM f g x = do - mx <- f x - return (g mx) - ----------------------------------------------------------------------------- -----------------------------Printing---------------------------------------- ----------------------------------------------------------------------------- -solDelim :: String -solDelim = "*********************************************" - --- pprintMany :: (F.PPrint a) => [a] -> Doc --- pprintMany xs = vcat [ F.pprint x $+$ text solDelim | x <- xs ] - -pprintMany :: [String] -> Doc -pprintMany xs = vcat [ text x $+$ text solDelim | x <- xs ] - -showGoals :: [[String]] -> String -showGoals [] = "" -showGoals (goal : goals) = - show goal ++ - "\n" ++ - replicate 12 ' ' ++ - showGoals goals - -showEmem :: (Show a1, Show a2) => [(Type, a1, a2)] -> String -showEmem emem = show $ showEmem' emem - -showEmem' :: (Show a1, Show a2) => [(Type, a1, a2)] -> [(String, String, String)] -showEmem' emem = map (\(t, e, i) -> (show e, showTy t, show i)) emem - -exprmemToExpr :: [(a2, CoreExpr, Int)] -> String -exprmemToExpr em = show $ map (\(_, e, i) -> show (fromAnf e, i) ++ " * ") em - -showCand :: (a, (Type, b)) -> (String, b) -showCand (_, (t, v)) = (showTy t, v) - -showCands :: [(a, (Type, b))] -> [(String, b)] -showCands = map showCand - -notrace :: String -> a -> a -notrace _ a = a - -instance PPrint AltCon - -showCoreAlt :: CoreAlt -> String -showCoreAlt (Alt (DataAlt altCon) vars expr) = - " For " ++ show altCon ++ " vars " ++ show vars ++ " expr " ++ show expr -showCoreAlt _ = " No! " - -showCoreAlts :: [CoreAlt] -> String -showCoreAlts alts = concatMap showCoreAlt alts diff --git a/src/Language/Haskell/Liquid/Synthesize/Monad.hs b/src/Language/Haskell/Liquid/Synthesize/Monad.hs deleted file mode 100644 index 8dcee2d2c7..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize/Monad.hs +++ /dev/null @@ -1,422 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FlexibleContexts #-} - -{-# OPTIONS_GHC -Wno-name-shadowing #-} - -module Language.Haskell.Liquid.Synthesize.Monad where - - -import Liquid.GHC.API as GHC -import Language.Haskell.Liquid.Bare.Resolve - as B -import Language.Haskell.Liquid.Types -import Language.Haskell.Liquid.Constraint.Types -import Language.Haskell.Liquid.Constraint.Env -import Language.Haskell.Liquid.Synthesize.GHC - hiding ( SSEnv ) -import Language.Haskell.Liquid.Synthesize.Misc - hiding ( notrace ) -import qualified Language.Fixpoint.Smt.Interface - as SMT -import Language.Fixpoint.Types hiding ( SEnv - , SVar - , Error - ) -import qualified Language.Fixpoint.Types as F -import qualified Language.Fixpoint.Types.Config - as F -import Control.Monad.State.Lazy -import qualified Data.HashMap.Strict as M -import Data.Maybe -import Data.List -import Data.Tuple.Extra - -localMaxMatchDepth :: SM Int -localMaxMatchDepth = maxMatchDepth . getConfig . sCGEnv <$> get - -------------------------------------------------------------------------------- --- | Synthesis Monad ---------------------------------------------------------- -------------------------------------------------------------------------------- - --- The state keeps a unique index for generation of fresh variables --- and the environment of variables to types that is expanded on lambda terms -type SSEnv = M.HashMap Symbol (SpecType, Var) -type SSDecrTerm = [(Var, [Var])] - -type ExprMemory = [(Type, CoreExpr, Int)] -type T = M.HashMap Type (CoreExpr, Int) -data SState - = SState { rEnv :: !REnv - , ssEnv :: !SSEnv -- Local Binders Generated during Synthesis - , ssIdx :: !Int - , ssDecrTerm :: !SSDecrTerm - , sContext :: !SMT.Context - , sCGI :: !CGInfo - , sCGEnv :: !CGEnv - , sFCfg :: !F.Config - , sDepth :: !Int - , sExprMem :: !ExprMemory - , sExprId :: !Int - , sArgsId :: !Int - , sArgsDepth :: !Int - , sUniVars :: ![Var] - , sFix :: !Var - , sGoalTys :: ![Type] - , sGoalTyVar :: !(Maybe [TyVar]) - , sUGoalTy :: !(Maybe [Type]) -- Types used for instantiation. - -- Produced by @withUnify@. - , sForalls :: !([Var], [[Type]]) -- [Var] are the parametric functions (except for the fixpoint) - -- e.g. Constructors, top-level functions. - -- [[Type]]: all the types that have instantiated [Var] so far. - , caseIdx :: !Int -- [ Temporary ] Index in list of scrutinees. - , scrutinees :: ![(CoreExpr, Type, TyCon)] - } - -type SM = StateT SState IO - -localMaxAppDepth :: SM Int -localMaxAppDepth = maxAppDepth . getConfig . sCGEnv <$> get - -localMaxArgsDepth :: SM Int -localMaxArgsDepth = maxArgsDepth . getConfig . sCGEnv <$> get - -locally :: SM a -> SM a -locally act = do - st <- get - r <- act - modify $ \s -> s{sCGEnv = sCGEnv st, sCGI = sCGI st, sExprMem = sExprMem st, scrutinees = scrutinees st} - return r - - -evalSM :: SM a -> SMT.Context -> SSEnv -> SState -> IO a -evalSM act ctx env st = do - let st' = st {ssEnv = env} - r <- evalStateT act st' - _ <- SMT.cleanupContext ctx - return r - -initState :: SMT.Context -> F.Config -> CGInfo -> CGEnv -> REnv -> Var -> [Var] -> SSEnv -> IO SState -initState ctx fcfg cgi cgenv renv xtop uniVars env = - return $ SState renv env 0 [] ctx cgi cgenv fcfg 0 exprMem0 0 0 0 uniVars xtop [] Nothing Nothing ([], []) 0 [] - where exprMem0 = initExprMem env - -getSEnv :: SM SSEnv -getSEnv = ssEnv <$> get - -getSEMem :: SM ExprMemory -getSEMem = sExprMem <$> get - -getSFix :: SM Var -getSFix = sFix <$> get - -getSUniVars :: SM [Var] -getSUniVars = sUniVars <$> get - -getSDecrTerms :: SM SSDecrTerm -getSDecrTerms = ssDecrTerm <$> get - -addsEnv :: [(Var, SpecType)] -> SM () -addsEnv xts = - mapM_ (\(x,t) -> modify (\s -> s {ssEnv = M.insert (symbol x) (t,x) (ssEnv s)})) xts - -addsEmem :: [(Var, SpecType)] -> SM () -addsEmem xts = do - curAppDepth <- sExprId <$> get - mapM_ (\(x,t) -> modify (\s -> s {sExprMem = (toType False t, GHC.Var x, curAppDepth+1) : sExprMem s})) xts - - -addEnv :: Var -> SpecType -> SM () -addEnv x t = do - liftCG0 (\γ -> γ += ("arg", symbol x, t)) - modify (\s -> s {ssEnv = M.insert (symbol x) (t,x) (ssEnv s)}) - -addEmem :: Var -> SpecType -> SM () -addEmem x t = do - let ht0 = toType False t - curAppDepth <- sExprId <$> get - xtop <- getSFix - (ht1, _) <- instantiateTL - let ht = if x == xtop then ht1 else ht0 - modify (\s -> s {sExprMem = (ht, GHC.Var x, curAppDepth) : sExprMem s}) - ---------------------------------------------------------------------------------------------- --- Handle structural termination checking -- ---------------------------------------------------------------------------------------------- -addDecrTerm :: Var -> [Var] -> SM () -addDecrTerm x vars = do - decrTerms <- getSDecrTerms - case lookup x decrTerms of - Nothing -> lookupAll x vars decrTerms - Just vars' -> do - let ix = elemIndex (x, vars') decrTerms - newDecrs = thisReplace (fromMaybe (error " [ addDecrTerm ] Index ") ix) (x, vars ++ vars') decrTerms - modify (\s -> s { ssDecrTerm = newDecrs }) - --- -lookupAll :: Var -> [Var] -> SSDecrTerm -> SM () -lookupAll x vars [] = modify (\s -> s {ssDecrTerm = (x, vars) : ssDecrTerm s}) -lookupAll x vars ((xl, vs):decrs) = - case find (== x) vs of - Nothing -> lookupAll x vars decrs - Just _ -> do - sDecrs <- ssDecrTerm <$> get - let newDecr = (xl, vars ++ [x] ++ vs) - i = fromMaybe (error " Write sth ") (elemIndex (xl, vs) sDecrs) - newDecrs = thisReplace i newDecr decrs - modify (\s -> s { ssDecrTerm = newDecrs }) - -thisReplace :: Int -> a -> [a] -> [a] -thisReplace i x l - = left ++ [x] ++ right - where left = take (i-1) l - right = drop i l - --- | Entry point. -structuralCheck :: [CoreExpr] -> SM [CoreExpr] -structuralCheck es - = do decr <- ssDecrTerm <$> get - fix <- sFix <$> get - return (filter (notStructural decr fix) es) - -structCheck :: Var -> CoreExpr -> (Maybe Var, [CoreExpr]) -structCheck xtop var@(GHC.Var v) - = if v == xtop - then (Just xtop, []) - else (Nothing, [var]) -structCheck xtop (GHC.App e1 (GHC.Type _)) - = structCheck xtop e1 -structCheck xtop (GHC.App e1 e2) - = (mbVar, e2:es) - where (mbVar, es) = structCheck xtop e1 -structCheck xtop (GHC.Let _ e) - = structCheck xtop e -structCheck _ e - = error (" StructCheck " ++ show e) - -notStructural :: SSDecrTerm -> Var -> CoreExpr -> Bool -notStructural decr xtop e - = case v of - Nothing -> True - Just _ -> foldr (\x b -> isDecreasing' x decr || b) False args - where (v, args) = structCheck xtop e - -isDecreasing' :: CoreExpr -> SSDecrTerm -> Bool -isDecreasing' (GHC.Var v) decr - = v `notElem` map fst decr -isDecreasing' _e _decr - = True ---------------------------------------------------------------------------------------------- --- END OF STRUCTURAL CHECK -- ---------------------------------------------------------------------------------------------- - -liftCG0 :: (CGEnv -> CG CGEnv) -> SM () -liftCG0 act = do - st <- get - let (cgenv, cgi) = runState (act (sCGEnv st)) (sCGI st) - modify (\s -> s {sCGI = cgi, sCGEnv = cgenv}) - - -liftCG :: CG a -> SM a -liftCG act = do - st <- get - let (x, cgi) = runState act (sCGI st) - modify (\s -> s {sCGI = cgi}) - return x - - -freshVarType :: Type -> SM Var -freshVarType t = (\i -> mkVar (Just "x") i t) <$> incrSM - - -freshVar :: SpecType -> SM Var -freshVar = freshVarType . toType False - -withIncrDepth :: Monoid a => SM a -> SM a -withIncrDepth m = do - s <- get - matchBound <- localMaxMatchDepth - let d = sDepth s - if d + 1 > matchBound - then return mempty - else do put s{sDepth = d + 1} - r <- m - modify $ \s -> s{sDepth = d} - return r - - -incrSM :: SM Int -incrSM = do s <- get - put s{ssIdx = ssIdx s + 1} - return (ssIdx s) - -incrCase :: SM Int -incrCase - = do s <- get - put s { caseIdx = caseIdx s + 1 } - return (caseIdx s) - -safeIxScruts :: Int -> [a] -> Maybe Int -safeIxScruts i l - | i >= length l = Nothing - | otherwise = Just i - -symbolExpr :: Type -> F.Symbol -> SM CoreExpr -symbolExpr τ x = incrSM >>= (\i -> return $ F.notracepp ("symExpr for " ++ F.showpp x) $ GHC.Var $ mkVar (Just $ F.symbolString x) i τ) - - -------------------------------------------------------------------------------------------------------- ------------------------------------------ Handle ExprMemory ------------------------------------------- -------------------------------------------------------------------------------------------------------- - --- | Initializes @ExprMemory@ structure. --- 1. Transforms refinement types to conventional (Haskell) types. --- 2. All @Depth@s are initialized to 0. -initExprMem :: SSEnv -> ExprMemory -initExprMem sEnv = map (\(_, (t, v)) -> (toType False t, GHC.Var v, 0)) (M.toList sEnv) - - --------------- Init @ExprMemory@ with instantiated functions with the right type (sUGoalTy) ----------- -insEMem0 :: SSEnv -> SM ExprMemory -insEMem0 senv = do - xtop <- getSFix - (ttop, _) <- instantiateTL - mbUTy <- sUGoalTy <$> get - uniVs <- sUniVars <$> get - - let ts = fromMaybe [] mbUTy - ts0 <- snd . sForalls <$> get - fs0 <- fst . sForalls <$> get - modify ( \s -> s { sForalls = (fs0, ts : ts0) } ) - - let handleIt e = case e of GHC.Var v -> if xtop == v - then (instantiate e (Just uniVs), ttop) - else change e - _ -> change e - change e = let { e' = instantiateTy e mbUTy; t' = exprType e' } - in (e', t') - - em0 = initExprMem senv - return $ map (\(_, e, i) -> let (e', t') = handleIt e - in (t', e', i)) em0 - -instantiateTy :: CoreExpr -> Maybe [Type] -> CoreExpr -instantiateTy e mbTy = - case mbTy of - Nothing -> e - Just tys -> fromMaybe e (applyTy tys e) - --- | Used for instantiation: Applies types to an expression. --- > The result does not have @forall@. --- Nothing as a result suggests that there are more types than foralls in the expression. -applyTy :: [Type] -> GHC.CoreExpr -> Maybe GHC.CoreExpr -applyTy [] e = case exprType e of - ForAllTy{} -> Nothing - _ -> Just e -applyTy (t:ts) e = case exprType e of - ForAllTy{} -> applyTy ts (GHC.App e (GHC.Type t)) - _ -> Nothing - --- | Instantiation based on current goal-type. -fixEMem :: SpecType -> SM () -fixEMem t - = do (fs, ts) <- sForalls <$> get - let uTys = unifyWith (toType False t) - needsFix <- case find (== uTys) ts of - Nothing -> return True -- not yet instantiated - Just _ -> return False -- already instantiated - - when needsFix $ - do modify (\s -> s { sForalls = (fs, uTys : ts)}) - let notForall e = case exprType e of {ForAllTy{} -> False; _ -> True} - es = map (\v -> instantiateTy (GHC.Var v) (Just uTys)) fs - fixEs = filter notForall es - thisDepth <- sDepth <$> get - let fixedEMem = map (\e -> (exprType e, e, thisDepth + 1)) fixEs - modify (\s -> s {sExprMem = fixedEMem ++ sExprMem s}) - ------------------------------------------------------------------------------------------------- ------------------------------- Special handle for the current fixpoint ------------------------- ------------------------------------------------------------------------------------------------- - --- | Instantiate the top-level variable. -instantiateTL :: SM (Type, GHC.CoreExpr) -instantiateTL = do - uniVars <- getSUniVars - xtop <- getSFix - let e = fromJust $ apply uniVars (GHC.Var xtop) - return (exprType e, e) - --- | Applies type variables (1st argument) to an expression. --- The expression is guaranteed to have the same level of --- parametricity (same number of @forall@) as the length of the 1st argument. --- > The result has zero @forall@. -apply :: [Var] -> GHC.CoreExpr -> Maybe GHC.CoreExpr -apply [] e = - case exprType e of - ForAllTy {} -> Nothing - _ -> Just e -apply (v:vs) e - = case exprType e of - ForAllTy{} -> apply vs (GHC.App e (GHC.Type (TyVarTy v))) - _ -> Nothing - -instantiate :: CoreExpr -> Maybe [Var] -> CoreExpr -instantiate e mbt = - case mbt of - Nothing -> e - Just tyVars -> fromMaybe e (apply tyVars e) - ------------------------------------------------------------------------------------------------------ - -withTypeEs :: SpecType -> SM [CoreExpr] -withTypeEs t = do - em <- sExprMem <$> get - return (map snd3 (filter (\x -> fst3 x == toType False t) em)) - -findCandidates :: Type -> -- Goal type: Find all candidate expressions of this type, - -- or that produce this type (i.e. functions). - SM ExprMemory -findCandidates goalTy = do - sEMem <- sExprMem <$> get - return (filter (goalType goalTy . fst3) sEMem) - -functionCands :: Type -> SM [(Type, GHC.CoreExpr, Int)] -functionCands goalTy = do - all <- findCandidates goalTy - return (filter (isFunction . fst3) all) - - ---------------------------------------------------------------------------------- ---------------------------- Generate error expression --------------------------- ---------------------------------------------------------------------------------- - -varError :: SM Var -varError = do - info <- ghcI . sCGI <$> get - let env = B.makeEnv (gsConfig $ giSpec info) (toGhcSrc $ giSrc info) mempty mempty - let name = giTargetMod $ giSrc info - let errSym = dummyLoc $ symbol "Language.Haskell.Liquid.Synthesize.Error.err" - case B.lookupGhcVar env name "Var" errSym of - Right v -> return v - Left e -> error (show e) - - -toGhcSrc :: TargetSrc -> GhcSrc -toGhcSrc a = Src - { _giTarget = giTarget a - , _giTargetMod = giTargetMod a - , _giCbs = giCbs a - , _gsTcs = gsTcs a - , _gsCls = gsCls a - , _giDerVars = giDerVars a - , _giImpVars = giImpVars a - , _giDefVars = giDefVars a - , _giUseVars = giUseVars a - , _gsExports = gsExports a - , _gsFiTcs = gsFiTcs a - , _gsFiDcs = gsFiDcs a - , _gsPrimTcs = gsPrimTcs a - , _gsQualImps = gsQualImps a - , _gsAllImps = gsAllImps a - , _gsTyThings = gsTyThings a - } diff --git a/src/Language/Haskell/Liquid/Synthesize/Termination.hs b/src/Language/Haskell/Liquid/Synthesize/Termination.hs deleted file mode 100644 index bef4f99229..0000000000 --- a/src/Language/Haskell/Liquid/Synthesize/Termination.hs +++ /dev/null @@ -1,24 +0,0 @@ -{-# LANGUAGE FlexibleInstances #-} - -{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} - -module Language.Haskell.Liquid.Synthesize.Termination ( - decrType - ) where - -import Language.Haskell.Liquid.Types -import qualified Language.Haskell.Liquid.Types.RefType - as R -import qualified Language.Fixpoint.Types as F -import Liquid.GHC.API - -decrType :: Var -> SpecType -> [Var] -> [(F.Symbol, SpecType)] -> SpecType -decrType _x ti xs _xts = - go xs ti - where - go (v:_) (RFun x i tx t r) - | isDecreasing mempty mempty tx = let Left (x', tx') = R.makeDecrType mempty [(v,(x,tx))] - in RFun x' i tx' t r - go (_:vs) (RFun x i tx t r) = RFun x i tx (go vs t) r - go vs (RAllT a t x) = RAllT a (go vs t) x - go _ t = t diff --git a/src/Language/Haskell/Liquid/UX/CmdLine.hs b/src/Language/Haskell/Liquid/UX/CmdLine.hs index 54e7215bca..0679cae7c0 100644 --- a/src/Language/Haskell/Liquid/UX/CmdLine.hs +++ b/src/Language/Haskell/Liquid/UX/CmdLine.hs @@ -410,10 +410,6 @@ config = cmdArgsMode $ Config { &= name "no-check-imports" &= help "Do not check the transitive imports; only check the target files." - , typedHoles - = def - &= name "typed-holes" - &= help "Use (refinement) typed-holes [currently warns on '_x' variables]" , typeclass = def &= help "Enable Typeclass" @@ -422,16 +418,6 @@ config = cmdArgsMode $ Config { = def &= help "Enable inlining of class methods" &= name "aux-inline" - , maxMatchDepth - = def - &= name "max-match-depth" - &= help "Define the number of expressions to pattern match on (typed-holes must be on to use this flag)." - , maxAppDepth - = def - &= name "max-app-depth" - , maxArgsDepth - = def - &= name "max-args-depth" , rwTerminationCheck = def @@ -730,12 +716,8 @@ defConfig = Config , nopolyinfer = False , compileSpec = False , noCheckImports = False - , typedHoles = False , typeclass = False , auxInline = False - , maxMatchDepth = 4 - , maxAppDepth = 2 - , maxArgsDepth = 1 , rwTerminationCheck = False , skipModule = False , noLazyPLE = False diff --git a/src/Language/Haskell/Liquid/UX/Config.hs b/src/Language/Haskell/Liquid/UX/Config.hs index 29694ee47f..003e9bfa2e 100644 --- a/src/Language/Haskell/Liquid/UX/Config.hs +++ b/src/Language/Haskell/Liquid/UX/Config.hs @@ -96,12 +96,8 @@ data Config = Config , reflection :: Bool -- ^ Allow "reflection"; switches on "--higherorder" and "--exactdc" , compileSpec :: Bool -- ^ Only "compile" the spec -- into .bspec file -- don't do any checking. , noCheckImports :: Bool -- ^ Do not check the transitive imports - , typedHoles :: Bool -- ^ Warn about "typed-holes" , typeclass :: Bool -- ^ enable typeclass support. , auxInline :: Bool -- ^ - , maxMatchDepth :: Int - , maxAppDepth :: Int - , maxArgsDepth :: Int , rwTerminationCheck :: Bool -- ^ Enable termination checking for rewriting , skipModule :: Bool -- ^ Skip this module entirely (don't even compile any specs in it) , noLazyPLE :: Bool diff --git a/tests/Synthesis.hs b/tests/Synthesis.hs deleted file mode 100644 index 3f68d80bd5..0000000000 --- a/tests/Synthesis.hs +++ /dev/null @@ -1,153 +0,0 @@ -{-# LANGUAGE TupleSections #-} - -module Main where - -import Test.Tasty -import Test.Tasty.HUnit - -import qualified Data.Text as T -import qualified Data.Text.IO as T -import System.FilePath -import System.Process -import System.IO -import System.Directory -import System.Exit -import System.IO.Unsafe -import Data.Tuple.Extra - -------------------------------------------------------------- --- | Contains the input files -------------------------------------------------------------- -synthesisTestsDir :: FilePath -synthesisTestsDir = "tests/synthesis/tests" -------------------------------------------------------------- - -------------------------------------------------------------- --- | Contains the results of the synthesis on the inputs -------------------------------------------------------------- -logDir :: FilePath -logDir = "tests/synthesis/logs" -------------------------------------------------------------- - -------------------------------------------------------------- --- | Contains the outputs that we need to check logs against -------------------------------------------------------------- -outputsDir :: FilePath -outputsDir = "tests/synthesis/static" -------------------------------------------------------------- - -main :: IO () -main = do - print " Synthesis test suite " - result <- fromInput - defaultMain (tests result) - -fromInput :: IO [(FilePath, T.Text, [[T.Text]])] -fromInput = do - res <- createLogs -- Get the filename from here - logs <- handleLogs (map thd3 res) - let filenames = map fst3 res - programNames = map (head . T.words . head . head) logs - result = zip3 filenames programNames logs - return result - -handleLogs :: [T.Text] -> IO [[[T.Text]]] -handleLogs texts - = return (map handleLog texts) - -keyword :: T.Text -keyword = T.pack " Hole Fills:" - -startsWith :: T.Text -> T.Text -> Bool -startsWith kw line = T.isPrefixOf kw line - --- | @walkFile@ returns empty means that there is no solution produced --- for given specification (needs to be checked) - -walkFile :: T.Text -> [T.Text] -walkFile text = dropWhile (not . startsWith keyword) ls - where ls = T.lines text - --- | Lines from the solution in the log file (without trailing characters) -handleLog :: T.Text -> [[T.Text]] -handleLog text = - let toBeParsed = walkFile text - sols = T.splitOn (T.pack delim) (T.unlines (tail toBeParsed)) - noTrailing = map (filter (not . T.null)) (map (map T.strip) (map T.lines sols)) - in noTrailing - - -delim :: String -delim = "*********************************************" - - -createLogs :: IO [(FilePath, ExitCode, T.Text)] -createLogs = do - files <- listDirectory synthesisTestsDir - let testFiles = filter (\x -> takeExtension x == ".hs") files - res <- mapM runLiquid testFiles - let (ecs, ts) = unzip res - fs = map dropExtension testFiles - return (zip3 fs ecs ts) - -runLiquid :: FilePath -> IO (ExitCode, T.Text) -runLiquid tgt = do - let inFile = synthesisTestsDir tgt - log = logDir (dropExtension tgt <.> ".log") - -- use `liquid` if its on the path, otherwise use stack to call it - bin <- maybe "stack exec -- liquid" - ( <> " --ghc-option=-hide-package=base" - <> " --ghc-option=-hide-package=containers" - ) <$> findExecutable "liquid" - withFile log WriteMode $ \h -> do - (_, _, _, ph) <- createProcess $ (shell (bin ++ ' ' : inFile)) { std_out = UseHandle h, std_err = UseHandle h } - exitCode <- waitForProcess ph - (exitCode, ) <$> T.readFile log - - -getSolutions :: FilePath -> IO T.Text -getSolutions tgt = do - let file = outputsDir tgt - T.readFile file - -mkTgt :: FilePath -> FilePath -mkTgt t = addExtension t ".hs" - - - --- | Get solution from outputs line by line in order to compare -lineFile :: T.Text -> T.Text -> [T.Text] -lineFile progName file = - dropWhile (\x -> not (startsWith (progName `T.append` (T.pack " ")) x) || - startsWith (progName `T.append` (T.pack " ::")) x) (T.lines file) - -clean :: [T.Text] -> [T.Text] -clean ls = filter (not . T.null) (map T.strip ls) - -processAnswers :: [(FilePath, T.Text, [[T.Text]])] -> [(FilePath, [[T.Text]], [T.Text])] -processAnswers = map processAnswer - -processAnswer :: (FilePath, T.Text, [[T.Text]]) -> (FilePath, [[T.Text]], [T.Text]) -processAnswer (fp, prog, ts) = - let file = unsafePerformIO (getSolutions (mkTgt fp)) - fileLines = lineFile prog file - cleanLines = clean fileLines - in (fp, ts, cleanLines) - -compareLines :: [T.Text] -> [T.Text] -> Bool -compareLines [] [] = True -compareLines (t:ts) (l:ls) = t == l && compareLines ts ls -compareLines _ _ = False - -buildTestCase :: (FilePath, [[T.Text]], [T.Text]) -> TestTree -buildTestCase (fp, ls, ts) - = testCase - fp - ((foldr (\l b -> compareLines ts l || b) False ls) @?= True) - -tests :: [(FilePath, T.Text, [[T.Text]])] -> TestTree -tests inputs = - let answers = processAnswers inputs - units = map buildTestCase answers - in testGroup " Tests for synthesis " units - diff --git a/tests/synthesis/TODO/ListConcat.hs b/tests/synthesis/TODO/ListConcat.hs deleted file mode 100644 index 4bfc57dc48..0000000000 --- a/tests/synthesis/TODO/ListConcat.hs +++ /dev/null @@ -1,30 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListConcat where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ measure length' @-} -{-@ length' :: [a] -> Nat @-} -length' :: [a] -> Int -length' [] = 0 -length' (x:xs) = 1 + length' xs - -{-@ measure sumLen @-} -{-@ sumLen :: [[a]] -> Nat @-} -sumLen :: [[a]] -> Int -sumLen [] = 0 -sumLen (x:xs) = length' x + sumLen xs - -{-@ append0 :: xs: [a] -> ys: [a] -> {v: [a] | length' v == length' xs + length' ys} @-} -append0 :: [a] -> [a] -> [a] -append0 [] ys = ys -append0 (x:xs) ys = x:append0 xs ys - -{-@ concat0 :: x: [[a]] -> { v: [a] | length' v == sumLen x } @-} -concat0 :: [[a]] -> [a] -concat0 = _goal --- concat0 x = --- case x of --- [] -> [] --- x3:x4 -> append0 x3 (concat0 x4) diff --git a/tests/synthesis/TODO/ListToBST.hs b/tests/synthesis/TODO/ListToBST.hs deleted file mode 100644 index d6b7ee1ce4..0000000000 --- a/tests/synthesis/TODO/ListToBST.hs +++ /dev/null @@ -1,44 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListToBST where - -import qualified Data.Set as S -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data BST [size] a = - Empty - | Node { x :: a, l :: BST { v: a | v < x }, r :: BST { v: a | x < v } } - @-} -data BST a = Empty | Node a (BST a) (BST a) - -{-@ measure size @-} -{-@ size :: BST a -> Nat @-} -size :: BST a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ measure bstElts @-} -{-@ bstElts :: BST a -> S.Set a @-} -bstElts :: Ord a => BST a -> S.Set a -bstElts Empty = S.empty -bstElts (Node x l r) = S.union (S.singleton x) (S.union (bstElts l) (bstElts r)) - -{-@ insert :: x: a -> t: BST a -> { v: BST a | bstElts v == S.union (S.singleton x) (bstElts t) } @-} -insert :: Ord a => a -> BST a -> BST a -insert x t = - case t of - Empty -> Node x Empty Empty - Node y l r -> - if x == y - then t - else if y <= x - then Node y l (insert x r) - else Node y (insert x l) r - -{-@ toBST :: xs: [a] -> { v: BST a | listElts xs == bstElts v } @-} -toBST :: Ord a => [a] -> BST a -toBST = _goal --- toBST xs = --- case xs of --- [] -> Empty --- x:xs' -> insert x (toBST xs') diff --git a/tests/synthesis/TODO/TreeToList.hs b/tests/synthesis/TODO/TreeToList.hs deleted file mode 100644 index 8aea9a9055..0000000000 --- a/tests/synthesis/TODO/TreeToList.hs +++ /dev/null @@ -1,42 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module TreeToList where - -import qualified Data.Set as S - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data Tree [size] a = - Empty - | Node { x:: a, l:: (Tree a), r:: (Tree a) } - @-} -data Tree a = Empty | Node a (Tree a) (Tree a) - -{-@ measure size @-} -{-@ size :: Tree a -> Nat @-} -size :: Tree a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ append' :: x: [a] -> y: [a] - -> { v: [a] | len v == len x + len y && - S.union (listElts x) (listElts y) == listElts v } - @-} -append' :: [a] -> [a] -> [a] -append' [] xs = xs -append' (y:ys) xs = y : append' ys xs - -{-@ measure treeElts @-} -{-@ treeElts :: Tree a -> Set a @-} -treeElts Empty = S.empty -treeElts (Node x l r) = S.union (S.singleton x) (S.union (treeElts l) (treeElts r)) - -{-@ toList :: x: Tree a - -> { v: [a] | len v == size x && listElts v == treeElts x} - @-} -toList :: Tree a -> [a] -toList = _goal --- toList t = --- case t of --- Empty -> [] --- Node x l r -> x : (append' (toList l) (toList r)) diff --git a/tests/synthesis/TODO/User.hs b/tests/synthesis/TODO/User.hs deleted file mode 100644 index 82cea989e6..0000000000 --- a/tests/synthesis/TODO/User.hs +++ /dev/null @@ -1,48 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module User where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ measure length' @-} -{-@ length' :: [a] -> Nat @-} -length' :: [a] -> Int -length' [] = 0 -length' (x:xs) = 1 + length' xs - -data Info = Info { sa :: Int, zc :: Int, loc :: Bool } - -data Address = Address { i :: Info, priv :: Bool } - -{-@ measure isPriv @-} -{-@ isPriv :: Address -> Bool @-} -isPriv :: Address -> Bool -isPriv (Address _ priv) = priv - -{-@ getPriv :: a:Address -> { v: Bool | v == isPriv a } @-} -getPriv :: Address -> Bool -getPriv a = isPriv a - -{-@ data AddressBook [size] = AddressBook { x :: [{v: Address | isPriv v}], y :: [{v: Address | not (isPriv v)}] } - @-} -data AddressBook = AddressBook [Address] [Address] - -{-@ measure size @-} -{-@ size :: AddressBook -> Nat @-} -size :: AddressBook -> Int -size (AddressBook bs ps) = length' bs + length' ps - -{-@ append :: xs: [a] -> ys: [a] -> { v: [a] | length' v == length' xs + length' ys } - @-} -append :: [a] -> [a] -> [a] -append [] ys = ys -append (x:xs) ys = x : append xs ys - -{-@ mergeAddressBooks :: a: AddressBook -> b: AddressBook -> {v: AddressBook | size v == size a + size b} @-} -mergeAddressBooks :: AddressBook -> AddressBook -> AddressBook -mergeAddressBooks = _goal --- mergeAddressBooks a b = --- case a of --- AddressBook x2 x3 -> --- case b of --- AddressBook x6 x7 -> AddressBook (append x2 x6) (append x3 x7) diff --git a/tests/synthesis/logs/.gitkeep b/tests/synthesis/logs/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/synthesis/static/Append.hs b/tests/synthesis/static/Append.hs deleted file mode 100644 index d04881d177..0000000000 --- a/tests/synthesis/static/Append.hs +++ /dev/null @@ -1,12 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Append where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ append :: xs: [a] -> ys: [a] -> { v: [a] | len v == len xs + len ys } @-} -append :: [a] -> [a] -> [a] -append x_S0 x_S1 = - case x_S0 of - [] -> x_S1 - (:) x_So x_Sp -> append x_Sp ((:) x_So x_S1) diff --git a/tests/synthesis/static/BSTFlatten.hs b/tests/synthesis/static/BSTFlatten.hs deleted file mode 100644 index 6f15ed7773..0000000000 --- a/tests/synthesis/static/BSTFlatten.hs +++ /dev/null @@ -1,74 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module BSTFlatten where - -import qualified Data.Set as S -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data BST [size] a = - Empty - | Node { x :: a, l :: BST { v: a | v < x }, r :: BST { v: a | x < v } } - @-} -data BST a = Empty | Node a (BST a) (BST a) - -{-@ measure size @-} -{-@ size :: BST a -> Nat @-} -size :: BST a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ measure bstElts @-} -{-@ bstElts :: BST a -> S.Set a @-} -bstElts :: Ord a => BST a -> S.Set a -bstElts Empty = S.empty -bstElts (Node x l r) = S.union (S.singleton x) (S.union (bstElts l) (bstElts r)) - -{-@ insert :: x: a -> t: BST a -> { v: BST a | bstElts v == S.union (S.singleton x) (bstElts t) } @-} -insert :: Ord a => a -> BST a -> BST a -insert x t = - case t of - Empty -> Node x Empty Empty - Node y l r -> - if x == y - then t - else if y <= x - then Node y l (insert x r) - else Node y (insert x l) r - -{-@ toBST :: xs: [a] -> { v: BST a | listElts xs == bstElts v } @-} -toBST :: Ord a => [a] -> BST a -toBST xs = - case xs of - [] -> Empty - x:xs' -> insert x (toBST xs') - -{-@ data IList [iLen] a = N | ICons { x0 :: a, xs0 :: IList { v: a | x0 < v } } @-} -data IList a = N | ICons a (IList a) - -{-@ measure iLen @-} -{-@ iLen :: IList a -> Nat @-} -iLen :: IList a -> Int -iLen N = 0 -iLen (ICons x xs) = 1 + iLen xs - -{-@ measure iElts @-} -{-@ iElts :: IList a -> S.Set a @-} -iElts N = S.empty -iElts (ICons x xs) = S.union (S.singleton x) (iElts xs) - -{-@ pivotAppend :: p: a -> xs: IList { v: a | v < p } -> ys: IList { v: a | v > p } - -> { v: IList a | iLen v == iLen xs + iLen ys + 1 && - iElts v == S.union (S.union (iElts xs) (iElts ys)) (S.singleton p) } - @-} -pivotAppend :: a -> IList a -> IList a -> IList a -pivotAppend p xs ys = - case xs of - N -> ICons p ys - ICons x5 x6 -> ICons x5 (pivotAppend p x6 ys) - -{-@ flatten :: t: BST a -> { v: IList a | iElts v == bstElts t } @-} -flatten :: BST a -> IList a -flatten x_S0 = - case x_S0 of - BSTFlatten.Empty -> N - BSTFlatten.Node x_S8 x_S9 x_Sa -> pivotAppend x_S8 (flatten x_S9) (flatten x_Sa) diff --git a/tests/synthesis/static/BSTSort.hs b/tests/synthesis/static/BSTSort.hs deleted file mode 100644 index 11e22e40c9..0000000000 --- a/tests/synthesis/static/BSTSort.hs +++ /dev/null @@ -1,82 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module BSTSort where - -import qualified Data.Set as S -import Language.Haskell.Liquid.Synthesize.Error - - -{-@ data BST [size] a = - Empty - | Node { x :: a, l :: BST { v: a | v < x }, r :: BST { v: a | x < v } } - @-} -data BST a = Empty | Node a (BST a) (BST a) - -{-@ measure size @-} -{-@ size :: BST a -> Nat @-} -size :: BST a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ measure bstElts @-} -{-@ bstElts :: BST a -> S.Set a @-} -bstElts :: Ord a => BST a -> S.Set a -bstElts Empty = S.empty -bstElts (Node x l r) = S.union (S.singleton x) (S.union (bstElts l) (bstElts r)) - -{-@ insert :: x: a -> t: BST a -> { v: BST a | bstElts v == S.union (S.singleton x) (bstElts t) } @-} -insert :: Ord a => a -> BST a -> BST a -insert x t = - case t of - Empty -> Node x Empty Empty - Node y l r -> - if x == y - then t - else if y <= x - then Node y l (insert x r) - else Node y (insert x l) r - -{-@ toBST :: xs: [a] -> { v: BST a | listElts xs == bstElts v } @-} -toBST :: Ord a => [a] -> BST a -toBST xs = - case xs of - [] -> Empty - x:xs' -> insert x (toBST xs') - -{-@ data IList [iLen] a = N | ICons { x0 :: a, xs0 :: IList { v: a | x0 < v } } @-} -data IList a = N | ICons a (IList a) - -{-@ measure iLen @-} -{-@ iLen :: IList a -> Nat @-} -iLen :: IList a -> Int -iLen N = 0 -iLen (ICons x xs) = 1 + iLen xs - -{-@ measure iElts @-} -{-@ iElts :: IList a -> S.Set a @-} -iElts N = S.empty -iElts (ICons x xs) = S.union (S.singleton x) (iElts xs) - -{-@ pivotAppend :: p: a -> xs: IList { v: a | v < p } -> ys: IList { v: a | v > p } - -> { v: IList a | iLen v == iLen xs + iLen ys + 1 && - iElts v == S.union (S.union (iElts xs) (iElts ys)) (S.singleton p) } - @-} -pivotAppend :: a -> IList a -> IList a -> IList a -pivotAppend p xs ys = - case xs of - N -> ICons p ys - ICons x5 x6 -> ICons x5 (pivotAppend p x6 ys) - -{-@ flatten :: t: BST a -> { v: IList a | iElts v == bstElts t } @-} -flatten :: BST a -> IList a -flatten t = - case t of - Empty -> N - Node x4 x5 x6 -> pivotAppend x4 (flatten x5) (flatten x6) - -{-@ sort' :: xs: [a] -> { v: IList a | iElts v == listElts xs } @-} -sort' :: Ord a => [a] -> IList a -sort' x_S1 = flatten (toBST x_S1) - - - diff --git a/tests/synthesis/static/BinHeapSingleton.hs b/tests/synthesis/static/BinHeapSingleton.hs deleted file mode 100644 index bde0275656..0000000000 --- a/tests/synthesis/static/BinHeapSingleton.hs +++ /dev/null @@ -1,24 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module BinHeapSingleton where - -import qualified Data.Set as S -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data Heap [size] a = Empty | Node { x :: a, l :: Heap { v: a | v > x }, r :: Heap { v: a | v > x } } @-} -data Heap a = Empty | Node a (Heap a) (Heap a) - -{-@ measure size @-} -{-@ size :: Heap a -> Nat @-} -size :: Heap a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ measure heapElts @-} -{-@ heapElts :: Heap a -> S.Set a @-} -heapElts Empty = S.empty -heapElts (Node x l r) = S.union (S.singleton x) (S.union (heapElts l) (heapElts r)) - -{-@ singleton :: x: a -> { v: Heap a | heapElts v == S.singleton x } @-} -singleton :: a -> Heap a -singleton x_S0 = Node x_S0 Empty Empty \ No newline at end of file diff --git a/tests/synthesis/static/Data.hs b/tests/synthesis/static/Data.hs deleted file mode 100644 index d44f5c7e76..0000000000 --- a/tests/synthesis/static/Data.hs +++ /dev/null @@ -1,17 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Data where - -import Language.Haskell.Liquid.Synthesize.Error - -data L a = C a (L a) | N - -{-@ measure length' @-} -{-@ length' :: L a -> Nat @-} -length' :: L a -> Int -length' N = 0 -length' (C _ xs) = 1 + length' xs - -{-@ ex :: x: L a -> { v: (L a) | length' v == length' x } @-} -ex :: L a -> L a -ex x_S0 = x_S0 \ No newline at end of file diff --git a/tests/synthesis/static/Data2.hs b/tests/synthesis/static/Data2.hs deleted file mode 100644 index dd24172064..0000000000 --- a/tests/synthesis/static/Data2.hs +++ /dev/null @@ -1,23 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Data2 where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data L [length'] a = N | C {x :: a, xs :: (L a)} @-} -data L a = C a (L a) | N - -{-@ measure length' @-} -{-@ length' :: L a -> Nat @-} -length' :: L a -> Int -length' N = 0 -length' (C _ xs) = 1 + length' xs - -{-@ appendL :: x: L a -> y: L a -> { v: L a | length' v == length' x + length' y } @-} -appendL N y = y -appendL (C x xs) y = C x (appendL xs y) - -{-@ ex1 :: xs:(L a) -> {v: (L a) | 2 * length' xs == length' v} @-} -ex1 :: L a -> L a -ex1 x_S0 = appendL x_S0 x_S0 - diff --git a/tests/synthesis/static/Data3.hs b/tests/synthesis/static/Data3.hs deleted file mode 100644 index 596480c7c3..0000000000 --- a/tests/synthesis/static/Data3.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Data3 where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data L [length'] a = N | C {x :: a, xs :: (L a)} @-} -data L a = C a (L a) | N - -{-@ measure length' @-} -{-@ length' :: L a -> Nat @-} -length' :: L a -> Int -length' N = 0 -length' (C _ xs) = 1 + length' xs - - -{-@ appendL :: x: L a -> y: L a -> - { v: L a | length' v == length' x + length' y } - @-} -appendL N y = y -appendL (C x xs) y = C x (appendL xs y) - -{-@ append :: xs: L a -> ys: L a -> - { v: L a | length' v == length' xs + length' ys } - @-} -append :: L a -> L a -> L a -append x_S0 x_S1 = appendL x_S0 x_S1 diff --git a/tests/synthesis/static/IntSimple.hs b/tests/synthesis/static/IntSimple.hs deleted file mode 100644 index af161807c8..0000000000 --- a/tests/synthesis/static/IntSimple.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module IntSimple where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ plus :: x: Int -> y: Int -> { v: Int | v == x + y } @-} -plus :: Int -> Int -> Int -plus x y = x + y - -{-@ one :: { v: Int | v == 1} @-} -one :: Int -one = 1 - -{-@ zero :: { v: Int | v == 0 } @-} -zero :: Int -zero = 0 - -{-@ measure length' @-} -{-@ length' :: [a] -> Nat @-} -length' :: [a] -> Int -length' [] = 0 -length' (x:xs) = 1 + length' xs - -{-@ next :: x: Int -> { v: Int | v == x + 1 } @-} -next :: Int -> Int -next x_S0 = plus one x_S0 diff --git a/tests/synthesis/static/ListId.hs b/tests/synthesis/static/ListId.hs deleted file mode 100644 index c1f40944b0..0000000000 --- a/tests/synthesis/static/ListId.hs +++ /dev/null @@ -1,7 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ listId :: xs:[a] -> {v:[a] | len xs == len v} @-} -listId :: [a] -> [a] -listId x_S0 = x_S0 diff --git a/tests/synthesis/static/ListInsertSort.hs b/tests/synthesis/static/ListInsertSort.hs deleted file mode 100644 index f2fe7745d4..0000000000 --- a/tests/synthesis/static/ListInsertSort.hs +++ /dev/null @@ -1,36 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListInsertSort where - -import qualified Data.Set as S - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data IList a = N | C { x :: a, xs :: (IList { v: a | x <= v}) } @-} -data IList a = N | C a (IList a) - -{-@ measure iLen @-} -{-@ iLen :: IList a -> Nat @-} -iLen :: IList a -> Int -iLen N = 0 -iLen (C x xs) = 1 + iLen xs - -{-@ measure iElems @-} -{-@ iElems :: IList a -> S.Set a @-} -iElems :: Ord a => IList a -> S.Set a -iElems N = S.empty -iElems (C x xs) = S.union (S.singleton x) (iElems xs) - -{-@ insert :: x: a -> xs: IList a -> { v: IList a | iElems v == S.union (S.singleton x) (iElems xs) } - @-} -insert :: Ord a => a -> IList a -> IList a -insert x N - = C x N -insert x (C x0 xs) - = if x <= x0 then C x (C x0 xs) else C x0 (insert x xs) - -{-@ insertSort :: xs: [a] -> { v: IList a | iElems v == listElts xs } @-} -insertSort x_S1 = - case x_S1 of - [] -> N - (:) x_Sc x_Sd -> insert x_Sc (insertSort x_Sd) diff --git a/tests/synthesis/static/ListNull.hs b/tests/synthesis/static/ListNull.hs deleted file mode 100644 index 582c1df7e2..0000000000 --- a/tests/synthesis/static/ListNull.hs +++ /dev/null @@ -1,20 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListNull where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ true :: { v: Bool | v } @-} -true :: Bool -true = True - -{-@ false :: {v: Bool | not v} @-} -false :: Bool -false = False - -{-@ isNull :: xs: [a] -> { v: Bool | (len xs == 0) <=> v } @-} -isNull :: [a] -> Bool -isNull x_S0 = - case x_S0 of - [] -> true - (:) x_Sc x_Sd -> false \ No newline at end of file diff --git a/tests/synthesis/static/ListZip.hs b/tests/synthesis/static/ListZip.hs deleted file mode 100644 index 76941a055f..0000000000 --- a/tests/synthesis/static/ListZip.hs +++ /dev/null @@ -1,15 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListZip where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ zip' :: xs: [a] -> {ys:[b] | len ys == len xs} -> {v:[(a, b)] | len v == len xs} @-} -zip' :: [a] -> [b] -> [(a, b)] -zip' x_S0 x_S1 = - case x_S0 of - [] -> [], b) - (:) x_Sl x_Sm -> - case x_S1 of - [] -> error " Dead code! " - (:) x_S14 x_S15 -> (:), b) (x_Sl, x_S14) (zip' x_Sm x_S15) \ No newline at end of file diff --git a/tests/synthesis/static/ListZipWith.hs b/tests/synthesis/static/ListZipWith.hs deleted file mode 100644 index 504cbfdb00..0000000000 --- a/tests/synthesis/static/ListZipWith.hs +++ /dev/null @@ -1,19 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListZipWith where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ zipWith' :: f: (a -> b -> c) - -> xs: [a] - -> { ys: [b] | len ys == len xs} - -> {v: [c] | len v == len xs } -@-} -zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c] -zipWith' x_S0 x_S1 x_S2 = - case x_S1 of - [] -> [] - (:) x_St x_Su -> - case x_S2 of - [] -> error " Dead code! " - (:) x_S1d x_S1e -> (:) (x_S0 x_St x_S1d) (zipWith' x_S0 x_Su x_S1e) \ No newline at end of file diff --git a/tests/synthesis/static/NestedListSimple.hs b/tests/synthesis/static/NestedListSimple.hs deleted file mode 100644 index f0666614d7..0000000000 --- a/tests/synthesis/static/NestedListSimple.hs +++ /dev/null @@ -1,9 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module NestedListSimple where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ foo :: { v: [[a]] | len v == 2} @-} -foo :: [[a]] -foo = (:) [] ((:) [] []) diff --git a/tests/synthesis/static/Stutter.hs b/tests/synthesis/static/Stutter.hs deleted file mode 100644 index 896009090e..0000000000 --- a/tests/synthesis/static/Stutter.hs +++ /dev/null @@ -1,11 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -import Language.Haskell.Liquid.Synthesize.Error - - -{-@ stutter :: xs:[a] -> {v:[a] | 2 * len xs == len v} @-} -stutter :: [a] -> [a] -stutter x_S0 = - case x_S0 of - [] -> [] - (:) x_Sa x_Sb -> (:) x_Sa ((:) x_Sa (stutter x_Sb)) \ No newline at end of file diff --git a/tests/synthesis/static/TreeOne.hs b/tests/synthesis/static/TreeOne.hs deleted file mode 100644 index 405462bb6b..0000000000 --- a/tests/synthesis/static/TreeOne.hs +++ /dev/null @@ -1,21 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module TreeOne where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data Tree [size] a = - Empty - | Node { x:: a, l:: (Tree a), r:: (Tree a) } - @-} -data Tree a = Empty | Node a (Tree a) (Tree a) - -{-@ measure size @-} -{-@ size :: Tree a -> Nat @-} -size :: Tree a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ one :: x: a -> {v: Tree a | size v == 1} @-} -one :: a -> Tree a -one x_S0 = Node x_S0 Empty Empty \ No newline at end of file diff --git a/tests/synthesis/static/TupleListSimple.hs b/tests/synthesis/static/TupleListSimple.hs deleted file mode 100644 index b55dfd468f..0000000000 --- a/tests/synthesis/static/TupleListSimple.hs +++ /dev/null @@ -1,9 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module TupleListSimple where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ foo :: x: a -> ( { v: [a] | len v == 1 }, { v: [a] | len v == 0 } ) @-} -foo :: a -> ([a], [a]) -foo x_S0 = ((:) x_S0 [], []) \ No newline at end of file diff --git a/tests/synthesis/static/map.hs b/tests/synthesis/static/map.hs deleted file mode 100644 index 840a10e5fc..0000000000 --- a/tests/synthesis/static/map.hs +++ /dev/null @@ -1,12 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Map where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ myMap :: (a -> b) -> xs:[a] -> {v:[b] | len v == len xs} @-} -myMap :: (a -> b) -> [a] -> [b] -myMap x_S0 x_S1 = - case x_S1 of - [] -> [] - (:) x_Sf x_Sg -> (:) (x_S0 x_Sf) (myMap x_S0 x_Sg) \ No newline at end of file diff --git a/tests/synthesis/static/single-elem-list.hs b/tests/synthesis/static/single-elem-list.hs deleted file mode 100644 index 9305951da1..0000000000 --- a/tests/synthesis/static/single-elem-list.hs +++ /dev/null @@ -1,8 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -import Language.Haskell.Liquid.Synthesize.Error - --- This is to test `nilDataCons`. -{-@ oneElem :: xs:a -> {v:[a] | len v == 1} @-} -oneElem :: a -> [a] -oneElem x_S0 = (:) x_S0 [] diff --git a/tests/synthesis/tests/Append.hs b/tests/synthesis/tests/Append.hs deleted file mode 100644 index 2dbeb090e1..0000000000 --- a/tests/synthesis/tests/Append.hs +++ /dev/null @@ -1,9 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Append where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ append :: xs: [a] -> ys: [a] -> { v: [a] | len v == len xs + len ys } @-} -append :: [a] -> [a] -> [a] -append = _goal diff --git a/tests/synthesis/tests/BSTFlatten.hs b/tests/synthesis/tests/BSTFlatten.hs deleted file mode 100644 index 5c2c4f1c45..0000000000 --- a/tests/synthesis/tests/BSTFlatten.hs +++ /dev/null @@ -1,71 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module BSTFlatten where - -import qualified Data.Set as S -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data BST [size] a = - Empty - | Node { x :: a, l :: BST { v: a | v < x }, r :: BST { v: a | x < v } } - @-} -data BST a = Empty | Node a (BST a) (BST a) - -{-@ measure size @-} -{-@ size :: BST a -> Nat @-} -size :: BST a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ measure bstElts @-} -{-@ bstElts :: BST a -> S.Set a @-} -bstElts :: Ord a => BST a -> S.Set a -bstElts Empty = S.empty -bstElts (Node x l r) = S.union (S.singleton x) (S.union (bstElts l) (bstElts r)) - -{-@ insert :: x: a -> t: BST a -> { v: BST a | bstElts v == S.union (S.singleton x) (bstElts t) } @-} -insert :: Ord a => a -> BST a -> BST a -insert x t = - case t of - Empty -> Node x Empty Empty - Node y l r -> - if x == y - then t - else if y <= x - then Node y l (insert x r) - else Node y (insert x l) r - -{-@ toBST :: xs: [a] -> { v: BST a | listElts xs == bstElts v } @-} -toBST :: Ord a => [a] -> BST a -toBST xs = - case xs of - [] -> Empty - x:xs' -> insert x (toBST xs') - -{-@ data IList [iLen] a = N | ICons { x0 :: a, xs0 :: IList { v: a | x0 < v } } @-} -data IList a = N | ICons a (IList a) - -{-@ measure iLen @-} -{-@ iLen :: IList a -> Nat @-} -iLen :: IList a -> Int -iLen N = 0 -iLen (ICons x xs) = 1 + iLen xs - -{-@ measure iElts @-} -{-@ iElts :: IList a -> S.Set a @-} -iElts N = S.empty -iElts (ICons x xs) = S.union (S.singleton x) (iElts xs) - -{-@ pivotAppend :: p: a -> xs: IList { v: a | v < p } -> ys: IList { v: a | v > p } - -> { v: IList a | iLen v == iLen xs + iLen ys + 1 && - iElts v == S.union (S.union (iElts xs) (iElts ys)) (S.singleton p) } - @-} -pivotAppend :: a -> IList a -> IList a -> IList a -pivotAppend p xs ys = - case xs of - N -> ICons p ys - ICons x5 x6 -> ICons x5 (pivotAppend p x6 ys) - -{-@ flatten :: t: BST a -> { v: IList a | iElts v == bstElts t } @-} -flatten :: BST a -> IList a -flatten = _goal diff --git a/tests/synthesis/tests/BSTSort.hs b/tests/synthesis/tests/BSTSort.hs deleted file mode 100644 index a236a59b0b..0000000000 --- a/tests/synthesis/tests/BSTSort.hs +++ /dev/null @@ -1,83 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module BSTSort where - -import qualified Data.Set as S -import Language.Haskell.Liquid.Synthesize.Error - - -{-@ data BST [size] a = - Empty - | Node { x :: a, l :: BST { v: a | v < x }, r :: BST { v: a | x < v } } - @-} -data BST a = Empty | Node a (BST a) (BST a) - -{-@ measure size @-} -{-@ size :: BST a -> Nat @-} -size :: BST a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ measure bstElts @-} -{-@ bstElts :: BST a -> S.Set a @-} -bstElts :: Ord a => BST a -> S.Set a -bstElts Empty = S.empty -bstElts (Node x l r) = S.union (S.singleton x) (S.union (bstElts l) (bstElts r)) - -{-@ insert :: x: a -> t: BST a -> { v: BST a | bstElts v == S.union (S.singleton x) (bstElts t) } @-} -insert :: Ord a => a -> BST a -> BST a -insert x t = - case t of - Empty -> Node x Empty Empty - Node y l r -> - if x == y - then t - else if y <= x - then Node y l (insert x r) - else Node y (insert x l) r - -{-@ toBST :: xs: [a] -> { v: BST a | listElts xs == bstElts v } @-} -toBST :: Ord a => [a] -> BST a -toBST xs = - case xs of - [] -> Empty - x:xs' -> insert x (toBST xs') - -{-@ data IList [iLen] a = N | ICons { x0 :: a, xs0 :: IList { v: a | x0 < v } } @-} -data IList a = N | ICons a (IList a) - -{-@ measure iLen @-} -{-@ iLen :: IList a -> Nat @-} -iLen :: IList a -> Int -iLen N = 0 -iLen (ICons x xs) = 1 + iLen xs - -{-@ measure iElts @-} -{-@ iElts :: IList a -> S.Set a @-} -iElts N = S.empty -iElts (ICons x xs) = S.union (S.singleton x) (iElts xs) - -{-@ pivotAppend :: p: a -> xs: IList { v: a | v < p } -> ys: IList { v: a | v > p } - -> { v: IList a | iLen v == iLen xs + iLen ys + 1 && - iElts v == S.union (S.union (iElts xs) (iElts ys)) (S.singleton p) } - @-} -pivotAppend :: a -> IList a -> IList a -> IList a -pivotAppend p xs ys = - case xs of - N -> ICons p ys - ICons x5 x6 -> ICons x5 (pivotAppend p x6 ys) - -{-@ flatten :: t: BST a -> { v: IList a | iElts v == bstElts t } @-} -flatten :: BST a -> IList a -flatten t = - case t of - Empty -> N - Node x4 x5 x6 -> pivotAppend x4 (flatten x5) (flatten x6) - -{-@ sort' :: xs: [a] -> { v: IList a | iElts v == listElts xs } @-} -sort' :: Ord a => [a] -> IList a -sort' = _goal --- sort' xs = flatten (toBST xs) - - - diff --git a/tests/synthesis/tests/BinHeapSingleton.hs b/tests/synthesis/tests/BinHeapSingleton.hs deleted file mode 100644 index cc4c3a7a22..0000000000 --- a/tests/synthesis/tests/BinHeapSingleton.hs +++ /dev/null @@ -1,25 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module BinHeapSingleton where - -import qualified Data.Set as S -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data Heap [size] a = Empty | Node { x :: a, l :: Heap { v: a | v > x }, r :: Heap { v: a | v > x } } @-} -data Heap a = Empty | Node a (Heap a) (Heap a) - -{-@ measure size @-} -{-@ size :: Heap a -> Nat @-} -size :: Heap a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ measure heapElts @-} -{-@ heapElts :: Heap a -> S.Set a @-} -heapElts Empty = S.empty -heapElts (Node x l r) = S.union (S.singleton x) (S.union (heapElts l) (heapElts r)) - -{-@ singleton :: x: a -> { v: Heap a | heapElts v == S.singleton x } @-} -singleton :: a -> Heap a -singleton = _goal --- singleton x = Node x Empty Empty \ No newline at end of file diff --git a/tests/synthesis/tests/Data.hs b/tests/synthesis/tests/Data.hs deleted file mode 100644 index c2a20c0bdc..0000000000 --- a/tests/synthesis/tests/Data.hs +++ /dev/null @@ -1,17 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Data where - -import Language.Haskell.Liquid.Synthesize.Error - -data L a = C a (L a) | N - -{-@ measure length' @-} -{-@ length' :: L a -> Nat @-} -length' :: L a -> Int -length' N = 0 -length' (C _ xs) = 1 + length' xs - -{-@ ex :: x: L a -> { v: (L a) | length' v == length' x } @-} -ex :: L a -> L a -ex = _hole \ No newline at end of file diff --git a/tests/synthesis/tests/Data2.hs b/tests/synthesis/tests/Data2.hs deleted file mode 100644 index 161424a79c..0000000000 --- a/tests/synthesis/tests/Data2.hs +++ /dev/null @@ -1,23 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Data2 where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data L [length'] a = N | C {x :: a, xs :: (L a)} @-} -data L a = C a (L a) | N - -{-@ measure length' @-} -{-@ length' :: L a -> Nat @-} -length' :: L a -> Int -length' N = 0 -length' (C _ xs) = 1 + length' xs - -{-@ appendL :: x: L a -> y: L a -> { v: L a | length' v == length' x + length' y } @-} -appendL N y = y -appendL (C x xs) y = C x (appendL xs y) - -{-@ ex1 :: xs:(L a) -> {v: (L a) | 2 * length' xs == length' v} @-} -ex1 :: L a -> L a -ex1 = _hole - diff --git a/tests/synthesis/tests/Data3.hs b/tests/synthesis/tests/Data3.hs deleted file mode 100644 index e083560a27..0000000000 --- a/tests/synthesis/tests/Data3.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Data3 where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data L [length'] a = N | C {x :: a, xs :: (L a)} @-} -data L a = C a (L a) | N - -{-@ measure length' @-} -{-@ length' :: L a -> Nat @-} -length' :: L a -> Int -length' N = 0 -length' (C _ xs) = 1 + length' xs - - -{-@ appendL :: x: L a -> y: L a -> - { v: L a | length' v == length' x + length' y } - @-} -appendL N y = y -appendL (C x xs) y = C x (appendL xs y) - -{-@ append :: xs: L a -> ys: L a -> - { v: L a | length' v == length' xs + length' ys } - @-} -append :: L a -> L a -> L a -append = _goal diff --git a/tests/synthesis/tests/IntSimple.hs b/tests/synthesis/tests/IntSimple.hs deleted file mode 100644 index d68b719040..0000000000 --- a/tests/synthesis/tests/IntSimple.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module IntSimple where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ plus :: x: Int -> y: Int -> { v: Int | v == x + y } @-} -plus :: Int -> Int -> Int -plus x y = x + y - -{-@ one :: { v: Int | v == 1} @-} -one :: Int -one = 1 - -{-@ zero :: { v: Int | v == 0 } @-} -zero :: Int -zero = 0 - -{-@ measure length' @-} -{-@ length' :: [a] -> Nat @-} -length' :: [a] -> Int -length' [] = 0 -length' (x:xs) = 1 + length' xs - -{-@ next :: x: Int -> { v: Int | v == x + 1 } @-} -next :: Int -> Int -next = _goal diff --git a/tests/synthesis/tests/ListId.hs b/tests/synthesis/tests/ListId.hs deleted file mode 100644 index 69c41d16b4..0000000000 --- a/tests/synthesis/tests/ListId.hs +++ /dev/null @@ -1,7 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ listId :: xs:[a] -> {v:[a] | len xs == len v} @-} -listId :: [a] -> [a] -listId = _listId diff --git a/tests/synthesis/tests/ListInsertSort.hs b/tests/synthesis/tests/ListInsertSort.hs deleted file mode 100644 index 884d6366a6..0000000000 --- a/tests/synthesis/tests/ListInsertSort.hs +++ /dev/null @@ -1,38 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListInsertSort where - -import qualified Data.Set as S - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data IList a = N | C { x :: a, xs :: (IList { v: a | x <= v}) } @-} -data IList a = N | C a (IList a) - -{-@ measure iLen @-} -{-@ iLen :: IList a -> Nat @-} -iLen :: IList a -> Int -iLen N = 0 -iLen (C x xs) = 1 + iLen xs - -{-@ measure iElems @-} -{-@ iElems :: IList a -> S.Set a @-} -iElems :: Ord a => IList a -> S.Set a -iElems N = S.empty -iElems (C x xs) = S.union (S.singleton x) (iElems xs) - -{-@ insert :: x: a -> xs: IList a -> { v: IList a | iElems v == S.union (S.singleton x) (iElems xs) } - @-} -insert :: Ord a => a -> IList a -> IList a -insert x N - = C x N -insert x (C x0 xs) - = if x <= x0 then C x (C x0 xs) else C x0 (insert x xs) - -{-@ insertSort :: xs: [a] -> { v: IList a | iElems v == listElts xs } @-} -insertSort :: Ord a => [a] -> IList a -insertSort = _goal --- insertSort xs = --- case xs of --- [] -> N --- x3:x4 -> insert x3 (insertSort x4) diff --git a/tests/synthesis/tests/ListNull.hs b/tests/synthesis/tests/ListNull.hs deleted file mode 100644 index 52091a83b7..0000000000 --- a/tests/synthesis/tests/ListNull.hs +++ /dev/null @@ -1,19 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListNull where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ true :: { v: Bool | v } @-} -true :: Bool -true = True - -{-@ false :: {v: Bool | not v} @-} -false :: Bool -false = False - -{-@ isNull :: xs: [a] -> { v: Bool | (len xs == 0) <=> v } @-} -isNull :: [a] -> Bool -isNull = _goal --- isNull [] = true --- isNull _ = false diff --git a/tests/synthesis/tests/ListZip.hs b/tests/synthesis/tests/ListZip.hs deleted file mode 100644 index 659e8f37c3..0000000000 --- a/tests/synthesis/tests/ListZip.hs +++ /dev/null @@ -1,18 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListZip where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ zip' :: xs: [a] -> {ys:[b] | len ys == len xs} -> {v:[(a, b)] | len v == len xs} @-} -zip' :: [a] -> [b] -> [(a, b)] -zip' = _goal - --- zip' xs ys = --- case xs of --- [] -> case ys of --- [] -> [] --- (x1:x2) -> error " len mismatch " --- x0:xs0 -> case ys of --- [] -> error " len mismatch " --- (y0:ys0) -> (x0, y0) : zip' xs0 ys0 diff --git a/tests/synthesis/tests/ListZipWith.hs b/tests/synthesis/tests/ListZipWith.hs deleted file mode 100644 index bbb6eebedb..0000000000 --- a/tests/synthesis/tests/ListZipWith.hs +++ /dev/null @@ -1,20 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module ListZipWith where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ zipWith' :: f: (a -> b -> c) - -> xs: [a] - -> { ys: [b] | len ys == len xs} - -> {v: [c] | len v == len xs } -@-} -zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c] -zipWith' = _goal --- zipWith' f xs ys = --- case xs of --- [] -> [] --- x3 : x4 -> --- case ys of --- [] -> error "error" --- x7 : x8 -> (f x3 x7) : (zipWith' x f x4 x8) \ No newline at end of file diff --git a/tests/synthesis/tests/NestedListSimple.hs b/tests/synthesis/tests/NestedListSimple.hs deleted file mode 100644 index 70344b3295..0000000000 --- a/tests/synthesis/tests/NestedListSimple.hs +++ /dev/null @@ -1,9 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module NestedListSimple where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ foo :: { v: [[a]] | len v == 2} @-} -foo :: [[a]] -foo = _goal diff --git a/tests/synthesis/tests/Stutter.hs b/tests/synthesis/tests/Stutter.hs deleted file mode 100644 index a51c6be955..0000000000 --- a/tests/synthesis/tests/Stutter.hs +++ /dev/null @@ -1,11 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -import Language.Haskell.Liquid.Synthesize.Error - - -{-@ stutter :: xs:[a] -> {v:[a] | 2 * len xs == len v} @-} -stutter :: [a] -> [a] -stutter = _x - --- stutter [] = [] --- stutter (x:xs) = x:x:stutter xs diff --git a/tests/synthesis/tests/TreeOne.hs b/tests/synthesis/tests/TreeOne.hs deleted file mode 100644 index f86c19fc85..0000000000 --- a/tests/synthesis/tests/TreeOne.hs +++ /dev/null @@ -1,21 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module TreeOne where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ data Tree [size] a = - Empty - | Node { x:: a, l:: (Tree a), r:: (Tree a) } - @-} -data Tree a = Empty | Node a (Tree a) (Tree a) - -{-@ measure size @-} -{-@ size :: Tree a -> Nat @-} -size :: Tree a -> Int -size Empty = 0 -size (Node x l r) = 1 + size l + size r - -{-@ one :: x: a -> {v: Tree a | size v == 1} @-} -one :: a -> Tree a -one = _goal \ No newline at end of file diff --git a/tests/synthesis/tests/TupleListSimple.hs b/tests/synthesis/tests/TupleListSimple.hs deleted file mode 100644 index 60d7528652..0000000000 --- a/tests/synthesis/tests/TupleListSimple.hs +++ /dev/null @@ -1,9 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module TupleListSimple where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ foo :: x: a -> ( { v: [a] | len v == 1 }, { v: [a] | len v == 0 } ) @-} -foo :: a -> ([a], [a]) -foo = _goal diff --git a/tests/synthesis/tests/map.hs b/tests/synthesis/tests/map.hs deleted file mode 100644 index dd788ae920..0000000000 --- a/tests/synthesis/tests/map.hs +++ /dev/null @@ -1,11 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -module Map where - -import Language.Haskell.Liquid.Synthesize.Error - -{-@ myMap :: (a -> b) -> xs:[a] -> {v:[b] | len v == len xs} @-} -myMap :: (a -> b) -> [a] -> [b] -myMap = _map --- map f [] = [] --- map f (x:xs) = f x : map f xs \ No newline at end of file diff --git a/tests/synthesis/tests/single-elem-list.hs b/tests/synthesis/tests/single-elem-list.hs deleted file mode 100644 index fd9c49a5fa..0000000000 --- a/tests/synthesis/tests/single-elem-list.hs +++ /dev/null @@ -1,8 +0,0 @@ -{-@ LIQUID "--typed-holes" @-} - -import Language.Haskell.Liquid.Synthesize.Error - --- This is to test `nilDataCons`. -{-@ oneElem :: xs:a -> {v:[a] | len v == 1} @-} -oneElem :: a -> [a] -oneElem = _oneElem From 7356058ea6760596c146ee537f0fae1245c8b106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Wed, 8 Feb 2023 20:28:14 -0300 Subject: [PATCH 122/219] Update liquid-fixpoint --- liquid-fixpoint | 2 +- stack.yaml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index dd58da1edd..0d08484369 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit dd58da1edd9560ed24d65ea1497248e207e7ee0c +Subproject commit 0d08484369589bc92b9f3817c1a7e415ebe66431 diff --git a/stack.yaml b/stack.yaml index fc10f525bf..c87d6bc063 100644 --- a/stack.yaml +++ b/stack.yaml @@ -26,6 +26,8 @@ packages: extra-deps: - hashable-1.3.5.0 - rest-rewrite-0.4.0 +- smtlib-backends-0.3 +- smtlib-backends-process-0.3 - git: https://github.com/qnikst/ghc-timings-report commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 # for tests From 815085bd4d50309f6089306fb4b5484b3fde6847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= Date: Thu, 9 Feb 2023 09:01:12 -0300 Subject: [PATCH 123/219] Update lf to v9.0.2 --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 11a773a08e..a45f8fe9f6 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 11a773a08e66cea13d8ddbf203ca32bd5cea97b2 +Subproject commit a45f8fe9f6ac2533228f9149926bf884a3525945 From 19f9ed1a4073032b4ee861435df57c60bd61c470 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Thu, 16 Feb 2023 14:43:38 +1300 Subject: [PATCH 124/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Qualifier --- .../Haskell/Liquid/Constraint/Qualifier.hs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Qualifier.hs b/src/Language/Haskell/Liquid/Constraint/Qualifier.hs index 6a8d264e94..e343bafebf 100644 --- a/src/Language/Haskell/Liquid/Constraint/Qualifier.hs +++ b/src/Language/Haskell/Liquid/Constraint/Qualifier.hs @@ -2,8 +2,6 @@ {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE FlexibleContexts #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Constraint.Qualifier ( giQuals , useSpcQuals @@ -172,8 +170,8 @@ refTypeQuals lEnv l tce t0 = go emptySEnv t0 go _ _ = [] goRefs c g rs = concat $ zipWith (goRef g) rs (rTyConPVs c) goRef _ (RProp _ (RHole _)) _ = [] - goRef g (RProp s t) _ = go (insertsSEnv g s) t - insertsSEnv = foldr (\(x, t) γ -> insertSEnv x (rTypeSort tce t) γ) + goRef g (RProp s t) _ = go (insertsSEnv' g s) t + insertsSEnv' = foldr (\(x, t) γ -> insertSEnv x (rTypeSort tce t) γ) refTopQuals :: (PPrint t, Reftable t, SubsTy RTyVar RSort t, Reftable (RTProp RTyCon RTyVar (UReft t))) @@ -184,8 +182,8 @@ refTopQuals :: (PPrint t, Reftable t, SubsTy RTyVar RSort t, Reftable (RTProp RT -> SEnv Sort -> RRType (UReft t) -> [Qualifier] -refTopQuals lEnv l tce t0 γ t - = [ mkQ v so pa | let (RR so (Reft (v, ra))) = rTypeSortedReft tce t +refTopQuals lEnv l tce t0 γ rrt + = [ mkQ' v so pa | let (RR so (Reft (v, ra))) = rTypeSortedReft tce rrt , pa <- conjuncts ra , not $ isHole pa , not $ isGradual pa @@ -193,12 +191,12 @@ refTopQuals lEnv l tce t0 γ t $ isNothing $ checkSorted (srcSpan l) (insertSEnv v so γ') pa ] ++ - [ mkP s e | let (MkUReft _ (Pr ps)) = fromMaybe (msg t) $ stripRTypeBase t + [ mkP s e | let (MkUReft _ (Pr ps)) = fromMaybe (msg rrt) $ stripRTypeBase rrt , p <- findPVar (ty_preds $ toRTypeRep t0) <$> ps , (s, _, e) <- pargs p ] where - mkQ = mkQual lEnv l t0 γ + mkQ' = mkQual lEnv l t0 γ mkP = mkPQual lEnv l tce t0 γ msg t = panic Nothing $ "Qualifier.refTopQuals: no typebase" ++ showpp t γ' = unionSEnv' γ lEnv From ac146965c58ac4e680eaf81f9f5e05ba3e506246 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Thu, 16 Feb 2023 14:43:54 +1300 Subject: [PATCH 125/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Split --- .../Haskell/Liquid/Constraint/Split.hs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Split.hs b/src/Language/Haskell/Liquid/Constraint/Split.hs index d81d38eca7..6d5b47841c 100644 --- a/src/Language/Haskell/Liquid/Constraint/Split.hs +++ b/src/Language/Haskell/Liquid/Constraint/Split.hs @@ -2,7 +2,6 @@ {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE FlexibleContexts #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -------------------------------------------------------------------------------- @@ -186,18 +185,18 @@ splitC allowTC (SubC γ t1 (RAllE x tx t2)) γ' <- γ += ("addAllBind 2", y, forallExprRefType γ tx) splitC allowTC (SubC γ' t1 (F.subst1 t2 (x, F.EVar y))) -splitC allowTC (SubC γ (RRTy env _ OCons t1) t2) - = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) γ xts +splitC allowTC (SubC cgenv (RRTy env _ OCons t1) t2) + = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) cgenv xts c1 <- splitC allowTC (SubC γ' t1' t2') - c2 <- splitC allowTC (SubC γ t1 t2 ) + c2 <- splitC allowTC (SubC cgenv t1 t2 ) return $ c1 ++ c2 where (xts, t1', t2') = envToSub env -splitC allowTC (SubC γ (RRTy e r o t1) t2) - = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) γ e +splitC allowTC (SubC cgenv (RRTy e r o t1) t2) + = do γ' <- foldM (\γ (x, t) -> γ `addSEnv` ("splitS", x,t)) cgenv e c1 <- splitC allowTC (SubR γ' o r) - c2 <- splitC allowTC (SubC γ t1 t2) + c2 <- splitC allowTC (SubC cgenv t1 t2) return $ c1 ++ c2 splitC allowTC (SubC γ (RFun x1 i1 t1 t1' r1) (RFun x2 i2 t2 t2' r2)) @@ -452,10 +451,10 @@ forallExprReft_ _ _ forallExprReftLookup :: CGEnv -> F.Symbol -> Maybe ([F.Symbol], [RFInfo], [SpecType], [RReft], SpecType) -forallExprReftLookup γ x = snap <$> F.lookupSEnv x (syenv γ) +forallExprReftLookup γ sym = snap <$> F.lookupSEnv sym (syenv γ) where - snap = mapFifth5 ignoreOblig . (\(_,(x,a,b,c),t)->(x,a,b,c,t)) . bkArrow . thd3 . bkUniv . lookup - lookup z = fromMaybe (panicUnbound γ z) (γ ?= F.symbol z) + snap = mapFifth5 ignoreOblig . (\(_,(x,a,b,c),t)->(x,a,b,c,t)) . bkArrow . thd3 . bkUniv . lookup' + lookup' z = fromMaybe (panicUnbound γ z) (γ ?= F.symbol z) -------------------------------------------------------------------------------- From e904c423bee74670792382643d9abcf790e72b09 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Thu, 16 Feb 2023 14:44:04 +1300 Subject: [PATCH 126/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.ToFixpoint --- .../Haskell/Liquid/Constraint/ToFixpoint.hs | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs b/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs index 0381c45f75..b11dff81fe 100644 --- a/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs +++ b/src/Language/Haskell/Liquid/Constraint/ToFixpoint.hs @@ -1,6 +1,5 @@ {-# LANGUAGE FlexibleContexts #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module Language.Haskell.Liquid.Constraint.ToFixpoint @@ -149,13 +148,13 @@ makeRewrites info sub = concatMap (makeRewriteOne tce) $ filter ((`S.member` rws canRewrite :: S.HashSet F.Symbol -> F.Expr -> F.Expr -> Bool -canRewrite freeVars from to = noFreeSyms && doesNotDiverge +canRewrite freeVars' from to = noFreeSyms && doesNotDiverge where - fromSyms = S.intersection freeVars (S.fromList $ F.syms from) - toSyms = S.intersection freeVars (S.fromList $ F.syms to) + fromSyms = S.intersection freeVars' (S.fromList $ F.syms from) + toSyms = S.intersection freeVars' (S.fromList $ F.syms to) noFreeSyms = S.null $ S.difference toSyms fromSyms - doesNotDiverge = Mb.isNothing (unify (S.toList freeVars) from to) - || Mb.isJust (unify (S.toList freeVars) to from) + doesNotDiverge = Mb.isNothing (unify (S.toList freeVars') from to) + || Mb.isJust (unify (S.toList freeVars') to from) refinementEQs :: LocSpecType -> [(F.Expr, F.Expr)] refinementEQs t = @@ -175,10 +174,10 @@ makeRewriteOne tce (_, t) rewrites :: F.Expr -> F.Expr -> [F.AutoRewrite] rewrites lhs rhs = - (guard (canRewrite freeVars lhs rhs) >> [F.AutoRewrite xs lhs rhs]) - ++ (guard (canRewrite freeVars rhs lhs) >> [F.AutoRewrite xs rhs lhs]) + (guard (canRewrite freeVars' lhs rhs) >> [F.AutoRewrite xs lhs rhs]) + ++ (guard (canRewrite freeVars' rhs lhs) >> [F.AutoRewrite xs rhs lhs]) - freeVars = S.fromList (ty_binds tRep) + freeVars' = S.fromList (ty_binds tRep) xs = do (sym, arg) <- zip (ty_binds tRep) (ty_args tRep) @@ -220,36 +219,36 @@ specTypeEq emb f t = F.mkEquation (F.symbol f) xts body tOut bExp = F.eApps (F.eVar f) (F.EVar <$> xs) makeSimplify :: (Var, SpecType) -> [F.Rewrite] -makeSimplify (x, t) - | not (GM.isDataConId x) +makeSimplify (var, t) + | not (GM.isDataConId var) = [] | otherwise - = go $ specTypeToResultRef (F.eApps (F.EVar $ F.symbol x) (F.EVar <$> ty_binds (toRTypeRep t))) t + = go $ specTypeToResultRef (F.eApps (F.EVar $ F.symbol var) (F.EVar <$> ty_binds (toRTypeRep t))) t where go (F.PAnd es) = concatMap go es - go (F.PAtom eq (F.EApp (F.EVar f) dc) bd) + go (F.PAtom eq (F.EApp (F.EVar f) expr) bd) | eq `elem` [F.Eq, F.Ueq] - , (F.EVar dc, xs) <- F.splitEApp dc - , dc == F.symbol x + , (F.EVar dc, xs) <- F.splitEApp expr + , dc == F.symbol var , all isEVar xs = [F.SMeasure f dc (fromEVar <$> xs) bd] - go (F.PIff (F.EApp (F.EVar f) dc) bd) - | (F.EVar dc, xs) <- F.splitEApp dc - , dc == F.symbol x + go (F.PIff (F.EApp (F.EVar f) expr) bd) + | (F.EVar dc, xs) <- F.splitEApp expr + , dc == F.symbol var , all isEVar xs = [F.SMeasure f dc (fromEVar <$> xs) bd] - go (F.EApp (F.EVar f) dc) - | (F.EVar dc, xs) <- F.splitEApp dc - , dc == F.symbol x + go (F.EApp (F.EVar f) expr) + | (F.EVar dc, xs) <- F.splitEApp expr + , dc == F.symbol var , all isEVar xs = [F.SMeasure f dc (fromEVar <$> xs) F.PTrue] - go (F.PNot (F.EApp (F.EVar f) dc)) - | (F.EVar dc, xs) <- F.splitEApp dc - , dc == F.symbol x + go (F.PNot (F.EApp (F.EVar f) expr)) + | (F.EVar dc, xs) <- F.splitEApp expr + , dc == F.symbol var , all isEVar xs = [F.SMeasure f dc (fromEVar <$> xs) F.PFalse] @@ -283,11 +282,11 @@ equationBody allowTC f xArgs e mbT -- NV Move this to types? -- sound but imprecise approximation of a type in the logic specTypeToLogic :: Bool -> [F.Expr] -> F.Expr -> SpecType -> F.Expr -specTypeToLogic allowTC es e t +specTypeToLogic allowTC es expr st | ok = F.subst su (F.PImp (F.pAnd args) res) | otherwise = F.PTrue where - res = specTypeToResultRef e t + res = specTypeToResultRef expr st args = zipWith mkExpr (mkReft <$> ts) es mkReft t = F.toReft $ Mb.fromMaybe mempty (stripRTypeBase t) mkExpr (F.Reft (v, ev)) e = F.subst1 ev (v, e) @@ -308,7 +307,7 @@ specTypeToLogic allowTC es e t :: ([(F.Symbol, SpecType)], [(F.Symbol, SpecType)]) (xs, ts) = unzip nocls :: ([F.Symbol], [SpecType]) - trep = toRTypeRep t + trep = toRTypeRep st specTypeToResultRef :: F.Expr -> SpecType -> F.Expr From eb4589f12207166a1c36c89bd9b6b62df4a816db Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Thu, 16 Feb 2023 14:44:33 +1300 Subject: [PATCH 127/219] Remove name shadowing from Language.Haskell.Liquid.Constraint.Types --- src/Language/Haskell/Liquid/Constraint/Types.hs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Types.hs b/src/Language/Haskell/Liquid/Constraint/Types.hs index 4b1f03159f..f080bd823e 100644 --- a/src/Language/Haskell/Liquid/Constraint/Types.hs +++ b/src/Language/Haskell/Liquid/Constraint/Types.hs @@ -3,8 +3,6 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE FlexibleInstances #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Constraint.Types ( -- * Constraint Generation Monad CG @@ -297,7 +295,7 @@ type RTyConIAl = M.HashMap RTyCon [RInv] -------------------------------------------------------------------------------- mkRTyConInv :: [(Maybe Var, F.Located SpecType)] -> RTyConInv -------------------------------------------------------------------------------- -mkRTyConInv ts = group [ (c, RInv (go ts) t v) | (v, t@(RApp c ts _ _)) <- strip <$> ts] +mkRTyConInv tss = group [ (c, RInv (go ts) t v) | (v, t@(RApp c ts _ _)) <- strip <$> tss] where strip = mapSnd (thrd3 . bkUniv . val) go ts | generic (toRSort <$> ts) = [] @@ -343,9 +341,9 @@ addRInv m (x, t) | otherwise = (x, t) where - ids = [id | tc <- M.keys m + ids = [id' | tc <- M.keys m , dc <- Ghc.tyConDataCons $ rtc_tc tc - , AnId id <- Ghc.dataConImplicitTyThings dc] + , AnId id' <- Ghc.dataConImplicitTyThings dc] res = ty_res . toRTypeRep conjoinInvariantShift :: SpecType -> SpecType -> SpecType @@ -385,15 +383,15 @@ restoreInvariant γ is = γ {invs = is} makeRecInvariants :: CGEnv -> [Var] -> CGEnv makeRecInvariants γ [x] = γ {invs = M.unionWith (++) (invs γ) is} where - is = M.map (map f . filter (isJust . (varType x `tcUnifyTy`) . toType False . _rinv_type)) (rinvs γ) - f i = i{_rinv_type = guard $ _rinv_type i} + is = M.map (map g . filter (isJust . (varType x `tcUnifyTy`) . toType False . _rinv_type)) (rinvs γ) + g i = i{_rinv_type = guard' $ _rinv_type i} - guard (RApp c ts rs r) + guard' (RApp c ts rs r) | Just f <- szFun <$> sizeFunction (rtc_info c) = RApp c ts rs (MkUReft (ref f $ F.toReft r) mempty) | otherwise = RApp c ts rs mempty - guard t + guard' t = t ref f (F.Reft(v, rr)) From 7324c91e656d63674876deaea42eb0779be8f655 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Thu, 16 Feb 2023 14:44:53 +1300 Subject: [PATCH 128/219] Remove name shadowing from Language.Haskell.Liquid.Termination.Structural --- src/Language/Haskell/Liquid/Termination/Structural.hs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Language/Haskell/Liquid/Termination/Structural.hs b/src/Language/Haskell/Liquid/Termination/Structural.hs index ddb152f94b..31296fad32 100644 --- a/src/Language/Haskell/Liquid/Termination/Structural.hs +++ b/src/Language/Haskell/Liquid/Termination/Structural.hs @@ -2,8 +2,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE LambdaCase #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} - module Language.Haskell.Liquid.Termination.Structural (terminationVars) where import Language.Haskell.Liquid.Types hiding (isDecreasing) @@ -176,12 +174,12 @@ addParam param env = case envCurrentFun env of | otherwise = fun addSynonym :: Var -> Var -> Env -> Env -addSynonym oldName newName env = env { envCheckedFuns = updateFun <$> envCheckedFuns env } +addSynonym oldName newName' env = env { envCheckedFuns = updateFun <$> envCheckedFuns env } where updateFun fun = fun { funParams = updateParam <$> funParams fun } updateParam param - | oldName `elemVarSet` paramNames param = param { paramNames = paramNames param `extendVarSet` newName } - | oldName `elemVarSet` paramSubterms param = param { paramSubterms = paramSubterms param `extendVarSet` newName } + | oldName `elemVarSet` paramNames param = param { paramNames = paramNames param `extendVarSet` newName' } + | oldName `elemVarSet` paramSubterms param = param { paramSubterms = paramSubterms param `extendVarSet` newName' } | otherwise = param addSubterms :: Var -> [Var] -> Env -> Env From 1b357be4e655d179214d190c91683463515f4cb8 Mon Sep 17 00:00:00 2001 From: Tommy Bidne Date: Thu, 16 Feb 2023 14:45:16 +1300 Subject: [PATCH 129/219] Remove name shadowing from Language.Haskell.Liquid.Transforms.CoreToLogic --- .../Haskell/Liquid/Transforms/CoreToLogic.hs | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs index f7e46e73a3..9d93059c6e 100644 --- a/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs +++ b/src/Language/Haskell/Liquid/Transforms/CoreToLogic.hs @@ -5,7 +5,6 @@ {-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-orphans #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-} module Language.Haskell.Liquid.Transforms.CoreToLogic ( coreToDef @@ -57,8 +56,8 @@ logicType :: (Reftable r) => Bool -> Type -> RRType r logicType allowTC τ = fromRTypeRep $ t { ty_binds = bs, ty_info = is, ty_args = as, ty_refts = rs} where t = toRTypeRep $ ofType τ - (bs, is, as, rs) = Misc.unzip4 $ dropWhile (isErasable . Misc.thd4) $ Misc.zip4 (ty_binds t) (ty_info t) (ty_args t) (ty_refts t) - isErasable = if allowTC then isEmbeddedClass else isClassType + (bs, is, as, rs) = Misc.unzip4 $ dropWhile (isErasable' . Misc.thd4) $ Misc.zip4 (ty_binds t) (ty_info t) (ty_args t) (ty_refts t) + isErasable' = if allowTC then isEmbeddedClass else isClassType {- | [NOTE:inlineSpecType type]: the refinement depends on whether the result type is a Bool or not: CASE1: measure f@logic :: X -> Bool <=> f@haskell :: x:X -> {v:Bool | v <=> (f@logic x)} @@ -68,16 +67,16 @@ logicType allowTC τ = fromRTypeRep $ t { ty_binds = bs, ty_info = is, ty_a inlineSpecType :: Bool -> Var -> SpecType inlineSpecType allowTC v = fromRTypeRep $ rep {ty_res = res `strengthen` r , ty_binds = xs} where - r = MkUReft (mkR (mkEApp f (mkA <$> vxs))) mempty + r = MkUReft (mkReft (mkEApp f (mkA <$> vxs))) mempty rep = toRTypeRep t res = ty_res rep xs = intSymbol (symbol ("x" :: String)) <$> [1..length $ ty_binds rep] - vxs = dropWhile (isErasable . snd) $ zip xs (ty_args rep) - isErasable = if allowTC then isEmbeddedClass else isClassType + vxs = dropWhile (isErasable' . snd) $ zip xs (ty_args rep) + isErasable' = if allowTC then isEmbeddedClass else isClassType f = dummyLoc (symbol v) t = ofType (GM.expandVarType v) :: SpecType mkA = EVar . fst - mkR = if isBool res then propReft else exprReft + mkReft = if isBool res then propReft else exprReft -- | Refine types of measures: keep going until you find the last data con! -- this code is a hack! we refine the last data constructor, @@ -88,14 +87,14 @@ inlineSpecType allowTC v = fromRTypeRep $ rep {ty_res = res `strengthen` r , ty -- formerly: strengthenResult' measureSpecType :: Bool -> Var -> SpecType -measureSpecType allowTC v = go mkT [] [(1::Int)..] t +measureSpecType allowTC v = go mkT [] [(1::Int)..] st where - mkR | boolRes = propReft - | otherwise = exprReft - mkT xs = MkUReft (mkR $ mkEApp f (EVar <$> reverse xs)) mempty - f = dummyLoc (symbol v) - t = ofType (GM.expandVarType v) :: SpecType - boolRes = isBool $ ty_res $ toRTypeRep t + mkReft | boolRes = propReft + | otherwise = exprReft + mkT xs = MkUReft (mkReft $ mkEApp locSym (EVar <$> reverse xs)) mempty + locSym = dummyLoc (symbol v) + st = ofType (GM.expandVarType v) :: SpecType + boolRes = isBool $ ty_res $ toRTypeRep st go f args i (RAllT a t r) = RAllT a (go f args i t) r go f args i (RAllP p t) = RAllP p $ go f args i t @@ -164,11 +163,11 @@ runToLogicWithBoolBinds xs tce lmap dm ferror m coreAltToDef :: (Reftable r) => Bool -> LocSymbol -> Var -> [Var] -> Var -> Type -> [C.CoreAlt] -> LogicM [Def (Located (RRType r)) DataCon] -coreAltToDef allowTC x z zs y t alts - | not (null litAlts) = measureFail x "Cannot lift definition with literal alternatives" +coreAltToDef allowTC locSym z zs y t alts + | not (null litAlts) = measureFail locSym "Cannot lift definition with literal alternatives" | otherwise = do - d1s <- F.notracepp "coreAltDefs-1" <$> mapM (mkAlt x cc myArgs z) dataAlts - d2s <- F.notracepp "coreAltDefs-2" <$> mkDef x cc myArgs z defAlts defExpr + d1s <- F.notracepp "coreAltDefs-1" <$> mapM (mkAlt locSym cc myArgs z) dataAlts + d2s <- F.notracepp "coreAltDefs-2" <$> mkDef locSym cc myArgs z defAlts defExpr return (d1s ++ d2s) where myArgs = reverse zs @@ -208,14 +207,14 @@ defArgs x = zipWith (\i t -> (defArg i, defRTyp t)) [0..] coreToDef :: Reftable r => Bool -> LocSymbol -> Var -> C.CoreExpr -> LogicM [Def (Located (RRType r)) DataCon] -coreToDef allowTC x _ e = go [] $ inlinePreds $ simplify allowTC e +coreToDef allowTC locSym _ = go [] . inlinePreds . simplify allowTC where go args (C.Lam x e) = go (x:args) e go args (C.Tick _ e) = go args e - go (z:zs) (C.Case _ y t alts) = coreAltToDef allowTC x z zs y t alts + go (z:zs) (C.Case _ y t alts) = coreAltToDef allowTC locSym z zs y t alts go (z:zs) e - | Just t <- isMeasureArg z = coreAltToDef allowTC x z zs z t [Alt C.DEFAULT [] e] - go _ _ = measureFail x "Does not have a case-of at the top-level" + | Just t <- isMeasureArg z = coreAltToDef allowTC locSym z zs z t [Alt C.DEFAULT [] e] + go _ _ = measureFail locSym "Does not have a case-of at the top-level" inlinePreds = inline (eqType boolTy . GM.expandVarType) @@ -241,7 +240,7 @@ varRType :: (Reftable r) => Var -> Located (RRType r) varRType = GM.varLocInfo ofType coreToFun :: Bool -> LocSymbol -> Var -> C.CoreExpr -> LogicM ([Var], Either Expr Expr) -coreToFun allowTC _ _v e = go [] $ normalize allowTC e +coreToFun allowTC _ _v = go [] . normalize allowTC where isE = if allowTC then GM.isEmbeddedDictVar else isErasable go acc (C.Lam x e) | isTyVar x = go acc e @@ -498,9 +497,9 @@ bops = M.fromList [ (numSymbol "+", Plus) realSymbol = symbol . (++) "GHC.Real." splitArgs :: Bool -> C.Expr t -> (C.Expr t, [C.Arg t]) -splitArgs allowTC e = (f, reverse es) +splitArgs allowTC exprt = (exprt', reverse args) where - (f, es) = go e + (exprt', args) = go exprt go (C.App (C.Var i) e) | ignoreVar i = go e go (C.App f (C.Var v)) | if allowTC then GM.isEmbeddedDictVar v else isErasable v = go f @@ -648,7 +647,7 @@ instance Simplify C.CoreExpr where inline _ (C.Type t) = C.Type t isUndefined :: CoreAlt -> Bool -isUndefined (Alt _ _ e) = isUndefinedExpr e +isUndefined (Alt _ _ exprCoreBndr) = isUndefinedExpr exprCoreBndr where isUndefinedExpr :: C.CoreExpr -> Bool -- auto generated undefined case: (\_ -> (patError @levity @type "error message")) void From c872c9b0d5f0e0ccad79932b4ac2a4244e415007 Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 17 Feb 2023 14:59:20 -0600 Subject: [PATCH 130/219] Fix broken links in doc --- .gitignore | 3 ++- .../docs/blogposts/2020-04-12-polymorphic-perplexion.lhs.md | 4 ++-- docs/mkDocs/docs/index.md | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 6e06898f63..f4181ce334 100644 --- a/.gitignore +++ b/.gitignore @@ -62,4 +62,5 @@ tests/**/*.o-boot .idea *.iml -.DS_Store \ No newline at end of file +.DS_Store +docs/mkDocs/site diff --git a/docs/mkDocs/docs/blogposts/2020-04-12-polymorphic-perplexion.lhs.md b/docs/mkDocs/docs/blogposts/2020-04-12-polymorphic-perplexion.lhs.md index 097bfef796..46eb09de34 100644 --- a/docs/mkDocs/docs/blogposts/2020-04-12-polymorphic-perplexion.lhs.md +++ b/docs/mkDocs/docs/blogposts/2020-04-12-polymorphic-perplexion.lhs.md @@ -28,8 +28,8 @@ that has puzzled me and other users several times. A Type for Ordered Lists ------------------------ -[Previously](2013-07-29-putting-things-in-order.lhs/) -we have seen how you can use LH to define a type of lists whose values are in increasing +[Previously](2013-07-29-putting-things-in-order.lhs.md) +we have seen how you can use LH to define a type of lists whose values are in increasing (ok, non-decreasing!) order. First, we define an `IncList a` type, with `Emp` ("empty") diff --git a/docs/mkDocs/docs/index.md b/docs/mkDocs/docs/index.md index ec1621e586..9b7c24709b 100644 --- a/docs/mkDocs/docs/index.md +++ b/docs/mkDocs/docs/index.md @@ -8,7 +8,7 @@ LiquidHaskell _(LH)_ refines Haskell's types with logical predicates that let yo

@@ -25,7 +25,7 @@ The input contract propagates to uses of head which are verified by

LH lets you avoid off-by-one errors that can lead to crashes or buffer overflows. -(more...) +(more...)

@@ -59,7 +59,7 @@ LH checks that functions terminate and so warns about the infinite recursion due

Write correctness requirements, for example a list is ordered, as refinements. LH makes illegal values be unrepresentable. -(more...) +(more...)

From c8e1e35b41587115c6dbbe87586b6d98d0b00b2c Mon Sep 17 00:00:00 2001 From: Kartik Singhal Date: Fri, 17 Feb 2023 15:43:48 -0600 Subject: [PATCH 131/219] Fix some broken external links as well in the docs --- .../2013-01-01-refinement-types-101.lhs.md | 6 +- ...-safely-catching-a-list-by-its-tail.lhs.md | 2 +- .../2020-08-20-lh-as-a-ghc-plugin.lhs.md | 6 +- docs/mkDocs/docs/install.md | 2 +- docs/mkDocs/docs/specifications.md | 66 +++++++++---------- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/docs/mkDocs/docs/blogposts/2013-01-01-refinement-types-101.lhs.md b/docs/mkDocs/docs/blogposts/2013-01-01-refinement-types-101.lhs.md index 193169350b..736f319e95 100644 --- a/docs/mkDocs/docs/blogposts/2013-01-01-refinement-types-101.lhs.md +++ b/docs/mkDocs/docs/blogposts/2013-01-01-refinement-types-101.lhs.md @@ -239,7 +239,7 @@ deducing that `n` is trivially non-negative when `0 < n` and that in the `otherwise` case, i.e. when `not (0 < n)` the value `0 - n` is indeed non-negative (lets not worry about underflows for the moment.) LiquidHaskell is able to automatically make these arithmetic deductions -by using an [SMT solver](http://rise4fun.com/Z3/) which has decision +by using an [SMT solver](https://github.com/Z3Prover/z3) which has decision built-in procedures for arithmetic, to reason about the logical refinements. @@ -310,8 +310,8 @@ Modular Verification -------------------- Incidentally, note the `import` statement at the top. Rather than rolling -our own `lAssert` we can import and use a pre-defined version `liquidAssert` -defined in an external [module](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/Language/Haskell/Liquid/Prelude.hs) +our own `lAssert` we can import and use a pre-defined version `liquidAssert` +defined in an external [module](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/liquid-prelude/src/Language/Haskell/Liquid/Prelude.hs)
286: {-@ truncate'' :: Int -> Int -> Int @-}
diff --git a/docs/mkDocs/docs/blogposts/2013-01-31-safely-catching-a-list-by-its-tail.lhs.md b/docs/mkDocs/docs/blogposts/2013-01-31-safely-catching-a-list-by-its-tail.lhs.md
index ad7ee2c702..63257d6589 100644
--- a/docs/mkDocs/docs/blogposts/2013-01-31-safely-catching-a-list-by-its-tail.lhs.md
+++ b/docs/mkDocs/docs/blogposts/2013-01-31-safely-catching-a-list-by-its-tail.lhs.md
@@ -44,7 +44,7 @@ That is, measures will appear in specifications but *never* inside code.
 
 
 
- Let's reuse this mechanism, this time, providing a [definition](https://github.com/ucsd-progsys/liquidhaskell/blob/master/include/GHC/Base.spec) for the measure
+ Let's reuse this mechanism, this time, providing a [definition](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/liquid-base/src/GHC/Base.spec) for the measure
 
48: measure len :: forall a. [a] -> GHC.Types.Int
 49: len ([])     = 0
 50: len (y:ys)   = 1 + (len ys) 
diff --git a/docs/mkDocs/docs/blogposts/2020-08-20-lh-as-a-ghc-plugin.lhs.md b/docs/mkDocs/docs/blogposts/2020-08-20-lh-as-a-ghc-plugin.lhs.md
index 6a681db3ec..0e435d15cb 100644
--- a/docs/mkDocs/docs/blogposts/2020-08-20-lh-as-a-ghc-plugin.lhs.md
+++ b/docs/mkDocs/docs/blogposts/2020-08-20-lh-as-a-ghc-plugin.lhs.md
@@ -110,9 +110,9 @@ run LH on the changed modules! If you use `stack` you may have to specify
 a few more dependencies, as the various packages are not (yet) on stackage, 
 as shown in the [demo `stack.yaml`](https://github.com/ucsd-progsys/lh-plugin-demo/blob/main/stack.yaml).
 No extra dependencies are needede if you use `cabal-v2`. In both cases,
-you can use the respective files [`stack.yaml`](https://github.com/ucsd-progsys/lh-plugin-demo/blob/main/stack.yaml.github) 
-and [`cabal.project`](https://github.com/ucsd-progsys/lh-plugin-demo/blob/main/cabal.project.github) 
-point to specific git snapshots if you want to use the most recent versions. 
+you can use the respective files [`stack.yaml`](https://github.com/ucsd-progsys/lh-plugin-demo/blob/main/stack.yaml)
+and [`cabal.project`](https://github.com/ucsd-progsys/lh-plugin-demo/blob/main/cabal.project)
+point to specific git snapshots if you want to use the most recent versions.
 If you clone the repo and run, e.g. `cabal v2-build` or `stack build` you'll get the following result, after the relevant dependencies 
 are downloaded and built of course...
 
diff --git a/docs/mkDocs/docs/install.md b/docs/mkDocs/docs/install.md
index 133412aa38..7f620a7eb7 100644
--- a/docs/mkDocs/docs/install.md
+++ b/docs/mkDocs/docs/install.md
@@ -7,7 +7,7 @@ This sections documents how to install LH and its dependencies.
 In order to use LiquidHaskell, you will need a [SMT solver](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories)
 installed on your system. Download and install at least one of:
 
-* [Z3](https://github.com/Z3Prover/z3) or [Microsoft official binary](https://www.microsoft.com/en-us/download/details.aspx?id=52270)
+* [Z3](https://github.com/Z3Prover/z3) or [Microsoft official binary](https://github.com/Z3Prover/z3/releases)
 * [CVC4](https://cvc4.github.io/)
 * [MathSat](https://mathsat.fbk.eu/)
 
diff --git a/docs/mkDocs/docs/specifications.md b/docs/mkDocs/docs/specifications.md
index 31f15d3927..74b05704b3 100644
--- a/docs/mkDocs/docs/specifications.md
+++ b/docs/mkDocs/docs/specifications.md
@@ -50,7 +50,7 @@ refinements for external packages (cfr. **"Providing Specifications for Existing
 ## Modules WITH code: Data
 
 Write the specification directly into the .hs or .lhs file,
-above the data definition. See, for example, [tests/pos/Map.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Map.hs):
+above the data definition. See, for example, [tests/pos/Map.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Map.hs):
 
 ```haskell
 {-@
@@ -67,7 +67,7 @@ data Map k a = Tip
 ```
 
 You can also write invariants for data type definitions
-together with the types. For example, see [tests/pos/record0.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/record0.hs):
+together with the types. For example, see [tests/pos/record0.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Record0.hs):
 
 ```haskell
 {-@ 
@@ -97,7 +97,7 @@ as  `data size (M1 a, M2 a) msize`.
 
 
 Finally you can specify the variance of type variables for data types.
-For example, see [tests/pos/Variance.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Variance.hs), where data type `Foo` has four
+For example, see [tests/pos/Variance.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Variance.hs), where data type `Foo` has four
 type variables `a`, `b`, `c`, `d`, specified as invariant, bivariant,
 covariant and contravariant, respectively.
 
@@ -109,7 +109,7 @@ data Foo a b c d
 ## Modules WITH code: Functions
 
 Write the specification directly into the .hs or .lhs file,
-above the function definition. [For example](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/spec0.hs):
+above the function definition. [For example](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Spec0.hs):
 
 ```haskell
 {-@ incr :: x:{v: Int | v > 0} -> {v: Int | v > x} @-}
@@ -119,7 +119,7 @@ incr x = x + 1
 
 ## Modules WITH code: Type Classes
 
-Write the specification directly into the .hs or .lhs file. The constrained variable must match the one from the class definition. A class must have at least one refinement signature (even if it's a trivial one) to be lifted to the refinement logic. [For example](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Class.hs):
+Write the specification directly into the .hs or .lhs file. The constrained variable must match the one from the class definition. A class must have at least one refinement signature (even if it's a trivial one) to be lifted to the refinement logic. [For example](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Class.hs):
 ```haskell
 class Semigroup a where
     {-@ mappend :: a -> a -> a @-}
@@ -151,7 +151,7 @@ The example above inlines the proofs directly into the instance definition. This
 ## Modules WITH code: Type Classes (Legacy)
 
 Write the specification directly into the .hs or .lhs file,
-above the type class definition. [For example](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Class.hs):
+above the type class definition. [For example](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Class.hs):
 
 ```haskell
 {-@ class Sized s where
@@ -165,7 +165,7 @@ Any measures used in the refined class definition will need to be
 *generic* (see [Specifying Measures](#specifying-measures)).
 
 As an alternative, you can refine class instances.
-[For example](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/classes/pos/Inst00.hs):
+[For example](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/classes/pos/Inst00.hs):
 
 ```haskell
 instance Compare Int where
@@ -298,7 +298,7 @@ following examples for details:
 
 **Status:** `experimental`
 
-There is experimental support for implicit arguments, solved for with congruence closure. For example, consider [Implicit1.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Implicit1.hs):
+There is experimental support for implicit arguments, solved for with congruence closure. For example, consider [Implicit1.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/implicit/pos/Implicit1.hs):
 
 ```haskell
 {-@ type IntN N = {v:Int | v = N} @-}
@@ -325,7 +325,7 @@ verbose. You can write predicate aliases like so:
 {-@ predicate Ge X Y = not (Lt X Y) @-}
 ```
 
-and then use the aliases inside refinements, [for example](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/pred.hs)
+and then use the aliases inside refinements, [for example](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Pred.hs)
 
 ```haskell
 {-@ incr :: x:{v:Int | (Pos v)} -> { v:Int | ((Pos v) && (Ge v x))} @-}
@@ -333,7 +333,7 @@ incr :: Int -> Int
 incr x = x + 1
 ```
 
-See [Data.Map](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/benchmarks/esop2013-submission/Base.hs) for a more substantial
+See [Data.Map](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/benchmarks/esop2013-submission/Base.hs) for a more substantial
 and compelling example.
 
 **Syntax:** The key requirements for type aliases are:
@@ -388,13 +388,13 @@ and:
 
     {-@ assert insert :: (Ord a) => a -> SortedList a -> SortedList a @-}
 
-see [tests/pos/ListSort.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/ListSort.hs)
+see [tests/pos/ListSort.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/ListSort.hs)
 
 and:
 
     {-@ assert insert :: (Ord k) => k -> a -> OMap k a -> OMap k a @-}
 
-see [tests/pos/Map.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Map.hs)
+see [tests/pos/Map.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Map.hs)
 
 **Syntax:** The key requirements for type aliases are:
 
@@ -410,7 +410,7 @@ For example, if `(+++)` is defined as a measure or reflected function, you can u
 
 Note: infix operators cannot contain the dot character `.`.
 
-If `(==>)` is a Haskell infix type ([see](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/T1567.hs)) 
+If `(==>)` is a Haskell infix type ([see](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/T1567.hs))
 
     infixr 1 ==> 
 
@@ -423,13 +423,13 @@ then to use it as infix in the refinements types you need to add the refinement
 
 They can be placed in a `.spec` file or in a .hs/.lhs file wrapped around `{-@ @-}`.
 
-Value measures: [GHC/Base.spec](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/liquid-base/src/GHC/Base.spec)
+Value measures: [GHC/Base.spec](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/liquid-base/src/GHC/Base.spec)
 
     measure len :: forall a. [a] -> GHC.Types.Int
     len ([])     = 0
     len (y:ys)   = 1 + len(ys)
 
-Propositional measures: [tests/pos/LambdaEval.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/LambdaEval.hs)
+Propositional measures: [tests/pos/LambdaEval.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/LambdaEval.hs)
 
 ```haskell
 {-@
@@ -445,7 +445,7 @@ isValue (Pair e1 e2) = ((? (isValue(e1))) && (? (isValue(e2))))
 @-}
 ```
 
-Raw measures: [tests/pos/meas8.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/meas8.hs)
+Raw measures: [tests/pos/meas8.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Meas8.hs)
 
 ```haskell
 {-@ measure rlen :: [a] -> Int
@@ -454,7 +454,7 @@ rlen (y:ys) = {v | v = (1 + rlen(ys))}
 @-}
 ```
 
-Generic measures: [tests/pos/Class.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Class.hs)
+Generic measures: [tests/pos/Class.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Class.hs)
 
 ```haskell
 {-@ class measure size :: a -> Int @-}
@@ -470,9 +470,9 @@ Generic measures: [tests/pos/Class.hs](https://github.com/ucsd-progsys/liquidhas
 
 **Note:** Measure names **do not** have to be the same as
 field name, e.g. we could call the measure `sz` in the above
-as shown in [tests/pos/Class2.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Class2.hs).
+as shown in [tests/pos/Class2.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Class2.hs).
 
-Haskell Functions as Measures (beta): [tests/pos/HaskellMeasure.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/HaskellMeasure.hs)
+Haskell Functions as Measures (beta): [tests/pos/HaskellMeasure.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/HaskellMeasure.hs)
 
 Inductive Haskell Functions from Data Types to some type can be lifted to logic
 
@@ -535,7 +535,7 @@ states that the *inner* `a` enjoys the property that the *outer* container
 is definitely a `Just` and furthermore, the inner value is exactly the same
 as the `fromJust` property of the outer container.
 
-As another example, suppose we have a [measure](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/liquid-containers/src/Data/Set.spec):
+As another example, suppose we have a [measure](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/liquid-containers/src/Data/Set.spec):
 
     measure listElts :: [a] -> (Set a)
     listElts([])   = {v | (? Set_emp(v))}
@@ -550,16 +550,16 @@ set of the elements belonging to the entire list.
 
 One often needs these *circular* or *self* invariants to connect different
 levels (or rather, to *reify* the connections between the two levels.) See
-[this test](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/maybe4.hs) for a simple example and `hedgeUnion` and
-[Data.Map.Base](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/benchmarks/esop2013-submission/Base.hs) for a complex one.
+[this test](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Maybe4.hs) for a simple example and `hedgeUnion` and
+[Data.Map.Base](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/benchmarks/esop2013-submission/Base.hs) for a complex one.
 
 
 # Abstract and Bounded Refinements
 
 This is probably the best example of the abstract refinement syntax:
 
-+ [Abstract Refinements](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/Map.hs)
-+ [Bounded Refinements](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/benchmarks/icfp15/pos/Overview.lhs)
++ [Abstract Refinements](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Map.hs)
++ [Bounded Refinements](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/benchmarks/icfp15/pos/Overview.lhs)
 
 Unfortunately, the best documentation for these two advanced features
 is the relevant papers at:
@@ -587,7 +587,7 @@ Invariants
 
 LH lets you locally associate invariants with specific data types.
 
-For example, in [tests/measure/pos/Using00.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/measure/pos/Using00.hs) every
+For example, in [tests/measure/pos/Using00.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/measure/pos/Using00.hs) every
 list is treated as a `Stream`. To establish this local invariant one can use the
 `using` declaration
 
@@ -600,9 +600,9 @@ calls* to List's constructors (ie., `:` and `[]`) satisfy it, and
 will assume that each list element that is created satisfies
 this invariant.
 
-With this, at the [above](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/measure/neg/Using00.hs) test LiquidHaskell
+With this, at the [above](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/measure/neg/Using00.hs) test LiquidHaskell
 proves that taking the `head` of a list is safe.
-But, at [tests/measure/neg/Using00.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/measure/neg/Using00.hs) the usage of
+But, at [tests/measure/neg/Using00.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/measure/neg/Using00.hs) the usage of
 `[]` falsifies this local invariant resulting in an "Invariant Check" error.
 
 **WARNING:** There is an older _global_ invariant mechanism that
@@ -653,7 +653,7 @@ You can also annotate a function as being a global rewrite rule by using the
 ## Limitations
 
 Currently, rewriting does not work if the equality that uses the rewrite rule
-includes parameters that contain inner refinements ([test](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/errors/ReWrite5.hs)).
+includes parameters that contain inner refinements ([test](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/errors/ReWrite5.hs)).
 
 Rewriting works by pattern-matching expressions to determine if there is a
 variable substitution that would allow it to match against either side of a
@@ -662,7 +662,7 @@ corresponding equality is generated. If one side of the equality contains any
 parameters that are not bound on the other side, it will not be possible to
 generate a rewrite in that direction, because those variables cannot be
 instantiated. Likewise, if there are free variables on both sides of an
-equality, no rewrite can be generated at all ([test](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/errors/ReWrite7.hs)).
+equality, no rewrite can be generated at all ([test](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/errors/ReWrite7.hs)).
 
 It's possible in theory for rewriting rules to diverge. We have a simple check 
 to ensure that rewriting rules that will always diverge do not get instantiated. 
@@ -715,7 +715,7 @@ There are several ways to specify qualifiers.
 
 ## By Separate `.hquals` Files
 
-You can write qualifier files e.g. [Prelude.hquals](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/include/Prelude.hquals)..
+You can write qualifier files e.g. [Prelude.hquals](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/include/Prelude.hquals)..
 
 If a module is called or imports
 
@@ -731,13 +731,13 @@ Additional qualifiers may be used by adding lines of the form:
 
     {-@ include  @-}
 
-to the Haskell source. See, [this](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/meas5.hs) for example.
+to the Haskell source. See, [this](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Meas5.hs) for example.
 
 
 ## In Haskell Source or Spec Files
 
 Finally, you can specifiers directly inside source (.hs or .lhs) or spec (.spec)
-files by writing as shown [here](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/qualTest.hs)
+files by writing as shown [here](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/QualTest.hs)
 
     {-@ qualif Foo(v:Int, a: Int) : (v = a + 100)   @-}
 
@@ -870,7 +870,7 @@ isOdd  n = not $ isEven n
 thus recovering a decreasing measure for the pair of functions, the
 pair of arguments. This can be encoded with the lexicographic
 termination annotation as shown above.
-See [tests/pos/mutrec.hs](https://github.com/ucsd-progsys/liquidhaskell/tree/develop/tests/pos/mutrec.hs) 
+See [tests/pos/mutrec.hs](https://github.com/ucsd-progsys/liquidhaskell/blob/develop/tests/pos/Mutrec.hs)
 for the full example.
 
 ## Automatic Termination Metrics

From 481a62ed37c8da5af5c3cfa56d4676cd332acac5 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:26:32 +1300
Subject: [PATCH 132/219] Remove name shadowing from
 Language.Haskell.Liquid.Transforms.InlineAux

---
 src/Language/Haskell/Liquid/Transforms/InlineAux.hs | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Transforms/InlineAux.hs b/src/Language/Haskell/Liquid/Transforms/InlineAux.hs
index b10af00f1a..d55be8b042 100644
--- a/src/Language/Haskell/Liquid/Transforms/InlineAux.hs
+++ b/src/Language/Haskell/Liquid/Transforms/InlineAux.hs
@@ -1,7 +1,5 @@
 {-# LANGUAGE FlexibleContexts #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
-
 module Language.Haskell.Liquid.Transforms.InlineAux
   ( inlineAux
   )
@@ -17,18 +15,18 @@ inlineAux :: UX.Config -> Module -> CoreProgram -> CoreProgram
 inlineAux cfg m cbs =  if UX.auxInline cfg then occurAnalysePgm m (const False) (const False) [] (map f cbs) else cbs
  where
   f :: CoreBind -> CoreBind
-  f all@(NonRec x e)
+  f all'@(NonRec x e)
     | Just (dfunId, methodToAux) <- M.lookup x auxToMethodToAux = NonRec
       x
       (inlineAuxExpr dfunId methodToAux e)
-    | otherwise = all
+    | otherwise = all'
   f (Rec bs) = Rec (fmap g bs)
    where
-    g all@(x, e)
+    g all'@(x, e)
       | Just (dfunId, methodToAux) <- M.lookup x auxToMethodToAux
       = (x, inlineAuxExpr dfunId methodToAux e)
       | otherwise
-      = all
+      = all'
   auxToMethodToAux = mconcat $ fmap (uncurry dfunIdSubst) (grepDFunIds cbs)
 
 
@@ -72,7 +70,7 @@ dfunIdSubst dfunId e = M.fromList $ zip auxIds (repeat (dfunId, methodToAux))
   methods = classAllSelIds cls
 
 inlineAuxExpr :: DFunId -> M.HashMap Id Id -> CoreExpr -> CoreExpr
-inlineAuxExpr dfunId methodToAux e = go e
+inlineAuxExpr dfunId methodToAux = go
  where
   go :: CoreExpr -> CoreExpr
   go (Lam b body) = Lam b (go body)

From 71e47da3b509e089c1e1ba5daa9bab10007d9cd8 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:26:53 +1300
Subject: [PATCH 133/219] Remove name shadowing from
 Language.Haskell.Liquid.Transforms.Rec

---
 src/Language/Haskell/Liquid/Transforms/Rec.hs | 26 +++++++++----------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Transforms/Rec.hs b/src/Language/Haskell/Liquid/Transforms/Rec.hs
index a4a1b8f898..2f4f1340a4 100644
--- a/src/Language/Haskell/Liquid/Transforms/Rec.hs
+++ b/src/Language/Haskell/Liquid/Transforms/Rec.hs
@@ -3,8 +3,6 @@
 {-# LANGUAGE NoMonomorphismRestriction #-}
 {-# LANGUAGE ScopedTypeVariables       #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
-
 module Language.Haskell.Liquid.Transforms.Rec (
      transformRecExpr, transformScope
      , outerScTr , innerScTr
@@ -103,8 +101,8 @@ innerScTr :: Functor f => f (Bind Id) -> f (Bind Id)
 innerScTr = (mapBnd scTrans <$>)
 
 scTrans :: Id -> Expr Id -> Expr Id
-scTrans x e = mapExpr scTrans $ foldr Let e0 bs
-  where (bs, e0)           = go [] x e
+scTrans id' expr = mapExpr scTrans $ foldr Let e0 bindIds
+  where (bindIds, e0)           = go [] id' expr
         go bs x (Let b e)  | isCaseArg x b = go (b:bs) x e
         go bs x (Tick t e) = second (Tick t) $ go bs x e
         go bs _ e          = (bs, e)
@@ -158,13 +156,13 @@ trans :: Foldable t
       -> t (Bind Id)
       -> Expr Var
       -> State TrEnv (Expr Id)
-trans vs ids bs (Let (Rec xes) e)
-  = fmap (mkLam . mkLet) (makeTrans vs liveIds e')
+trans vs ids bs (Let (Rec xes) expr)
+  = fmap (mkLam . mkLet') (makeTrans vs liveIds e')
   where liveIds = mkAlive <$> ids
-        mkLet e = foldr Let e bs
+        mkLet' e = foldr Let e bs
         mkLam e = foldr Lam e $ vs ++ liveIds
-        e'      = Let (Rec xes') e
-        xes'    = second mkLet <$> xes
+        e'      = Let (Rec xes') expr
+        xes'    = second mkLet' <$> xes
 
 trans _ _ _ _ = panic Nothing "TransformRec.trans called with invalid input"
 
@@ -190,7 +188,7 @@ makeTrans vs ids (Let (Rec xes) e)
 makeTrans _ _ _ = panic Nothing "TransformRec.makeTrans called with invalid input"
 
 mkRecBinds :: [(b, Expr b)] -> Bind b -> Expr b -> Expr b
-mkRecBinds xes rs e = Let rs (L.foldl' f e xes)
+mkRecBinds xes rs expr = Let rs (L.foldl' f expr xes)
   where f e (x, xe) = Let (NonRec x xe) e
 
 mkSubs :: (Eq k, Hashable k)
@@ -203,11 +201,11 @@ mkFreshIds :: [TyVar]
            -> [Var]
            -> Var
            -> State TrEnv ([Var], Id)
-mkFreshIds tvs ids x
-  = do ids'  <- mapM fresh ids
+mkFreshIds tvs origIds var
+  = do ids'  <- mapM fresh origIds
        let ids'' = map setIdTRecBound ids'
-       let t  = mkForAllTys ((`Bndr` Required) <$> tvs) $ mkType (reverse ids'') $ varType x
-       let x' = setVarType x t
+       let t  = mkForAllTys ((`Bndr` Required) <$> tvs) $ mkType (reverse ids'') $ varType var
+       let x' = setVarType var t
        return (ids'', x')
   where
     mkType ids ty = foldl (\t x -> FunTy VisArg Many (varType x) t) ty ids -- FIXME(adinapoli): Is 'VisArg' OK here?

From 450d16109b30b9d520aba8e4c25f8c87befe8e7e Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:27:03 +1300
Subject: [PATCH 134/219] Remove name shadowing from
 Language.Haskell.Liquid.Transforms.RefSplit

---
 src/Language/Haskell/Liquid/Transforms/RefSplit.hs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Transforms/RefSplit.hs b/src/Language/Haskell/Liquid/Transforms/RefSplit.hs
index cb68c4e0ae..102a9f421c 100644
--- a/src/Language/Haskell/Liquid/Transforms/RefSplit.hs
+++ b/src/Language/Haskell/Liquid/Transforms/RefSplit.hs
@@ -2,7 +2,6 @@
 {-# LANGUAGE UndecidableInstances #-}
 
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 
 module Language.Haskell.Liquid.Transforms.RefSplit (
 
@@ -68,11 +67,11 @@ splitRType f (RAppTy tx t r) = (RAppTy tx1 t1 r1, RAppTy tx2 t2 r2)
         (tx1, tx2) = splitRType f tx
         (t1,  t2)  = splitRType f t
         (r1,  r2)  = splitRef   f r
-splitRType f (RRTy xs r o t) = (RRTy xs1 r1 o t1, RRTy xs2 r2 o t2)
+splitRType f (RRTy xs r o rt) = (RRTy xs1 r1 o rt1, RRTy xs2 r2 o rt2)
   where
         (xs1, xs2) = unzip (go <$> xs)
         (r1, r2) = splitRef   f r
-        (t1, t2) = splitRType f t
+        (rt1, rt2) = splitRType f rt
 
         go (x, t) = let (t1, t2) = splitRType f t in ((x,t1), (x, t2))
 splitRType f (RHole r) = (RHole r1, RHole r2)

From 3074f519f4dc10efcbd712031b8de1f260f835bc Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:27:18 +1300
Subject: [PATCH 135/219] Remove name shadowing from
 Language.Haskell.Liquid.Transforms.Rewrite

---
 .../Haskell/Liquid/Transforms/Rewrite.hs      | 27 +++++++++----------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs
index b8d4499030..f34093e4e7 100644
--- a/src/Language/Haskell/Liquid/Transforms/Rewrite.hs
+++ b/src/Language/Haskell/Liquid/Transforms/Rewrite.hs
@@ -7,7 +7,6 @@
 {-# LANGUAGE UndecidableInstances      #-}
 {-# LANGUAGE FlexibleContexts          #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
 
 -- | This module contains functions for recursively "rewriting"
@@ -104,7 +103,7 @@ untick (Tick _ e) = untick e
 untick e          = e 
 
 tidyTuples :: RewriteRule
-tidyTuples e = Just $ evalState (go e) []
+tidyTuples ce = Just $ evalState (go ce) []
   where
     go (Tick t e)
       = Tick t <$> go e
@@ -144,10 +143,10 @@ tidyTuples e = Just $ evalState (go e) []
 
 
 normalizeTuples :: CoreBind -> CoreBind
-normalizeTuples b
-  | NonRec x e <- b
+normalizeTuples cb
+  | NonRec x e <- cb
   = NonRec x $ go e
-  | Rec xes <- b
+  | Rec xes <- cb
   = let (xs,es) = unzip xes in
     Rec $ zip xs (go <$> es)
   where
@@ -300,9 +299,9 @@ simplifyPatTuple :: RewriteRule
 
 _tidyAlt :: Int -> Maybe CoreExpr -> Maybe CoreExpr
 
-_tidyAlt n (Just (Let (NonRec x e) rest))
+_tidyAlt n (Just (Let (NonRec cb expr) rest))
   | Just (yes, e') <- takeBinds n rest
-  = Just $ Let (NonRec x e) $ foldl (\e (x, ex) -> Let (NonRec x ex) e) e' (reverse $ go $ reverse yes)
+  = Just $ Let (NonRec cb expr) $ foldl (\e (x, ex) -> Let (NonRec x ex) e) e' (reverse $ go $ reverse yes)
 
   where
     go xes@((_, e):_) = let bs = grapBinds e in mapSnd (replaceBinds bs) <$> xes
@@ -342,9 +341,9 @@ varTuple x
   = Nothing
 
 takeBinds  :: Nat -> CoreExpr -> Maybe ([(Var, CoreExpr)], CoreExpr)
-takeBinds n e
-  | n < 2     = Nothing
-  | otherwise = {- mapFst reverse <$> -} go n e
+takeBinds nat ce
+  | nat < 2     = Nothing
+  | otherwise = {- mapFst reverse <$> -} go nat ce
     where
       go 0 e                      = Just ([], e)
       go n (Let (NonRec x e) e')  = do (xes, e'') <- go (n-1) e'
@@ -388,11 +387,11 @@ hasTuple ys = stepE
 --------------------------------------------------------------------------------
 
 replaceTuple :: [Var] -> CoreExpr -> CoreExpr -> Maybe CoreExpr
-replaceTuple ys e e'           = stepE e
+replaceTuple ys ce ce'           = stepE ce
   where
-    t'                          = Ghc.exprType e'
+    t'                          = Ghc.exprType ce'
     stepE e
-     | Just xs <- isVarTup ys e = Just $ substTuple xs ys e'
+     | Just xs <- isVarTup ys e = Just $ substTuple xs ys ce'
      | otherwise                = go e
     stepA (Alt DEFAULT xs err)  = Just (Alt DEFAULT xs (replaceIrrefutPat t' err))
     stepA (Alt c xs e)          = Alt c xs   <$> stepE e
@@ -401,7 +400,7 @@ replaceTuple ys e e'           = stepE e
     go _                        = Nothing
 
 _showExpr :: CoreExpr -> String
-_showExpr e = show' e
+_showExpr = show'
   where
     show' (App e1 e2) = show' e1 ++ " " ++ show' e2
     show' (Var x)     = _showVar x

From c49859b0a4530d67cd6a9cc50bf313e7a9dafdb4 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:27:36 +1300
Subject: [PATCH 136/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.Bounds

---
 src/Language/Haskell/Liquid/Types/Bounds.hs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/Bounds.hs b/src/Language/Haskell/Liquid/Types/Bounds.hs
index 1df13a33f4..c8b26d9aa9 100644
--- a/src/Language/Haskell/Liquid/Types/Bounds.hs
+++ b/src/Language/Haskell/Liquid/Types/Bounds.hs
@@ -4,7 +4,6 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric      #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
 
 module Language.Haskell.Liquid.Types.Bounds (
@@ -63,13 +62,13 @@ instance (PPrint e, PPrint t) => (Show (Bound t e)) where
 
 
 instance (PPrint e, PPrint t) => (PPrint (Bound t e)) where
-  pprintTidy k (Bound s vs ps xs e) = "bound" <+> pprintTidy k s <+>
+  pprintTidy k (Bound s vs ps ys e) = "bound" <+> pprintTidy k s <+>
                                       "forall" <+> pprintTidy k vs <+> "." <+>
                                       pprintTidy k (fst <$> ps) <+> "=" <+>
-                                      ppBsyms k (fst <$> xs) <+> pprintTidy k e
+                                      ppBsyms k (fst <$> ys) <+> pprintTidy k e
     where
       ppBsyms _ [] = ""
-      ppBsyms k xs = "\\" <+> pprintTidy k xs <+> "->"
+      ppBsyms k' xs = "\\" <+> pprintTidy k' xs <+> "->"
 
 instance Bifunctor Bound where
   first  f (Bound s vs ps xs e) = Bound s (f <$> vs) (Misc.mapSnd f <$> ps) (Misc.mapSnd f <$> xs) e
@@ -77,7 +76,7 @@ instance Bifunctor Bound where
 
 makeBound :: (PPrint r, UReftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r)
           => RRBound RSort -> [RRType r] -> [F.Symbol] -> RRType r -> RRType r
-makeBound (Bound _  vs ps xs p) ts qs
+makeBound (Bound _  vs ps xs expr) ts qs
          = RRTy cts mempty OCons
   where
     cts  = (\(x, t) -> (x, foldr subsTyVarMeet t su)) <$> cts'
@@ -85,7 +84,7 @@ makeBound (Bound _  vs ps xs p) ts qs
     cts' = makeBoundType penv rs xs
 
     penv = zip (val . fst <$> ps) qs
-    rs   = bkImp [] p
+    rs   = bkImp [] expr
 
     bkImp acc (F.PImp p q) = bkImp (p:acc) q
     bkImp acc p          = p:acc
@@ -129,10 +128,10 @@ isPApp penv (F.EApp e _)         = isPApp penv e
 isPApp _    _                  = False
 
 toUsedPVars :: [(F.Symbol, F.Symbol)] -> F.Expr -> (F.Symbol, [PVar ()])
-toUsedPVars penv q@(F.EApp _ e) = (x, [toUsedPVar penv q])
+toUsedPVars penv q@(F.EApp _ expr) = (sym, [toUsedPVar penv q])
   where
     -- NV : TODO make this a better error
-    x = case {- unProp -} e of {F.EVar x -> x; e -> todo Nothing ("Bound fails in " ++ show e) }
+    sym = case {- unProp -} expr of {F.EVar x -> x; e -> todo Nothing ("Bound fails in " ++ show e) }
 toUsedPVars _ _ = impossible Nothing "This cannot happen"
 
 toUsedPVar :: [(F.Symbol, F.Symbol)] -> F.Expr -> PVar ()

From 866cb157ebfdd9ce0190e673c794c09e70e519a1 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:27:43 +1300
Subject: [PATCH 137/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.Equality

---
 src/Language/Haskell/Liquid/Types/Equality.hs | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/Equality.hs b/src/Language/Haskell/Liquid/Types/Equality.hs
index 688eb9697a..aa3eaa83cb 100644
--- a/src/Language/Haskell/Liquid/Types/Equality.hs
+++ b/src/Language/Haskell/Liquid/Types/Equality.hs
@@ -1,7 +1,5 @@
 {-# LANGUAGE FlexibleInstances    #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
-
 -- Syntactic Equality of Types up tp forall type renaming
 
 module Language.Haskell.Liquid.Types.Equality where 
@@ -18,14 +16,14 @@ instance REq SpecType where
   t1 =*= t2 = compareRType t1 t2 
   
 compareRType :: SpecType -> SpecType -> Bool 
-compareRType i1 i2 = res && unify vs   
+compareRType i1 i2 = res && unify ys
   where 
     unify vs = and (sndEq <$> L.groupBy (\(x1,_) (x2,_) -> x1 == x2) vs) 
     sndEq [] = True 
     sndEq [_] = True 
     sndEq ((_,y):xs) = all (==y) (snd <$> xs)
 
-    (res, vs) = runWriter (go i1 i2)
+    (res, ys) = runWriter (go i1 i2)
     go :: SpecType -> SpecType -> Writer [(RTyVar, RTyVar)] Bool  
     go (RAllT x1 t1 r1) (RAllT x2 t2 r2)
       | RTV v1 <- ty_var_value x1

From 7266380a52f9368d7f7df23280975d7103fc9dd5 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:34:19 +1300
Subject: [PATCH 138/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.Fresh

---
 src/Language/Haskell/Liquid/Types/Fresh.hs | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/Fresh.hs b/src/Language/Haskell/Liquid/Types/Fresh.hs
index ba8797abe5..40fd3515e0 100644
--- a/src/Language/Haskell/Liquid/Types/Fresh.hs
+++ b/src/Language/Haskell/Liquid/Types/Fresh.hs
@@ -7,8 +7,6 @@
 {-# LANGUAGE UndecidableInstances  #-}
 {-# LANGUAGE ConstraintKinds       #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
-
 module Language.Haskell.Liquid.Types.Fresh
   ( Freshable(..)
   , refreshTy
@@ -137,13 +135,13 @@ refreshRefType allowTC (RAllT α t r)
 refreshRefType allowTC (RAllP π t)
   = RAllP π <$> refresh allowTC t
 
-refreshRefType allowTC (RImpF b i t t' _)
-  | b == F.dummySymbol = (\b t1 t2 -> RImpF b i t1 t2 mempty) <$> fresh <*> refresh allowTC t <*> refresh allowTC t'
-  | otherwise          = (\t1 t2 -> RImpF b i t1 t2 mempty)   <$> refresh allowTC t <*> refresh allowTC t'
+refreshRefType allowTC (RImpF sym i t t' _)
+  | sym == F.dummySymbol = (\b t1 t2 -> RImpF b i t1 t2 mempty) <$> fresh <*> refresh allowTC t <*> refresh allowTC t'
+  | otherwise          = (\t1 t2 -> RImpF sym i t1 t2 mempty)   <$> refresh allowTC t <*> refresh allowTC t'
 
-refreshRefType allowTC (RFun b i t t' _)
-  | b == F.dummySymbol = (\b t1 t2 -> RFun b i t1 t2 mempty) <$> fresh <*> refresh allowTC t <*> refresh allowTC t'
-  | otherwise          = (\t1 t2 -> RFun b i t1 t2 mempty)   <$> refresh allowTC t <*> refresh allowTC t'
+refreshRefType allowTC (RFun sym i t t' _)
+  | sym == F.dummySymbol = (\b t1 t2 -> RFun b i t1 t2 mempty) <$> fresh <*> refresh allowTC t <*> refresh allowTC t'
+  | otherwise          = (\t1 t2 -> RFun sym i t1 t2 mempty)   <$> refresh allowTC t <*> refresh allowTC t'
 
 refreshRefType _ (RApp rc ts _ _) | isClass rc
   = return $ rRCls rc ts
@@ -261,8 +259,8 @@ refreshArgsSub t
 refreshPs :: (FreshM m) => SpecType -> m SpecType
 refreshPs = mapPropM go
   where
-    go (RProp s t) = do
-      t'    <- refreshPs t
+    go (RProp s st) = do
+      t'    <- refreshPs st
       xs    <- mapM (const fresh) s
       let su = F.mkSubst [(y, F.EVar x) | (x, (y, _)) <- zip xs s]
       return $ RProp [(x, t) | (x, (_, t)) <- zip xs s] $ F.subst su t'

From 9c92b4f77ad95f3e11203d469cfbe71fed19ca52 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:41:48 +1300
Subject: [PATCH 139/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.PredType

---
 src/Language/Haskell/Liquid/Types/PredType.hs | 45 +++++++++----------
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/PredType.hs b/src/Language/Haskell/Liquid/Types/PredType.hs
index 192be1f814..1961170d68 100644
--- a/src/Language/Haskell/Liquid/Types/PredType.hs
+++ b/src/Language/Haskell/Liquid/Types/PredType.hs
@@ -5,7 +5,6 @@
 {-# LANGUAGE UndecidableInstances #-}
 
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
 
 module Language.Haskell.Liquid.Types.PredType (
@@ -155,7 +154,7 @@ dataConResultTy dc αs t = mkFamilyTyConApp tc tArgs'
 
 meetWorkWrapRep :: DataCon -> SpecRep -> SpecRep -> SpecRep
 meetWorkWrapRep c workR wrapR
-  | 0 <= pad
+  | 0 <= pad'
   = workR { ty_binds = xs ++ ty_binds wrapR
           , ty_args  = ts ++ zipWith F.meet ts' (ty_args wrapR)
           , ty_res   = strengthenRType (ty_res workR)    (ty_res  wrapR)
@@ -164,9 +163,9 @@ meetWorkWrapRep c workR wrapR
   | otherwise
   = panic (Just (getSrcSpan c)) errMsg
   where
-    pad       = {- F.tracepp ("MEETWKRAP: " ++ show (ty_vars workR)) $ -} workN - wrapN
-    (xs, _)   = splitAt pad (ty_binds workR)
-    (ts, ts') = splitAt pad (ty_args  workR)
+    pad'      = {- F.tracepp ("MEETWKRAP: " ++ show (ty_vars workR)) $ -} workN - wrapN
+    (xs, _)   = splitAt pad' (ty_binds workR)
+    (ts, ts') = splitAt pad' (ty_args  workR)
     workN     = length      (ty_args  workR)
     wrapN     = length      (ty_args  wrapR)
     errMsg    = "Unsupported Work/Wrap types for Data Constructor " ++ showPpr c
@@ -183,17 +182,17 @@ dcWrapSpecType allowTC dc (DataConP _ _ vs ps cs yts rt _ _ _)
     mkArrow makeVars' ps [] ts' rt'
   where
     isCls    = Ghc.isClassTyCon $ Ghc.dataConTyCon dc
-    (xs, ts) = unzip (reverse yts)
+    (as, sts) = unzip (reverse yts)
     mkDSym z = F.symbol z `F.suffixSymbol` F.symbol dc
-    ys       = mkDSym <$> xs
+    bs       = mkDSym <$> as
     tx _  []     []     []     = []
     tx su (x:xs) (y:ys) (t:ts) = (y, classRFInfo allowTC , if allowTC && isCls then t else F.subst (F.mkSubst su) t, mempty)
                                : tx ((x, F.EVar y):su) xs ys ts
     tx _ _ _ _ = panic Nothing "PredType.dataConPSpecType.tx called on invalid inputs"
-    yts'     = tx [] xs ys ts
+    yts'     = tx [] as bs sts
     ts'      = map ("" , classRFInfo allowTC , , mempty) cs ++ yts'
-    su       = F.mkSubst [(x, F.EVar y) | (x, y) <- zip xs ys]
-    rt'      = F.subst su rt
+    subst    = F.mkSubst [(x, F.EVar y) | (x, y) <- zip as bs]
+    rt'      = F.subst subst rt
     makeVars = zipWith (\v a -> RTVar v (rTVarInfo a :: RTVInfo RSort)) vs (fst $ splitForAllTyCoVars $ dataConRepType dc)
     makeVars' = zip makeVars (repeat mempty)
 
@@ -337,7 +336,7 @@ substPVar src dst = go
     go (RImpF x i t t' r) = RImpF x i (go t)  (go t') (goRR r)
     go (RAllE x t t')     = RAllE x   (go t)  (go t')
     go (REx x t t')       = REx x     (go t)  (go t')
-    go (RRTy e r o t)     = RRTy e'   (goRR r) o (go t) where e' = [(x, go t) | (x, t) <- e]
+    go (RRTy e r o rt)    = RRTy e'   (goRR r) o (go rt) where e' = [(x, go t) | (x, t) <- e]
     go (RAppTy t1 t2 r)   = RAppTy    (go t1) (go t2) (goRR r)
     go (RHole r)          = RHole     (goRR r)
     go t@(RExprArg  _)    = t
@@ -356,12 +355,12 @@ substPVar src dst = go
 substPred :: String -> (RPVar, SpecProp) -> SpecType -> SpecType
 -------------------------------------------------------------------------------
 
-substPred _   (π, RProp ss (RVar a1 r1)) t@(RVar a2 r2)
+substPred _   (rp, RProp ss (RVar a1 r1)) t@(RVar a2 r2)
   | isPredInReft && a1 == a2    = RVar a1 $ meetListWithPSubs πs ss r1 r2'
   | isPredInReft                = panic Nothing ("substPred RVar Var Mismatch" ++ show (a1, a2))
   | otherwise                   = t
   where
-    (r2', πs)                   = splitRPvar π r2
+    (r2', πs)                   = splitRPvar rp r2
     isPredInReft                = not $ null πs
 
 substPred msg su@(π, _ ) (RApp c ts rs r)
@@ -377,22 +376,22 @@ substPred msg (p, tp) (RAllP q@PV{} t)
 
 substPred msg su (RAllT a t r)  = RAllT a (substPred msg su t) r
 
-substPred msg su@(π,prop) (RFun x i t t' r)
+substPred msg su@(rp,prop) (RFun x i rt rt' r)
 --                        = RFun x (substPred msg su t) (substPred msg su t') r
-  | null πs                     = RFun x i (substPred msg su t) (substPred msg su t') r
+  | null πs                     = RFun x i (substPred msg su rt) (substPred msg su rt') r
   | otherwise                   =
       let sus = (\π -> F.mkSubst (zip (fst <$> rf_args prop) (thd3 <$> pargs π))) <$> πs in
-      foldl (\t su -> t `F.meet` F.subst su (rf_body prop)) (RFun x i (substPred msg su t) (substPred msg su t') r') sus
-  where (r', πs)                = splitRPvar π r
+      foldl (\t subst -> t `F.meet` F.subst subst (rf_body prop)) (RFun x i (substPred msg su rt) (substPred msg su rt') r') sus
+  where (r', πs)                = splitRPvar rp r
 -- ps has   , pargs :: ![(t, Symbol, Expr)]
 
 -- AT: just a copy of the other case, mutatis mutandi. (is there a less hacky way?)
-substPred msg su@(π,prop) (RImpF x i t t' r)
-  | null πs                     = RImpF x i (substPred msg su t) (substPred msg su t') r
+substPred msg su@(rp,prop) (RImpF x i rt rt' r)
+  | null πs                     = RImpF x i (substPred msg su rt) (substPred msg su rt') r
   | otherwise                   =
       let sus = (\π -> F.mkSubst (zip (fst <$> rf_args prop) (thd3 <$> pargs π))) <$> πs in
-      foldl (\t su -> t `F.meet` F.subst su (rf_body prop)) (RImpF x i (substPred msg su t) (substPred msg su t') r') sus
-  where (r', πs)                = splitRPvar π r
+      foldl (\t subst -> t `F.meet` F.subst subst (rf_body prop)) (RImpF x i (substPred msg su rt) (substPred msg su rt') r') sus
+  where (r', πs)                = splitRPvar rp r
 
 
 
@@ -427,8 +426,8 @@ substRCon msg (_, RProp ss t1@(RApp c1 ts1 rs1 r1)) t2@(RApp c2 ts2 rs2 _) πs r
     ts                     = F.subst su $ safeZipWith (msg ++ ": substRCon")  strSub  ts1  ts2
     rs                     = F.subst su $ safeZipWith (msg ++ ": substRCon2") strSubR rs1' rs2'
     (rs1', rs2')           = pad "substRCon" F.top rs1 rs2
-    strSub r1 r2           = meetListWithPSubs πs ss r1 r2
-    strSubR r1 r2          = meetListWithPSubsRef πs ss r1 r2
+    strSub x r2           = meetListWithPSubs πs ss x r2
+    strSubR x r2          = meetListWithPSubsRef πs ss x r2
 
     su = F.mkSubst $ zipWith (\s1 s2 -> (s1, F.EVar s2)) (rvs t1) (rvs t2)
 

From 138839e22b4b1e5501835a0acd1d4e75c318fd2b Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:44:28 +1300
Subject: [PATCH 140/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.PrettyPrint

---
 .../Haskell/Liquid/Types/PrettyPrint.hs       | 25 +++++++++----------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs
index ae16ed5165..712628475c 100644
--- a/src/Language/Haskell/Liquid/Types/PrettyPrint.hs
+++ b/src/Language/Haskell/Liquid/Types/PrettyPrint.hs
@@ -12,7 +12,6 @@
 {-# LANGUAGE ScopedTypeVariables  #-}
 
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 
 module Language.Haskell.Liquid.Types.PrettyPrint
   ( -- * Printable RTypes
@@ -258,8 +257,8 @@ pprRtype bb p (RAppTy t t' r)
   = F.ppTy r $ pprRtype bb p t <+> pprRtype bb p t'
 pprRtype bb p (RRTy e _ OCons t)
   = sep [braces (pprRsubtype bb p e) <+> "=>", pprRtype bb p t]
-pprRtype bb p (RRTy e r o t)
-  = sep [ppp (pprint o <+> ppe <+> pprint r), pprRtype bb p t]
+pprRtype bb p (RRTy e r o rt)
+  = sep [ppp (pprint o <+> ppe <+> pprint r), pprRtype bb p rt]
   where
     ppe         = hsep (punctuate comma (ppxt <$> e)) <+> dcolon
     ppp  doc    = text "<<" <+> doc <+> text ">>"
@@ -299,19 +298,19 @@ ppExists
       PPrint (RType c tv ()), F.Reftable (RTProp c tv r),
       F.Reftable (RTProp c tv ()))
   => PPEnv -> Prec -> RType c tv r -> Doc
-ppExists bb p t
-  = text "exists" <+> brackets (intersperse comma [pprDbind bb topPrec x t | (x, t) <- zs]) <-> dot <-> pprRtype bb p t'
-    where (zs,  t')               = split [] t
+ppExists bb p rt
+  = text "exists" <+> brackets (intersperse comma [pprDbind bb topPrec x t | (x, t) <- ws]) <-> dot <-> pprRtype bb p rt'
+    where (ws,  rt')               = split [] rt
           split zs (REx x t t')   = split ((x,t):zs) t'
           split zs t                = (reverse zs, t)
 
 ppAllExpr
   :: (OkRT c tv r, PPrint (RType c tv r), PPrint (RType c tv ()))
   => PPEnv -> Prec -> RType c tv r -> Doc
-ppAllExpr bb p t
-  = text "forall" <+> brackets (intersperse comma [pprDbind bb topPrec x t | (x, t) <- zs]) <-> dot <-> pprRtype bb p t'
+ppAllExpr bb p rt
+  = text "forall" <+> brackets (intersperse comma [pprDbind bb topPrec x t | (x, t) <- ws]) <-> dot <-> pprRtype bb p rt'
     where
-      (zs,  t')               = split [] t
+      (ws,  rt')               = split [] rt
       split zs (RAllE x t t') = split ((x,t):zs) t'
       split zs t              = (reverse zs, t)
 
@@ -338,12 +337,12 @@ pprDbind bb p x t
 pprRtyFun
   :: ( OkRT c tv r, PPrint (RType c tv r), PPrint (RType c tv ()))
   => PPEnv -> Doc -> RType c tv r -> Doc
-pprRtyFun bb prefix t = hsep (prefix : dArgs ++ [dOut])
+pprRtyFun bb prefix rt = hsep (prefix : dArgs ++ [dOut])
   where
     dArgs               = concatMap ppArg args
     dOut                = pprRtype bb topPrec out
     ppArg (b, t, a)     = [pprDbind bb funPrec b t, a]
-    (args, out)         = brkFun t
+    (args, out)         = brkFun rt
 
 {-
 pprRtyFun bb prefix t
@@ -492,10 +491,10 @@ reduceFilters renderer fs err = filter (filterDoesMatchErr renderer err) fs
 
 filterDoesMatchErr :: (e -> String) -> e -> Filter -> Bool
 filterDoesMatchErr _        _ AnyFilter = True
-filterDoesMatchErr renderer e (StringFilter filter) = stringMatch filter (renderer e)
+filterDoesMatchErr renderer e (StringFilter filter') = stringMatch filter' (renderer e)
 
 stringMatch :: String -> String -> Bool
-stringMatch filter str = filter `L.isInfixOf` str
+stringMatch filter' str = filter' `L.isInfixOf` str
 
 -- | Used in `filterReportErrorsWith'`
 data FilterReportErrorsArgs m filter msg e a =

From 23744bba931e5a9844e99873f1dbe7b8e8c84099 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Thu, 23 Feb 2023 10:49:06 +1300
Subject: [PATCH 141/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.RefType

---
 src/Language/Haskell/Liquid/Types/RefType.hs | 59 ++++++++++----------
 1 file changed, 29 insertions(+), 30 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/RefType.hs b/src/Language/Haskell/Liquid/Types/RefType.hs
index 0ced6a89b6..3277d50c21 100644
--- a/src/Language/Haskell/Liquid/Types/RefType.hs
+++ b/src/Language/Haskell/Liquid/Types/RefType.hs
@@ -15,7 +15,6 @@
 
 {-# OPTIONS_GHC -Wno-incomplete-patterns #-} -- TODO(#1918): Only needed for GHC <9.0.1.
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 {-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
 
 -- | Refinement Types. Mostly mirroring the GHC Type definition, but with
@@ -145,14 +144,14 @@ import Data.List (foldl')
 strengthenDataConType :: (Var, SpecType) -> (Var, SpecType)
 strengthenDataConType (x, t) = (x, fromRTypeRep trep {ty_res = tres})
   where
-    tres     = F.notracepp _msg $ ty_res trep `strengthen` MkUReft (exprReft expr) mempty
+    tres     = F.notracepp _msg $ ty_res trep `strengthen` MkUReft (exprReft expr') mempty
     trep     = toRTypeRep t
     _msg     = "STRENGTHEN-DATACONTYPE x = " ++ F.showpp (x, zip xs ts)
     (xs, ts) = dataConArgs trep
     as       = ty_vars  trep
     x'       = symbol x
-    expr | null xs && null as = EVar x'
-         | otherwise          = mkEApp (dummyLoc x') (EVar <$> xs)
+    expr' | null xs && null as = EVar x'
+          | otherwise          = mkEApp (dummyLoc x') (EVar <$> xs)
 
 
 dataConArgs :: SpecRep -> ([Symbol], [SpecType])
@@ -167,9 +166,9 @@ pdVar :: PVar t -> Predicate
 pdVar v        = Pr [uPVar v]
 
 findPVar :: [PVar (RType c tv ())] -> UsedPVar -> PVar (RType c tv ())
-findPVar ps p = PV name ty v (zipWith (\(_, _, e) (t, s, _) -> (t, s, e)) (pargs p) args)
+findPVar ps upv = PV name ty v (zipWith (\(_, _, e) (t, s, _) -> (t, s, e)) (pargs upv) args)
   where
-    PV name ty v args = fromMaybe (msg p) $ L.find ((== pname p) . pname) ps
+    PV name ty v args = fromMaybe (msg upv) $ L.find ((== pname upv) . pname) ps
     msg p = panic Nothing $ "RefType.findPVar" ++ showpp p ++ "not found"
 
 -- | Various functions for converting vanilla `Reft` to `Spec`
@@ -505,7 +504,7 @@ kindToBRType :: Monoid r => Type -> BRType r
 kindToBRType = kindToRType_ bareOfType
 
 kindToRType_ :: (Type -> z) -> Type -> z
-kindToRType_ ofType        = ofType . go
+kindToRType_ ofType'       = ofType' . go
   where
     go t
      | t == typeSymbolKind = stringTy
@@ -536,7 +535,7 @@ rPred     = RAllP
 
 rEx :: Foldable t
     => t (Symbol, RType c tv r) -> RType c tv r -> RType c tv r
-rEx xts t = foldr (\(x, tx) t -> REx x tx t) t xts
+rEx xts rt = foldr (\(x, tx) t -> REx x tx t) rt xts
 
 rApp :: TyCon
      -> [RType RTyCon tv r]
@@ -626,7 +625,7 @@ strengthenRefType_ ::
          ) => (RType c tv r -> RType c tv r -> RType c tv r)
            ->  RType c tv r -> RType c tv r -> RType c tv r
 
-strengthenRefTypeGen t1 t2 = strengthenRefType_ f t1 t2
+strengthenRefTypeGen = strengthenRefType_ f
   where
     f (RVar v1 r1) t  = RVar v1 (r1 `meet` fromMaybe mempty (stripRTypeBase t))
     f t (RVar _ r1)  = t `strengthen` r1
@@ -1041,7 +1040,7 @@ subsTyVars
   -> t (tv, RType c tv (), RType c tv r)
   -> RType c tv r
   -> RType c tv r
-subsTyVars meet ats t = foldl' (flip (subsTyVar meet)) t ats
+subsTyVars meet' ats t = foldl' (flip (subsTyVar meet')) t ats
 
 subsTyVar
   :: (Eq tv, Hashable tv, Reftable r, TyConable c,
@@ -1053,7 +1052,7 @@ subsTyVar
   -> (tv, RType c tv (), RType c tv r)
   -> RType c tv r
   -> RType c tv r
-subsTyVar meet        = subsFree meet S.empty
+subsTyVar meet'        = subsFree meet' S.empty
 
 subsFree
   :: (Eq tv, Hashable tv, Reftable r, TyConable c,
@@ -1079,9 +1078,9 @@ subsFree m s z@(α, τ, _) (RApp c ts rs r)
   = RApp c' (subsFree m s z <$> ts) (subsFreeRef m s z <$> rs) (subt (α, τ) r)
     where z' = (α, τ) -- UNIFY: why instantiating INSIDE parameters?
           c' = if α `S.member` s then c else subt z' c
-subsFree meet s (α', τ, t') (RVar α r)
+subsFree meet' s (α', τ, t') (RVar α r)
   | α == α' && not (α `S.member` s)
-  = if meet then t' `strengthen` subt (α, τ) r else t'
+  = if meet' then t' `strengthen` subt (α, τ) r else t'
   | otherwise
   = RVar (subt (α', τ) α) r
 subsFree m s z (RAllE x t t')
@@ -1326,7 +1325,7 @@ instance (SubsTy tv ty ty) => SubsTy tv ty (PVKind ty) where
   subt _   PVHProp   = PVHProp
 
 instance (SubsTy tv ty ty) => SubsTy tv ty (PVar ty) where
-  subt su (PV n t v xts) = PV n (subt su t) v [(subt su t, x, y) | (t,x,y) <- xts]
+  subt su (PV n pvk v xts) = PV n (subt su pvk) v [(subt su t, x, y) | (t,x,y) <- xts]
 
 instance SubsTy RTyVar RSort RTyCon where
    subt z c = RTyCon tc ps' i
@@ -1582,9 +1581,9 @@ rTypeSort tce = typeSort tce . toType True
 --------------------------------------------------------------------------------
 applySolution :: (Functor f) => FixSolution -> f SpecType -> f SpecType
 --------------------------------------------------------------------------------
-applySolution = fmap . fmap . mapReft . appSolRefa
+applySolution = fmap . fmap . mapReft' . appSolRefa
   where
-    mapReft f (MkUReft (Reft (x, z)) p) = MkUReft (Reft (x, f z)) p
+    mapReft' f (MkUReft (Reft (x, z)) p) = MkUReft (Reft (x, f z)) p
 
 appSolRefa :: Visitable t
            => M.HashMap KVar Expr -> t -> t
@@ -1709,10 +1708,10 @@ grabArgs τs τ
 expandProductType :: (PPrint r, Reftable r, SubsTy RTyVar (RType RTyCon RTyVar ()) r, Reftable (RTProp RTyCon RTyVar r))
                   => Var -> RType RTyCon RTyVar r -> RType RTyCon RTyVar r
 expandProductType x t
-  | isTrivial       = t
+  | isTrivial'      = t
   | otherwise       = fromRTypeRep $ trep {ty_binds = xs', ty_info=is', ty_args = ts', ty_refts = rs'}
      where
-      isTrivial     = ofType (varType x) == toRSort t
+      isTrivial'    = ofType (varType x) == toRSort t
       τs            = map irrelevantMult $ fst $ splitFunTys $ snd $ splitForAllTyCoVars $ toType False t
       trep          = toRTypeRep t
       (xs',is',ts',rs') = unzip4 $ concatMap mkProductTy $ zip5 τs (ty_binds trep) (ty_info trep) (ty_args trep) (ty_refts trep)
@@ -1818,11 +1817,11 @@ mkDType :: Symbolic a
 mkDType autoenv xvs acc [(v, (x, t))]
   = Left ((x, ) $ t `strengthen` tr)
   where
-    tr = uTop $ Reft (vv, pOr (r:acc))
-    r  = cmpLexRef xvs (v', vv, f)
-    v' = symbol v
-    f  = mkDecrFun autoenv  t
-    vv = "vvRec"
+    tr  = uTop $ Reft (vv', pOr (r:acc))
+    r   = cmpLexRef xvs (v', vv', f)
+    v'  = symbol v
+    f   = mkDecrFun autoenv  t
+    vv' = "vvRec"
 
 mkDType autoenv xvs acc ((v, (x, t)):vxts)
   = mkDType autoenv ((v', x, f):xvs) (r:acc) vxts
@@ -1859,10 +1858,10 @@ cmpLexRef vxs (v, x, g)
   where zero = ECon $ I 0
 
 makeLexRefa :: [Located Expr] -> [Located Expr] -> UReft Reft
-makeLexRefa es' es = uTop $ Reft (vv, PIff (EVar vv) $ pOr rs)
+makeLexRefa es' es = uTop $ Reft (vv', PIff (EVar vv') $ pOr rs)
   where
-    rs = makeLexReft [] [] (val <$> es) (val <$> es')
-    vv = "vvRec"
+    rs  = makeLexReft [] [] (val <$> es) (val <$> es')
+    vv' = "vvRec"
 
 makeLexReft :: [(Expr, Expr)] -> [Expr] -> [Expr] -> [Expr] -> [Expr]
 makeLexReft _ acc [] []
@@ -1919,7 +1918,7 @@ ppVars :: (PPrint a) => Tidy -> [a] -> Doc
 ppVars k as = "forall" <+> hcat (punctuate " " (F.pprintTidy k <$> as)) <+> "."
 
 ppFields :: (PPrint k, PPrint v) => Tidy -> Doc -> [(k, v)] -> Doc
-ppFields k sep kvs = hcat $ punctuate sep (F.pprintTidy k <$> kvs)
+ppFields k sep' kvs = hcat $ punctuate sep' (F.pprintTidy k <$> kvs)
 
 ppMbSizeFun :: Maybe SizeFun -> Doc
 ppMbSizeFun Nothing  = ""
@@ -1949,8 +1948,8 @@ tyVarsPosition :: RType RTyCon tv r -> Positions tv
 tyVarsPosition = go (Just True)
   where
     go p (RVar t _)        = report p t
-    go p (RFun _ _ t1 t2 _)  = go (flip p) t1 <> go p t2
-    go p (RImpF _ _ t1 t2 _) = go (flip p) t1 <> go p t2
+    go p (RFun _ _ t1 t2 _)  = go (flip' p) t1 <> go p t2
+    go p (RImpF _ _ t1 t2 _) = go (flip' p) t1 <> go p t2
     go p (RAllT _ t _)     = go p t
     go p (RAllP _ t)       = go p t
     go p (RApp c ts _ _)   = mconcat (zipWith go (getPosition p <$> varianceTyArgs (rtc_info c)) ts)
@@ -1968,7 +1967,7 @@ tyVarsPosition = go (Just True)
     report Nothing v      = Pos [] [] [v]
     report (Just True) v  = Pos [v] [] []
     report (Just False) v = Pos [] [v] []
-    flip = fmap not
+    flip' = fmap not
 
 data Positions a = Pos {ppos :: [a], pneg ::  [a], punknown :: [a]}
 

From e722c2c37539c4fe78d604fcf0c1d6624d882df7 Mon Sep 17 00:00:00 2001
From: Renan 
Date: Sun, 15 Aug 2021 18:25:13 -0300
Subject: [PATCH 142/219] Add GHC.Num.abs spec

---
 liquid-base/src/GHC/Num.spec | 2 ++
 tests/neg/abs.hs             | 5 +++++
 tests/pos/abs.hs             | 5 +++++
 3 files changed, 12 insertions(+)
 create mode 100644 tests/neg/abs.hs
 create mode 100644 tests/pos/abs.hs

diff --git a/liquid-base/src/GHC/Num.spec b/liquid-base/src/GHC/Num.spec
index 3809a3e3ea..23a5877589 100644
--- a/liquid-base/src/GHC/Num.spec
+++ b/liquid-base/src/GHC/Num.spec
@@ -9,5 +9,7 @@ GHC.Num.negate :: (GHC.Num.Num a)
                => x:a
                -> {v:a | v = -x}
 
+GHC.Num.abs :: (GHC.Num.Num a) => a -> {x:a | x >= 0}
+
 GHC.Num.+ :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x + y }
 GHC.Num.- :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x - y }
diff --git a/tests/neg/abs.hs b/tests/neg/abs.hs
new file mode 100644
index 0000000000..8d9fd2e9d2
--- /dev/null
+++ b/tests/neg/abs.hs
@@ -0,0 +1,5 @@
+module AbsNegTest where
+
+{-@ f :: Int -> {n:Int | n < 0} @-}
+f :: Int -> Int
+f x = abs x
diff --git a/tests/pos/abs.hs b/tests/pos/abs.hs
new file mode 100644
index 0000000000..5165173ab1
--- /dev/null
+++ b/tests/pos/abs.hs
@@ -0,0 +1,5 @@
+module AbsPosTest where
+
+{-@ f :: Int -> {n:Int | n >= 0} @-}
+f :: Int -> Int
+f x = abs x

From c6aa459036225aba5eab46f467620305c49d24ac Mon Sep 17 00:00:00 2001
From: Renan 
Date: Sat, 21 Nov 2020 11:41:05 -0300
Subject: [PATCH 143/219] fix real exponential spec

---
 liquid-base/src/GHC/Real.spec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/liquid-base/src/GHC/Real.spec b/liquid-base/src/GHC/Real.spec
index 830ec4fbb8..05b795b2f0 100644
--- a/liquid-base/src/GHC/Real.spec
+++ b/liquid-base/src/GHC/Real.spec
@@ -2,7 +2,7 @@ module spec GHC.Real where
 
 import GHC.Types
 
-(GHC.Real.^) :: (GHC.Num.Num a, GHC.Real.Integral b) => a:a -> n:b -> {v:a | v == 0 <=> a == 0 }
+(GHC.Real.^) :: (GHC.Num.Num a, GHC.Real.Integral b) => n:a -> {m:b | m >= 0} -> {k:a | (m == 0 => k == 1) && ((n == 0 && m /= 0) <=> k == 0)}
 
 GHC.Real.fromIntegral    :: (GHC.Real.Integral a, GHC.Num.Num b) => x:a -> {v:b|v=x}
 

From 1e74d258996bc63a84e3e706fa9d52ec0effcea0 Mon Sep 17 00:00:00 2001
From: Renan 
Date: Sat, 21 Nov 2020 12:49:04 -0300
Subject: [PATCH 144/219] write tests for real exponential spec

---
 tests/neg/exponential1.hs |  5 +++++
 tests/neg/exponential2.hs |  6 ++++++
 tests/pos/exponential.hs  | 18 ++++++++++++++++++
 3 files changed, 29 insertions(+)
 create mode 100644 tests/neg/exponential1.hs
 create mode 100644 tests/neg/exponential2.hs
 create mode 100644 tests/pos/exponential.hs

diff --git a/tests/neg/exponential1.hs b/tests/neg/exponential1.hs
new file mode 100644
index 0000000000..0935362d5a
--- /dev/null
+++ b/tests/neg/exponential1.hs
@@ -0,0 +1,5 @@
+-- negative test for real exponentiation
+module Foo where
+
+ex5 :: Float -> Int -> Float
+ex5 x y = x ^ y
diff --git a/tests/neg/exponential2.hs b/tests/neg/exponential2.hs
new file mode 100644
index 0000000000..bc95695c0b
--- /dev/null
+++ b/tests/neg/exponential2.hs
@@ -0,0 +1,6 @@
+-- negative test for real exponentiation
+module Foo where
+
+{-@ ex6 :: {n:Float | n /= 0} -> Int -> Float @-}
+ex6 :: Float -> Int -> Float
+ex6 x y = 1 / (x ^ y)
diff --git a/tests/pos/exponential.hs b/tests/pos/exponential.hs
new file mode 100644
index 0000000000..c5ff34c39c
--- /dev/null
+++ b/tests/pos/exponential.hs
@@ -0,0 +1,18 @@
+-- positive tests for real exponentiation
+module Foo where
+
+{-@ ex1 :: Float -> Nat -> Float @-}
+ex1 :: Float -> Int -> Float
+ex1 x y = x ^ y
+
+{-@ ex2 :: {n:Float | n /= 0} -> Nat -> Float @-}
+ex2 :: Float -> Int -> Float
+ex2 x y = 5 / (x ^ y)
+
+{-@ ex3 :: Float -> {n:Nat | n == 0} -> {v:Float | v == 1} @-}
+ex3 :: Float -> Int -> Float
+ex3 x y = 1 / (x ^ y)
+
+{-@ ex4 :: {b:Float | b == 0} -> {n:Nat | n /= 0} -> {v:Float | v == 0} @-}
+ex4 :: Float -> Int -> Float
+ex4 x y = x ^ y

From 151ef514083418ffb1e9eee69b150089c1d653e1 Mon Sep 17 00:00:00 2001
From: Renan 
Date: Sun, 5 Mar 2023 13:45:42 -0300
Subject: [PATCH 145/219] Attend PR suggestion

---
 liquid-base/src/GHC/Num.spec |  2 +-
 tests/pos/abs.hs             | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/liquid-base/src/GHC/Num.spec b/liquid-base/src/GHC/Num.spec
index 23a5877589..9e0bf0772d 100644
--- a/liquid-base/src/GHC/Num.spec
+++ b/liquid-base/src/GHC/Num.spec
@@ -9,7 +9,7 @@ GHC.Num.negate :: (GHC.Num.Num a)
                => x:a
                -> {v:a | v = -x}
 
-GHC.Num.abs :: (GHC.Num.Num a) => a -> {x:a | x >= 0}
+GHC.Num.abs :: (GHC.Num.Num a) => x:a -> {y:a | (x >= 0) ==> (y = x) && (x < 0) ==> y = -x}
 
 GHC.Num.+ :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x + y }
 GHC.Num.- :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x - y }
diff --git a/tests/pos/abs.hs b/tests/pos/abs.hs
index 5165173ab1..477adbdf22 100644
--- a/tests/pos/abs.hs
+++ b/tests/pos/abs.hs
@@ -3,3 +3,15 @@ module AbsPosTest where
 {-@ f :: Int -> {n:Int | n >= 0} @-}
 f :: Int -> Int
 f x = abs x
+
+{-@ g :: {n:Int | n >= 0} -> {m:Int | m = n} @-}
+g :: Int -> Int
+g x = abs x
+
+{-@ h :: {n:Int | n < 0} -> {m:Int | m = -n} @-}
+h :: Int -> Int
+h x = abs x
+
+{-@ f :: Int -> {n:Int | n >= 0} @-}
+f :: Int -> Int
+f x = abs x

From 82572db32cae682c5aa3fdf166d3955f183f3158 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Sun, 5 Mar 2023 17:45:17 -0300
Subject: [PATCH 146/219] Trivial change to test CircleCI

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 880e529ba6..ce9a4fe11c 100644
--- a/README.md
+++ b/README.md
@@ -142,6 +142,7 @@ You can directly extend and run the tests by modifying the files in
 
     tests/harness/
 
+
 ### Parallelism in Tests
 
 Most tests run in parallel, with a few module dependencies built sequentially in

From 0e62f18762116d036c0af99c2d88cb9612ccaba3 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:34:18 +1300
Subject: [PATCH 147/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.Types

---
 src/Language/Haskell/Liquid/Types/Types.hs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/Types.hs b/src/Language/Haskell/Liquid/Types/Types.hs
index fcc5ccf8f0..86e56ba817 100644
--- a/src/Language/Haskell/Liquid/Types/Types.hs
+++ b/src/Language/Haskell/Liquid/Types/Types.hs
@@ -12,7 +12,6 @@
 {-# LANGUAGE DerivingVia                #-}
 
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 
 -- | This module should contain all the global type definitions and basic instances.
 
@@ -418,7 +417,7 @@ toLogicMap ls = mempty {lmSymDefs = M.fromList $ map toLMap ls}
     toLMap (x, ys, e) = (F.val x, LMap {lmVar = x, lmArgs = ys, lmExpr = e})
 
 eAppWithMap :: LogicMap -> F.Located Symbol -> [Expr] -> Expr -> Expr
-eAppWithMap lmap f es def
+eAppWithMap lmap f es expr
   | Just (LMap _ xs e) <- M.lookup (F.val f) (lmSymDefs lmap)
   , length xs == length es
   = F.subst (F.mkSubst $ zip xs es) e
@@ -426,7 +425,7 @@ eAppWithMap lmap f es def
   , isApp e
   = F.subst (F.mkSubst $ zip xs es) $ dropApp e (length xs - length es)
   | otherwise
-  = def
+  = expr
 
 dropApp :: Expr -> Int -> Expr
 dropApp e i | i <= 0 = e
@@ -1398,7 +1397,7 @@ mkArrow :: [(RTVar tv (RType c tv ()), r)]
         -> [(Symbol, RFInfo, RType c tv r, r)]
         -> RType c tv r
         -> RType c tv r
-mkArrow αs πs yts xts = mkUnivs αs πs . mkArrs RImpF yts. mkArrs RFun xts
+mkArrow αs πs yts zts = mkUnivs αs πs . mkArrs RImpF yts . mkArrs RFun zts
   where
     mkArrs f xts t  = foldr (\(b,i,t1,r) t2 -> f b i t1 t2 r) t xts
 
@@ -1440,7 +1439,7 @@ mkUnivs :: (Foldable t, Foldable t1)
         -> t1 (PVar (RType c tv ()))
         -> RType c tv r
         -> RType c tv r
-mkUnivs αs πs t = foldr (\(a,r) t -> RAllT a t r) (foldr RAllP t πs) αs
+mkUnivs αs πs rt = foldr (\(a,r) t -> RAllT a t r) (foldr RAllP rt πs) αs
 
 bkUnivClass :: SpecType -> ([(SpecRTVar, RReft)],[PVar RSort], [(RTyCon, [SpecType])], SpecType )
 bkUnivClass t        = (as, ps, cs, t2)
@@ -2071,7 +2070,7 @@ allErrors = dErrors
 --------------------------------------------------------------------------------
 
 printWarning :: Logger -> DynFlags -> Warning -> IO ()
-printWarning logger dyn (Warning span doc) = GHC.putWarnMsg logger dyn span doc
+printWarning logger dyn (Warning srcSpan doc) = GHC.putWarnMsg logger dyn srcSpan doc
 
 --------------------------------------------------------------------------------
 -- | Error Data Type -----------------------------------------------------------
@@ -2326,7 +2325,7 @@ instance F.PPrint t => F.PPrint (RClass t) where
                 = ppMethods k ("class" <+> supers ts) n as [(m, RISig t) | (m, t) <- mts]
     where
       supers [] = ""
-      supers ts = tuplify (F.pprintTidy k   <$> ts) <+> "=>"
+      supers xs = tuplify (F.pprintTidy k   <$> xs) <+> "=>"
       tuplify   = parens . hcat . punctuate ", "
 
 
@@ -2334,7 +2333,7 @@ instance F.PPrint t => F.PPrint (RILaws t) where
   pprintTidy k (RIL n ss ts mts _) = ppEqs k ("instance laws" <+> supers ss) n ts mts
    where
     supers [] = ""
-    supers ts = tuplify (F.pprintTidy k   <$> ts) <+> "=>"
+    supers xs = tuplify (F.pprintTidy k   <$> xs) <+> "=>"
     tuplify   = parens . hcat . punctuate ", "
 
 

From f73e41b530ebdf109e22749e1336ff252cd2a477 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:34:30 +1300
Subject: [PATCH 148/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.Variance

---
 src/Language/Haskell/Liquid/Types/Variance.hs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/Variance.hs b/src/Language/Haskell/Liquid/Types/Variance.hs
index 0ad27550b3..991aef0bd8 100644
--- a/src/Language/Haskell/Liquid/Types/Variance.hs
+++ b/src/Language/Haskell/Liquid/Types/Variance.hs
@@ -4,7 +4,6 @@
 
 {-# OPTIONS_GHC -Wno-incomplete-patterns #-} -- TODO(#1918): Only needed for GHC <9.0.1.
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 
 module Language.Haskell.Liquid.Types.Variance (
   Variance(..), VarianceInfo, makeTyConVariance, flipVariance
@@ -60,13 +59,13 @@ instance F.PPrint Variance where
 
 
 makeTyConVariance :: TyCon -> VarianceInfo
-makeTyConVariance c = varSignToVariance <$> tvs
+makeTyConVariance tyCon = varSignToVariance <$> tvs
   where
-    tvs = GM.tyConTyVarsDef c
+    tvs = GM.tyConTyVarsDef tyCon
 
-    varsigns = if Ghc.isTypeSynonymTyCon c
-                  then go True (fromJust $ Ghc.synTyConRhs_maybe c)
-                  else L.nub $ concatMap goDCon $ Ghc.tyConDataCons c
+    varsigns = if Ghc.isTypeSynonymTyCon tyCon
+                  then go True (fromJust $ Ghc.synTyConRhs_maybe tyCon)
+                  else L.nub $ concatMap goDCon $ Ghc.tyConDataCons tyCon
 
     varSignToVariance v = case filter (\p -> GM.showPpr (fst p) == GM.showPpr v) varsigns of
                             []       -> Invariant
@@ -81,13 +80,13 @@ makeTyConVariance c = varSignToVariance <$> tvs
     go pos (TyVarTy v)       = [(v, pos)]
     go pos (AppTy t1 t2)     = go pos t1 ++ go pos t2
     go pos (TyConApp c' ts)
-       | c == c'
+       | tyCon == c'
        = []
 
 -- NV fix that: what happens if we have mutually recursive data types?
 -- now just provide "default" Bivariant for mutually rec types.
 -- but there should be a finer solution
-       | mutuallyRecursive c c'
+       | mutuallyRecursive tyCon c'
        = concatMap (goTyConApp pos Bivariant) ts
        | otherwise
        = concat $ zipWith (goTyConApp pos) (makeTyConVariance c') ts

From 6d18821d4cd978949c6c4c0efdb092cd491368da Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:35:27 +1300
Subject: [PATCH 149/219] Remove name shadowing from
 Language.Haskell.Liquid.Types.Visitors

---
 src/Language/Haskell/Liquid/Types/Visitors.hs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Types/Visitors.hs b/src/Language/Haskell/Liquid/Types/Visitors.hs
index d2130651ff..5055661824 100644
--- a/src/Language/Haskell/Liquid/Types/Visitors.hs
+++ b/src/Language/Haskell/Liquid/Types/Visitors.hs
@@ -2,7 +2,6 @@
 {-# LANGUAGE FlexibleInstances         #-}
 {-# LANGUAGE FlexibleContexts          #-}
 {-# LANGUAGE ScopedTypeVariables       #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 
 module Language.Haskell.Liquid.Types.Visitors (
 
@@ -160,7 +159,7 @@ data CoreVisitor env acc = CoreVisitor
   }
 
 coreVisitor :: CoreVisitor env acc -> env -> acc -> [CoreBind] -> acc
-coreVisitor vis env acc cbs   = snd (foldl' step (env, acc) cbs)
+coreVisitor vis cenv cacc cbs = snd (foldl' step (cenv, cacc) cbs)
   where
     stepXE (env, acc) (x,e)   = (env', stepE env' acc'   e)
       where

From 7d8ea1732bf71d8c01a74672130ffabfa1ae34bf Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:37:34 +1300
Subject: [PATCH 150/219] Remove name shadowing from
 Language.Haskell.Liquid.UX.ACSS

---
 src/Language/Haskell/Liquid/UX/ACSS.hs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/Language/Haskell/Liquid/UX/ACSS.hs b/src/Language/Haskell/Liquid/UX/ACSS.hs
index 78c21e6858..c2e54c810e 100644
--- a/src/Language/Haskell/Liquid/UX/ACSS.hs
+++ b/src/Language/Haskell/Liquid/UX/ACSS.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -Wno-name-shadowing -Wno-incomplete-uni-patterns #-}
+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
 
 -- | Formats Haskell source code as HTML with CSS and Mouseover Type Annotations
 module Language.Haskell.Liquid.UX.ACSS (
@@ -97,11 +97,11 @@ annotTokenise baseLoc tx (src, annm) = zipWith (\(x,y) z -> (x,y,z)) toks annots
     linWidth   = length $ show $ length $ lines src
 
 spanAnnot :: Int -> AnnMap -> Loc -> Annotation
-spanAnnot w (Ann ts es _ _) span = A t e b
+spanAnnot w (Ann ts es _ _) loc = A t e b
   where
-    t = fmap snd (M.lookup span ts)
-    e = "ERROR" <$ find (span `inRange`) [(x,y) | (x,y,_) <- es]
-    b = spanLine w span
+    t = fmap snd (M.lookup loc ts)
+    e = "ERROR" <$ find (loc `inRange`) [(x,y) | (x,y,_) <- es]
+    b = spanLine w loc
 
 spanLine :: t -> Loc -> Maybe (Int, t)
 spanLine w (L (l, c))
@@ -114,7 +114,7 @@ inRange (L (l0, c0)) (L (l, c), L (l', c'))
 
 tokeniseWithCommentTransform :: Maybe (String -> [(TokenType, String)]) -> String -> [(TokenType, String)]
 tokeniseWithCommentTransform Nothing  = tokenise
-tokeniseWithCommentTransform (Just f) = concatMap (expand f) . tokenise
+tokeniseWithCommentTransform (Just g) = concatMap (expand g) . tokenise
   where expand f (Comment, s) = f s
         expand _ z            = [z]
 
@@ -261,7 +261,7 @@ data Lit = Code {unL :: String} | Lit {unL :: String} deriving (Show)
 -- Also, importantly, accepts non-standard DOS and Mac line ending characters.
 -- And retains the trailing '\n' character in each resultant string.
 inlines :: String -> [String]
-inlines s = lines' s id
+inlines str = lines' str id
   where
   lines' []             acc = [acc []]
   lines' ('\^M':'\n':s) acc = acc ['\n'] : lines' s id  -- DOS
@@ -296,4 +296,4 @@ joinL :: [Lit] -> [Lit]
 joinL []                  = []
 joinL (Code c:Code c2:xs) = joinL (Code (c++c2):xs)
 joinL (Lit c :Lit c2 :xs) = joinL (Lit  (c++c2):xs)
-joinL (any:xs)            = any: joinL xs
+joinL (lit:xs)            = lit: joinL xs

From 94bfed3f050522a3cd770de0cae03f942a49c273 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:45:24 +1300
Subject: [PATCH 151/219] Remove name shadowing from
 Language.Haskell.Liquid.UX.Annotate

---
 src/Language/Haskell/Liquid/UX/Annotate.hs | 59 ++++++++++++----------
 1 file changed, 31 insertions(+), 28 deletions(-)

diff --git a/src/Language/Haskell/Liquid/UX/Annotate.hs b/src/Language/Haskell/Liquid/UX/Annotate.hs
index 6e3e972180..f08639d2c7 100644
--- a/src/Language/Haskell/Liquid/UX/Annotate.hs
+++ b/src/Language/Haskell/Liquid/UX/Annotate.hs
@@ -4,7 +4,6 @@
 {-# LANGUAGE FlexibleInstances          #-}
 
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 
 ---------------------------------------------------------------------------
 -- | This module contains the code that uses the inferred types to generate
@@ -427,7 +426,7 @@ instance ToJSON Loc where
                              , "column"   .= toJSON c ]
 
 instance ToJSON AnnErrors where
-  toJSON (AnnErrors errs) = Array $ V.fromList (toJ <$> errs)
+  toJSON (AnnErrors errors) = Array $ V.fromList (toJ <$> errors)
     where
       toJ (l,l',s)        = object [ "start"   .= toJSON l
                                    , "stop"    .= toJSON l'
@@ -445,9 +444,9 @@ dropErrorLoc msg
     (_, msg') = break (' ' ==) msg
 
 instance (Show k, ToJSON a) => ToJSON (Assoc k a) where
-  toJSON (Asc kas) = object [ tshow k .= toJSON a | (k, a) <- M.toList kas ]
+  toJSON (Asc kas) = object [ tshow' k .= toJSON a | (k, a) <- M.toList kas ]
     where
-      tshow        = fromString . show
+      tshow'       = fromString . show
 
 instance ToJSON ACSS.AnnMap where
   toJSON a = object [ "types"   .= toJSON (annTypes     a)
@@ -466,11 +465,11 @@ annErrors :: ACSS.AnnMap -> AnnErrors
 annErrors = AnnErrors . ACSS.errors
 
 annTypes         :: ACSS.AnnMap -> AnnTypes
-annTypes a       = grp [(l, c, ann1 l c x s) | (l, c, x, s) <- binders]
+annTypes a       = grp [(l, c, ann1 l c x s) | (l, c, x, s) <- binders']
   where
     ann1 l c x s = A1 x s l c
     grp          = L.foldl' (\m (r,c,x) -> ins r c x m) (Asc M.empty)
-    binders      = [(l, c, x, s) | (L (l, c), (x, s)) <- M.toList $ ACSS.types a]
+    binders'     = [(l, c, x, s) | (L (l, c), (x, s)) <- M.toList $ ACSS.types a]
 
 ins :: (Eq k, Eq k1, Hashable k, Hashable k1)
     => k -> k1 -> a -> Assoc k (Assoc k1 a) -> Assoc k (Assoc k1 a)
@@ -499,25 +498,29 @@ tokeniseWithLoc = ACSS.tokeniseWithLoc (Just tokAnnot)
 --------------------------------------------------------------------------------
 
 _anns :: AnnTypes
-_anns = i [(5,   i [( 14, A1 { ident = "foo"
-                             , ann   = "int -> int"
-                             , row   = 5
-                             , col   = 14
-                             })
-                  ]
-          )
-         ,(9,   i [( 22, A1 { ident = "map"
-                            , ann   = "(a -> b) -> [a] -> [b]"
-                            , row   = 9
-                            , col   = 22
-                            })
-                  ,( 28, A1 { ident = "xs"
-                            , ann   = "[b]"
-                            , row   = 9
-                            , col   = 28
-                            })
-                  ])
-         ]
-
-i :: (Eq k, Hashable k) => [(k, a)] -> Assoc k a
-i = Asc . M.fromList
+_anns =
+  mkAssoc
+    [ (5, mkAssoc
+            [ ( 14, A1 { ident = "foo"
+                       , ann   = "int -> int"
+                       , row   = 5
+                       , col   = 14
+                       })
+            ]
+      )
+    , (9, mkAssoc
+            [ ( 22, A1 { ident = "map"
+                       , ann   = "(a -> b) -> [a] -> [b]"
+                       , row   = 9
+                       , col   = 22
+                       })
+            , ( 28, A1 { ident = "xs"
+                       , ann   = "[b]"
+                       , row   = 9
+                       , col   = 28
+                       })
+            ])
+    ]
+
+mkAssoc :: (Eq k, Hashable k) => [(k, a)] -> Assoc k a
+mkAssoc = Asc . M.fromList

From 092e17cbc81b911ec269da0d559911bb75ded6c7 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:48:14 +1300
Subject: [PATCH 152/219] Remove name shadowing from
 Language.Haskell.Liquid.UX.CmdLine

---
 src/Language/Haskell/Liquid/UX/CmdLine.hs | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/Language/Haskell/Liquid/UX/CmdLine.hs b/src/Language/Haskell/Liquid/UX/CmdLine.hs
index 0679cae7c0..7d496b8eaa 100644
--- a/src/Language/Haskell/Liquid/UX/CmdLine.hs
+++ b/src/Language/Haskell/Liquid/UX/CmdLine.hs
@@ -9,7 +9,6 @@
 {-# OPTIONS_GHC -Wno-orphans #-}
 {-# OPTIONS_GHC -Wwarn=deprecations #-}
 {-# OPTIONS_GHC -fno-cse #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 {-# LANGUAGE FlexibleContexts #-}
 
 -- | This module contains all the code needed to output the result which
@@ -526,9 +525,9 @@ findSmtSolver :: FC.SMTSolver -> IO (Maybe FC.SMTSolver)
 findSmtSolver smt = maybe Nothing (const $ Just smt) <$> findExecutable (show smt)
 
 fixConfig :: Config -> IO Config
-fixConfig cfg = do
+fixConfig config' = do
   pwd <- getCurrentDirectory
-  cfg <- canonicalizePaths pwd cfg
+  cfg <- canonicalizePaths pwd config'
   return $ canonConfig cfg
 
 -- | Attempt to canonicalize all `FilePath's in the `Config' so we don't have
@@ -772,8 +771,8 @@ resultWithContext :: F.FixResult UserError -> IO (FixResult CError)
 resultWithContext (F.Unsafe s es)  = F.Unsafe s    <$> errorsWithContext es
 resultWithContext (F.Safe   stats) = return (F.Safe stats)
 resultWithContext (F.Crash  es s)  = do
-  let (errs, msgs) = unzip es
-  errs' <- errorsWithContext errs
+  let (userErrs, msgs) = unzip es
+  errs' <- errorsWithContext userErrs
   return (F.Crash (zip errs' msgs) s)
 
 
@@ -855,10 +854,10 @@ fixMessageDoc msg = vcat (text <$> lines msg)
 reportUrl = text "Please submit a bug report at: https://github.com/ucsd-progsys/liquidhaskell" -}
 
 addErrors :: FixResult a -> [a] -> FixResult a
-addErrors r []               = r
-addErrors (Safe s) errs      = Unsafe s errs
-addErrors (Unsafe s xs) errs = Unsafe s (xs ++ errs)
-addErrors r  _               = r
+addErrors r []                 = r
+addErrors (Safe s) errors      = Unsafe s errors
+addErrors (Unsafe s xs) errors = Unsafe s (xs ++ errors)
+addErrors r  _                 = r
 
 instance Fixpoint (F.FixResult CError) where
   toFix = vcat . map snd . orMessages . resDocs F.Full

From 053b48752cd4054e72cfc85e1481d27bd6273875 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:49:59 +1300
Subject: [PATCH 153/219] Remove name shadowing from
 Language.Haskell.Liquid.UX.DiffCheck

---
 src/Language/Haskell/Liquid/UX/DiffCheck.hs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/Language/Haskell/Liquid/UX/DiffCheck.hs b/src/Language/Haskell/Liquid/UX/DiffCheck.hs
index 9a4b75ca93..f332c9c606 100644
--- a/src/Language/Haskell/Liquid/UX/DiffCheck.hs
+++ b/src/Language/Haskell/Liquid/UX/DiffCheck.hs
@@ -9,7 +9,6 @@
 {-# LANGUAGE TupleSections     #-}
 
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
 {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
 
 module Language.Haskell.Liquid.UX.DiffCheck (

From e588d1d85644f874d628c5fb9ec35abfc6059a7b Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:50:26 +1300
Subject: [PATCH 154/219] Remove name shadowing from
 Language.Haskell.Liquid.UX.Errors

---
 src/Language/Haskell/Liquid/UX/Errors.hs | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/Language/Haskell/Liquid/UX/Errors.hs b/src/Language/Haskell/Liquid/UX/Errors.hs
index 5b0a82ba20..b5d30d2386 100644
--- a/src/Language/Haskell/Liquid/UX/Errors.hs
+++ b/src/Language/Haskell/Liquid/UX/Errors.hs
@@ -3,8 +3,6 @@
 {-# LANGUAGE TupleSections     #-}
 {-# LANGUAGE BangPatterns      #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
-
 -- | This module contains the functions related to @Error@ type,
 -- in particular, to @tidyError@ using a solution, and @pprint@ errors.
 

From d63eec60acdc0ebfd4f4017298dd6839bb3e4706 Mon Sep 17 00:00:00 2001
From: Tommy Bidne 
Date: Mon, 6 Mar 2023 10:51:15 +1300
Subject: [PATCH 155/219] Remove name shadowing from
 Language.Haskell.Liquid.UX.QuasiQuoter

---
 src/Language/Haskell/Liquid/UX/QuasiQuoter.hs | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs
index 81b43916ef..1f4f74079f 100644
--- a/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs
+++ b/src/Language/Haskell/Liquid/UX/QuasiQuoter.hs
@@ -4,8 +4,6 @@
 {-# LANGUAGE TupleSections         #-}
 {-# LANGUAGE OverloadedStrings     #-}
 
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
-
 module Language.Haskell.Liquid.UX.QuasiQuoter
 -- (
 --     -- * LiquidHaskell Specification QuasiQuoter
@@ -62,14 +60,14 @@ lqDec src = do
       prg <- pragAnnD ModuleAnnotation $
                conE 'LiquidQuote `appE` dataToExpQ' spec
       case mkSpecDecs spec of
-        Left err ->
-          throwErrorInQ err
+        Left uerr ->
+          throwErrorInQ uerr
         Right decs ->
           return $ prg : decs
 
 throwErrorInQ :: UserError -> Q a
-throwErrorInQ err =
-  fail . showpp =<< runIO (errorsWithContext [err])
+throwErrorInQ uerr =
+  fail . showpp =<< runIO (errorsWithContext [uerr])
 
 --------------------------------------------------------------------------------
 -- Liquid Haskell to Template Haskell ------------------------------------------
@@ -154,10 +152,10 @@ simplifyBareType'' (tvs, cls) (RFun _ _ i o _)
 simplifyBareType'' (tvs, cls) (RAllT tv t _) =
   simplifyBareType'' (ty_var_value tv : tvs, cls) t
 
-simplifyBareType'' (tvs, cls) t =
+simplifyBareType'' (tvs, cls) bt =
   ForallT ((\t -> PlainTV (symbolName t) SpecifiedSpec) <$> reverse tvs)
     <$> mapM simplifyBareType' (reverse cls)
-    <*> simplifyBareType' t
+    <*> simplifyBareType' bt
 
 
 data Simpl a = Simplified a

From d8349b67b9e16545a757a198d65f0b0dbd3362b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Sun, 5 Mar 2023 20:05:28 -0300
Subject: [PATCH 156/219] Fix parentheses in GHC.Num.abs spec

---
 liquid-base/src/GHC/Num.spec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/liquid-base/src/GHC/Num.spec b/liquid-base/src/GHC/Num.spec
index 9e0bf0772d..7f1755bfd2 100644
--- a/liquid-base/src/GHC/Num.spec
+++ b/liquid-base/src/GHC/Num.spec
@@ -9,7 +9,7 @@ GHC.Num.negate :: (GHC.Num.Num a)
                => x:a
                -> {v:a | v = -x}
 
-GHC.Num.abs :: (GHC.Num.Num a) => x:a -> {y:a | (x >= 0) ==> (y = x) && (x < 0) ==> y = -x}
+GHC.Num.abs :: (GHC.Num.Num a) => x:a -> {y:a | (x >= 0 ==> y = x) && (x < 0 ==> y = -x) }
 
 GHC.Num.+ :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x + y }
 GHC.Num.- :: (GHC.Num.Num a) => x:a -> y:a -> {v:a | v = x - y }

From 37776da1c31d90c070888230ba67b1c9f64c3fc8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Sun, 5 Mar 2023 20:05:59 -0300
Subject: [PATCH 157/219] Avoid redefining function in abs test

---
 tests/pos/abs.hs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/pos/abs.hs b/tests/pos/abs.hs
index 477adbdf22..8d0320193d 100644
--- a/tests/pos/abs.hs
+++ b/tests/pos/abs.hs
@@ -12,6 +12,6 @@ g x = abs x
 h :: Int -> Int
 h x = abs x
 
-{-@ f :: Int -> {n:Int | n >= 0} @-}
-f :: Int -> Int
-f x = abs x
+{-@ f2 :: Int -> {n:Int | n >= 0} @-}
+f2 :: Int -> Int
+f2 x = abs x

From ccc5862467fe7dfde3f91257dd82513634f360f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Sun, 5 Mar 2023 20:13:47 -0300
Subject: [PATCH 158/219] Rename abs tests and add them to the tests.cabal file

---
 tests/neg/{abs.hs => AbsNegTest.hs} | 1 +
 tests/pos/{abs.hs => AbsPosTest.hs} | 0
 tests/tests.cabal                   | 2 ++
 3 files changed, 3 insertions(+)
 rename tests/neg/{abs.hs => AbsNegTest.hs} (59%)
 rename tests/pos/{abs.hs => AbsPosTest.hs} (100%)

diff --git a/tests/neg/abs.hs b/tests/neg/AbsNegTest.hs
similarity index 59%
rename from tests/neg/abs.hs
rename to tests/neg/AbsNegTest.hs
index 8d9fd2e9d2..3a77120fde 100644
--- a/tests/neg/abs.hs
+++ b/tests/neg/AbsNegTest.hs
@@ -1,3 +1,4 @@
+{-@ LIQUID "--expect-error-containing=AbsNegTest.hs:6:1" @-}
 module AbsNegTest where
 
 {-@ f :: Int -> {n:Int | n < 0} @-}
diff --git a/tests/pos/abs.hs b/tests/pos/AbsPosTest.hs
similarity index 100%
rename from tests/pos/abs.hs
rename to tests/pos/AbsPosTest.hs
diff --git a/tests/tests.cabal b/tests/tests.cabal
index 909c9aa366..da8b88fdf1 100644
--- a/tests/tests.cabal
+++ b/tests/tests.cabal
@@ -1123,6 +1123,7 @@ executable unit-neg
 
     other-modules:
                       AbsApp
+                    , AbsNegTest
                     , AdtPeano0
                     , AdtPeano1
                     , Alias00
@@ -1711,6 +1712,7 @@ executable unit-pos-2
 
     other-modules:
                       Abs
+                    , AbsPosTest
                     , Absref_crash0
                     , Absref_crash
                     , Ackermann

From c0be9abab383f0ee6d1c97bab1856b6e1570d186 Mon Sep 17 00:00:00 2001
From: Afonso Rafael 
Date: Mon, 6 Mar 2023 12:07:38 +0100
Subject: [PATCH 159/219] Selective on the way variables are printed

Instead of printing all variables with their respective unique we
print them depending on if they were renamed or not.
---
 .../Haskell/Liquid/Constraint/Relational.hs   | 153 ++++++++++--------
 src/Language/Haskell/Liquid/Synthesize.hs     |   2 +-
 src/Language/Haskell/Liquid/Synthesize/GHC.hs | 122 +++++++-------
 3 files changed, 148 insertions(+), 129 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs
index f6f97b72bf..8c80774257 100644
--- a/src/Language/Haskell/Liquid/Constraint/Relational.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs
@@ -40,6 +40,7 @@ import           Language.Haskell.Liquid.Synthesize.GHC
                                                 , fromAnf
                                                 , pprintBody'
                                                 , handleVar
+                                                , RenVars
                                                 )
 
 import           Liquid.GHC.API                 ( Alt
@@ -123,15 +124,17 @@ consRelTop cfg ti chk syn γ ψ (x, y, t, s, ra, rp) = traceChk "Init" e d t s p
     consRelCheckBind (UnaryTyping chk (\γγ ee -> removeAbsRef <$> syn γγ ee)) γ' ψ e d t' s' ra rp
     when (relationalHints cfg) $ 
       modify $ \cgi -> cgi
-      { relHints = relHint
-                      (relSigToUnSig (toExpr x) (toExpr y) t' s' rp)
-                      hintName
-                      (relTermToUnTerm argNames x y hintName (toCoreExpr e) (toCoreExpr d))
+      { relHints = relHint renVars
+                   (relSigToUnSig (toExpr x) (toExpr y) t' s' rp)
+                   hintName
+                   (relTermToUnTerm argNames x y hintName
+                    (toCoreExpr e) (toCoreExpr d))
                     $+$ relHints cgi
       }
   where
-    argNames = (fst $ vargs t', fst $ vargs s')
-    toExpr = F.EVar . F.symbol
+    argNames@(left, right) = (fst $ vargs t', fst $ vargs s')
+    renVars = map F.symbolSafeString $ left ++ right
+    toExpr  = F.EVar . F.symbol
     toCoreExpr = GM.unTickExpr . binderToExpr
     p = fromRelExpr rp
     γ' = γ `setLocation` Sp.Span (GM.fSrcSpan (F.loc t))
@@ -287,6 +290,7 @@ mkRelThmVar' c thm x y = mkCopyWithName (name x ++ cname y ++ thm) x
 cap :: String -> String
 cap (c:cs) = toUpper c : cs
 cap cs = cs
+
 type ArgMapping = ([F.Symbol], [F.Symbol])
 
 relTermToUnTerm :: ArgMapping -> Var -> Var -> Var -> CoreExpr -> CoreExpr -> CoreExpr
@@ -329,9 +333,10 @@ relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2)
   , areCompatible f1 f2
   , areCompatible x1 x2
   = traceWhenLoud
-      ("relTermToUnTerm App common arg " ++ show x1 ++ " " ++ show x2) $ 
-    App (App (App (relTermToUnTerm' m relTerms f1 f2) x1) x2) relX
-    where relX = mkLambdaUnit x1 x2 (Ghc.exprType x1) (Ghc.exprType x2)
+      ("relTermToUnTerm App common arg " ++ show x1 ++ " " ++ show x2)
+      $ App (App (App (relTermToUnTerm' m relTerms f1 f2) x1) x2) relX
+    where
+      relX = mkLambdaUnit m x1 x2 (Ghc.exprType x1) (Ghc.exprType x2)
 relTermToUnTerm' m relTerms (Lam α1 e1) (Lam α2 e2) 
   | Ghc.isTyVar α1, Ghc.isTyVar α2
   = relTermToUnTerm' m relTerms e1 e2
@@ -382,30 +387,32 @@ relTermToUnTerm' m relTerms (Case d1 x1 t1 as1) (Case d2 x2 t2 as2) =
       ))
     as1
     where (x1l, x2r) = mkRelCopies x1 x2
-relTermToUnTerm' _ _ e1 e2
+relTermToUnTerm' m _ e1 e2
   = traceWhenLoud ("relTermToUnTerm': can't proceed proof generation on e1:\n" ++ F.showpp e1 ++ "\ne2:\n" ++ F.showpp e2) $
       Tick (Ghc.SourceNote realSpan info) $
-        mkLambdaUnit e1 e2 (Ghc.exprType e1) (Ghc.exprType e2)
+        mkLambdaUnit m e1 e2 (Ghc.exprType e1) (Ghc.exprType e2)
   where
     realLoc  = Ghc.mkRealSrcLoc (Ghc.mkFastString "") 0 0
     realSpan = Ghc.mkRealSrcSpan realLoc realLoc
-    left     = coreToGoal True e1 
-    right    = coreToGoal True e2
+    renVars  = map F.symbolSafeString $ fst m ++ snd m
+    left     = coreToGoal renVars True e1 
+    right    = coreToGoal renVars True e2
     info     = "GOAL: " ++ left ++ " ~ " ++ right
 
 {- function to print CoreExpr as strings in order to
 insert them as goal comments on the output of the proof.
 when the boolean argument short is true, if the goal is
 bigger then 20 chars then the string is trimed. -}
-coreToGoal :: Bool -> CoreExpr -> String
-coreToGoal short e
+coreToGoal :: RenVars -> Bool -> CoreExpr -> String
+coreToGoal rvs short e
   | bool                      = "()"
   | short && length goal <= 20 = goal
   | short                     = take 20 goal ++ " (...) "
   | otherwise                 = goal
   where
-    goal = unwords $ words $ concat $ splitOn "\n" $ pprintBody' expr
-    (expr, bool) = cleanUnTerms $ fromAnf e
+    goal = unwords $ words $ concat $ splitOn "\n"
+           $ pprintBody' rvs expr
+    (expr, bool) = cleanUnTerms rvs $ fromAnf e
 
 areCompatible :: CoreExpr -> CoreExpr -> Bool
 areCompatible e1 e2 = areCompatibleTy (Ghc.exprType e1) (Ghc.exprType e2)
@@ -427,17 +434,19 @@ areCompatibleTy t1 (Ghc.ForAllTy _ t2)
   = areCompatibleTy t1 t2
 areCompatibleTy _ _ = False
 
-mkLambdaUnit :: CoreExpr -> CoreExpr -> Type -> Type -> CoreExpr
-mkLambdaUnit e1 e2 (Ghc.ForAllTy _ t1) (Ghc.ForAllTy _ t2) = mkLambdaUnit e1 e2 t1 t2
-mkLambdaUnit e1 e2 (Ghc.FunTy Ghc.InvisArg _ _ t1) (Ghc.FunTy Ghc.InvisArg _ _ t2) = mkLambdaUnit e1 e2 t1 t2
-mkLambdaUnit e1 e2 (Ghc.FunTy Ghc.VisArg _ _ t1) (Ghc.FunTy Ghc.VisArg _ _ t2) 
+mkLambdaUnit :: ArgMapping
+             -> CoreExpr -> CoreExpr -> Type -> Type -> CoreExpr
+mkLambdaUnit m e1 e2 (Ghc.ForAllTy _ t1) (Ghc.ForAllTy _ t2) =
+  mkLambdaUnit m e1 e2 t1 t2
+mkLambdaUnit m e1 e2 (Ghc.FunTy Ghc.InvisArg _ _ t1) (Ghc.FunTy Ghc.InvisArg _ _ t2) = mkLambdaUnit m e1 e2 t1 t2
+mkLambdaUnit m e1 e2 (Ghc.FunTy Ghc.VisArg _ _ t1) (Ghc.FunTy Ghc.VisArg _ _ t2) 
   = Lam (GM.stringVar "_" Ghc.unitTy) $ 
       Lam (GM.stringVar "_" Ghc.unitTy) $ 
-        Lam (GM.stringVar "_" Ghc.unitTy) $ mkLambdaUnit e1 e2 t1 t2
-mkLambdaUnit _ _ t1@Ghc.FunTy{} t2 = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2
-mkLambdaUnit _ _ t1 t2@Ghc.FunTy{} = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2
+        Lam (GM.stringVar "_" Ghc.unitTy) $ mkLambdaUnit m e1 e2 t1 t2
+mkLambdaUnit _ _ _ t1@Ghc.FunTy{} t2 = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2
+mkLambdaUnit _ _ _ t1 t2@Ghc.FunTy{} = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2
 
-mkLambdaUnit e1 e2 _ _
+mkLambdaUnit m e1 e2 _ _
   | Ghc.FunTy {}    <- Ghc.exprType e1
   , Ghc.FunTy {}    <- Ghc.exprType e2 = Ghc.unitExpr
   | Ghc.ForAllTy {} <- Ghc.exprType e1
@@ -447,53 +456,59 @@ mkLambdaUnit e1 e2 _ _
   where
     genConst          = Var $ GM.stringVar "const" Ghc.unitTy
     genConstU         = App genConst Ghc.unitExpr
-    (cle1, patError1) = cleanUnTerms e1
-    (cle2, patError2) = cleanUnTerms e2
+    renVars           = map F.symbolSafeString $ fst m ++ snd m
+    (cle1, patError1) = cleanUnTerms renVars e1
+    (cle2, patError2) = cleanUnTerms renVars e2
 
-cleanUnTerms :: CoreExpr -> (CoreExpr, Bool)
+cleanUnTerms :: RenVars -> CoreExpr -> (CoreExpr, Bool)
 {- Maybe have to do some cleaning to the vars here -}
-cleanUnTerms var@(Var v)
-  | handleVar v == "patError" = (var, True)
+cleanUnTerms rvs var@(Var v)
+  | handleVar rvs v == "patError" = (var, True)
   | otherwise                 = (var, False)
-cleanUnTerms l@Lit{} = (l, False)
-cleanUnTerms (App f e)
-  | Type{} <- GM.unTickExpr e = cleanUnTerms f
-cleanUnTerms (App f (Var v))
-  | GM.isEmbeddedDictVar v = cleanUnTerms f
-cleanUnTerms (App f e) = (App core1 core2, bool1 || bool2)
+
+cleanUnTerms _ (Lit (Ghc.LitString _)) = (Ghc.unitExpr, False)
+cleanUnTerms _ l@Lit{} = (l, False)
+
+cleanUnTerms rvs (App f e)
+  | Type{} <- GM.unTickExpr e = cleanUnTerms rvs f
+cleanUnTerms rvs (App f (Var v))
+  | GM.isEmbeddedDictVar v = cleanUnTerms rvs f
+cleanUnTerms rvs (App f e) = (App core1 core2, bool1 || bool2)
   where
-    (core1, bool1) = cleanUnTerms f
-    (core2, bool2) = cleanUnTerms e
-cleanUnTerms (Lam α e)
-  | Ghc.isTyVar α = cleanUnTerms e
+    (core1, bool1) = cleanUnTerms rvs f
+    (core2, bool2) = cleanUnTerms rvs e
+cleanUnTerms rvs (Lam α e)
+  | Ghc.isTyVar α = cleanUnTerms rvs e
   | otherwise     = (Lam α core, bool)
     where
-      (core, bool) = cleanUnTerms e
+      (core, bool) = cleanUnTerms rvs e
 
-cleanUnTerms (Let (NonRec v e1) e2) = 
+cleanUnTerms rvs (Let (NonRec v e1) e2) = 
   (Let (NonRec v core1) core2, bool1 || bool2)
   where
-    (core1, bool1) = cleanUnTerms e1
-    (core2, bool2) = cleanUnTerms e2
+    (core1, bool1) = cleanUnTerms rvs e1
+    (core2, bool2) = cleanUnTerms rvs e2
 
-cleanUnTerms (Let r e) = (Let r core, bool)
+cleanUnTerms rvs (Let r e) = (Let r core, bool)
   -- TODO: cleanUnTerms <$> r
   where
-    (core, bool) = cleanUnTerms e
+    (core, bool) = cleanUnTerms rvs e
 
-cleanUnTerms (Case e v t alts) = (Case core v t clAlts, bool1 || bool2)
+cleanUnTerms rvs (Case e v t alts) = (Case core v t clAlts, bool1 || bool2)
   where
-    (core,   bool1) = cleanUnTerms e
-    (clAlts, bool2) = cleanCase alts
+    (core,   bool1) = cleanUnTerms rvs e
+    (clAlts, bool2) = cleanCase rvs alts
 
-cleanUnTerms e = error ("cleanUnTerms: " ++ F.showpp e)
+cleanUnTerms _ e = error ("cleanUnTerms: " ++ F.showpp e)
 
-cleanCase :: [(a, b, CoreExpr)] -> ([(a, b, CoreExpr)], Bool)
-cleanCase alts = (zip3 altcs vss cores, bool)
+cleanCase :: RenVars -> [(a, b, CoreExpr)] -> ([(a, b, CoreExpr)], Bool)
+cleanCase rvs alts = (zip3 altcs vss cores, bool)
   where
     (altcs, vss, altesBools) = unzip3 $
                                map (\(altc, vs, alte) ->
-                                       (altc, vs, cleanUnTerms alte)) alts
+                                       (altc
+                                       , vs
+                                       , cleanUnTerms rvs alte)) alts
     (cores, bool) = or <$> unzip altesBools
 
 
@@ -1321,22 +1336,22 @@ relWfError loc e1 e2 t1 t2 p msg
 -- Pretty Printing Unary Proofs ------------------------------
 --------------------------------------------------------------
 
-relHint :: SpecType -> Ghc.Var -> CoreExpr -> Doc
-relHint t v e = text "import GHC.Types"
-                $+$ text ""
-                $+$ text "{- HLINT ignore \"Use camelCase\" -}"
-                $+$ text ("{-@ " ++ name
-                           ++ " :: "
-                           ++ F.showpp t
-                           ++ " @-}")
-                $+$ text (name
-                           ++ " :: "
-                           ++ removeIdent (toType False t))
-                $+$ text (coreToHs t v (fromAnf e))
-                $+$ text ""
-                $+$ text "{- BARE CORE"
-                $+$ text (show e)
-                $+$ text "-}"
+relHint :: RenVars -> SpecType -> Ghc.Var -> CoreExpr -> Doc
+relHint rvs t v e = text "import GHC.Types"
+                    $+$ text ""
+                    $+$ text "{- HLINT ignore \"Use camelCase\" -}"
+                    $+$ text ("{-@ " ++ name
+                              ++ " :: "
+                              ++ F.showpp t
+                              ++ " @-}")
+                    $+$ text (name
+                              ++ " :: "
+                              ++ removeIdent (toType False t))
+                    $+$ text (coreToHs rvs t v (fromAnf e))
+                    $+$ text ""
+                    $+$ text "{- BARE CORE"
+                    $+$ text (show e)
+                    $+$ text "-}"
   where name = Ghc.occNameString $ Ghc.getOccName v
 
 removeIdent :: Type -> String
diff --git a/src/Language/Haskell/Liquid/Synthesize.hs b/src/Language/Haskell/Liquid/Synthesize.hs
index 8f03c605cc..8193cb244f 100644
--- a/src/Language/Haskell/Liquid/Synthesize.hs
+++ b/src/Language/Haskell/Liquid/Synthesize.hs
@@ -56,7 +56,7 @@ synthesize tgt fcfg cginfo =
 
       return $ ErrHole loc (
         if not (null fills)
-          then text "\n Hole Fills:" $+$ pprintMany (map (coreToHs typeOfTopLvlBnd topLvlBndr . fromAnf) fills)
+          then text "\n Hole Fills:" $+$ pprintMany (map (coreToHs [] typeOfTopLvlBnd topLvlBndr . fromAnf) fills)
           else mempty) mempty (symbol x) typeOfTopLvlBnd
 
 
diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
index cee02d61c0..284250174f 100644
--- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs
+++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
@@ -10,7 +10,6 @@ module Language.Haskell.Liquid.Synthesize.GHC where
 import qualified Language.Fixpoint.Types       as F
 import           Language.Haskell.Liquid.Types
 
-
 import           Data.Default
 import           Data.Maybe                     ( fromMaybe )
 import           Liquid.GHC.TypeRep
@@ -115,8 +114,6 @@ fromAnf' (App e1 e2) bnds
 
 fromAnf' t@Type{} bnds = (t, bnds)
 
-fromAnf' (Lit (GHC.LitString _)) bnds = (GHC.unitExpr, bnds)
-
 fromAnf' l@Lit{} bnds = (l, bnds)
 
 fromAnf' (Tick s e) bnds = (Tick s e', bnds')
@@ -128,10 +125,14 @@ fromAnf' e _ = error $ "fromAnf: unsupported core expression "
 
 -- | Function used for pretty printing core as Haskell source.
 --   Input does not contain let bindings.
-coreToHs :: SpecType -> Var -> CoreExpr -> String
-coreToHs _ v e = pprintSymbols (handleVar v
-                                ++ " "
-                                ++ pprintFormals caseIndent e)
+coreToHs :: RenVars -> SpecType -> Var -> CoreExpr -> String
+coreToHs rvs _ v e = pprintSymbols (handleVar ((getOccString v):rvs) v
+                                     ++ " "
+                                     ++ pprintFormals
+                                     ((getOccString v):rvs)
+                                     caseIndent e)
+
+type RenVars       = [String]
 
 caseIndent :: Int
 caseIndent = 2
@@ -158,18 +159,18 @@ pprintSym symbols s
         prefix = takeWhile (== ' ') s
         suffix = dropWhile (== ' ') s
 
-pprintFormals :: Int -> CoreExpr -> String
-pprintFormals i e = handleLam "= " i e
+pprintFormals :: RenVars -> Int -> CoreExpr -> String
+pprintFormals rvs i e = handleLam rvs "= " i e
 
-handleLam :: String -> Int -> CoreExpr -> String
-handleLam char i (Lam v e)
-  | isTyVar   v = " {- tyVar -}"     ++ handleLam char i e
-  | isTcTyVar v = " {- isTcTyVar -}" ++ handleLam char i e
-  | isTyCoVar v = " {- isTyCoVar -}" ++ handleLam char i e
-  | isCoVar   v = " {- isCoVar -}"   ++ handleLam char i e
-  | isId      v = handleVar v ++ " " ++ handleLam char i e  
-  | otherwise   = handleVar v ++ " " ++ handleLam char i e
-handleLam char i e = char ++ pprintBody i e
+handleLam :: RenVars -> String -> Int -> CoreExpr -> String
+handleLam rvs char i (Lam v e)
+  | isTyVar   v = " {- tyVar -}"         ++ handleLam rvs char i e
+  | isTcTyVar v = " {- isTcTyVar -}"     ++ handleLam rvs char i e
+  | isTyCoVar v = " {- isTyCoVar -}"     ++ handleLam rvs char i e
+  | isCoVar   v = " {- isCoVar -}"       ++ handleLam rvs char i e
+  | isId      v = handleVar rvs v ++ " " ++ handleLam rvs char i e  
+  | otherwise   = handleVar rvs v ++ " " ++ handleLam rvs char i e
+handleLam rvs char i e = char ++ pprintBody rvs i e
 
 
 {- If a specific function is built-in into haskell it will still
@@ -196,11 +197,11 @@ getExternalName n = mod ++ outName
 
 {- Handle the multiple types of variables one might encounter
 in Haskell. -}
-handleVar :: Var -> String
-handleVar v
+handleVar :: RenVars -> Var -> String
+handleVar vars v
   | isTyConName     name = "{- TyConName -}"
   | isTyVarName     name = "{- TyVar -}"
-  | isSystemName    name = getSysName name
+  | isSystemName    name = getSysName vars name
 --                           ++ "{- SysName -}"
   | isWiredInName   name = getLocalName name
 --                           ++ "{- WiredInName -}"
@@ -215,12 +216,15 @@ handleVar v
     name = varName v
 
 
-getSysName :: Name -> String
-getSysName n
-  | elem '#' occ = head (splitOn "$##" occ)
-  | otherwise      = occ
+getSysName :: RenVars -> Name -> String
+getSysName vars n
+  | elem occ vars = occ
+  | elem '#' occ  = (head $ splitOn "$##" occ) ++ ['_', last uni]
+  | otherwise     = occ ++ ['_', last uni]
   where
-    occ        = getOccString n
+    occ = getOccString n
+    uni = show $ nameUnique n
+
 {- Should not be done here, but function used to check if is an
 undesirable variable or not (I#) -}
 undesirableVar :: CoreExpr -> Bool
@@ -235,64 +239,64 @@ checkUnit (Var v)
   | otherwise = False
 checkUnit _ = False  
 ----------------------------------------------------------------------
-pprintBody' :: CoreExpr -> String
-pprintBody' = pprintBody 0
+pprintBody' :: RenVars -> CoreExpr -> String
+pprintBody' rvs e = pprintBody rvs 0 e
 
-pprintBody :: Int -> CoreExpr -> String
-pprintBody i e@Lam{} = "(\\" ++ handleLam " -> " i e ++ ")"
+pprintBody :: RenVars -> Int -> CoreExpr -> String
+pprintBody rvs i e@Lam{} = "(\\" ++ handleLam rvs " -> " i e ++ ")"
 
-pprintBody _ var@(Var v)
+pprintBody rvs _ var@(Var v)
   | undesirableVar var = ""
-  | otherwise          = handleVar v
+  | otherwise          = handleVar rvs v
 
-pprintBody i (App e Type{}) = pprintBody i e
+pprintBody rvs i (App e Type{}) = pprintBody rvs i e
     
-pprintBody i (App e1 e2)
-  | undesirableVar e1 = pprintBody i e2
-  | undesirableVar e2 = pprintBody i e1
-  | checkUnit e2      = pprintBody i e1
+pprintBody rvs i (App e1 e2)
+  | undesirableVar e1 = pprintBody rvs i e2
+  | undesirableVar e2 = pprintBody rvs i e1
+  | checkUnit e2      = pprintBody rvs i e1
                         ++ " "
-                        ++ pprintBody i e2
+                        ++ pprintBody rvs i e2
   | otherwise = "(" ++ left ++ ")\n"
                 ++ indent (i + 1)
                 ++ "(" ++ right ++ ")"
   where
-    left  = pprintBody i e1
-    right = pprintBody (i+1) e2
+    left  = pprintBody rvs i e1
+    right = pprintBody rvs (i+1) e2
 
-pprintBody _ l@(Lit literal) =
+pprintBody _ _ l@(Lit literal) =
   case isLitValue_maybe literal of
     Just i   -> show i
     Nothing  -> show l
 
-pprintBody i (Case e _ _ alts)
-  = "case " ++ pprintBody i e ++ " of"
-  ++ concatMap (pprintAlts (i + caseIndent)) alts
+pprintBody rvs i (Case e _ _ alts)
+  = "case " ++ pprintBody rvs i e ++ " of"
+  ++ concatMap (pprintAlts rvs (i + caseIndent)) alts
 
-pprintBody _ Type{} = "{- Type -}"
+pprintBody _ _ Type{} = "{- Type -}"
 
-pprintBody i (Let (NonRec x e1) e2) =
+pprintBody rvs i (Let (NonRec x e1) e2) =
   letExp ++
   eqlExp ++
-  indent i ++ pprintBody (i+1) e2
+  indent i ++ pprintBody rvs (i+1) e2
   where
-    letExp      = "let " ++ handleVar x ++ " = "
-    eqlExp      = pprintBody firstIdent e1 ++ " in\n"
+    letExp      = "let " ++ handleVar rvs x ++ " = "
+    eqlExp      = pprintBody rvs firstIdent e1 ++ " in\n"
     firstIdent  = i + caseIndent*2 + length letExp
     
-pprintBody _ (Let Rec{} _) = "{- let rec -}"
+pprintBody _ _ (Let Rec{} _) = "{- let rec -}"
 
-pprintBody i (Tick (SourceNote _ s) e)
+pprintBody rvs i (Tick (SourceNote _ s) e)
   | expr == "()" = "{- " ++ s ++ " -} " ++ expr
   | otherwise    = "{- " ++ s ++ " -}"
                    ++ "\n" ++ indent i
                    ++ expr
   where
-    expr = pprintBody i e
+    expr = pprintBody rvs i e
 
-pprintBody i (Tick _ e) = pprintBody i e
+pprintBody rvs i (Tick _ e) = pprintBody rvs i e
 
-pprintBody _ e = error (" Not yet implemented for e = " ++ show e)
+pprintBody _ _ e = error (" Not yet implemented for e = " ++ show e)
 
 {-
 data Alt Var = Alt AltCon [Var] (Expr Var)
@@ -301,18 +305,18 @@ data AltCon = DataAlt DataCon
             | LitAlt  Literal
             | DEFAULT
 -}
-pprintAlts :: Int -> Alt Var -> String
-pprintAlts i (DataAlt dataCon, vs, e)
+pprintAlts :: RenVars -> Int -> Alt Var -> String
+pprintAlts rvs i (DataAlt dataCon, vs, e)
   = "\n" ++ indent i
     ++ elCase
-    ++ pprintBody (i + newIndent) e
+    ++ pprintBody rvs (i + newIndent) e
   where
     elCase = getOccString (getName dataCon)
-             ++ concatMap (\v -> " " ++ handleVar v) vs
+             ++ concatMap (\v -> " " ++ handleVar rvs v) vs
              ++ " -> "
     newIndent = length elCase
     
-pprintAlts _ _ =
+pprintAlts _ _ _ =
   error " Pretty printing for pattern match on datatypes. "
 
 

From 8f83829014614d930d441a2e1b565f9b0be15503 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Mon, 6 Mar 2023 15:30:47 -0300
Subject: [PATCH 160/219] Remove description of the script/test folder from the
 README

---
 README.md | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/README.md b/README.md
index ce9a4fe11c..588f7e6291 100644
--- a/README.md
+++ b/README.md
@@ -107,11 +107,6 @@ For documentation on the `test-driver` executable itself, please refer to the
 `README.md` in `tests/` or run `cabal run tests:test-driver -- --help` or `stack
 run test-driver -- --help`
 
-There are particular scripts for running LH in the different modes, e.g. for different 
-compiler versions. These scripts are in:
-
-    $ ./scripts/test
-
 So you can run *all* the tests by
 
     $ ./scripts/test/test_plugin.sh
@@ -142,7 +137,6 @@ You can directly extend and run the tests by modifying the files in
 
     tests/harness/
 
-
 ### Parallelism in Tests
 
 Most tests run in parallel, with a few module dependencies built sequentially in

From 42bec756ef77a8adc191f24ceec9add5e7e6a1c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Mon, 6 Mar 2023 15:38:45 -0300
Subject: [PATCH 161/219] Update question on testing different versions of GHC

---
 README.md | 20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/README.md b/README.md
index 588f7e6291..0b90a6312a 100644
--- a/README.md
+++ b/README.md
@@ -343,26 +343,12 @@ compilation might fail with an error, typically because some `ghc` API function
 The way to fix it is to modify the [GHC.API][] shim module and perform any required change, likely by 
 conditionally compiling some code in a `CPP` block. For minor changes, it's usually enough to perform small
 changes, but for more tricky migrations it might be necessary to backport some GHC code, or create some
-patter synonym to deal with changes in type constructors. You can see an example of this technique in
-action by looking at the pattern synonym for [FunTy][].
+patter synonym to deal with changes in type constructors.
 
 ## Is there a way to run the testsuite for different versions of GHC?
 
-Yes. The easiest way is to run one of the scripts inside the `scripts/test` directory. We provide scripts
-to run the testsuite for a variety of GHC versions, mostly using `stack` but also with `cabal` (e.g.
-`test_plugin.sh`). If run without arguments, the script will run the _full_ testsuite. If an argument
-is given, only a particular pattern/test will be run. Running
-
-```
-./scripts/test/test_plugin.sh BST
-```
-
-will run all the tests which name matches "BST". In case the "fast recompilation" is desired, it's totally
-possibly to pass `LIQUID_DEV_MODE` to the script, for example:
-
-```
-LIQUID_DEV_MODE=true ./scripts/test/test_plugin.sh
-```
+Currently, no. Only one version of GHC is supported and that is the one
+that can be tested with `./scripts/test/test_plugin.sh`.
 
 [GHC.API]: https://github.com/ucsd-progsys/liquidhaskell/blob/develop/src/Language/Haskell/Liquid/GHC/API.hs
 [FunTy]: https://github.com/ucsd-progsys/liquidhaskell/blob/develop/src/Language/Haskell/Liquid/GHC/API.hs#L224

From 3d5812cbf68ecaa8b1b30cbde7e5153eb1a1a6c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Mon, 6 Mar 2023 15:48:56 -0300
Subject: [PATCH 162/219] Update links in the readme

---
 README.md | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md
index 0b90a6312a..4da962076c 100644
--- a/README.md
+++ b/README.md
@@ -350,8 +350,7 @@ patter synonym to deal with changes in type constructors.
 Currently, no. Only one version of GHC is supported and that is the one
 that can be tested with `./scripts/test/test_plugin.sh`.
 
-[GHC.API]: https://github.com/ucsd-progsys/liquidhaskell/blob/develop/src/Language/Haskell/Liquid/GHC/API.hs
-[FunTy]: https://github.com/ucsd-progsys/liquidhaskell/blob/develop/src/Language/Haskell/Liquid/GHC/API.hs#L224
+[GHC.API]: src-ghc/Liquid/GHC/API.hs
 
 # GHC Plugin Development FAQs
 
@@ -372,23 +371,23 @@ to map back and forth (sometimes in a partial way) between old and new data stru
 using**.
 
 
-[Plugin]:              https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Plugin.hs
-[GHC.Plugin]:          https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Plugin.hs
-[GHC.Interface]:       https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Interface.hs
-[SpecFinder]:          https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Plugin/SpecFinder.hs
-[BareSpec]:            https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/Types/Specs.hs#L301
-[LiftedSpec]:          https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/Types/Specs.hs#L476
-[TargetSrc]:           https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/Types/Specs.hs#L160
+[Plugin]:              src/Language/Haskell/Liquid/GHC/Plugin.hs
+[GHC.Plugin]:          src/Language/Haskell/Liquid/GHC/Plugin.hs
+[GHC.Interface]:       src-ghc/Liquid/GHC/Interface.hs
+[SpecFinder]:          src/Language/Haskell/Liquid/GHC/Plugin/SpecFinder.hs
+[BareSpec]:            src/Language/Haskell/Liquid/Types/Specs.hs#L361
+[LiftedSpec]:          src/Language/Haskell/Liquid/Types/Specs.hs#L554
+[TargetSrc]:           src/Language/Haskell/Liquid/Types/Specs.hs#L157
 [Ghc monad]:           https://hackage.haskell.org/package/ghc-8.10.1/docs/GHC.html#t:Ghc
 [HscEnv]:              https://hackage.haskell.org/package/ghc-8.10.1/docs/GHC.html#t:HscEnv
 [DynFlags]:            https://hackage.haskell.org/package/ghc-8.10.1/docs/GHC.html#t:DynFlags
 [GhcMonad]:            https://hackage.haskell.org/package/ghc-8.10.1/docs/GHC.html#t:GhcMonad
-[GhcMonadLike]:        https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/GhcMonadLike.hs
-[typechecking phase]:  https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Plugin.hs#L196-L224
+[GhcMonadLike]:        src-ghc/Liquid/GHC/GhcMonadLike.hs
+[typechecking phase]:  src/Language/Haskell/Liquid/GHC/Plugin.hs#L206-L222
 [ghcide]:              https://github.com/haskell/ghcide
-[findRelevantSpecs]:   https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Plugin/SpecFinder.hs#L61
+[findRelevantSpecs]:   src/Language/Haskell/Liquid/GHC/Plugin/SpecFinder.hs#L61
 [core binds]:          https://hackage.haskell.org/package/ghc-8.10.1/docs/CoreSyn.html#t:CoreBind
-[configureGhcTargets]: https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Interface.hs#L268
-[processTargetModule]: https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Interface.hs#L468
-[processModule]:       https://github.com/ucsd-progsys/liquidhaskell/blob/9a2f8284c5fe5b18ed0410e842acd3329a629a6b/src/Language/Haskell/Liquid/GHC/Plugin.hs#L393
+[configureGhcTargets]: src-ghc/Liquid/GHC/Interface.hs#L252
+[processTargetModule]: src-ghc/Liquid/GHC/Interface.hs#L481
+[processModule]:       src/Language/Haskell/Liquid/GHC/Plugin.hs#L393
 

From b77c13fd01fc8ae2436ab4333c82b1fa069fbd60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Mon, 6 Mar 2023 15:51:24 -0300
Subject: [PATCH 163/219] Remove FAQ on the old executable that is now removed

---
 README.md | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/README.md b/README.md
index 4da962076c..8ce6da2a94 100644
--- a/README.md
+++ b/README.md
@@ -354,13 +354,6 @@ that can be tested with `./scripts/test/test_plugin.sh`.
 
 # GHC Plugin Development FAQs
 
-## Is it possible that the behaviour of the old executable and the new / the plugin differ?
-
-It might happen, yes, but the surface area is fairly small. Both modules work by producing a [TargetSrc][]
-that is passed to the internal LH API, which is shared by _both_ modules. Therefore, any difference in 
-behaviour has to be researched in the code path that produces such [TargetSrc][]. For the [GHC.Plugin][] this
-happens in the `makeTargetSrc`, whereas for the [GHC.Interface][] this happens inside the [makeGhcSrc][] function.
-
 ## Why is the GHC.Interface using slightly different types than the GHC.Plugin module?
 
 Mostly for backward-compatibility and for historical reasons. Types like [BareSpec][] used to be type alias

From af627dde4b74cc8e25a2dd4a78e5b981ec7f8e93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Mon, 6 Mar 2023 16:00:58 -0300
Subject: [PATCH 164/219] Update note on test parallelism

---
 README.md | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 8ce6da2a94..6935bbe6ab 100644
--- a/README.md
+++ b/README.md
@@ -139,9 +139,7 @@ You can directly extend and run the tests by modifying the files in
 
 ### Parallelism in Tests
 
-Most tests run in parallel, with a few module dependencies built sequentially in
-advance. Benchmarks are run sequentially after all other tests have finished.
-For details on adding tests, see note [Parallel_Tests] in `tests/test.hs`.
+Tests run in parallel, unless the flag `--measure-timings` is specified to `test_plugin.sh`.
 
 ## How to create performance comparison charts
 

From 9534254f4bb338c10957557cc0c422f608111c52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Mon, 6 Mar 2023 16:58:13 -0300
Subject: [PATCH 165/219] Another style edit

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6935bbe6ab..ae46926e8a 100644
--- a/README.md
+++ b/README.md
@@ -107,7 +107,7 @@ For documentation on the `test-driver` executable itself, please refer to the
 `README.md` in `tests/` or run `cabal run tests:test-driver -- --help` or `stack
 run test-driver -- --help`
 
-So you can run *all* the tests by
+You can run *all* the tests by
 
     $ ./scripts/test/test_plugin.sh
 

From 128a8a7f09182554fa2d018359a5269671ea441c Mon Sep 17 00:00:00 2001
From: Afonso Rafael 
Date: Tue, 7 Mar 2023 17:10:11 +0100
Subject: [PATCH 166/219] Clean the App that require cleaning.

On {- App (App (App (relTermToUnTerm f1 f2) x1) x2) relX -} both x1
and x2 are not being cleaned of constructs we don't want to print. So
we need to use cleanUnTerms on them.
---
 .../Haskell/Liquid/Constraint/Relational.hs   | 27 ++++++++++++++-----
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs
index 8c80774257..abab4821c4 100644
--- a/src/Language/Haskell/Liquid/Constraint/Relational.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs
@@ -135,7 +135,7 @@ consRelTop cfg ti chk syn γ ψ (x, y, t, s, ra, rp) = traceChk "Init" e d t s p
     argNames@(left, right) = (fst $ vargs t', fst $ vargs s')
     renVars = map F.symbolSafeString $ left ++ right
     toExpr  = F.EVar . F.symbol
-    toCoreExpr = GM.unTickExpr . binderToExpr
+    toCoreExpr = fromAnf . GM.unTickExpr . binderToExpr
     p = fromRelExpr rp
     γ' = γ `setLocation` Sp.Span (GM.fSrcSpan (F.loc t))
     cbs = giCbs $ giSrc ti
@@ -325,17 +325,25 @@ relTermToUnTerm' m relTerms (App f1 v1) (App f2 v2)
   , areCompatible v1 v2
   , Just relX <- lookup (x1, x2) relTerms
   = traceWhenLoud
-      ("relTermToUnTerm App lookup " ++ show x1 ++ " ~ " ++ show x2 ++ " ~> " ++ show relX) $ 
-    App (App (App (relTermToUnTerm' m relTerms f1 f2) v1) v2) relX
-relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2) 
+      ("relTermToUnTerm App lookup "
+       ++ show x1 ++ " ~ " ++ show x2 ++ " ~> " ++ show relX) $ 
+    App (App (App (relTermToUnTerm' m relTerms f1 f2) v1') v2') relX
+    where
+      renVars  = map F.symbolSafeString $ fst m ++ snd m
+      (v1', _) = cleanUnTerms renVars v1
+      (v2', _) = cleanUnTerms renVars v2
+relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2)
   | isCommonArg x1
   , isCommonArg x2
   , areCompatible f1 f2
   , areCompatible x1 x2
   = traceWhenLoud
       ("relTermToUnTerm App common arg " ++ show x1 ++ " " ++ show x2)
-      $ App (App (App (relTermToUnTerm' m relTerms f1 f2) x1) x2) relX
+      $ App (App (App (relTermToUnTerm' m relTerms f1 f2) x1') x2') relX
     where
+      renVars  = map F.symbolSafeString $ fst m ++ snd m
+      (x1', _) = cleanUnTerms renVars x1
+      (x2', _) = cleanUnTerms renVars x2
       relX = mkLambdaUnit m x1 x2 (Ghc.exprType x1) (Ghc.exprType x2)
 relTermToUnTerm' m relTerms (Lam α1 e1) (Lam α2 e2) 
   | Ghc.isTyVar α1, Ghc.isTyVar α2
@@ -350,13 +358,18 @@ relTermToUnTerm' m relTerms (Lam x1 e1) (Lam x2 e2)
     (e1l, e2r) = subRelCopiesWithMapping m e1 x1 e2 x2
 relTermToUnTerm' m relTerms (Let (NonRec x1 d1) e1) (Let (NonRec x2 d2) e2) 
   | areCompatible d1 d2
-  = Let (NonRec x1l d1) $ Let (NonRec x2r d2) $ Let (NonRec relX relD) $ 
+  = Let (NonRec x1l d1')
+    $ Let (NonRec x2r d2')
+    $ Let (NonRec relX relD) $ 
     relTermToUnTerm' m (((x1l, x2r), Var relX) : relTerms) e1l e2r
     where 
       relX = mkRelLemmaVar x1 x2
       relD = relTermToUnTerm' m relTerms d1 d2
       (x1l, x2r) = mkRelCopies x1 x2
       (e1l, e2r) = subRelCopies e1 x1 e2 x2
+      renVars    = map F.symbolSafeString $ fst m ++ snd m
+      (d1', _)   = cleanUnTerms renVars d1
+      (d2', _)   = cleanUnTerms renVars d2
 -- TODO: test recursive and mutually recursive lets
 relTermToUnTerm' m relTerms (Let (Rec bs1) e1) (Let (Rec bs2) e2) 
   | length bs1 == length bs2
@@ -1347,7 +1360,7 @@ relHint rvs t v e = text "import GHC.Types"
                     $+$ text (name
                               ++ " :: "
                               ++ removeIdent (toType False t))
-                    $+$ text (coreToHs rvs t v (fromAnf e))
+                    $+$ text (coreToHs rvs t v e)
                     $+$ text ""
                     $+$ text "{- BARE CORE"
                     $+$ text (show e)

From 7daeb7c7ece7eb1f9eb595f254bc8d965872bf85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Fri, 10 Mar 2023 08:59:49 -0300
Subject: [PATCH 167/219] Bump bounds of liquid-* packages for ghc-9.0.2

---
 liquid-base/liquid-base.cabal             | 17 ++++++----------
 liquid-bytestring/liquid-bytestring.cabal |  9 ++++-----
 liquid-containers/liquid-containers.cabal |  8 ++++----
 liquid-ghc-prim/liquid-ghc-prim.cabal     |  9 ++++-----
 liquid-parallel/liquid-parallel.cabal     |  9 ++++-----
 liquid-platform/liquid-platform.cabal     | 24 +++++++++++------------
 liquid-prelude/liquid-prelude.cabal       | 10 +++++-----
 liquid-vector/liquid-vector.cabal         |  8 ++++----
 8 files changed, 43 insertions(+), 51 deletions(-)

diff --git a/liquid-base/liquid-base.cabal b/liquid-base/liquid-base.cabal
index 659c8fa8ee..45f0f7487e 100644
--- a/liquid-base/liquid-base.cabal
+++ b/liquid-base/liquid-base.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.0
 name:               liquid-base
-version:            4.14.3.0
+version:            4.15.1.0
 synopsis:           Drop-in base replacement for LiquidHaskell
 description:        Drop-in base replacement for LiquidHaskell.
 license:            BSD3
@@ -23,7 +23,7 @@ data-files:         src/Data/*.spec
                     src/Control/*.spec
 
 custom-setup
-  setup-depends: Cabal, base, liquidhaskell
+  setup-depends: Cabal<4, base<5, liquidhaskell
 
 library
   exposed-modules:  Control.Applicative
@@ -244,17 +244,12 @@ library
                     Liquid.Prelude.Totality
 
   hs-source-dirs:     src
-  build-depends:      
-                      liquid-ghc-prim
-                    , liquidhaskell        >= 0.8.10.1
-  if impl(ghc < 9)
-    build-depends:    integer-gmp < 1.0.4.0
-                    , base                 == 4.14.3.0
-  else
-    build-depends:    base                 ^>= 4.15.0.0
+  build-depends:
+                      base                 ^>= 4.15.1.0
+                    , liquid-ghc-prim
+                    , liquidhaskell        >= 0.9.0.2
   default-language:   Haskell2010
   default-extensions: PackageImports
                       NoImplicitPrelude
   if impl(ghc >= 8.10)
     ghc-options: -fplugin=LiquidHaskell -fplugin-opt=LiquidHaskell:--no-positivity-check
-  
\ No newline at end of file
diff --git a/liquid-bytestring/liquid-bytestring.cabal b/liquid-bytestring/liquid-bytestring.cabal
index 94400d4dd4..d0429be800 100644
--- a/liquid-bytestring/liquid-bytestring.cabal
+++ b/liquid-bytestring/liquid-bytestring.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.24
 name:               liquid-bytestring
-version:            0.10.10.0
+version:            0.10.12.1
 synopsis:           LiquidHaskell specs for the bytestring package
 description:        LiquidHaskell specs for the bytestring package.
 license:            BSD3
@@ -20,7 +20,7 @@ data-files:           src/Data/ByteString.spec
                       src/Data/ByteString/Lazy/Char8.spec
 
 custom-setup
-  setup-depends: Cabal, base, liquidhaskell
+  setup-depends: Cabal<4, base<5, liquidhaskell
 
 library
   exposed-modules:    Data.ByteString
@@ -48,10 +48,9 @@ library
 
   hs-source-dirs:     src
   build-depends:      liquid-base          < 5
-                    , bytestring           >= 0.10.10.0 && < 0.11
-                    , liquidhaskell        >= 0.8.10.1
+                    , bytestring           >= 0.10.12.1 && < 0.11
+                    , liquidhaskell        >= 0.9.0.2
   default-language:   Haskell2010
   default-extensions: PackageImports
   if impl(ghc >= 8.10)
     ghc-options: -fplugin=LiquidHaskell
-  
\ No newline at end of file
diff --git a/liquid-containers/liquid-containers.cabal b/liquid-containers/liquid-containers.cabal
index a7f6da4c32..785d2d89ae 100644
--- a/liquid-containers/liquid-containers.cabal
+++ b/liquid-containers/liquid-containers.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.24
 name:               liquid-containers
-version:            0.6.2.1
+version:            0.6.4.1
 synopsis:           LiquidHaskell specs for the containers package
 description:        LiquidHaskell specs for the containers package.
 license:            BSD3
@@ -15,7 +15,7 @@ build-type:         Custom
 data-files:           src/Data/Set.spec
 
 custom-setup
-  setup-depends: Cabal, base, liquidhaskell
+  setup-depends: Cabal<4, base<5, liquidhaskell
 
 library
   exposed-modules:    Data.Containers.ListUtils
@@ -49,8 +49,8 @@ library
                       Utils.Containers.Internal.StrictPair
   hs-source-dirs:     src
   build-depends:      liquid-base          < 5
-                    , containers           >= 0.6.2.1 && < 0.7
-                    , liquidhaskell        >= 0.8.10.1
+                    , containers           >= 0.6.4.1 && < 0.7
+                    , liquidhaskell        >= 0.9.0.2
   default-language:   Haskell2010
   default-extensions: PackageImports
   if impl(ghc >= 8.10)
diff --git a/liquid-ghc-prim/liquid-ghc-prim.cabal b/liquid-ghc-prim/liquid-ghc-prim.cabal
index 1b229d75d7..57a92292a0 100644
--- a/liquid-ghc-prim/liquid-ghc-prim.cabal
+++ b/liquid-ghc-prim/liquid-ghc-prim.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.24
 name:               liquid-ghc-prim
-version:            0.6.1
+version:            0.7.0.1
 synopsis:           Drop-in ghc-prim replacement for LiquidHaskell
 description:        Drop-in ghc-prim replacement for LiquidHaskell.
 license:            BSD3
@@ -16,7 +16,7 @@ data-files:         src/GHC/*.spec
 
 
 custom-setup
-  setup-depends: Cabal, base, liquidhaskell
+  setup-depends: Cabal<4, base<5, liquidhaskell
 
 library
   exposed-modules:
@@ -36,12 +36,11 @@ library
                     GHC.Types
 
   hs-source-dirs:     src
-  build-depends:      ghc-prim             >= 0.6.1 && < 0.8
-                    , liquidhaskell        >= 0.8.10.1
+  build-depends:      ghc-prim             >= 0.7.0 && < 0.8
+                    , liquidhaskell        >= 0.9.0.2
   default-language:   Haskell2010
   default-extensions: PackageImports
                       NoImplicitPrelude
                       MagicHash
   if impl(ghc >= 8.10)
     ghc-options: -fplugin=LiquidHaskell
-  
\ No newline at end of file
diff --git a/liquid-parallel/liquid-parallel.cabal b/liquid-parallel/liquid-parallel.cabal
index d14ca60cd3..778c6175fd 100644
--- a/liquid-parallel/liquid-parallel.cabal
+++ b/liquid-parallel/liquid-parallel.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.24
 name:               liquid-parallel
-version:            3.2.2.0
+version:            3.2.2.0.1
 synopsis:           LiquidHaskell specs for the parallel package
 description:        LiquidHaskell specs for the parallel package.
 license:            BSD3
@@ -15,7 +15,7 @@ build-type:         Custom
 data-files:           src/Control/Parallel/Strategies.spec
 
 custom-setup
-  setup-depends: Cabal, base, liquidhaskell
+  setup-depends: Cabal<4, base<5, liquidhaskell
 
 library
   exposed-modules:    Control.Seq
@@ -23,10 +23,9 @@ library
                       Control.Parallel.Strategies
   hs-source-dirs:     src
   build-depends:      liquid-base          < 4.16
-                    , parallel             >= 3.2.0.0 && < 3.3
-                    , liquidhaskell        >= 0.8.10.1
+                    , parallel             >= 3.2.2.0 && < 3.3
+                    , liquidhaskell        >= 0.9.0.2
   default-language:   Haskell2010
   default-extensions: PackageImports
   if impl(ghc >= 8.10)
     ghc-options: -fplugin=LiquidHaskell
-  
\ No newline at end of file
diff --git a/liquid-platform/liquid-platform.cabal b/liquid-platform/liquid-platform.cabal
index 214facca6b..7045d12eb5 100644
--- a/liquid-platform/liquid-platform.cabal
+++ b/liquid-platform/liquid-platform.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.22
 name:               liquid-platform
-version:            0.8.10.2
+version:            0.9.0.2
 synopsis:           A battery-included platform for LiquidHaskell
 description:        A battery-included platform for LiquidHaskell.
 license:            BSD3
@@ -25,34 +25,34 @@ executable liquidhaskell
     buildable: False
   else
     buildable: True
-    build-depends:      liquid-base       >= 4.14.1.0 && < 5
-                      , liquid-containers >= 0.6.2.1  && < 0.7
-                      , liquid-prelude    >= 0.8.10.2
-                      , liquid-vector     >= 0.12.1.2 && < 0.13
-                      , liquid-bytestring >= 0.10.0.0 && < 0.11
-                      , liquidhaskell     >= 0.8.10.2
+    build-depends:      liquid-base       >= 4.15.1.0 && < 5
+                      , liquid-containers >= 0.6.4.1  && < 0.7
+                      , liquid-prelude    >= 0.9.0.2
+                      , liquid-vector     >= 0.12.3.1 && < 0.13
+                      , liquid-bytestring >= 0.10.12.1 && < 0.11
+                      , liquidhaskell     >= 0.9.0.2
                       , filepath
                       , process           >= 1.6.0.0 && < 1.7
                       , cmdargs           >= 0.10    && < 0.11
 
   if flag(devel)
     ghc-options: -Werror
-  
+
 
 executable gradual
   main-is:          src/Gradual.hs
-  build-depends:    base            >= 4.8.1.0 && < 5
+  build-depends:    base            >= 4.15.1.0 && < 5
                   , cmdargs
                   , hscolour
-                  , liquid-fixpoint >= 0.7.0.5
-                  , liquidhaskell   >= 0.8.10.1
+                  , liquid-fixpoint >= 0.9.0.2
+                  , liquidhaskell   >= 0.9.0.2
   default-language: Haskell2010
   buildable:        False
   ghc-options:      -W -threaded
 
   if flag(devel)
     ghc-options: -Werror
-  
+
 
 executable target
   main-is:          src/Target.hs
diff --git a/liquid-prelude/liquid-prelude.cabal b/liquid-prelude/liquid-prelude.cabal
index f4e9a130d5..1481ffb9fa 100644
--- a/liquid-prelude/liquid-prelude.cabal
+++ b/liquid-prelude/liquid-prelude.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.24
 name:               liquid-prelude
-version:            0.8.10.2
+version:            0.9.0.2
 synopsis:           General utility modules for LiquidHaskell
 description:        General utility modules for LiquidHaskell.
 license:            BSD3
@@ -13,7 +13,7 @@ homepage:           https://github.com/ucsd-progsys/liquidhaskell
 build-type:         Custom
 
 custom-setup
-  setup-depends: Cabal, base, liquidhaskell
+  setup-depends: Cabal<4, base<5, liquidhaskell
 
 library
   exposed-modules:  Language.Haskell.Liquid.RTick
@@ -29,9 +29,9 @@ library
                     KMeansHelper
   hs-source-dirs:     src
   build-depends:      liquid-base          < 5
-                    , bytestring           >= 0.10.0.0 && < 0.11
-                    , containers           >= 0.6.0.0  && < 0.7
-                    , liquidhaskell        >= 0.8.10.2
+                    , bytestring           >= 0.10.12.1 && < 0.11
+                    , containers           >= 0.6.4.1  && < 0.7
+                    , liquidhaskell        >= 0.9.0.2
   default-language:   Haskell2010
   if impl(ghc >= 8.10)
     ghc-options: -fplugin=LiquidHaskell
diff --git a/liquid-vector/liquid-vector.cabal b/liquid-vector/liquid-vector.cabal
index d64d7c5a28..249b584060 100644
--- a/liquid-vector/liquid-vector.cabal
+++ b/liquid-vector/liquid-vector.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.24
 name:               liquid-vector
-version:            0.12.1.2
+version:            0.12.3.1
 synopsis:           LiquidHaskell specs for the vector package
 description:        LiquidHaskell specs for the vector package.
 license:            BSD3
@@ -15,7 +15,7 @@ build-type:         Custom
 data-files:           src/Data/Vector.spec
 
 custom-setup
-  setup-depends: Cabal, base, liquidhaskell
+  setup-depends: Cabal<4, base<5, liquidhaskell
 
 library
   exposed-modules:    Data.Vector.Internal.Check
@@ -46,8 +46,8 @@ library
                       Data.Vector
   hs-source-dirs:     src
   build-depends:      liquid-base          < 4.16
-                    , vector               >= 0.12.1.2 && < 0.13
-                    , liquidhaskell        >= 0.8.10.1
+                    , vector               >= 0.12.3.1 && < 0.13
+                    , liquidhaskell        >= 0.9.0.2
   default-language:   Haskell2010
   default-extensions: PackageImports
   if impl(ghc >= 8.10)

From 1ad91ae2da8546850498a8400371f43d07481f25 Mon Sep 17 00:00:00 2001
From: Renan 
Date: Fri, 10 Mar 2023 20:41:21 -0300
Subject: [PATCH 168/219] Improve Tests

---
 liquid-base/src/GHC/Real.spec                       | 2 +-
 tests/neg/Exponential1NegTest.hs                    | 5 +++++
 tests/neg/Exponential2NegTest.hs                    | 6 ++++++
 tests/neg/exponential1.hs                           | 5 -----
 tests/neg/exponential2.hs                           | 6 ------
 tests/pos/{exponential.hs => ExponentialPosTest.hs} | 3 +--
 tests/tests.cabal                                   | 3 +++
 7 files changed, 16 insertions(+), 14 deletions(-)
 create mode 100644 tests/neg/Exponential1NegTest.hs
 create mode 100644 tests/neg/Exponential2NegTest.hs
 delete mode 100644 tests/neg/exponential1.hs
 delete mode 100644 tests/neg/exponential2.hs
 rename tests/pos/{exponential.hs => ExponentialPosTest.hs} (87%)

diff --git a/liquid-base/src/GHC/Real.spec b/liquid-base/src/GHC/Real.spec
index 05b795b2f0..b67039f25c 100644
--- a/liquid-base/src/GHC/Real.spec
+++ b/liquid-base/src/GHC/Real.spec
@@ -2,7 +2,7 @@ module spec GHC.Real where
 
 import GHC.Types
 
-(GHC.Real.^) :: (GHC.Num.Num a, GHC.Real.Integral b) => n:a -> {m:b | m >= 0} -> {k:a | (m == 0 => k == 1) && ((n == 0 && m /= 0) <=> k == 0)}
+(GHC.Real.^) :: (GHC.Num.Num a, GHC.Real.Integral b) => x:a -> y:{n:b | n >= 0} -> {z:a | (y == 0 => z == 1) && ((x == 0 && y /= 0) <=> z == 0)}
 
 GHC.Real.fromIntegral    :: (GHC.Real.Integral a, GHC.Num.Num b) => x:a -> {v:b|v=x}
 
diff --git a/tests/neg/Exponential1NegTest.hs b/tests/neg/Exponential1NegTest.hs
new file mode 100644
index 0000000000..bbf6082559
--- /dev/null
+++ b/tests/neg/Exponential1NegTest.hs
@@ -0,0 +1,5 @@
+{-@ LIQUID "--expect-error-containing=Exponential1NegTest.hs:5:1" @-}
+module Exponential1NegTest where
+
+ex5 :: Float -> Int -> Float
+ex5 x y = x ^ y
diff --git a/tests/neg/Exponential2NegTest.hs b/tests/neg/Exponential2NegTest.hs
new file mode 100644
index 0000000000..8aaf9ca837
--- /dev/null
+++ b/tests/neg/Exponential2NegTest.hs
@@ -0,0 +1,6 @@
+{-@ LIQUID "--expect-error-containing=Exponential2NegTest.hs:6:20" @-}
+module Exponential2NegTest where
+
+{-@ ex6 :: {n:Float | n /= 0} -> Int -> Float @-}
+ex6 :: Float -> Int -> Float
+ex6 x y = 1 / (x ^ y)
diff --git a/tests/neg/exponential1.hs b/tests/neg/exponential1.hs
deleted file mode 100644
index 0935362d5a..0000000000
--- a/tests/neg/exponential1.hs
+++ /dev/null
@@ -1,5 +0,0 @@
--- negative test for real exponentiation
-module Foo where
-
-ex5 :: Float -> Int -> Float
-ex5 x y = x ^ y
diff --git a/tests/neg/exponential2.hs b/tests/neg/exponential2.hs
deleted file mode 100644
index bc95695c0b..0000000000
--- a/tests/neg/exponential2.hs
+++ /dev/null
@@ -1,6 +0,0 @@
--- negative test for real exponentiation
-module Foo where
-
-{-@ ex6 :: {n:Float | n /= 0} -> Int -> Float @-}
-ex6 :: Float -> Int -> Float
-ex6 x y = 1 / (x ^ y)
diff --git a/tests/pos/exponential.hs b/tests/pos/ExponentialPosTest.hs
similarity index 87%
rename from tests/pos/exponential.hs
rename to tests/pos/ExponentialPosTest.hs
index c5ff34c39c..066bf3ccb8 100644
--- a/tests/pos/exponential.hs
+++ b/tests/pos/ExponentialPosTest.hs
@@ -1,5 +1,4 @@
--- positive tests for real exponentiation
-module Foo where
+module ExponentialPosTest where
 
 {-@ ex1 :: Float -> Nat -> Float @-}
 ex1 :: Float -> Int -> Float
diff --git a/tests/tests.cabal b/tests/tests.cabal
index 909c9aa366..5d34ef4b35 100644
--- a/tests/tests.cabal
+++ b/tests/tests.cabal
@@ -1167,6 +1167,8 @@ executable unit-neg
                     , ExactADT6
                     , ExactGADT6
                     , ExactGADT7
+                    , Exponential1NegTest
+                    , Exponential2NegTest
                     , Fail1
                     , Fail
                     , FilterAbs
@@ -1823,6 +1825,7 @@ executable unit-pos-2
                     , ExactGADT6
                     , ExactGADT
                     , Exp0
+                    , ExponentialPosTest
                     , Extype
                     , Fail
                     , FailName

From 79f22c18ee916ba8e1b9e48ab2240dd232ec4f14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Facundo=20Dom=C3=ADnguez?= 
Date: Fri, 10 Mar 2023 21:27:43 -0300
Subject: [PATCH 169/219] Trivial change to README for CI to run

---
 tests/README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/README.md b/tests/README.md
index b073c47ca0..23750c159b 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -14,6 +14,7 @@
   containing `pos` and `neg` subfolders for positive and negative tests
   respectively.
 
+
 ## `test-driver` Executable
 
 See the code for comments and documentation that is likely more up to date than

From 83ac97bc752a71a4e542039538ce489288039ae5 Mon Sep 17 00:00:00 2001
From: Afonso Rafael 
Date: Fri, 17 Mar 2023 16:38:13 +0100
Subject: [PATCH 170/219] Handling cases in fromANF.

---
 .../Haskell/Liquid/Constraint/Relational.hs   |  6 ++++--
 src/Language/Haskell/Liquid/Synthesize/GHC.hs | 21 ++++++++++---------
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs
index abab4821c4..1c8ce798ca 100644
--- a/src/Language/Haskell/Liquid/Constraint/Relational.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs
@@ -135,7 +135,8 @@ consRelTop cfg ti chk syn γ ψ (x, y, t, s, ra, rp) = traceChk "Init" e d t s p
     argNames@(left, right) = (fst $ vargs t', fst $ vargs s')
     renVars = map F.symbolSafeString $ left ++ right
     toExpr  = F.EVar . F.symbol
-    toCoreExpr = fromAnf . GM.unTickExpr . binderToExpr
+    toCoreExpr =
+      fst . cleanUnTerms renVars . fromAnf . GM.unTickExpr . binderToExpr
     p = fromRelExpr rp
     γ' = γ `setLocation` Sp.Span (GM.fSrcSpan (F.loc t))
     cbs = giCbs $ giSrc ti
@@ -507,7 +508,8 @@ cleanUnTerms rvs (Let r e) = (Let r core, bool)
   where
     (core, bool) = cleanUnTerms rvs e
 
-cleanUnTerms rvs (Case e v t alts) = (Case core v t clAlts, bool1 || bool2)
+cleanUnTerms rvs (Case e v t alts) =
+  (Case core v t clAlts, bool1 || bool2)
   where
     (core,   bool1) = cleanUnTerms rvs e
     (clAlts, bool2) = cleanCase rvs alts
diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
index 284250174f..58080c09e9 100644
--- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs
+++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
@@ -86,15 +86,14 @@ fromAnf'
 fromAnf' (Lam b e) bnds
   = let (e', bnds') = fromAnf' e bnds
     in  (Lam b e', bnds')
-  
-fromAnf' (Let (NonRec rb lb) e) bnds
-  | elem '#' (show rb) = let (lb', bnds') = fromAnf' lb bnds
-                         in  fromAnf' e ((rb, lb') : bnds')
 
-  | otherwise = (Let (NonRec rb lb') e', binds'')
+fromAnf' (Let (NonRec rb lb) e) bnds = fromAnf' e ((rb, lb') : bnds')
+--  | elem '#' (show rb) = let (lb', bnds') = fromAnf' lb bnds
+--                         in  fromAnf' e ((rb, lb') : bnds')
+--  | otherwise = (Let (NonRec rb lb') e', binds'')
   where
-    (lb', bnds') = fromAnf' lb bnds
-    (e', binds'') = fromAnf' e ((rb, lb') : bnds')
+    (lb', bnds')  = fromAnf' lb bnds
+--    (e', binds'') = fromAnf' e ((rb, lb') : bnds')
 
 fromAnf' (Let (Rec {}) _) _ =
   error " By construction, no recursive bindings in let expression. "
@@ -103,9 +102,11 @@ fromAnf' (Var var) bnds
   = (fromMaybe (Var var) (lookup var bnds), bnds)
 
 fromAnf' (Case scr bnd tp alts) bnds
-  = (Case scr bnd tp (
-        map (\(altc, xs, e) ->
-               (altc, xs, fst $ fromAnf' e bnds)) alts), bnds)
+  = (Case scr' bnd tp
+      ( map (\(altc, xs, e) ->
+                (altc, xs, fst $ fromAnf' e bnds)) alts), bnds')
+  where
+    ( scr', bnds' ) = fromAnf' scr bnds
 
 fromAnf' (App e1 e2) bnds
   = let (e1', bnds')  = fromAnf' e1 bnds

From bcd76f0f67961540f2120cee79af61b92508a98d Mon Sep 17 00:00:00 2001
From: Afonso Rafael 
Date: Fri, 17 Mar 2023 16:47:36 +0100
Subject: [PATCH 171/219] Comment on cleanUnTerms error.

---
 src/Language/Haskell/Liquid/Constraint/Relational.hs | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs
index 1c8ce798ca..1aecccd106 100644
--- a/src/Language/Haskell/Liquid/Constraint/Relational.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs
@@ -135,8 +135,15 @@ consRelTop cfg ti chk syn γ ψ (x, y, t, s, ra, rp) = traceChk "Init" e d t s p
     argNames@(left, right) = (fst $ vargs t', fst $ vargs s')
     renVars = map F.symbolSafeString $ left ++ right
     toExpr  = F.EVar . F.symbol
-    toCoreExpr =
-      fst . cleanUnTerms renVars . fromAnf . GM.unTickExpr . binderToExpr
+
+    {- cleanUnTerms in toCoreExpr generates:
+       Expression: patError ()
+       Type: forall a. Addr# -> a
+       Args: [()]
+    -}    
+    toCoreExpr = fromAnf . GM.unTickExpr . binderToExpr
+--      fst . cleanUnTerms renVars
+--      . fromAnf . GM.unTickExpr . binderToExpr
     p = fromRelExpr rp
     γ' = γ `setLocation` Sp.Span (GM.fSrcSpan (F.loc t))
     cbs = giCbs $ giSrc ti

From e9d34920af4f3f662263f8ad82648c23ce2e8d2f Mon Sep 17 00:00:00 2001
From: Lisa Vasilenko 
Date: Mon, 20 Mar 2023 14:09:28 +0000
Subject: [PATCH 172/219] fix hlint

---
 .../Haskell/Liquid/Constraint/Relational.hs   | 47 +++++++++----------
 src/Language/Haskell/Liquid/Synthesize/GHC.hs |  4 +-
 2 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs
index 1aecccd106..4ee407c6bf 100644
--- a/src/Language/Haskell/Liquid/Constraint/Relational.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs
@@ -124,7 +124,7 @@ consRelTop cfg ti chk syn γ ψ (x, y, t, s, ra, rp) = traceChk "Init" e d t s p
     consRelCheckBind (UnaryTyping chk (\γγ ee -> removeAbsRef <$> syn γγ ee)) γ' ψ e d t' s' ra rp
     when (relationalHints cfg) $ 
       modify $ \cgi -> cgi
-      { relHints = relHint renVars
+      { relHints = relHint (renVars argNames)
                    (relSigToUnSig (toExpr x) (toExpr y) t' s' rp)
                    hintName
                    (relTermToUnTerm argNames x y hintName
@@ -132,8 +132,7 @@ consRelTop cfg ti chk syn γ ψ (x, y, t, s, ra, rp) = traceChk "Init" e d t s p
                     $+$ relHints cgi
       }
   where
-    argNames@(left, right) = (fst $ vargs t', fst $ vargs s')
-    renVars = map F.symbolSafeString $ left ++ right
+    argNames = (fst $ vargs t', fst $ vargs s')
     toExpr  = F.EVar . F.symbol
 
     {- cleanUnTerms in toCoreExpr generates:
@@ -309,6 +308,9 @@ isCommonArg x | Type{} <- GM.unTickExpr x = False
 isCommonArg x | Var v <- GM.unTickExpr x = not (GM.isEmbeddedDictVar v)
 isCommonArg _ = True
 
+renVars :: ArgMapping -> RenVars
+renVars (lvars, rvars) = map F.symbolSafeString $ lvars ++ rvars
+
 relTermToUnTerm' :: ArgMapping -> [((Var, Var), CoreExpr)] -> CoreExpr -> CoreExpr -> CoreExpr
 relTermToUnTerm' _ relTerms (Var x1) (Var x2)
   | Just relX <- lookup (x1, x2) relTerms 
@@ -337,9 +339,9 @@ relTermToUnTerm' m relTerms (App f1 v1) (App f2 v2)
        ++ show x1 ++ " ~ " ++ show x2 ++ " ~> " ++ show relX) $ 
     App (App (App (relTermToUnTerm' m relTerms f1 f2) v1') v2') relX
     where
-      renVars  = map F.symbolSafeString $ fst m ++ snd m
-      (v1', _) = cleanUnTerms renVars v1
-      (v2', _) = cleanUnTerms renVars v2
+      rvs = renVars m
+      (v1', _) = cleanUnTerms rvs v1
+      (v2', _) = cleanUnTerms rvs v2
 relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2)
   | isCommonArg x1
   , isCommonArg x2
@@ -349,9 +351,9 @@ relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2)
       ("relTermToUnTerm App common arg " ++ show x1 ++ " " ++ show x2)
       $ App (App (App (relTermToUnTerm' m relTerms f1 f2) x1') x2') relX
     where
-      renVars  = map F.symbolSafeString $ fst m ++ snd m
-      (x1', _) = cleanUnTerms renVars x1
-      (x2', _) = cleanUnTerms renVars x2
+      rvs = renVars m
+      (x1', _) = cleanUnTerms rvs x1
+      (x2', _) = cleanUnTerms rvs x2
       relX = mkLambdaUnit m x1 x2 (Ghc.exprType x1) (Ghc.exprType x2)
 relTermToUnTerm' m relTerms (Lam α1 e1) (Lam α2 e2) 
   | Ghc.isTyVar α1, Ghc.isTyVar α2
@@ -375,9 +377,9 @@ relTermToUnTerm' m relTerms (Let (NonRec x1 d1) e1) (Let (NonRec x2 d2) e2)
       relD = relTermToUnTerm' m relTerms d1 d2
       (x1l, x2r) = mkRelCopies x1 x2
       (e1l, e2r) = subRelCopies e1 x1 e2 x2
-      renVars    = map F.symbolSafeString $ fst m ++ snd m
-      (d1', _)   = cleanUnTerms renVars d1
-      (d2', _)   = cleanUnTerms renVars d2
+      rvs        = renVars m
+      (d1', _)   = cleanUnTerms rvs d1
+      (d2', _)   = cleanUnTerms rvs d2
 -- TODO: test recursive and mutually recursive lets
 relTermToUnTerm' m relTerms (Let (Rec bs1) e1) (Let (Rec bs2) e2) 
   | length bs1 == length bs2
@@ -415,9 +417,9 @@ relTermToUnTerm' m _ e1 e2
   where
     realLoc  = Ghc.mkRealSrcLoc (Ghc.mkFastString "") 0 0
     realSpan = Ghc.mkRealSrcSpan realLoc realLoc
-    renVars  = map F.symbolSafeString $ fst m ++ snd m
-    left     = coreToGoal renVars True e1 
-    right    = coreToGoal renVars True e2
+    rvs      = renVars m
+    left     = coreToGoal rvs True e1 
+    right    = coreToGoal rvs True e2
     info     = "GOAL: " ++ left ++ " ~ " ++ right
 
 {- function to print CoreExpr as strings in order to
@@ -477,9 +479,9 @@ mkLambdaUnit m e1 e2 _ _
   where
     genConst          = Var $ GM.stringVar "const" Ghc.unitTy
     genConstU         = App genConst Ghc.unitExpr
-    renVars           = map F.symbolSafeString $ fst m ++ snd m
-    (cle1, patError1) = cleanUnTerms renVars e1
-    (cle2, patError2) = cleanUnTerms renVars e2
+    rvs               = renVars m
+    (cle1, patError1) = cleanUnTerms rvs e1
+    (cle2, patError2) = cleanUnTerms rvs e2
 
 cleanUnTerms :: RenVars -> CoreExpr -> (CoreExpr, Bool)
 {- Maybe have to do some cleaning to the vars here -}
@@ -1362,13 +1364,8 @@ relHint :: RenVars -> SpecType -> Ghc.Var -> CoreExpr -> Doc
 relHint rvs t v e = text "import GHC.Types"
                     $+$ text ""
                     $+$ text "{- HLINT ignore \"Use camelCase\" -}"
-                    $+$ text ("{-@ " ++ name
-                              ++ " :: "
-                              ++ F.showpp t
-                              ++ " @-}")
-                    $+$ text (name
-                              ++ " :: "
-                              ++ removeIdent (toType False t))
+                    $+$ text ("{-@ " ++ name ++ " :: " ++ F.showpp t ++ " @-}")
+                    $+$ text (name ++ " :: " ++ removeIdent (toType False t))
                     $+$ text (coreToHs rvs t v e)
                     $+$ text ""
                     $+$ text "{- BARE CORE"
diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
index 58080c09e9..ac5afa17fd 100644
--- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs
+++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
@@ -127,10 +127,10 @@ fromAnf' e _ = error $ "fromAnf: unsupported core expression "
 -- | Function used for pretty printing core as Haskell source.
 --   Input does not contain let bindings.
 coreToHs :: RenVars -> SpecType -> Var -> CoreExpr -> String
-coreToHs rvs _ v e = pprintSymbols (handleVar ((getOccString v):rvs) v
+coreToHs rvs _ v e = pprintSymbols (handleVar (getOccString v:rvs) v
                                      ++ " "
                                      ++ pprintFormals
-                                     ((getOccString v):rvs)
+                                     (getOccString v:rvs)
                                      caseIndent e)
 
 type RenVars       = [String]

From 50a4690ee68acd3b102de73015f113b2c67dbfe8 Mon Sep 17 00:00:00 2001
From: Lisa Vasilenko 
Date: Mon, 20 Mar 2023 14:10:52 +0000
Subject: [PATCH 173/219] fix hlint

---
 src/Language/Haskell/Liquid/Synthesize/GHC.hs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
index ac5afa17fd..b6cd49c7e3 100644
--- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs
+++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
@@ -220,7 +220,7 @@ handleVar vars v
 getSysName :: RenVars -> Name -> String
 getSysName vars n
   | elem occ vars = occ
-  | elem '#' occ  = (head $ splitOn "$##" occ) ++ ['_', last uni]
+  | elem '#' occ  = head (splitOn "$##" occ) ++ ['_', last uni]
   | otherwise     = occ ++ ['_', last uni]
   where
     occ = getOccString n

From 7aa63415c41ed6218394c2e3edcbdfccd640474f Mon Sep 17 00:00:00 2001
From: Lisa Vasilenko 
Date: Mon, 20 Mar 2023 14:51:33 +0000
Subject: [PATCH 174/219] add translation tests

---
 .github/workflows/haskell.yml                 |   1 +
 tests/relational/pos/R2Dcounting.hs           |  76 ++++
 .../relational/pos/RConstantTimeComparison.hs | 339 +-----------------
 tests/relational/pos/RIncr.hs                 |   8 +-
 tests/relational/pos/RMap.hs                  |  22 ++
 tests/relational/pos/RMemAlloc.hs             |  48 +++
 tests/relational/pos/RPatError.hs             |  22 ++
 tests/relational/pos/RVar.hs                  |  25 ++
 8 files changed, 216 insertions(+), 325 deletions(-)
 create mode 100644 tests/relational/pos/R2Dcounting.hs
 create mode 100644 tests/relational/pos/RMap.hs
 create mode 100644 tests/relational/pos/RMemAlloc.hs
 create mode 100644 tests/relational/pos/RPatError.hs
 create mode 100644 tests/relational/pos/RVar.hs

diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml
index e7507034a4..d51c7ed948 100644
--- a/.github/workflows/haskell.yml
+++ b/.github/workflows/haskell.yml
@@ -41,6 +41,7 @@ jobs:
       run: |
         chmod +x ./tests/relational/rtest
         ./tests/relational/rtest
+        ./tests/relational/rtest
       shell: bash  
     - name: Test Non-Relational
       run: |
diff --git a/tests/relational/pos/R2Dcounting.hs b/tests/relational/pos/R2Dcounting.hs
new file mode 100644
index 0000000000..b7e1a49411
--- /dev/null
+++ b/tests/relational/pos/R2Dcounting.hs
@@ -0,0 +1,76 @@
+{- 2DCount 16/3/24 | Changed on Nov 22 2022 -}
+{-# LANGUAGE  FlexibleContexts #-}
+{-@ LIQUID "--relational-hints" @-}
+{-@ LIQUID "--reflection" @-}
+{-@ LIQUID "--ple" @-}
+
+module R2Dcounting
+  ( module R2Dcounting ) where
+
+{-@ infix <*> @-}
+{-@ infix :   @-}
+
+import RTick
+import Language.Haskell.Liquid.ProofCombinators
+import Prelude hiding (return, (>>=), pure, length, (<*>), fmap)
+
+--- Proof ---
+{-@ relational count2Df1 ~ count2Df2
+     :: { p1:([Int] -> Bool) -> e1:Int -> l1:[[Int]] -> RTick.Tick Int
+        ~ p2:([Int] -> Bool) -> e2:Int -> l2:[[Int]] -> RTick.Tick Int
+        | !(true :=> true)
+          :=> !(e1 = e2 && p1 = p2)
+          :=> !(l1 = l2)
+          :=> RTick.tcost (r1 p1 e1 l1)
+            <= RTick.tcost (r2 p2 e2 l2) } @-}
+--- End ---
+
+{-@ reflect count2D @-}
+count2D :: (Int -> [Int] -> Tick Int)
+  -> ([Int] -> Bool)
+  -> Int
+  -> [[Int]]
+  -> Tick Int
+count2D _    _ _ [] = return 0
+count2D find p x (l:m) =
+  count2D find p x m >>= count2D' (p l) (find x l)
+
+{-@ reflect count2Df1 @-}
+count2Df1 :: ([Int] -> Bool) -> Int -> [[Int]] -> Tick Int
+count2Df1 _ _ _      = return 0
+count2Df1 p x (l:m)  = count2Df1 p x m >>= count2D' (p l) (find1 x l)
+
+{-@ reflect count2Df2 @-}
+count2Df2 :: ([Int] -> Bool) -> Int -> [[Int]] -> Tick Int
+count2Df2 _ _ _      = return 0
+count2Df2 p x (l:m)  = count2Df2 p x m >>= count2D' (p l) (find2 x l)
+
+
+{-@ reflect count2D' @-}
+count2D' :: Bool -> Tick Int -> Int -> Tick Int
+count2D' b c r = if b then fmap (plus r) c else return r
+
+{-@ reflect plus @-}
+{-@ plus :: Int -> Int -> Int @-}
+plus :: Int -> Int -> Int
+plus x y = x + y
+
+{-@ reflect find1 @-}
+find1 :: Int -> [Int] -> Tick Int
+{-@ find1 :: Int -> [Int] -> {t:RTick.Tick Int | 0 <= tcost t} @-}
+find1 _ []    = return 0
+find1 x (y:ys)
+  | x == y    = return 1
+  | otherwise = step 1 (find1 x ys)
+
+{-@ reflect find2 @-}
+{-@ find2 :: Int -> [Int] -> {t:RTick.Tick Int | 0 <= tcost t} @-}
+find2 :: Int -> [Int] -> Tick Int
+find2 _ []     = return 0
+find2 x (y:ys) = step 1 (eqBind 0 (find2 x ys) (find2Cond (if x == y then 1 else 0)))
+
+{-@ reflect find2Cond @-}
+{-@ find2Cond :: Int -> Int -> {t:RTick.Tick Int | 0 == tcost t} @-}
+find2Cond :: Int -> Int -> Tick Int
+find2Cond _ 1 = return 1
+find2Cond d _ = return d
diff --git a/tests/relational/pos/RConstantTimeComparison.hs b/tests/relational/pos/RConstantTimeComparison.hs
index 6f3535a656..bf6e20bb13 100644
--- a/tests/relational/pos/RConstantTimeComparison.hs
+++ b/tests/relational/pos/RConstantTimeComparison.hs
@@ -2,21 +2,19 @@
 --
 -- Liquidate your assets: reasoning about resource usage in Liquid Haskell.
 --
-
-{-@ LIQUID "--reflection" @-}
-{-@ LIQUID "--ple"        @-}
+{-@ LIQUID "--relational-hints" @-}
+{-@ LIQUID "--reflection"      @-}
+{-@ LIQUID "--ple"             @-}
 
 module RConstantTimeComparison
   (module RConstantTimeComparison) where
 
-import Prelude hiding ( pure, return, and, fmap, Functor(..), Applicative(..), Monad(..), (=<<) )
-
-import qualified Control.Applicative as A
-import qualified Control.Monad       as M
-import qualified Data.Functor        as F
-
+import Prelude hiding ( pure, return, and, fmap, length )
 
+import RTick
 import Language.Haskell.Liquid.ProofCombinators
+import Lists
+import Erasure
 
 --
 -- Proving a password comparisons function adheres to the
@@ -28,22 +26,23 @@ data Bit = Zero | One deriving Eq
 {-@ reflect comp @-}
 {-@ comp
      :: xs:[Bit]
-     -> { ys:[Bit] | len xs == len ys }
-     -> { t:Tick Bool | tcost t == len xs }
+     -> { ys:[Bit] | length xs == length ys }
+     -> { t:Tick Bool | tcost t == length xs }
 @-}
 comp :: [Bit] -> [Bit] -> Tick Bool
 comp []       _        = return True
 comp (x : xs) (y : ys) = let Tick m v = comp xs ys in
   Tick (m + 1) (and (x == y) v)
 
+--- Proof ---
 {-@ relational comp ~ comp 
       :: { xs1:[Bit] -> ys1:[Bit] -> t:Tick Bool
-        ~ xs2:[Bit] -> ys2:[Bit] -> t:Tick Bool
-        | xs1 = xs2 
-            :=> len xs1 == len ys1 && len xs1 == len ys2
-            :=> RConstantTimeComparison.tcost (RConstantTimeComparison.comp xs1 ys1) 
-                  == RConstantTimeComparison.tcost (RConstantTimeComparison.comp xs1 ys2) }
-@-}
+         ~ xs2:[Bit] -> ys2:[Bit] -> t:Tick Bool
+         | !(xs1 = xs2) 
+            :=> !(Lists.length xs1 == Lists.length ys1 && Lists.length xs1 == Lists.length ys2)
+            :=> RTick.tcost (RConstantTimeComparison.comp xs1 ys1) 
+                  == RTick.tcost (RConstantTimeComparison.comp xs1 ys2) } @-}
+--- End ---
 
 {-
 Previous comp:
@@ -62,309 +61,3 @@ Tick m f  Tick n x = Tick (1 + m + n) (f x)
 {-@ and :: Bool -> Bool -> Bool @-}
 and :: Bool -> Bool -> Bool
 and x y = x && y
-
-
--------------------------------------------------------------------------------
--- | 'Tick' datatype for recording resource usage:
--------------------------------------------------------------------------------
-
-{-@ data Tick a = Tick { tcost :: Int, tval :: a } @-}
-data Tick a = Tick { tcost :: Int, tval :: a }
-
-{-@ measure ttcost @-}
-ttcost :: Tick a -> Int 
-ttcost (Tick c _) = c
-
--------------------------------------------------------------------------------
--- | Primitive resource operators:
--------------------------------------------------------------------------------
-
-instance F.Functor Tick where
-  fmap = fmap
-
-{-@ reflect fmap @-}
-{-@ fmap :: f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (tcost t1) (f (tval t1)) == t } @-}
-fmap :: (a -> b) -> Tick a -> Tick b
-fmap f (Tick m x) = Tick m (f x)
-
-instance A.Applicative Tick where
-  pure  = pure
-  (<*>) = (<*>)
-
-{-@ reflect pure @-}
-{-@ pure :: x:a -> { t:Tick a | x == tval t && 0 == tcost t } @-}
-pure :: a -> Tick a
-pure x = Tick 0 x
-
-{-@ reflect <*> @-}
-{-@ (<*>) :: t1:Tick (a -> b) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval  t && tcost t1 + tcost t2 == tcost t } @-}
-infixl 4 <*>
-(<*>) :: Tick (a -> b) -> Tick a -> Tick b
-Tick m f <*> Tick n x = Tick (m + n) (f x)
-
-{-@ reflect liftA2 @-}
-{-@ liftA2 :: f:(a -> b -> c) -> t1:Tick a -> t2:Tick b -> { t:Tick c | f (tval t1) (tval t2) == tval  t && tcost t1 + tcost t2 == tcost t } @-}
-liftA2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c
-liftA2 f (Tick m x) (Tick n y) = Tick (m + n) (f x y)
-
-instance M.Monad Tick where
-  return = return
-  (>>=)  = (>>=)
-
-{-@ reflect return @-}
-{-@ return :: x:a -> { t:Tick a | x == tval t && 0 == tcost t } @-}
-return :: a -> Tick a
-return x = Tick 0 x
-
-{-@ reflect >>= @-}
-{-@ (>>=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1))  == tval  t && tcost t1 + tcost (f (tval t1)) == tcost t } @-}
-infixl 4 >>=
-(>>=) :: Tick a -> (a -> Tick b) -> Tick b
-Tick m x >>= f = let Tick n y = f x in Tick (m + n) y
-
-{-@ reflect =<< @-}
-{-@ (=<<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1))  == tval  t && tcost t1 + tcost (f (tval t1)) == tcost t } @-}
-infixl 4 =<<
-(=<<) :: (a -> Tick b) -> Tick a -> Tick b
-f =<< Tick m x = let Tick n y = f x in Tick (m + n) y
-
-{-@ reflect ap @-}
-{-@ ap :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval  t && tcost t1 + tcost t2 == tcost t } @-}
-ap :: Tick (a -> b) -> Tick a -> Tick b
-ap (Tick m f) (Tick n x) = Tick (m + n) (f x)
-
-{-@ reflect liftM @-}
-{-@ liftM :: f:(a -> b) -> t1:Tick a -> { t:Tick b | tcost t1 == tcost t } @-}
-liftM :: (a -> b) -> Tick a -> Tick b
-liftM f (Tick m x) = Tick m (f x)
-
-{-@ reflect liftM2 @-}
-{-@ liftM2 :: f:(a -> b -> c) -> t1:Tick a -> t2:Tick b -> { t:Tick c | f (tval t1) (tval t2) == tval  t && tcost t1 + tcost t2 == tcost t } @-}
-liftM2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c
-liftM2 f (Tick m x) (Tick n y) = Tick (m + n) (f x y)
-
--------------------------------------------------------------------------------
-
-{-@ reflect eqBind @-}
-{-@ eqBind
-     :: n:Int
-     -> t1:Tick a
-     -> f:(a -> { tf:Tick b | n == tcost tf })
-     -> { t:Tick b | tval (f (tval t1))
-                     == tval t && tcost t1 + n == tcost t }
-@-}
-eqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b
-eqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y
-
-{-@ reflect leqBind @-}
-{-@ leqBind :: n:Int -> t1:Tick a -> f:(a -> { tf:Tick b | n >= tcost tf }) -> { t:Tick b | tcost t1 + n >= tcost t } @-}
-leqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b
-leqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y
-
-{-@ reflect geqBind @-}
-{-@ geqBind :: n:Int -> t1:Tick a -> f:(a -> { tf:Tick b | n <= tcost tf }) -> { t2:Tick b | tcost t1 + n <= tcost t2 } @-}
-geqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b
-geqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y
-
--------------------------------------------------------------------------------
--- | Resource modifiers:
--------------------------------------------------------------------------------
-
-{-@ reflect step @-}
-{-@ step :: m:Int -> t1:Tick a -> { t:Tick a | tval t1 == tval t && m + tcost t1 == tcost t } @-}
-step :: Int -> Tick a -> Tick a
-step m (Tick n x) = Tick (m + n) x
-
---
--- @wait := step 1 . return@.
---
-{-@ reflect wait @-}
-{-@ wait :: x:a -> { t:Tick a | x == tval t && 1 == tcost t } @-}
-wait :: a -> Tick a
-wait x = Tick 1 x
-
---
--- @waitN (n > 0) := step n . return@.
---
-{-@ reflect waitN @-}
-{-@ waitN :: n:Nat -> x:a -> { t:Tick a | x == tval t && n == tcost t } @-}
-waitN :: Int -> a -> Tick a
-waitN n x = Tick n x
-
---
--- @go := step (-1) . return@.
---
-{-@ reflect go @-}
-{-@ go :: x:a -> { t:Tick a | x == tval t && (-1) == tcost t } @-}
-go :: a -> Tick a
-go x = Tick (-1) x
-
---
--- @goN (n > 0) := step (-n) . return@.
---
-{-@ reflect goN @-}
-{-@ goN :: { n:Nat | n > 0 } -> x:a -> { t:Tick a | x == tval t && (-n) == tcost t } @-}
-goN :: Int -> a -> Tick a
-goN n x = Tick (-n) x
-
---
--- @wmap f := step 1 . fmap f@.
---
-{-@ reflect wmap @-}
-{-@ wmap :: f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (1 + tcost t1) (f (tval t1)) == t } @-}
-wmap :: (a -> b) -> Tick a -> Tick b
-wmap f (Tick m x) = Tick (1 + m) (f x)
-
---
--- @wmapN (n > 0) f := step n . fmap f@.
---
-{-@ reflect wmapN @-}
-{-@ wmapN :: { m:Nat | m > 0 } -> f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (m + tcost t1) (f (tval t1)) == t } @-}
-wmapN :: Int -> (a -> b) -> Tick a -> Tick b
-wmapN m f (Tick n x) = Tick (m + n) (f x)
-
---
--- @gmap f := step (-1) . fmap f@.
---
-{-@ reflect gmap @-}
-{-@ gmap :: f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (tcost t1 - 1) (f (tval t1)) == t } @-}
-gmap :: (a -> b) -> Tick a -> Tick b
-gmap f (Tick m x) = Tick (m - 1) (f x)
-
---
--- @gmapN (n > 0) f := step (-n) . fmap f@.
---
-{-@ reflect gmapN @-}
-{-@ gmapN :: { m:Nat | m > 0 } -> f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (tcost t1 - m) (f (tval t1)) == t } @-}
-gmapN :: Int -> (a -> b) -> Tick a -> Tick b
-gmapN m f (Tick n x) = Tick (n - m) (f x)
-
---
--- \"wapp\": @(f ) := step 1 . (f <*>)@.
---
-{-@ reflect  @-}
-{-@ () :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval  t && 1 + tcost t1 + tcost t2 == tcost t } @-}
-infixl 4 
-() :: Tick (a -> b) -> Tick a -> Tick b
-Tick m f  Tick n x = Tick (1 + m + n) (f x)
-
---
--- \"wwapp\": @(f ) := step 2 . (f <*>)@.
---
-{-@ reflect  @-}
-{-@ () :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval  t && 2 + tcost t1 + tcost t2 == tcost t } @-}
-infixl 4 
-() :: Tick (a -> b) -> Tick a -> Tick b
-Tick m f  Tick n x = Tick (2 + m + n) (f x)
-
---
--- \"gapp\": @(f <\>) := step (-1) . (f <*>)@.
---
-{-@ reflect <\> @-}
-{-@ (<\>) :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval  t && tcost t1 + tcost t2 - 1 == tcost t } @-}
-infixl 4 <\>
-(<\>) :: Tick (a -> b) -> Tick a -> Tick b
-Tick m f <\> Tick n x = Tick (m + n - 1) (f x)
-
---
--- \"ggapp\": @(f <\\>) := step (-2) . (f <*>)@.
---
-{-@ reflect <\\> @-}
-{-@ (<\\>) :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval  t && tcost t1 + tcost t2 - 2 == tcost t } @-}
-infixl 4 <\\>
-(<\\>) :: Tick (a -> b) -> Tick a -> Tick b
-Tick m f <\\> Tick n x = Tick (m + n - 2) (f x)
-
---
--- \"wbind\": @(>/= f) := step 1 . (>>= f)@.
---
-{-@ reflect >/= @-}
-{-@ (>/=)
-     :: t1:Tick a
-     -> f:(a -> Tick b)
-     -> { t:Tick b | (tval (f (tval t1)) == tval t)
-        && (1 + tcost t1 + tcost (f (tval t1))) == tcost t }
-@-}
-infixl 4 >/=
-(>/=) :: Tick a -> (a -> Tick b) -> Tick b
-Tick m x >/= f = let Tick n y = f x in Tick (1 + m + n) y
-
---
--- \"wbind\": @(f =/<) := step 1 . (f =<<)@.
---
-{-@ reflect =/< @-}
-{-@ (=/<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval  t && 1 + tcost t1 + tcost (f (tval t1)) == tcost t } @-}
-infixl 4 =/<
-(=/<) :: (a -> Tick b) -> Tick a -> Tick b
-f =/< Tick m x = let Tick n y = f x in Tick (1 + m + n) y
-
---
--- \"wwbind\": @(>//= f) := step 2 . (>>= f)@.
---
-{-@ reflect >//= @-}
-{-@ (>//=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1)) == tval  t && 2 + tcost t1 + tcost (f (tval t1)) == tcost t } @-}
-infixl 4 >//=
-(>//=) :: Tick a -> (a -> Tick b) -> Tick b
-Tick m x >//= f = let Tick n y = f x in Tick (2 + m + n) y
-
---
--- \"wwbind\": @(f =//<) := step 2 . (f =<<)@.
---
-{-@ reflect =//< @-}
-{-@ (=//<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval  t && 2 + tcost t1 + tcost (f (tval t1)) == tcost t } @-}
-infixl 4 =//<
-(=//<) :: (a -> Tick b) -> Tick a -> Tick b
-f =//< Tick m x = let Tick n y = f x in Tick (2 + m + n) y
-
---
--- \"gbind\": @(>\= f) := step (-1) . (>>= f)@.
---
-{-@ reflect >\= @-}
-{-@ (>\=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1)) == tval t && tcost t1 + tcost (f (tval t1)) - 1 == tcost t } @-}
-infixl 4 >\=
-(>\=) :: Tick a -> (a -> Tick b) -> Tick b
-Tick m x >\= f = let Tick n y = f x in Tick (m + n - 1) y
-
---
--- \"gbind\": @(f =\<) := step (-1) . (f =<<)@.
---
-{-@ reflect =\< @-}
-{-@ (=\<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval  t && tcost t1 + tcost (f (tval t1)) - 1 == tcost t } @-}
-infixl 4 =\<
-(=\<) :: (a -> Tick b) -> Tick a -> Tick b
-f =\< Tick m x = let Tick n y = f x in Tick (m + n - 1) y
-
---
--- \"ggbind\": @(>\= f) := step (-2) . (>>= f)@.
---
-{-@ reflect >\\= @-}
-{-@ (>\\=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1)) == tval  t && tcost t1 + tcost (f (tval t1)) - 2 == tcost t } @-}
-infixl 4 >\\=
-(>\\=) :: Tick a -> (a -> Tick b) -> Tick b
-Tick m x >\\= f = let Tick n y = f x in Tick (m + n - 2) y
-
---
--- \"ggbind\": @(f =\\<) := step (-2) . (f =<<)@.
---
-{-@ reflect =\\< @-}
-{-@ (=\\<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval  t && tcost t1 + tcost (f (tval t1)) - 2 == tcost t } @-}
-infixl 4 =\\<
-(=\\<) :: (a -> Tick b) -> Tick a -> Tick b
-f =\\< Tick m x = let Tick n y = f x in Tick (m + n - 2) y
-
--------------------------------------------------------------------------------
--- | Memoisation:
--------------------------------------------------------------------------------
-
-{-@ reflect pay @-}
-{-@ pay :: m:Int -> { t1:Tick a | m <= tcost t1 } -> { t:Tick ({ t2 : Tick a | tcost t1 - m == tcost t2 }) | m == tcost t } @-}
-pay :: Int -> Tick a -> Tick (Tick a)
-pay m (Tick n x) = Tick m (Tick (n - m) x)
-
-
-{-@ reflect zipWithM @-}
-{-@ zipWithM :: f:(a -> b -> Tick c) -> x:Tick a -> y:Tick b 
-              -> {t:Tick c | tcost t == tcost x + tcost y + tcost (f (tval x) (tval y))
-                           && tval t == tval (f (tval x) (tval y)) } @-}
-zipWithM :: (a -> b -> Tick c) -> Tick a -> Tick b -> Tick c
-zipWithM f (Tick c1 x1) (Tick c2 x2) = let Tick c x = f x1 x2 in Tick (c + c1 + c2) x
diff --git a/tests/relational/pos/RIncr.hs b/tests/relational/pos/RIncr.hs
index 32a08411ca..4beb67684a 100644
--- a/tests/relational/pos/RIncr.hs
+++ b/tests/relational/pos/RIncr.hs
@@ -1,11 +1,15 @@
+{-@ LIQUID "--relational-hint" @-}
 {-@ LIQUID "--reflection" @-}
 {-@ LIQUID "--ple"        @-}
 
-module RIncr () where
+module RIncr where
 
+{-@ reflect incr @-}
 incr :: Int -> Int
 incr x = x + 1
 
+--- Proof ---
 {-@ relational incr ~ incr :: { xl : Int -> Int 
                               ~ xr : Int -> Int
-                              | xl < xr :=> r1 xl < r2 xr } @-}
+                              | !(xl < xr) :=> r1 xl < r2 xr } @-}
+--- End ---
\ No newline at end of file
diff --git a/tests/relational/pos/RMap.hs b/tests/relational/pos/RMap.hs
new file mode 100644
index 0000000000..56cfe939bc
--- /dev/null
+++ b/tests/relational/pos/RMap.hs
@@ -0,0 +1,22 @@
+{-@ LIQUID "--relational-hint" @-}
+{-@ LIQUID "--reflection" @-}
+{-@ LIQUID "--ple" @-}
+
+module RMap where
+import Prelude hiding (map)
+
+type List a = [a]
+
+{-@ reflect map @-}
+map :: (Int -> Int) -> List Int -> List Int
+map _ [] = []
+map f (x:xs) = f x:map f xs
+
+--- Proof ---
+{-@ relational map ~ map ::
+            { f1:(x1:Int -> Int) -> xs1:List Int -> List Int 
+            ~ f2:(x2:Int -> Int) -> xs2:List Int -> List Int 
+            | !(true :=> true) 
+                :=> !(len xs1 = len xs2)
+                :=> len (r1 f1 xs1) = len (r2 f2 xs2) } @-}
+--- End ---
\ No newline at end of file
diff --git a/tests/relational/pos/RMemAlloc.hs b/tests/relational/pos/RMemAlloc.hs
new file mode 100644
index 0000000000..62c6b99cd3
--- /dev/null
+++ b/tests/relational/pos/RMemAlloc.hs
@@ -0,0 +1,48 @@
+{-@ LIQUID "--reflection"       @-}
+{-@ LIQUID "--ple"              @-}
+{- LIQUID "--relational-hints" @-}
+module RMemAlloc where
+
+import RTick
+import Prelude hiding (pure, foldl)
+import Language.Haskell.Liquid.ProofCombinators
+
+{-@ reflect foldl @-}
+{-@ foldl :: (Int -> Int -> Int) -> Int -> xs:[Int] -> { t:Tick Int | tcost t == len xs } @-}
+foldl :: (Int -> Int -> Int) -> Int -> [Int] -> Tick Int
+foldl _ z [] = pure z
+foldl f z (x : xs) = let w = f z x in 1 `step` foldl f w xs
+
+{-@ reflect foldl' @-}
+{-@ foldl' :: (Int -> Int -> Int) -> Int -> xs:[Int] -> { t:Tick Int | tcost t == 0 } @-}
+foldl' :: (Int -> Int -> Int) -> Int -> [Int] -> Tick Int
+foldl' _ z [] = pure z
+foldl' f z (x : xs) = let w = f z x in w `seq` foldl' f w xs
+
+{-@ relational foldl ~ foldl' :: { f1:(Int -> Int -> Int) -> acc1:Int -> xs1:[Int] -> Tick Int
+                                 ~ f2:(Int -> Int -> Int) -> acc2:Int -> xs2:[Int] -> Tick Int
+                                 | true :=> f1 = f2 && acc1 = acc2 :=> xs1 = xs2 
+                                    :=> true } @-}
+
+{-@ reflect length1 @-}
+length1 :: [Int] -> Tick Int
+length1 = foldl' upd 0 
+
+{-@ reflect upd @-}
+upd :: Int -> Int -> Int
+upd x _ = x + 1 
+
+{-@ reflect length2 @-}
+length2 :: [Int] -> Tick Int
+length2 = foldl upd 0 
+
+{-@ relational length1 ~ length2 :: { xs1:[Int] -> Tick Int 
+                                    ~ xs2:[Int] -> Tick Int 
+                                    | xs1 = xs2 
+                                        :=> RTick.tcost (RMemAlloc.length2 xs1) - RTick.tcost (RMemAlloc.length1 xs1) = len xs1} @-}
+
+{-@ reflect len @-}
+{-@ len :: [a] -> Nat @-}
+len :: [a] -> Int
+len [] = 0
+len (_:xs) = 1 + len xs
diff --git a/tests/relational/pos/RPatError.hs b/tests/relational/pos/RPatError.hs
new file mode 100644
index 0000000000..d415d1d9d6
--- /dev/null
+++ b/tests/relational/pos/RPatError.hs
@@ -0,0 +1,22 @@
+{- LIQUID "--relational-hints" @-}
+{-@ LIQUID "--reflection" @-}
+{-@ LIQUID "--ple" @-}
+module RPatError where
+
+import Prelude hiding (zip)
+
+{-@ measure len @-}
+{-@ len :: [a] -> Nat @-}
+len :: [a] -> Int
+len [] = 0
+len (_:xs) = 1 + len xs
+
+{-@ reflect zip @-}
+{-@ zip :: xs:[Int] -> {ys:[Int]|ys = xs} -> () @-}
+zip :: [Int] -> [Int] -> ()
+zip [] [] = ()
+zip (_:xs) (_:ys) = zip xs ys
+
+{-@ relational zip ~ zip :: { xs1:[Int] -> ys1:[Int] -> ()
+                            ~ xs2:[Int] -> ys2:[Int] -> ()
+                            | true :=> ys1 = xs1 && ys2 = xs2 :=> true } @-}
\ No newline at end of file
diff --git a/tests/relational/pos/RVar.hs b/tests/relational/pos/RVar.hs
new file mode 100644
index 0000000000..761efb2abb
--- /dev/null
+++ b/tests/relational/pos/RVar.hs
@@ -0,0 +1,25 @@
+{-@ LIQUID "--relational-hint" @-}
+{-@ LIQUID "--reflection" @-}
+{-@ LIQUID "--ple"        @-}
+
+module RVar where
+
+{-@ measure RVar.x1 :: Int @-}
+{-@ measure RVar.x2 :: Int @-}
+x1, x2 :: Int
+x1 = 0
+x2 = 1
+
+{-@ reflect y1 @-}
+{-@ reflect y2 @-}
+y1, y2 :: Int
+y1 = x1
+y2 = x2
+
+--- Proof ---
+{-@ assume relX1X2 :: {x1 <= x2} @-}
+relX1X2 :: ()
+relX1X2 = ()
+
+{-@ relational y1 ~ y2 :: { Int ~ Int | r1 <= r2 } @-}
+--- End ---
\ No newline at end of file

From 150ab2822f426dda83b366c0d45e5db2828aed5f Mon Sep 17 00:00:00 2001
From: Lisa Vasilenko 
Date: Mon, 20 Mar 2023 18:55:59 +0000
Subject: [PATCH 175/219] switch to ormolu formatting

---
 .../Haskell/Liquid/Constraint/Relational.hs   |   8 +-
 src/Language/Haskell/Liquid/Liquid.hs         |  26 +-
 src/Language/Haskell/Liquid/Synthesize/GHC.hs |  73 +--
 tests/relational/pos/Erasure.hs               | 509 ++++++++++++++++++
 tests/relational/pos/Lists.hs                 | 191 +++++++
 tests/relational/pos/RTick.hs                 | 374 +++++++++++++
 tests/relational/rtest                        |   2 +-
 7 files changed, 1132 insertions(+), 51 deletions(-)
 create mode 100644 tests/relational/pos/Erasure.hs
 create mode 100644 tests/relational/pos/Lists.hs
 create mode 100644 tests/relational/pos/RTick.hs

diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs
index 4ee407c6bf..df03bcbf05 100644
--- a/src/Language/Haskell/Liquid/Constraint/Relational.hs
+++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs
@@ -38,7 +38,7 @@ import           Language.Haskell.Liquid.Constraint.Types
 import           Language.Haskell.Liquid.Synthesize.GHC
                                                 ( coreToHs
                                                 , fromAnf
-                                                , pprintBody'
+                                                , pprintBody
                                                 , handleVar
                                                 , RenVars
                                                 )
@@ -434,7 +434,7 @@ coreToGoal rvs short e
   | otherwise                 = goal
   where
     goal = unwords $ words $ concat $ splitOn "\n"
-           $ pprintBody' rvs expr
+           $ pprintBody rvs expr
     (expr, bool) = cleanUnTerms rvs $ fromAnf e
 
 areCompatible :: CoreExpr -> CoreExpr -> Bool
@@ -1361,9 +1361,7 @@ relWfError loc e1 e2 t1 t2 p msg
 --------------------------------------------------------------
 
 relHint :: RenVars -> SpecType -> Ghc.Var -> CoreExpr -> Doc
-relHint rvs t v e = text "import GHC.Types"
-                    $+$ text ""
-                    $+$ text "{- HLINT ignore \"Use camelCase\" -}"
+relHint rvs t v e = text "{- HLINT ignore \"Use camelCase\" -}"
                     $+$ text ("{-@ " ++ name ++ " :: " ++ F.showpp t ++ " @-}")
                     $+$ text (name ++ " :: " ++ removeIdent (toType False t))
                     $+$ text (coreToHs rvs t v e)
diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs
index 941a77bb89..7d9d018ada 100644
--- a/src/Language/Haskell/Liquid/Liquid.hs
+++ b/src/Language/Haskell/Liquid/Liquid.hs
@@ -29,6 +29,8 @@ import           System.Console.CmdArgs.Verbosity (whenLoud, whenNormal)
 import           Control.Monad (when, unless)
 import qualified Data.Maybe as Mb
 import qualified Data.List  as L 
+import qualified Data.Text  as T 
+import           Ormolu (ormolu, defaultConfig, OrmoluException)
 import qualified Control.Exception as Ex
 import qualified Language.Haskell.Liquid.UX.DiffCheck as DC
 import           Language.Haskell.Liquid.Misc
@@ -273,18 +275,13 @@ solveCs cfg tgt cgi info names = do
   when (relationalHints cfg) $ do
     let hintName     = takeBaseName tgt ++ "_relToUn"
     let hintFile     = replaceBaseName tgt hintName
-    let flags        = "{-@ LIQUID \"--reflection\" @-}\n{-@ LIQUID \"--ple\"        @-}\n\n"
-    let moduleFile   = "module " ++
-                       hintName ++
-                       " ( module " ++
-                       hintName ++
-                       ") where\nimport " ++
-                       takeBaseName tgt ++ "\n"
-
+    let flags        = "{-@ LIQUID \"--reflection\" @-}\n"
+                        ++ "{-@ LIQUID \"--ple\"        @-}\n\n"
+    let moduleFile   = "module " ++ hintName ++ " ( module " ++ hintName ++ ") where\n"
     let listOfImps   = map (\imp -> F.symbolicString imp)
-                       (S.toList $ gsAllImps $ giSrc info)
-    let imports      =
-          L.intercalate "\n" $ map ("import " ++) listOfImps
+                        (S.toList $ gsAllImps $ giSrc info) 
+                        ++ [takeBaseName tgt, "GHC.Types", "GHC.Classes"]
+    let imports      = L.intercalate "\n" $ map ("import " ++) listOfImps
 
     {-
       Modules that have the form of: "import moduleName (function)",
@@ -298,7 +295,12 @@ solveCs cfg tgt cgi info names = do
     -}    
     let hints        = render (relHints cgi)
     unless (null hints) $ do
-      writeFile hintFile (flags ++ moduleFile ++ imports ++ "\n" ++ hints)
+      let hintRaw = flags ++ moduleFile ++ imports ++ "\n" ++ hints
+      hintOrmolu <- try (ormolu defaultConfig hintFile hintRaw) :: IO (Either OrmoluException T.Text)
+      case hintOrmolu of
+        Left ex -> do writeFile hintFile hintRaw
+                      whenLoud $ print ex
+        Right hintFormatted -> writeFile hintFile (T.unpack hintFormatted) 
       putStrLn "****** Relational Hints ********************************************************"
       putStrLn $ "Saved to file: " ++ hintFile
   let resModel      = resModel' `addErrors` (e2u cfg sol <$> (lErrors ++ hErrors ++ relWf cgi)) 
diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
index b6cd49c7e3..83704c7b36 100644
--- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs
+++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs
@@ -171,7 +171,7 @@ handleLam rvs char i (Lam v e)
   | isCoVar   v = " {- isCoVar -}"       ++ handleLam rvs char i e
   | isId      v = handleVar rvs v ++ " " ++ handleLam rvs char i e  
   | otherwise   = handleVar rvs v ++ " " ++ handleLam rvs char i e
-handleLam rvs char i e = char ++ pprintBody rvs i e
+handleLam rvs char i e = char ++ pprintBody' rvs i e
 
 
 {- If a specific function is built-in into haskell it will still
@@ -216,6 +216,8 @@ handleVar vars v
     name :: Name
     name = varName v
 
+occStr :: Var -> String
+occStr = getOccString . varName
 
 getSysName :: RenVars -> Name -> String
 getSysName vars n
@@ -240,64 +242,69 @@ checkUnit (Var v)
   | otherwise = False
 checkUnit _ = False  
 ----------------------------------------------------------------------
-pprintBody' :: RenVars -> CoreExpr -> String
-pprintBody' rvs e = pprintBody rvs 0 e
+pprintBody :: RenVars -> CoreExpr -> String
+pprintBody rvs = pprintBody' rvs 0
 
-pprintBody :: RenVars -> Int -> CoreExpr -> String
-pprintBody rvs i e@Lam{} = "(\\" ++ handleLam rvs " -> " i e ++ ")"
+pprintBody' :: RenVars -> Int -> CoreExpr -> String
+pprintBody' rvs i e@Lam{} = "(\\" ++ handleLam rvs " -> " i e ++ ")"
 
-pprintBody rvs _ var@(Var v)
+pprintBody' rvs _ var@(Var v)
   | undesirableVar var = ""
   | otherwise          = handleVar rvs v
 
-pprintBody rvs i (App e Type{}) = pprintBody rvs i e
+pprintBody' rvs i (App e Type{}) = pprintBody' rvs i e
     
-pprintBody rvs i (App e1 e2)
-  | undesirableVar e1 = pprintBody rvs i e2
-  | undesirableVar e2 = pprintBody rvs i e1
-  | checkUnit e2      = pprintBody rvs i e1
-                        ++ " "
-                        ++ pprintBody rvs i e2
-  | otherwise = "(" ++ left ++ ")\n"
-                ++ indent (i + 1)
-                ++ "(" ++ right ++ ")"
-  where
-    left  = pprintBody rvs i e1
-    right = pprintBody rvs (i+1) e2
-
-pprintBody _ _ l@(Lit literal) =
+pprintBody' rvs i (App e1 e2)
+  | undesirableVar e1 = pprintBody' rvs i e2
+  | undesirableVar e2 = pprintBody' rvs i e1
+  | otherwise = paren e1 True left ++ " " ++ paren e2 False right
+  where  
+    left  = pprintBody' rvs i e1
+    right = pprintBody' rvs (i+1) e2
+
+pprintBody' _ _ l@(Lit literal) =
   case isLitValue_maybe literal of
     Just i   -> show i
     Nothing  -> show l
 
-pprintBody rvs i (Case e _ _ alts)
-  = "case " ++ pprintBody rvs i e ++ " of"
+pprintBody' rvs i (Case e _ _ alts)
+  = "case " ++ pprintBody' rvs i e ++ " of"
   ++ concatMap (pprintAlts rvs (i + caseIndent)) alts
 
-pprintBody _ _ Type{} = "{- Type -}"
+pprintBody' _ _ Type{} = "{- Type -}"
 
-pprintBody rvs i (Let (NonRec x e1) e2) =
+pprintBody' rvs i (Let (NonRec x e1) e2) =
   letExp ++
   eqlExp ++
-  indent i ++ pprintBody rvs (i+1) e2
+  indent i ++ pprintBody' rvs (i+1) e2
   where
     letExp      = "let " ++ handleVar rvs x ++ " = "
-    eqlExp      = pprintBody rvs firstIdent e1 ++ " in\n"
+    eqlExp      = pprintBody' rvs firstIdent e1 ++ " in\n"
     firstIdent  = i + caseIndent*2 + length letExp
     
-pprintBody _ _ (Let Rec{} _) = "{- let rec -}"
+pprintBody' _ _ (Let Rec{} _) = "{- let rec -}"
 
-pprintBody rvs i (Tick (SourceNote _ s) e)
+pprintBody' rvs i (Tick (SourceNote _ s) e)
   | expr == "()" = "{- " ++ s ++ " -} " ++ expr
   | otherwise    = "{- " ++ s ++ " -}"
                    ++ "\n" ++ indent i
                    ++ expr
   where
-    expr = pprintBody rvs i e
+    expr = pprintBody' rvs i e
+
+pprintBody' rvs i (Tick _ e) = pprintBody' rvs i e
+
+pprintBody' _ _ e = error (" Not yet implemented for e = " ++ show e)
 
-pprintBody rvs i (Tick _ e) = pprintBody rvs i e
+parenVars :: [String]
+parenVars = ["+", "-", "*", "/", "%", "?", ":", "++", "==", "/="]
 
-pprintBody _ _ e = error (" Not yet implemented for e = " ++ show e)
+paren :: CoreExpr -> Bool -> String -> String
+paren (Var v) _ res | occStr v `notElem` parenVars = res
+paren (App _ _) True res = res
+paren Tick{} _ res = res
+paren Lit{} _ res = res
+paren _ _ res = "(" ++ res ++ ")"
 
 {-
 data Alt Var = Alt AltCon [Var] (Expr Var)
@@ -310,7 +317,7 @@ pprintAlts :: RenVars -> Int -> Alt Var -> String
 pprintAlts rvs i (DataAlt dataCon, vs, e)
   = "\n" ++ indent i
     ++ elCase
-    ++ pprintBody rvs (i + newIndent) e
+    ++ pprintBody' rvs (i + newIndent) e
   where
     elCase = getOccString (getName dataCon)
              ++ concatMap (\v -> " " ++ handleVar rvs v) vs
diff --git a/tests/relational/pos/Erasure.hs b/tests/relational/pos/Erasure.hs
new file mode 100644
index 0000000000..0a6f85dc2c
--- /dev/null
+++ b/tests/relational/pos/Erasure.hs
@@ -0,0 +1,509 @@
+--
+-- Liquidate your assets: reasoning about resource usage in Liquid Haskell.
+--
+
+{-@ LIQUID "--reflection" @-}
+
+{-@ infix <*>  @-}
+{-@ infix   @-}
+{-@ infix  @-}
+{-@ infix <\>  @-}
+{-@ infix <\\> @-}
+{-@ infix >>=  @-}
+{-@ infix =<<  @-}
+{-@ infix >/=  @-}
+{-@ infix =/<  @-}
+{-@ infix >//= @-}
+{-@ infix =//< @-}
+{-@ infix >\=  @-}
+{-@ infix =\<  @-}
+{-@ infix >\\= @-}
+{-@ infix =\\< @-}
+
+module Erasure (module Erasure) where
+
+import RTick
+import Language.Haskell.Liquid.ProofCombinators
+
+--
+-- Erasing all the library's cost annotations. In practice, we define the
+-- erase function, ⟨·⟩, as a set of inference rules.
+--
+
+--
+--       ⟨t⟩ == x
+--  -----------------
+--   ⟨step m t⟩ == x
+--
+{-@ assume erase_step :: m:Int -> x:a -> { t:Tick a | erase t == x } -> { erase (step m t) == x } @-}
+erase_step :: Int -> a -> Tick a -> Proof
+erase_step _ _ _ = ()
+
+--
+--
+--  -----------------
+--   ⟨wait x⟩ == x
+--
+{-@ assume erase_wait :: x:a -> { erase (wait x) == x } @-}
+erase_wait :: a -> Proof
+erase_wait _ = ()
+
+--
+--
+--  ------------------
+--   ⟨waitN n x⟩ == x
+--
+{-@ assume erase_waitN :: n:Int -> x:a -> { erase (waitN n x) == x } @-}
+erase_waitN :: Int -> a -> Proof
+erase_waitN _ _ = ()
+
+--
+--
+--  -------------
+--   ⟨go x⟩ == x
+--
+{-@ assume erase_go :: x:a -> { erase (go x) == x } @-}
+erase_go :: a -> Proof
+erase_go _ = ()
+
+--
+--
+--  ----------------
+--   ⟨goN n x⟩ == x
+--
+{-@ assume erase_goN :: n:Int -> x:a -> { erase (goN n x) == x } @-}
+erase_goN :: Int -> a -> Proof
+erase_goN _ _ = ()
+
+--
+--        ⟨t⟩ == x
+--  ---------------------
+--    ⟨fmap f t⟩ == f x
+--
+{-@ assume erase_fmap :: f:(a -> b) -> x:a -> { t:Tick a | erase t == x } -> { erase (fmap f t) == f x } @-}
+erase_fmap :: (a -> b) -> a -> Tick a -> Proof
+erase_fmap _ _ _ = ()
+
+--
+--        ⟨t⟩ == x
+--  ---------------------
+--    ⟨wmap f t⟩ == f x
+--
+{-@ assume erase_wmap :: f:(a -> b) -> x:a -> { t:Tick a | erase t == x } -> { erase (wmap f t) == f x } @-}
+erase_wmap :: (a -> b) -> a -> Tick a -> Proof
+erase_wmap _ _ _ = ()
+
+--
+--        ⟨t⟩ == x
+--  -----------------------
+--    ⟨wmapN n f t⟩ == f x
+--
+{-@ assume erase_wmapN
+     :: m:Int
+     -> f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { erase (wmapN m f t) == f x }
+@-}
+erase_wmapN :: Int -> (a -> b) -> a -> Tick a -> Proof
+erase_wmapN _ _ _ _ = ()
+
+--
+--        ⟨t⟩ == x
+--  ---------------------
+--    ⟨gmap f t⟩ == f x
+--
+{-@ assume erase_gmap
+     :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { erase (gmap f t) == f x }
+@-}
+erase_gmap :: (a -> b) -> a -> Tick a -> Proof
+erase_gmap _ _ _ = ()
+
+--
+--        ⟨t⟩ == x
+--  ----------------------
+--    ⟨gmap n f t⟩ == f x
+--
+{-@ assume erase_gmapN
+     :: m:Int
+     -> f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { erase (gmapN m f t) == f x }
+@-}
+erase_gmapN :: Int -> (a -> b) -> a -> Tick a -> Proof
+erase_gmapN _ _ _ _ = ()
+
+--
+--
+--  ----------------
+--    ⟨pure x⟩ == x
+--
+{-@ assume erase_pure :: x:a -> { erase (pure x) == x } @-}
+erase_pure :: a -> Proof
+erase_pure _ = ()
+
+--
+--    ⟨tf⟩ == f   ⟨tx⟩ == x
+--  -------------------------
+--      ⟨tf <*> tx⟩ == f x
+--
+{-@ assume erase_app
+     :: f:(a -> b)
+     -> x:a
+     -> { tf:Tick (a -> b) | erase tf == f }
+     -> { tx:Tick a | erase tx == x }
+     -> { erase (tf <*> tx) == f x }
+@-}
+erase_app :: (a -> b) -> a -> Tick (a -> b) -> Tick a -> Proof
+erase_app _ _ _ _ = ()
+
+--
+--    ⟨tf⟩ == f   ⟨tx⟩ == x
+--  -------------------------
+--      ⟨tf  tx⟩ == f x
+--
+{-@ assume erase_wapp
+     :: f:(a -> b)
+     -> x:a
+     -> { tf:Tick (a -> b) | erase tf == f }
+     -> { tx:Tick a | erase tx == x }
+     -> { erase (tf  tx) == f x }
+@-}
+erase_wapp :: (a -> b) -> a -> Tick (a -> b) -> Tick a -> Proof
+erase_wapp _ _ _ _ = ()
+
+--
+--    ⟨tf⟩ == f   ⟨tx⟩ == x
+--  -------------------------
+--      ⟨tf  tx⟩ == f x
+--
+{-@ assume erase_wwapp
+     :: f:(a -> b)
+     -> x:a
+     -> { tf:Tick (a -> b) | erase tf == f }
+     -> { tx:Tick a | erase tx == x }
+     -> { erase (tf  tx) == f x }
+@-}
+erase_wwapp :: (a -> b) -> a -> Tick (a -> b) -> Tick a -> Proof
+erase_wwapp _ _ _ _ = ()
+
+--
+--    ⟨tf⟩ == f   ⟨tx⟩ == x
+--  -------------------------
+--      ⟨tf <\> tx⟩ == f x
+--
+{-@ assume erase_gapp
+     :: f:(a -> b)
+     -> x:a
+     -> { tf:Tick (a -> b) | erase tf == f }
+     -> { tx:Tick a | erase tx == x }
+     -> { erase (tf <\> tx) == f x }
+@-}
+erase_gapp :: (a -> b) -> a -> Tick (a -> b) -> Tick a -> Proof
+erase_gapp _ _ _ _ = ()
+
+--
+--    ⟨tf⟩ == f   ⟨tx⟩ == x
+--  -------------------------
+--     ⟨tf <\\> tx⟩ == f x
+--
+{-@ assume erase_ggapp
+     :: f:(a -> b)
+     -> x:a
+     -> { tf:Tick (a -> b) | erase tf == f }
+     -> { tx:Tick a | erase tx == x }
+     -> { erase (tf <\\> tx) == f x }
+@-}
+erase_ggapp :: (a -> b) -> a -> Tick (a -> b) -> Tick a -> Proof
+erase_ggapp _ _ _ _ = ()
+
+--
+--      ⟨tx⟩ == x   ⟨ty⟩ == y
+--  -------------------------------
+--    ⟨liftA2 f tx ty⟩ == f x y
+--
+{-@ assume erase_liftA2
+     :: f:(a -> b -> c)
+     -> x:a
+     -> y:b
+     -> { tx:Tick a | erase tx == x }
+     -> { ty:Tick b | erase ty == y }
+     -> { erase (liftA2 f tx ty) == f x y }
+@-}
+erase_liftA2 :: (a -> b -> c) -> a -> b -> Tick a -> Tick b -> Proof
+erase_liftA2 _ _ _ _ _ = ()
+
+--
+--
+--  ------------------
+--    ⟨return x⟩ == x
+--
+{-@ assume erase_return :: x:a -> { erase (return x) == x } @-}
+erase_return :: a -> Proof
+erase_return _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t >>= g⟩ == f x
+--
+{-@ assume erase_bind
+     :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (t >>= g) == f x }
+@-}
+erase_bind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_bind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t =<< g⟩ == f x
+--
+{-@ assume erase_flipped_bind
+     :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (g =<< t) == f x }
+@-}
+erase_flipped_bind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_flipped_bind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--     ⟨eqBind n t g⟩ == f x
+--
+{-@ assume erase_eqBind
+     :: n:Int
+     -> f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (eqBind n t g) == f x }
+@-}
+erase_eqBind :: Int -> (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_eqBind _ _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--    ⟨leqBind n t g⟩ == f x
+--
+{-@ assume erase_leqBind
+     :: n:Int
+     -> f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (leqBind n t g) == f x }
+@-}
+erase_leqBind :: Int -> (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_leqBind _ _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--    ⟨geqBind n t g⟩ == f x
+--
+{-@ assume erase_geqBind
+     :: n:Int
+     -> f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (geqBind n t g) == f x }
+@-}
+erase_geqBind :: Int -> (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_geqBind _ _ _ _ _ = ()
+
+--
+--   ⟨tf⟩ == f   ⟨tx⟩ == x
+--  ------------------------
+--     ⟨ap tf tx⟩ == f x
+--
+{-@ assume erase_ap
+     :: f:(a -> b)
+     -> x:a
+     -> { tf:Tick (a -> b) | erase tf == f }
+     -> { tx:Tick a | erase tx == x }
+     -> { erase (ap tf tx) == f x }
+@-}
+erase_ap :: (a -> b) -> a -> Tick (a -> b) -> Tick a -> Proof
+erase_ap _ _ _ _ = ()
+
+--
+--        ⟨t⟩ == x
+--  ---------------------
+--    ⟨liftM f t⟩ == f x
+--
+{-@ assume erase_liftM
+     :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { erase (liftM f t) == f x }
+@-}
+erase_liftM :: (a -> b) -> a -> Tick a -> Proof
+erase_liftM _ _ _ = ()
+
+--
+--      ⟨tx⟩ == x   ⟨ty⟩ == y
+--  -------------------------------
+--    ⟨liftM2 f tx ty⟩ == f x y
+--
+{-@ assume erase_liftM2
+     :: f:(a -> b -> c)
+     -> x:a
+     -> y:b
+     -> { tx:Tick a | erase tx == x }
+     -> { ty:Tick b | erase ty == y }
+     -> { erase (liftM2 f tx ty) == f x y }
+@-}
+erase_liftM2 :: (a -> b -> c) -> a -> b -> Tick a -> Tick b -> Proof
+erase_liftM2 _ _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t >/= g⟩ == f x
+--
+{-@ assume erase_wbind
+     :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (t >/= g) == f x }
+@-}
+erase_wbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_wbind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t =/< g⟩ == f x
+--
+{-@ assume erase_flipped_wbind
+     :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (g =/< t) == f x }
+@-}
+erase_flipped_wbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_flipped_wbind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t >//= g⟩ == f x
+--
+{-@ assume erase_wwbind :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (t >//= g) == f x }
+@-}
+erase_wwbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_wwbind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t =//< g⟩ == f x
+--
+{-@ assume erase_flipped_wwbind :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (g =//< t) == f x }
+@-}
+erase_flipped_wwbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_flipped_wwbind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t >\= g⟩ == f x
+--
+{-@ assume erase_gbind :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (t >\= g) == f x }
+@-}
+erase_gbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_gbind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t =\< g⟩ == f x
+--
+{-@ assume erase_flipped_gbind :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (g =\< t) == f x }
+@-}
+erase_flipped_gbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_flipped_gbind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t >\\= g⟩ == f x
+--
+{-@ assume erase_ggbind :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (t >\\= g) == f x }
+@-}
+erase_ggbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_ggbind _ _ _ _ = ()
+
+--
+--    ⟨t⟩ == x   ⟨g x⟩ == f x
+--  ----------------------------
+--       ⟨t =\\< g⟩ == f x
+--
+{-@ assume erase_flipped_ggbind :: f:(a -> b)
+     -> x:a
+     -> { t:Tick a | erase t == x }
+     -> { g:(a -> Tick b) | erase (g x) == f x }
+     -> { erase (g =\\< t) == f x }
+@-}
+erase_flipped_ggbind :: (a -> b) -> a -> Tick a -> (a -> Tick b) -> Proof
+erase_flipped_ggbind _ _ _ _ = ()
+
+--
+--       ⟨t⟩ == x
+--  --------------------
+--    ⟨⟨pay n t⟩⟩ == x
+--
+{-@ assume erase_pay :: n:Int
+     -> x:a
+     -> { t:Tick a | n <= tcost t && erase t == x }
+     -> { erase (erase (pay n t)) == x }
+@-}
+erase_pay :: Int -> a -> Tick a -> Proof
+erase_pay _ _ _ = ()
+
+-------------------------------------------------------------------------------
+-- | Helper functions:
+-------------------------------------------------------------------------------
+
+--
+-- Inference rules without any premises are clearly equivalent to 'tval'.
+--
+{-@ reflect erase @-}
+{-@ erase :: Tick a -> a @-}
+erase :: Tick a -> a
+erase (Tick _ x) = x
diff --git a/tests/relational/pos/Lists.hs b/tests/relational/pos/Lists.hs
new file mode 100644
index 0000000000..ddcdc28e33
--- /dev/null
+++ b/tests/relational/pos/Lists.hs
@@ -0,0 +1,191 @@
+
+--
+-- Liquidate your assets: reasoning about resource usage in Liquid Haskell.
+--
+
+{-@ LIQUID "--reflection" @-}
+
+module Lists (module Lists) where
+
+import Prelude hiding
+  ( Functor(..)
+  , Applicative(..)
+  , Monad(..)
+  , drop
+  , length
+  , take
+  )
+
+import RTick
+import Language.Haskell.Liquid.ProofCombinators
+import Erasure
+
+{-@ type OList a = [a]<{\h x -> h <= x }> @-}
+
+--
+-- Some functions on lists. Throughout this file the cost model is the number
+-- of recursive calls.
+--
+
+-------------------------------------------------------------------------------
+-- | Measures:
+-------------------------------------------------------------------------------
+
+{-@ measure length @-}
+{-@ length :: [a] -> Nat @-}
+length :: [a] -> Int
+length []       = 0
+length (_ : xs) = 1 + length xs
+
+-------------------------------------------------------------------------------
+-- | Functions:
+-------------------------------------------------------------------------------
+
+--
+-- Constructing lists:
+--
+
+--
+-- We redefine ':' because Liquid Haskell doesn't like @(x:)@ in some
+-- proofs.
+--
+{-@ reflect cons @-}
+{-@ cons :: forall 

a -> Bool>. x:a -> xs:[a

]

+ -> { zs:[a]

| 1 + length xs == length zs } +@-} +cons :: a -> [a] -> [a] +cons x xs = x : xs + +-- +-- Taking and dropping: +-- + +{-@ reflect takeLE @-} +{-@ takeLE :: n:Nat -> { xs:[a] | n <= length xs } + -> { t:Tick { zs:[a] | n == length zs } | tcost t == n } +@-} +takeLE :: Int -> [a] -> Tick [a] +takeLE _ [] = pure [] +takeLE 0 _ = pure [] +takeLE n (x : xs) = pure (cons x) takeLE (n - 1) xs + +{-@ reflect dropLE @-} +{-@ dropLE :: n:Nat -> { xs:[a] | n <= length xs } + -> { t:Tick { zs:[a] | length xs - n == length zs } | tcost t == n } +@-} +dropLE :: Int -> [a] -> Tick [a] +dropLE _ [] = pure [] +dropLE 0 xs = pure xs +dropLE n (_ : xs) = step 1 (dropLE (n - 1) xs) + +------------------------------------------------------------------------------- +-- | Erasure proofs: +------------------------------------------------------------------------------- +-- +-- We prove that erasing the annotations from 'takeLE' and 'dropLE' +-- returns the standard 'take' and 'drop' functions. +-- + +-- Functions: ----------------------------------------------------------------- + +{-@ reflect take @-} +{-@ take :: n:Nat -> { xs:[a] | n <= length xs } -> {o:[a] | length o == n } @-} +take :: Int -> [a] -> [a] +take _ [] = [] +take 0 _ = [] +take n (x : xs) = x : take (n - 1) xs + +{-@ reflect drop @-} +{-@ drop :: n:Nat -> { xs:[a] | n <= length xs } -> {o:[a] | length o == length xs - n }@-} +drop :: Int -> [a] -> [a] +drop _ [] = [] +drop 0 xs = xs +drop n (_ : xs) = drop (n - 1) xs + +-- Proofs: -------------------------------------------------------------------- + +{-@ takeLE_erase :: n:Nat -> { xs:[a] | n <= length xs } + -> { erase (takeLE n xs) == take n xs } +@-} +takeLE_erase :: Int -> [a] -> Proof +takeLE_erase n [] + = erase (takeLE n []) + -- { defn. of takeLE } + === erase (pure []) + ? erase_pure [] + === [] + -- { defn. of take } + === take n [] + *** QED +takeLE_erase 0 xs + = erase (takeLE 0 xs) + -- { defn. of takeLE } + === erase (pure []) + ? erase_pure [] + === [] + -- { defn. of take } + === take 0 xs + *** QED +takeLE_erase n (x : xs) + = erase (takeLE n (x : xs)) + -- { defn. of takeLE } + === tval (pure (cons x) takeLE (n - 1) xs) + ? takeLE_erase (n - 1) xs + ? erase_pure (cons x) + ? erase_wapp (cons x) (take (n - 1) xs) (pure (cons x)) (takeLE (n - 1) xs) + === cons x (take (n - 1) xs) + -- { defn. of cons } + === x : take (n - 1) xs + -- { defn. of take } + === take n (x : xs) + *** QED + +{-@ dropLE_erase :: n:Nat -> { xs:[a] | n <= length xs } + -> { erase (dropLE n xs) == drop n xs } +@-} +dropLE_erase :: Int -> [a] -> Proof +dropLE_erase n [] + = erase (dropLE n []) + -- { defn. of dropLE } + === erase (pure []) + ? erase_pure [] + === [] + -- { defn. of drop } + === drop n [] + *** QED +dropLE_erase 0 xs + = erase (dropLE 0 xs) + -- { defn. of dropLE } + === erase (pure xs) + ? erase_pure xs + === xs + -- { defn. of drop } + === drop 0 xs + *** QED +dropLE_erase n (x : xs) + = erase (dropLE n (x : xs)) + -- { defn. of dropLE } + === erase (step 1 (dropLE (n - 1) xs)) + ? dropLE_erase (n - 1) xs + ? erase_step 1 (drop (n - 1) xs) (dropLE (n - 1) xs) + === drop n (x : xs) + *** QED + + +data P a b = P a b +{-@ data P a b

b -> Bool> = P {left :: a, rigth :: b

}@-} +{-@ reflect split @-} +split :: [a] -> P [a] [a] +{-@ split + :: x:[a] + -> P <{\l r -> (2 + <= length x => + (length l < length x && length r < length x)) + && length l + length r + == length x && (((length x) mod 2 == 0 ) + => (length l == length x / 2 && length r + == length x / 2))}> [a] [a] +@-} + +split xs = P (take n xs) (drop n xs) + where n = length xs `div` 2 \ No newline at end of file diff --git a/tests/relational/pos/RTick.hs b/tests/relational/pos/RTick.hs new file mode 100644 index 0000000000..80df526c39 --- /dev/null +++ b/tests/relational/pos/RTick.hs @@ -0,0 +1,374 @@ + +-- +-- Liquidate your assets: reasoning about resource usage in Liquid Haskell. +-- Martin A.T. Handley, Niki Vazou, and Graham Hutton. +-- + +{-@ LIQUID "--reflection" @-} + +module RTick + ( + + -- Tick datatype: + Tick(..) + , ttcost + -- Primitive resource operators: + , fmap + , pure + , (<*>) + , liftA2 + , return + , (>>=) + , (=<<) + , eqBind + , leqBind + , geqBind + , ap + , liftM + , liftM2 + -- Resource modifiers: + , step + , wait -- step 1 . return + , waitN -- step (n > 0) . return + , go -- step (-1) . return + , goN -- step (n < 0) . return + , wmap -- step 1 . fmap f + , wmapN -- step (n > 0) . fmap f + , gmap -- step (-1) . fmap f + , gmapN -- step (n < 0) . fmap f + , () -- step 1 . (f <*>) + , () -- step 2 . (f <*>) + , (<\>) -- step (-1) . (f <*>) + , (<\\>) -- step (-2) . (f <*>) + , (>/=) -- step 1 . (>>= f) + , (=/<) -- step 1 . (>>= f) + , (>//=) -- step 2 . (>>= f) + , (=//<) -- step 2 . (>>= f) + , (>\=) -- step (-1) . (>>= f) + , (=\<) -- step (-1) . (>>= f) + , (>\\=) -- step (-2) . (>>= f) + , (=\\<) -- step (-2) . (>>= f) + -- Memoisation: + , pay + , zipWithM + + + ) where + +import Prelude hiding ( Functor(..), Applicative(..), Monad(..), (=<<) ) + +import qualified Control.Applicative as A +import qualified Control.Monad as M +import qualified Data.Functor as F + +-- +-- The 'Tick' datatype and its corresponding resource modifiers. +-- +-- See 'ResourceModifiers.hs' for proofs that all resource modifiers +-- can be defined using 'return', '(>>=) 'and 'step'. +-- + +------------------------------------------------------------------------------- +-- | 'Tick' datatype for recording resource usage: +------------------------------------------------------------------------------- + +{-@ data Tick a = Tick { tcost :: Int, tval :: a } @-} +data Tick a = Tick { tcost :: Int, tval :: a } + +{-@ measure ttcost @-} +ttcost :: Tick a -> Int +ttcost (Tick c _) = c + +------------------------------------------------------------------------------- +-- | Primitive resource operators: +------------------------------------------------------------------------------- + +instance F.Functor Tick where + fmap = fmap + +{-@ reflect fmap @-} +{-@ fmap :: f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (tcost t1) (f (tval t1)) == t } @-} +fmap :: (a -> b) -> Tick a -> Tick b +fmap f (Tick m x) = Tick m (f x) + +instance A.Applicative Tick where + pure = pure + (<*>) = (<*>) + +{-@ reflect pure @-} +{-@ pure :: x:a -> { t:Tick a | x == tval t && 0 == tcost t } @-} +pure :: a -> Tick a +pure x = Tick 0 x + +{-@ reflect <*> @-} +{-@ (<*>) :: t1:Tick (a -> b) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval t && tcost t1 + tcost t2 == tcost t } @-} +infixl 4 <*> +(<*>) :: Tick (a -> b) -> Tick a -> Tick b +Tick m f <*> Tick n x = Tick (m + n) (f x) + +{-@ reflect liftA2 @-} +{-@ liftA2 :: f:(a -> b -> c) -> t1:Tick a -> t2:Tick b -> { t:Tick c | f (tval t1) (tval t2) == tval t && tcost t1 + tcost t2 == tcost t } @-} +liftA2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c +liftA2 f (Tick m x) (Tick n y) = Tick (m + n) (f x y) + +instance M.Monad Tick where + return = return + (>>=) = (>>=) + +{-@ reflect return @-} +{-@ return :: x:a -> { t:Tick a | x == tval t && 0 == tcost t } @-} +return :: a -> Tick a +return x = Tick 0 x + +{-@ reflect >>= @-} +{-@ (>>=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1)) == tval t && tcost t1 + tcost (f (tval t1)) == tcost t } @-} +infixl 4 >>= +(>>=) :: Tick a -> (a -> Tick b) -> Tick b +Tick m x >>= f = let Tick n y = f x in Tick (m + n) y + +{-@ reflect =<< @-} +{-@ (=<<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval t && tcost t1 + tcost (f (tval t1)) == tcost t } @-} +infixl 4 =<< +(=<<) :: (a -> Tick b) -> Tick a -> Tick b +f =<< Tick m x = let Tick n y = f x in Tick (m + n) y + +{-@ reflect ap @-} +{-@ ap :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval t && tcost t1 + tcost t2 == tcost t } @-} +ap :: Tick (a -> b) -> Tick a -> Tick b +ap (Tick m f) (Tick n x) = Tick (m + n) (f x) + +{-@ reflect liftM @-} +{-@ liftM :: f:(a -> b) -> t1:Tick a -> { t:Tick b | tcost t1 == tcost t } @-} +liftM :: (a -> b) -> Tick a -> Tick b +liftM f (Tick m x) = Tick m (f x) + +{-@ reflect liftM2 @-} +{-@ liftM2 :: f:(a -> b -> c) -> t1:Tick a -> t2:Tick b -> { t:Tick c | f (tval t1) (tval t2) == tval t && tcost t1 + tcost t2 == tcost t } @-} +liftM2 :: (a -> b -> c) -> Tick a -> Tick b -> Tick c +liftM2 f (Tick m x) (Tick n y) = Tick (m + n) (f x y) + +------------------------------------------------------------------------------- + +{-@ reflect eqBind @-} +{-@ eqBind + :: n:Int + -> t1:Tick a + -> f:(a -> { tf:Tick b | n == tcost tf }) + -> { t:Tick b | tval (f (tval t1)) + == tval t && tcost t1 + n == tcost t } +@-} +eqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b +eqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y + +{-@ reflect leqBind @-} +{-@ leqBind :: n:Int -> t1:Tick a -> f:(a -> { tf:Tick b | n >= tcost tf }) -> { t:Tick b | tcost t1 + n >= tcost t } @-} +leqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b +leqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y + +{-@ reflect geqBind @-} +{-@ geqBind :: n:Int -> t1:Tick a -> f:(a -> { tf:Tick b | n <= tcost tf }) -> { t2:Tick b | tcost t1 + n <= tcost t2 } @-} +geqBind :: Int -> Tick a -> (a -> Tick b) -> Tick b +geqBind _ (Tick m x) f = let Tick n y = f x in Tick (m + n) y + +------------------------------------------------------------------------------- +-- | Resource modifiers: +------------------------------------------------------------------------------- + +{-@ reflect step @-} +{-@ step :: m:Int -> t1:Tick a -> { t:Tick a | tval t1 == tval t && m + tcost t1 == tcost t } @-} +step :: Int -> Tick a -> Tick a +step m (Tick n x) = Tick (m + n) x + +-- +-- @wait := step 1 . return@. +-- +{-@ reflect wait @-} +{-@ wait :: x:a -> { t:Tick a | x == tval t && 1 == tcost t } @-} +wait :: a -> Tick a +wait x = Tick 1 x + +-- +-- @waitN (n > 0) := step n . return@. +-- +{-@ reflect waitN @-} +{-@ waitN :: n:Nat -> x:a -> { t:Tick a | x == tval t && n == tcost t } @-} +waitN :: Int -> a -> Tick a +waitN n x = Tick n x + +-- +-- @go := step (-1) . return@. +-- +{-@ reflect go @-} +{-@ go :: x:a -> { t:Tick a | x == tval t && (-1) == tcost t } @-} +go :: a -> Tick a +go x = Tick (-1) x + +-- +-- @goN (n > 0) := step (-n) . return@. +-- +{-@ reflect goN @-} +{-@ goN :: { n:Nat | n > 0 } -> x:a -> { t:Tick a | x == tval t && (-n) == tcost t } @-} +goN :: Int -> a -> Tick a +goN n x = Tick (-n) x + +-- +-- @wmap f := step 1 . fmap f@. +-- +{-@ reflect wmap @-} +{-@ wmap :: f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (1 + tcost t1) (f (tval t1)) == t } @-} +wmap :: (a -> b) -> Tick a -> Tick b +wmap f (Tick m x) = Tick (1 + m) (f x) + +-- +-- @wmapN (n > 0) f := step n . fmap f@. +-- +{-@ reflect wmapN @-} +{-@ wmapN :: { m:Nat | m > 0 } -> f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (m + tcost t1) (f (tval t1)) == t } @-} +wmapN :: Int -> (a -> b) -> Tick a -> Tick b +wmapN m f (Tick n x) = Tick (m + n) (f x) + +-- +-- @gmap f := step (-1) . fmap f@. +-- +{-@ reflect gmap @-} +{-@ gmap :: f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (tcost t1 - 1) (f (tval t1)) == t } @-} +gmap :: (a -> b) -> Tick a -> Tick b +gmap f (Tick m x) = Tick (m - 1) (f x) + +-- +-- @gmapN (n > 0) f := step (-n) . fmap f@. +-- +{-@ reflect gmapN @-} +{-@ gmapN :: { m:Nat | m > 0 } -> f:(a -> b) -> t1:Tick a -> { t:Tick b | Tick (tcost t1 - m) (f (tval t1)) == t } @-} +gmapN :: Int -> (a -> b) -> Tick a -> Tick b +gmapN m f (Tick n x) = Tick (n - m) (f x) + +-- +-- \"wapp\": @(f ) := step 1 . (f <*>)@. +-- +{-@ reflect @-} +{-@ () :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval t && 1 + tcost t1 + tcost t2 == tcost t } @-} +infixl 4 +() :: Tick (a -> b) -> Tick a -> Tick b +Tick m f Tick n x = Tick (1 + m + n) (f x) + +-- +-- \"wwapp\": @(f ) := step 2 . (f <*>)@. +-- +{-@ reflect @-} +{-@ () :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval t && 2 + tcost t1 + tcost t2 == tcost t } @-} +infixl 4 +() :: Tick (a -> b) -> Tick a -> Tick b +Tick m f Tick n x = Tick (2 + m + n) (f x) + +-- +-- \"gapp\": @(f <\>) := step (-1) . (f <*>)@. +-- +{-@ reflect <\> @-} +{-@ (<\>) :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval t && tcost t1 + tcost t2 - 1 == tcost t } @-} +infixl 4 <\> +(<\>) :: Tick (a -> b) -> Tick a -> Tick b +Tick m f <\> Tick n x = Tick (m + n - 1) (f x) + +-- +-- \"ggapp\": @(f <\\>) := step (-2) . (f <*>)@. +-- +{-@ reflect <\\> @-} +{-@ (<\\>) :: t1:(Tick (a -> b)) -> t2:Tick a -> { t:Tick b | (tval t1) (tval t2) == tval t && tcost t1 + tcost t2 - 2 == tcost t } @-} +infixl 4 <\\> +(<\\>) :: Tick (a -> b) -> Tick a -> Tick b +Tick m f <\\> Tick n x = Tick (m + n - 2) (f x) + +-- +-- \"wbind\": @(>/= f) := step 1 . (>>= f)@. +-- +{-@ reflect >/= @-} +{-@ (>/=) + :: t1:Tick a + -> f:(a -> Tick b) + -> { t:Tick b | (tval (f (tval t1)) == tval t) + && (1 + tcost t1 + tcost (f (tval t1))) == tcost t } +@-} +infixl 4 >/= +(>/=) :: Tick a -> (a -> Tick b) -> Tick b +Tick m x >/= f = let Tick n y = f x in Tick (1 + m + n) y + +-- +-- \"wbind\": @(f =/<) := step 1 . (f =<<)@. +-- +{-@ reflect =/< @-} +{-@ (=/<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval t && 1 + tcost t1 + tcost (f (tval t1)) == tcost t } @-} +infixl 4 =/< +(=/<) :: (a -> Tick b) -> Tick a -> Tick b +f =/< Tick m x = let Tick n y = f x in Tick (1 + m + n) y + +-- +-- \"wwbind\": @(>//= f) := step 2 . (>>= f)@. +-- +{-@ reflect >//= @-} +{-@ (>//=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1)) == tval t && 2 + tcost t1 + tcost (f (tval t1)) == tcost t } @-} +infixl 4 >//= +(>//=) :: Tick a -> (a -> Tick b) -> Tick b +Tick m x >//= f = let Tick n y = f x in Tick (2 + m + n) y + +-- +-- \"wwbind\": @(f =//<) := step 2 . (f =<<)@. +-- +{-@ reflect =//< @-} +{-@ (=//<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval t && 2 + tcost t1 + tcost (f (tval t1)) == tcost t } @-} +infixl 4 =//< +(=//<) :: (a -> Tick b) -> Tick a -> Tick b +f =//< Tick m x = let Tick n y = f x in Tick (2 + m + n) y + +-- +-- \"gbind\": @(>\= f) := step (-1) . (>>= f)@. +-- +{-@ reflect >\= @-} +{-@ (>\=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1)) == tval t && tcost t1 + tcost (f (tval t1)) - 1 == tcost t } @-} +infixl 4 >\= +(>\=) :: Tick a -> (a -> Tick b) -> Tick b +Tick m x >\= f = let Tick n y = f x in Tick (m + n - 1) y + +-- +-- \"gbind\": @(f =\<) := step (-1) . (f =<<)@. +-- +{-@ reflect =\< @-} +{-@ (=\<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval t && tcost t1 + tcost (f (tval t1)) - 1 == tcost t } @-} +infixl 4 =\< +(=\<) :: (a -> Tick b) -> Tick a -> Tick b +f =\< Tick m x = let Tick n y = f x in Tick (m + n - 1) y + +-- +-- \"ggbind\": @(>\= f) := step (-2) . (>>= f)@. +-- +{-@ reflect >\\= @-} +{-@ (>\\=) :: t1:Tick a -> f:(a -> Tick b) -> { t:Tick b | tval (f (tval t1)) == tval t && tcost t1 + tcost (f (tval t1)) - 2 == tcost t } @-} +infixl 4 >\\= +(>\\=) :: Tick a -> (a -> Tick b) -> Tick b +Tick m x >\\= f = let Tick n y = f x in Tick (m + n - 2) y + +-- +-- \"ggbind\": @(f =\\<) := step (-2) . (f =<<)@. +-- +{-@ reflect =\\< @-} +{-@ (=\\<) :: f:(a -> Tick b) -> t1:Tick a -> { t:Tick b | tval (f (tval t1)) == tval t && tcost t1 + tcost (f (tval t1)) - 2 == tcost t } @-} +infixl 4 =\\< +(=\\<) :: (a -> Tick b) -> Tick a -> Tick b +f =\\< Tick m x = let Tick n y = f x in Tick (m + n - 2) y + +------------------------------------------------------------------------------- +-- | Memoisation: +------------------------------------------------------------------------------- + +{-@ reflect pay @-} +{-@ pay :: m:Int -> { t1:Tick a | m <= tcost t1 } -> { t:Tick ({ t2 : Tick a | tcost t1 - m == tcost t2 }) | m == tcost t } @-} +pay :: Int -> Tick a -> Tick (Tick a) +pay m (Tick n x) = Tick m (Tick (n - m) x) + + +{-@ reflect zipWithM @-} +{-@ zipWithM :: f:(a -> b -> Tick c) -> x:Tick a -> y:Tick b + -> {t:Tick c | tcost t == tcost x + tcost y + tcost (f (tval x) (tval y)) + && tval t == tval (f (tval x) (tval y)) } @-} +zipWithM :: (a -> b -> Tick c) -> Tick a -> Tick b -> Tick c +zipWithM f (Tick c1 x1) (Tick c2 x2) = let Tick c x = f x1 x2 in Tick (c + c1 + c2) x diff --git a/tests/relational/rtest b/tests/relational/rtest index 360c6ad884..fb25c26aa6 100755 --- a/tests/relational/rtest +++ b/tests/relational/rtest @@ -8,7 +8,7 @@ for f in tests/relational/pos/* do echo echo $f - if ! liquid $f --ple --reflection + if ! liquid $f --ple --reflection --idirs=tests/relational/pos then rc=1 fi From 04635369b07ac289ee240f6897d0183d228db372 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 20 Mar 2023 18:56:54 +0000 Subject: [PATCH 176/219] add ttest --- tests/relational/ttest | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100755 tests/relational/ttest diff --git a/tests/relational/ttest b/tests/relational/ttest new file mode 100755 index 0000000000..6ae3552e08 --- /dev/null +++ b/tests/relational/ttest @@ -0,0 +1,40 @@ +#!/bin/bash + +# USAGE (runs translation tests from https://github.com/oquechy/relational-liquid-haskell): +# $ cd liquidhaskell +# $ chmod +x tests/relational/ttest +# $ ./tests/relational/ttest + +relpath="../relational-liquid-haskell" +if [ ! -z "$1" ] + then + relpath="$1" +fi + +# Return code +rc=0 + + +# Test relational examples +echo "$relpath/examples/relational/"* | tr " " "\n" | grep -v "_relToUn\.hs$" \ + | while read -r f ; do + echo + echo $f + if ! liquid $f --ple --reflection --relational-hints --idirs="$relpath/examples/relational" --idirs="$relpath/examples/src" + then + rc=1 + fi +done + +# Test translations +echo "$relpath/examples/relational/"* | tr " " "\n" | grep "_relToUn\.hs$" \ + | while read -r f ; do + echo + echo $f + if ! liquid $f --ple --reflection --relational-hints --idirs="$relpath/examples/relational" --idirs="$relpath/examples/src" + then + rc=1 + fi +done + +exit $rc \ No newline at end of file From c387ac9501f0ae6f940521601e4a9f6c03ff2c23 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 22 Mar 2023 15:57:58 +0000 Subject: [PATCH 177/219] remove case on I# --- .../Haskell/Liquid/Constraint/Relational.hs | 7 +++---- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index f150a49952..558f99dc9a 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -371,7 +371,7 @@ relTermToUnTerm' m relTerms (Let (NonRec x1 d1) e1) (Let (NonRec x2 d2) e2) = Let (NonRec x1l d1') $ Let (NonRec x2r d2') $ Let (NonRec relX relD) $ relTermToUnTerm' m (((x1l, x2r), Var relX) : relTerms) e1l e2r where - relX = mkRelLemmaVar x1 x2 + relX = mkRelLemmaVar x1l x2r relD = relTermToUnTerm' m relTerms d1 d2 (x1l, x2r) = mkRelCopies x1 x2 (e1l, e2r) = subRelCopies e1 x1 e2 x2 @@ -484,9 +484,8 @@ addLemma e lm = App (App cnst e) lm where cnst = Var $ GM.stringVar "const" Ghc.unitTy -- q = Var $ GM.stringVar "?" Ghc.unitTy - + cleanUnTerms :: RenVars -> CoreExpr -> (CoreExpr, Bool) -{- Maybe have to do some cleaning to the vars here -} cleanUnTerms rvs var@(Var v) | handleVar rvs v == "patError" = (var, True) | otherwise = (var, False) @@ -1253,7 +1252,7 @@ mkRelCopies x1 x2 = (mkCopyWithSuffix relSuffixL x1, mkCopyWithSuffix relSuffixR mkCopyWithName :: String -> Var -> Var mkCopyWithName s v = traceWhenLoud ("mkCopyWithName: produced an occ name " ++ Ghc.getOccString (varName v')) v' -- where v' = GM.stringVar s (Ghc.exprType (Var v)) - where v' = Ghc.setVarName v $ Ghc.mkSystemName (Ghc.getUnique v) (Ghc.mkVarOcc s) + where v' = Ghc.setVarName v $ Ghc.mkInternalName (Ghc.getUnique v) (Ghc.mkVarOcc s) (Ghc.getSrcSpan v) mkCopyWithSuffix :: String -> Var -> Var mkCopyWithSuffix s v = mkCopyWithName (Ghc.getOccString v ++ s) v diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index bf93e75bde..5dcee11470 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -102,12 +102,20 @@ fromAnf' (Let (Rec {}) _) _ = fromAnf' (Var var) bnds = (fromMaybe (Var var) (lookup var bnds), bnds) +fromAnf' (Case scr bnd _ [(GHC.DataAlt c, [x], e)]) bnds + | c == GHC.intDataCon + = fromAnf' e $ (x, scr'):bnds'' + where + bnds'' = (bnd, scr'):bnds' + (scr', bnds') = fromAnf' scr bnds + fromAnf' (Case scr bnd tp alts) bnds = (Case scr' bnd tp - ( map (\(altc, xs, e) -> - (altc, xs, fst $ fromAnf' e bnds)) alts), bnds') + (map (\(altc, xs, e) -> + (altc, xs, fst $ fromAnf' e bnds'')) alts), bnds'') where - ( scr', bnds' ) = fromAnf' scr bnds + bnds'' = (bnd, scr'):bnds' + (scr', bnds') = fromAnf' scr bnds fromAnf' (App e1 e2) bnds = let (e1', bnds') = fromAnf' e1 bnds @@ -200,14 +208,14 @@ getExternalName n = mod ++ outName {- Handle the multiple types of variables one might encounter in Haskell. -} handleVar :: RenVars -> Var -> String -handleVar vars v +handleVar vars v | isTyConName name = "{- TyConName -}" | isTyVarName name = "{- TyVar -}" | isSystemName name = getSysName vars name -- ++ "{- SysName -}" | isWiredInName name = getLocalName name -- ++ "{- WiredInName -}" - | isInternalName name = getOccString name + | isInternalName name = getSysName vars name -- ++ "{- Internal -}" | isExternalName name = getExternalName name -- ++ "{- external name -}" @@ -301,6 +309,7 @@ parenVars = ["+", "-", "*", "/", "%", "?", ":", "++", "==", "/="] paren :: CoreExpr -> Bool -> String -> String paren (Var v) _ res | occStr v `notElem` parenVars = res paren (App _ _) True res = res +paren (App (Var i) _) _ res | occStr i == "I#" = res paren Tick{} _ res = res paren Lit{} _ res = res paren _ _ res = "(" ++ res ++ ")" From 3329cc2aa5a4dfaf15d4d1b700ffcf4d35952a38 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 22 Mar 2023 17:30:08 +0000 Subject: [PATCH 178/219] add lemmas on application --- .../Haskell/Liquid/Constraint/Relational.hs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index 558f99dc9a..3855fe7410 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -328,7 +328,7 @@ relTermToUnTerm' m relTerms (App f1 v1) (App f2 v2) , GM.isEmbeddedDictVar x2 , areCompatible f1 f2 = relTermToUnTerm' m relTerms f1 f2 -relTermToUnTerm' m relTerms _e1@(App f1 v1) _e2@(App f2 v2) +relTermToUnTerm' m relTerms e1@(App f1 v1) e2@(App f2 v2) | Var x1 <- GM.unTickExpr v1 , Var x2 <- GM.unTickExpr v2 , areCompatible f1 f2 @@ -338,11 +338,14 @@ relTermToUnTerm' m relTerms _e1@(App f1 v1) _e2@(App f2 v2) ("relTermToUnTerm App lookup " ++ show x1 ++ " ~ " ++ show x2 ++ " ~> " ++ show relX) $ App (App (App (relTermToUnTerm' m relTerms f1 f2) v1') v2') relX + `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' where rvs = renVars m (v1', _) = cleanUnTerms rvs v1 (v2', _) = cleanUnTerms rvs v2 -relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2) + (e1', p1) = cleanUnTerms rvs e1 + (e2', p2) = cleanUnTerms rvs e2 +relTermToUnTerm' m relTerms e1@(App f1 x1) e2@(App f2 x2) | isCommonArg x1 , isCommonArg x2 , areCompatible f1 f2 @@ -350,10 +353,13 @@ relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2) = traceWhenLoud ("relTermToUnTerm App common arg " ++ show x1 ++ " " ++ show x2) $ App (App (App (relTermToUnTerm' m relTerms f1 f2) x1') x2') relX + `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' where rvs = renVars m (x1', _) = cleanUnTerms rvs x1 (x2', _) = cleanUnTerms rvs x2 + (e1', p1) = cleanUnTerms rvs e1 + (e2', p2) = cleanUnTerms rvs e2 relX = mkLambdaUnit m x1 x2 (Ghc.exprType x1) (Ghc.exprType x2) relTermToUnTerm' m relTerms (Lam α1 e1) (Lam α2 e2) | Ghc.isTyVar α1, Ghc.isTyVar α2 @@ -420,6 +426,10 @@ relTermToUnTerm' m _ e1 e2 right = coreToGoal rvs True e2 info = "GOAL: " ++ left ++ " ~ " ++ right +guardLemma :: Bool -> CoreExpr -> CoreExpr +guardLemma True _ = Ghc.unitExpr +guardLemma False e = e + {- function to print CoreExpr as strings in order to insert them as goal comments on the output of the proof. when the boolean argument short is true, if the goal is From fd901f52e655f196103cc89aa024d5ae70aabd26 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 27 Mar 2023 11:56:46 +0100 Subject: [PATCH 179/219] support translation of non-anf --- .../Haskell/Liquid/Constraint/Relational.hs | 42 +++++++------------ src/Language/Haskell/Liquid/Synthesize/GHC.hs | 3 +- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index 3855fe7410..892da6478d 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -311,7 +311,9 @@ isCommonArg _ = True renVars :: ArgMapping -> RenVars renVars (lvars, rvars) = map F.symbolSafeString $ lvars ++ rvars -relTermToUnTerm' :: ArgMapping -> [((Var, Var), CoreExpr)] -> CoreExpr -> CoreExpr -> CoreExpr +type TranslationEnv = [((Var, Var), CoreExpr)] + +relTermToUnTerm' :: ArgMapping -> TranslationEnv -> CoreExpr -> CoreExpr -> CoreExpr relTermToUnTerm' _ relTerms (Var x1) (Var x2) | Just relX <- lookup (x1, x2) relTerms = relX @@ -328,39 +330,23 @@ relTermToUnTerm' m relTerms (App f1 v1) (App f2 v2) , GM.isEmbeddedDictVar x2 , areCompatible f1 f2 = relTermToUnTerm' m relTerms f1 f2 -relTermToUnTerm' m relTerms e1@(App f1 v1) e2@(App f2 v2) - | Var x1 <- GM.unTickExpr v1 - , Var x2 <- GM.unTickExpr v2 - , areCompatible f1 f2 - , areCompatible v1 v2 - , Just relX <- lookup (x1, x2) relTerms - = traceWhenLoud - ("relTermToUnTerm App lookup " - ++ show x1 ++ " ~ " ++ show x2 ++ " ~> " ++ show relX) $ - App (App (App (relTermToUnTerm' m relTerms f1 f2) v1') v2') relX - `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' - where - rvs = renVars m - (v1', _) = cleanUnTerms rvs v1 - (v2', _) = cleanUnTerms rvs v2 - (e1', p1) = cleanUnTerms rvs e1 - (e2', p2) = cleanUnTerms rvs e2 -relTermToUnTerm' m relTerms e1@(App f1 x1) e2@(App f2 x2) +relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2) | isCommonArg x1 , isCommonArg x2 , areCompatible f1 f2 , areCompatible x1 x2 = traceWhenLoud - ("relTermToUnTerm App common arg " ++ show x1 ++ " " ++ show x2) $ - App (App (App (relTermToUnTerm' m relTerms f1 f2) x1') x2') relX - `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' + ("relTermToUnTerm App common arg " ++ show x1 ++ " ~ " ++ show x2) $ + App (App (App relF x1') x2') relX + -- `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' where + relF = relTermToUnTerm' m relTerms f1 f2 + relX = relTermToUnTerm' m relTerms x1 x2 rvs = renVars m (x1', _) = cleanUnTerms rvs x1 (x2', _) = cleanUnTerms rvs x2 - (e1', p1) = cleanUnTerms rvs e1 - (e2', p2) = cleanUnTerms rvs e2 - relX = mkLambdaUnit m x1 x2 (Ghc.exprType x1) (Ghc.exprType x2) + -- (e1', p1) = cleanUnTerms rvs e1 + -- (e2', p2) = cleanUnTerms rvs e2 relTermToUnTerm' m relTerms (Lam α1 e1) (Lam α2 e2) | Ghc.isTyVar α1, Ghc.isTyVar α2 = relTermToUnTerm' m relTerms e1 e2 @@ -426,9 +412,9 @@ relTermToUnTerm' m _ e1 e2 right = coreToGoal rvs True e2 info = "GOAL: " ++ left ++ " ~ " ++ right -guardLemma :: Bool -> CoreExpr -> CoreExpr -guardLemma True _ = Ghc.unitExpr -guardLemma False e = e +-- guardLemma :: Bool -> CoreExpr -> CoreExpr +-- guardLemma True _ = Ghc.unitExpr +-- guardLemma False e = e {- function to print CoreExpr as strings in order to insert them as goal comments on the output of the proof. diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 5dcee11470..6c6a060543 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -220,7 +220,7 @@ handleVar vars v | isExternalName name = getExternalName name -- ++ "{- external name -}" | otherwise = "{- Not properly handled -}" - ++ show name + ++ show (getOccString name) where name :: Name name = varName v @@ -310,7 +310,6 @@ paren :: CoreExpr -> Bool -> String -> String paren (Var v) _ res | occStr v `notElem` parenVars = res paren (App _ _) True res = res paren (App (Var i) _) _ res | occStr i == "I#" = res -paren Tick{} _ res = res paren Lit{} _ res = res paren _ _ res = "(" ++ res ++ ")" From 1fecc01eef37a31cbcade0f96d31f82f171ad154 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 27 Mar 2023 12:13:04 +0100 Subject: [PATCH 180/219] switch to ormolu formatter --- liquidhaskell.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index bae66745d6..d0eb1cd2a7 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -253,6 +253,7 @@ library , recursion-schemes < 5.3 , data-fix , extra + , ormolu default-language: Haskell98 default-extensions: PatternGuards, RecordWildCards, DoAndIfThenElse ghc-options: -W -fwarn-missing-signatures -j From a28dc4df2eaa313ed2cacf64a73cf4e773dd1d5b Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 27 Mar 2023 14:47:53 +0100 Subject: [PATCH 181/219] fix parens --- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 6c6a060543..975938d36b 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -308,7 +308,7 @@ parenVars = ["+", "-", "*", "/", "%", "?", ":", "++", "==", "/="] paren :: CoreExpr -> Bool -> String -> String paren (Var v) _ res | occStr v `notElem` parenVars = res -paren (App _ _) True res = res +-- paren (App _ _) True res = res paren (App (Var i) _) _ res | occStr i == "I#" = res paren Lit{} _ res = res paren _ _ res = "(" ++ res ++ ")" From fc7213a0ca81555ef1ffe03fd2a348cad5e0a20e Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 28 Mar 2023 16:07:50 +0200 Subject: [PATCH 182/219] update to GHC 9.2 --- liquid-fixpoint | 2 +- liquidhaskell.cabal | 1 + src-ghc/Liquid/GHC/Misc.hs | 14 ------- .../Haskell/Liquid/Constraint/Relational.hs | 41 ++++--------------- src/Language/Haskell/Liquid/Liquid.hs | 8 ++-- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 12 +++--- 6 files changed, 20 insertions(+), 58 deletions(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index 0d08484369..ab9ee7e85c 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit 0d08484369589bc92b9f3817c1a7e415ebe66431 +Subproject commit ab9ee7e85c22a951c99bd4dd6bbb7f52d197fdd4 diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 48e3535ca5..e7527f7d74 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -132,6 +132,7 @@ library other-modules: Language.Haskell.Liquid.GHC.Plugin.SpecFinder Language.Haskell.Liquid.GHC.Plugin.Types Language.Haskell.Liquid.GHC.Plugin.Util + Language.Haskell.Liquid.Synthesize.GHC hs-source-dirs: src src-ghc build-depends: base >= 4.11.1.0 && < 5 diff --git a/src-ghc/Liquid/GHC/Misc.hs b/src-ghc/Liquid/GHC/Misc.hs index 8cc559aff9..2f3f7c52d0 100644 --- a/src-ghc/Liquid/GHC/Misc.hs +++ b/src-ghc/Liquid/GHC/Misc.hs @@ -97,20 +97,6 @@ stringVar s t = mkLocalVar VanillaId name Many t vanillaIdInfo name = mkInternalName (mkUnique 'x' 25) occ noSrcSpan occ = mkVarOcc s -mkLocVar :: Int -> String -> Type -> Var -mkLocVar i s t = mkLocalVar VanillaId name Many t vanillaIdInfo - where - name = mkInternalName unique occ noSrcSpan - unique = mkLocalUnique i - occ = mkVarOcc s - -{- -Taken from GHC.Types.Unique -url: https://hackage.haskell.org/package/ghc-9.4.4/docs/src/GHC.Types.Unique.html#Unique --} -mkLocalUnique :: Int -> Unique -mkLocalUnique i = mkUnique 'X' i - -- FIXME: plugging in dummy type like this is really dangerous maybeAuxVar :: Symbol -> Maybe Var maybeAuxVar s diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index c1198cd5ec..e469326ae4 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -379,16 +379,15 @@ relTermToUnTerm' m relTerms (Let (Rec bs1) e1) (Let (Rec bs2) e2) relBs = zipWith (\(x1, d1) (x2, d2) -> (mkRelLemmaVar x1 x2, relTermToUnTerm' m relTerms' d1 d2)) bs1 bs2 relTermToUnTerm' m relTerms (Case d1 x1 t1 as1) (Case d2 x2 t2 as2) = Case d1 x1l t1 $ map - (\(c1, bs1, e1) -> + (\(Ghc.Alt c1 bs1 e1) -> let bs1l = map (mkCopyWithSuffix relSuffixL) bs1 in - ( c1 - , bs1l - , Case d2 x2r t2 $ map - (\(c2, bs2, e2) -> + ( Ghc.Alt c1 bs1l $ + Case d2 x2r t2 $ map + (\(Ghc.Alt c2 bs2 e2) -> let bs2r = map (mkCopyWithSuffix relSuffixR) bs2 e1l = subVarAndTys ((x1, x1l) : zip bs1 bs1l) e1 e2r = subVarAndTys ((x2, x2r) : zip bs2 bs2r) e2 - in (c2, bs2r, relTermToUnTerm' m relTerms e1l e2r) + in (Ghc.Alt c2 bs2r $ relTermToUnTerm' m relTerms e1l e2r) ) as2 )) @@ -516,11 +515,12 @@ cleanUnTerms rvs (Case e v t alts) = cleanUnTerms _ e = error ("cleanUnTerms: " ++ F.showpp e) -cleanCase :: RenVars -> [(a, b, CoreExpr)] -> ([(a, b, CoreExpr)], Bool) -cleanCase rvs alts = (zip3 altcs vss cores, bool) +cleanCase :: RenVars -> [Ghc.Alt CoreBndr] -> ([Ghc.Alt CoreBndr], Bool) +cleanCase rvs alts = ( map (\(a, b, c) -> Ghc.Alt a b c) $ zip3 altcs vss cores + , bool) where (altcs, vss, altesBools) = unzip3 $ - map (\(altc, vs, alte) -> + map (\(Ghc.Alt altc vs alte) -> (altc , vs , cleanUnTerms rvs alte)) alts @@ -1091,29 +1091,6 @@ mkRelCopiesWithMapping m@([], []) x1 x2 = (x1', x2', m) where (x1', x2') = mkRelCopies x1 x2 mkRelCopiesWithMapping m x1 x2 = getMapping m x1 x2 -subVarAndTys :: [(Var, Var)] -> CoreExpr -> CoreExpr -subVarAndTys xs = subTy (M.fromList xsTyVars) . sub (M.fromList xsVars) - where - xsVars = map (B.second Var) xs - xsTyVars = map (B.second TyVarTy) xs - -getMapping :: ArgMapping -> Var -> Var -> (Var, Var, ArgMapping) -getMapping m@([], []) x1 x2 = (x1, x2, m) -getMapping (x1' : xs1, x2' : xs2) x1 x2 = - ( mkCopyWithName (F.symbolString x1') x1 - , mkCopyWithName (F.symbolString x2') x2 - , (xs1, xs2) - ) -getMapping (m1, m2) x1 x2 - = F.panic $ - "getMapping " ++ F.showpp x1 ++ F.showpp x2 ++ ":" - ++ "expected the same number of args on left and right, got " ++ F.showpp m1 ++ "; " ++ F.showpp m2 - -mkRelCopiesWithMapping :: ArgMapping -> Var -> Var -> (Var, Var, ArgMapping) -mkRelCopiesWithMapping m@([], []) x1 x2 = (x1', x2', m) - where (x1', x2') = mkRelCopies x1 x2 -mkRelCopiesWithMapping m x1 x2 = getMapping m x1 x2 - mkRelCopies :: Var -> Var -> (Var, Var) mkRelCopies x1 x2 = (mkCopyWithSuffix relSuffixL x1, mkCopyWithSuffix relSuffixR x2) diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index 51cba97ada..a0a1ea8fde 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -255,9 +255,6 @@ solveCs cfg tgt cgi info names = do `addErrors` makeFailErrors (S.toList failBs) rf `addErrors` makeFailUseErrors (S.toList failBs) (giCbs $ giSrc info) let lErrors = applySolution sol <$> logErrors cgi - hErrors <- if typedHoles cfg - then synthesize tgt fcfg (cgi{holesMap = applySolution sol <$> holesMap cgi}) - else return [] when (relationalHints cfg) $ do let hintName = takeBaseName tgt ++ "_relToUn" let hintFile = replaceBaseName tgt hintName @@ -289,11 +286,12 @@ solveCs cfg tgt cgi info names = do Right hintFormatted -> writeFile hintFile (T.unpack hintFormatted) putStrLn "****** Relational Hints ********************************************************" putStrLn $ "Saved to file: " ++ hintFile - let resModel = resModel' `addErrors` (e2u cfg sol <$> (lErrors ++ hErrors ++ relWf cgi)) + let resModel = resModel' `addErrors` (e2u cfg sol <$> (lErrors ++ relWf cgi)) let out0 = mkOutput cfg resModel sol (annotMap cgi) return $ out0 { o_vars = names } { o_result = resModel } + e2u :: Config -> F.FixSolution -> Error -> UserError e2u cfg s = fmap F.pprint . tidyError cfg s @@ -340,4 +338,4 @@ splitFails fs (F.Unsafe s xs) = (mkRes r, snd <$> rfails) mkRes [] = F.Safe s mkRes ys = F.Unsafe s ys - + \ No newline at end of file diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 975938d36b..3e028ab0a2 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -102,7 +102,7 @@ fromAnf' (Let (Rec {}) _) _ = fromAnf' (Var var) bnds = (fromMaybe (Var var) (lookup var bnds), bnds) -fromAnf' (Case scr bnd _ [(GHC.DataAlt c, [x], e)]) bnds +fromAnf' (Case scr bnd _ [GHC.Alt (GHC.DataAlt c) [x] e]) bnds | c == GHC.intDataCon = fromAnf' e $ (x, scr'):bnds'' where @@ -111,8 +111,8 @@ fromAnf' (Case scr bnd _ [(GHC.DataAlt c, [x], e)]) bnds fromAnf' (Case scr bnd tp alts) bnds = (Case scr' bnd tp - (map (\(altc, xs, e) -> - (altc, xs, fst $ fromAnf' e bnds'')) alts), bnds'') + (map (\(GHC.Alt altc xs e) -> + (GHC.Alt altc xs (fst $ fromAnf' e bnds''))) alts), bnds'') where bnds'' = (bnd, scr'):bnds' (scr', bnds') = fromAnf' scr bnds @@ -321,7 +321,7 @@ data AltCon = DataAlt DataCon | DEFAULT -} pprintAlts :: RenVars -> Int -> Alt Var -> String -pprintAlts rvs i (DataAlt dataCon, vs, e) +pprintAlts rvs i (GHC.Alt (DataAlt dataCon) vs e) = "\n" ++ indent i ++ elCase ++ pprintBody' rvs (i + newIndent) e @@ -433,14 +433,14 @@ varsCB (GHC.Rec _) _ = notrace " [ symbolToVarCB ] Rec " [] varsE :: GHC.CoreExpr -> [Var] varsE (GHC.Lam a e) = a : varsE e varsE (GHC.Let (GHC.NonRec b _) e) = b : varsE e -varsE (GHC.Case _ b _ alts) = foldr (\(_, vars, e) res -> vars ++ varsE e ++ res) [b] alts +varsE (GHC.Case _ b _ alts) = foldr (\(GHC.Alt _ vars e) res -> vars ++ varsE e ++ res) [b] alts varsE (GHC.Tick _ e) = varsE e varsE _ = [] caseVarsE :: GHC.CoreExpr -> [Var] caseVarsE (GHC.Lam _ e) = caseVarsE e caseVarsE (GHC.Let (GHC.NonRec _ _) e) = caseVarsE e -caseVarsE (GHC.Case _ b _ alts) = foldr (\(_, _, e) res -> caseVarsE e ++ res) [b] alts +caseVarsE (GHC.Case _ b _ alts) = foldr (\(GHC.Alt _ _ e) res -> caseVarsE e ++ res) [b] alts caseVarsE (GHC.Tick _ e) = caseVarsE e caseVarsE _ = [] From 71c0625cc7a7a243dd476b6cf3d3d18ca71b8909 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 28 Mar 2023 16:23:03 +0200 Subject: [PATCH 183/219] review merge --- .github/workflows/hlint.yml | 7 ++----- src/Language/Haskell/Liquid/Liquid.hs | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/hlint.yml b/.github/workflows/hlint.yml index f815a094ae..7e198862fe 100644 --- a/.github/workflows/hlint.yml +++ b/.github/workflows/hlint.yml @@ -7,12 +7,9 @@ on: jobs: build: name: hlint - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - - name: fix ncurses version - run: sudo apt-get install libncurses5 - - uses: actions/checkout@v3 with: submodules: true @@ -20,7 +17,7 @@ jobs: - uses: haskell/actions/hlint-setup@v2 name: Set up HLint with: - version: "3.4" + version: "3.4" - uses: haskell/actions/hlint-run@v2 name: hlint diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index a0a1ea8fde..f8ab8544eb 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -338,4 +338,4 @@ splitFails fs (F.Unsafe s xs) = (mkRes r, snd <$> rfails) mkRes [] = F.Safe s mkRes ys = F.Unsafe s ys - \ No newline at end of file + From d6604f6bd70b98b5effe63ee73e3a0dafef6e714 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 29 Mar 2023 22:29:52 +0200 Subject: [PATCH 184/219] update fixpoint version --- liquid-fixpoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquid-fixpoint b/liquid-fixpoint index ab9ee7e85c..0d08484369 160000 --- a/liquid-fixpoint +++ b/liquid-fixpoint @@ -1 +1 @@ -Subproject commit ab9ee7e85c22a951c99bd4dd6bbb7f52d197fdd4 +Subproject commit 0d08484369589bc92b9f3817c1a7e415ebe66431 From a51d9ae9e49ce8fffe9529093569f9750d14005d Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 29 Mar 2023 22:36:35 +0200 Subject: [PATCH 185/219] fix hlint --- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 3e028ab0a2..a23eee3ec1 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -112,7 +112,7 @@ fromAnf' (Case scr bnd _ [GHC.Alt (GHC.DataAlt c) [x] e]) bnds fromAnf' (Case scr bnd tp alts) bnds = (Case scr' bnd tp (map (\(GHC.Alt altc xs e) -> - (GHC.Alt altc xs (fst $ fromAnf' e bnds''))) alts), bnds'') + GHC.Alt altc xs (fst $ fromAnf' e bnds'')) alts), bnds'') where bnds'' = (bnd, scr'):bnds' (scr', bnds') = fromAnf' scr bnds From d74e120fcdea8c7765e82e553a04817cb2a3363b Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 30 Mar 2023 12:07:18 +0200 Subject: [PATCH 186/219] update ci script --- .github/workflows/haskell.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index d51c7ed948..3f9ba123ef 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -21,7 +21,7 @@ jobs: - uses: freckle/stack-cache-action@main - uses: actions/setup-haskell@v1 with: - ghc-version: '8.10.3' + ghc-version: '9.2.5' enable-stack: true stack-version: 'latest' @@ -45,7 +45,9 @@ jobs: shell: bash - name: Test Non-Relational run: | + stack --no-terminal --stack-yaml stack.yaml clean + mkdir -p /tmp/junit/stack stack --no-terminal --stack-yaml stack.yaml run test-driver stack --no-terminal --stack-yaml stack.yaml test tests:tasty - stack --no-terminal --stack-yaml stack.yaml test -j1 liquidhaskell:liquidhaskell-parser --flag liquidhaskell:devel + stack --no-terminal --stack-yaml stack.yaml test -j1 liquidhaskell:liquidhaskell-parser << parameters.extra_build_flags >> From 78f3f2680555f3ffbbbc587638b1d1450567025e Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 30 Mar 2023 13:32:46 +0200 Subject: [PATCH 187/219] revert ghc version --- .github/workflows/haskell.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 3f9ba123ef..9505be16c3 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -21,7 +21,7 @@ jobs: - uses: freckle/stack-cache-action@main - uses: actions/setup-haskell@v1 with: - ghc-version: '9.2.5' + ghc-version: '8.10.7' enable-stack: true stack-version: 'latest' @@ -42,12 +42,4 @@ jobs: chmod +x ./tests/relational/rtest ./tests/relational/rtest ./tests/relational/rtest - shell: bash - - name: Test Non-Relational - run: | - stack --no-terminal --stack-yaml stack.yaml clean - mkdir -p /tmp/junit/stack - stack --no-terminal --stack-yaml stack.yaml run test-driver - stack --no-terminal --stack-yaml stack.yaml test tests:tasty - stack --no-terminal --stack-yaml stack.yaml test -j1 liquidhaskell:liquidhaskell-parser << parameters.extra_build_flags >> - + shell: bash \ No newline at end of file From 032db24f18dc2bc472aed034a31cae37f9910665 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 3 Apr 2023 13:21:45 +0200 Subject: [PATCH 188/219] update ghc version in Haskell CI --- .github/workflows/haskell.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 9505be16c3..a3790413d3 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -19,9 +19,9 @@ jobs: with: submodules: recursive - uses: freckle/stack-cache-action@main - - uses: actions/setup-haskell@v1 + - uses: actions/setup-haskell@v2 with: - ghc-version: '8.10.7' + ghc-version: '9.2.5' enable-stack: true stack-version: 'latest' From 0d340aebdba71497e2b8fd1cfa470bbf2881ba89 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 3 Apr 2023 13:25:44 +0200 Subject: [PATCH 189/219] switch to mainained haskell setup CI --- .github/workflows/haskell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index a3790413d3..00fc439b7f 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -19,7 +19,7 @@ jobs: with: submodules: recursive - uses: freckle/stack-cache-action@main - - uses: actions/setup-haskell@v2 + - uses: haskell/actions/setup@v2 with: ghc-version: '9.2.5' enable-stack: true From a554a054932de6473f8c2dd8440164d54fc183fd Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Mon, 3 Apr 2023 14:20:52 +0200 Subject: [PATCH 190/219] remove CI that used liquid binary --- .github/workflows/haskell.yml | 45 ----------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 .github/workflows/haskell.yml diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml deleted file mode 100644 index 00fc439b7f..0000000000 --- a/.github/workflows/haskell.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: stack install & run examples - -on: - push: - branches: '**' - pull_request: - branches: '**' - -permissions: - contents: read - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - uses: freckle/stack-cache-action@main - - uses: haskell/actions/setup@v2 - with: - ghc-version: '9.2.5' - enable-stack: true - stack-version: 'latest' - - - name: Install Z3 - run: | - wget https://github.com/Z3Prover/z3/releases/download/z3-4.9.1/z3-4.9.1-x64-glibc-2.31.zip - unzip z3-4.9.1-x64-glibc-2.31.zip - rm -f z3-4.9.1-x64-glibc-2.31.zip - sudo cp z3-4.9.1-x64-glibc-2.31/bin/libz3.a /usr/local/lib - sudo cp z3-4.9.1-x64-glibc-2.31/bin/z3 /usr/local/bin - sudo cp z3-4.9.1-x64-glibc-2.31/include/* /usr/local/include - rm -rf z3-4.9.1-x64-glibc-2.31 - z3 --version - - name: Build - run: stack setup && stack install - - name: Test Relational - run: | - chmod +x ./tests/relational/rtest - ./tests/relational/rtest - ./tests/relational/rtest - shell: bash \ No newline at end of file From 1e49c602663609f09a4d767f0f65f01added0135 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 4 Apr 2023 12:10:38 +0200 Subject: [PATCH 191/219] upd stack --- stack.yaml.lock | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/stack.yaml.lock b/stack.yaml.lock index a3456d5945..ef98059d77 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -18,6 +18,20 @@ packages: size: 4018 original: hackage: rest-rewrite-0.4.0 +- completed: + hackage: smtlib-backends-0.3@sha256:917d88540a9ede7beedbe2ed13b492acddbce394d30ccf5d0ef4f4fba9aa2c12,1157 + pantry-tree: + sha256: 59b578ae7df155a6c73a513358370747e3cc6229ebb44adaba9e0935f811539c + size: 275 + original: + hackage: smtlib-backends-0.3 +- completed: + hackage: smtlib-backends-process-0.3@sha256:d4d7d02859383e0a43db2d8ce7ef01deffe1bcd356b2ff8626925c3a1c8db922,1600 + pantry-tree: + sha256: d7d8ec52d07f4a59614000fd93d77b109d085d58f2d96e2c4b972f541c4e8287 + size: 461 + original: + hackage: smtlib-backends-process-0.3 - completed: commit: 45ef3498e35897712bde8e002ce18df6d55f8b15 git: https://github.com/qnikst/ghc-timings-report From f2a8990362d81f34fba41754cd8e8eb099826604 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 4 Apr 2023 13:55:16 +0200 Subject: [PATCH 192/219] upperbound ormolu --- liquidhaskell.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index e7527f7d74..2e195305de 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -161,6 +161,7 @@ library , mtl >= 2.1 , optics >= 0.2 , optparse-applicative < 0.18 + , ormolu < 0.5.1 , githash , megaparsec >= 8 , pretty >= 1.1 @@ -178,7 +179,6 @@ library , recursion-schemes < 5.3 , data-fix , extra - , ormolu default-language: Haskell98 default-extensions: PatternGuards, RecordWildCards, DoAndIfThenElse ghc-options: -W -fwarn-missing-signatures From 06c735a3d686f1fa05923ae3fe662d00fd0b3571 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 5 Apr 2023 13:23:04 +0200 Subject: [PATCH 193/219] fix circle ci script cabal_900 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 984a6ad96f..260d2d6e5a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -91,7 +91,7 @@ commands: - run: name: Test building the profiling driver command: | - cabal exec -- ghc scripts/ProfilingDriver.hs + cabal exec -- ghc -hide-package ghc-lib-parser scripts/ProfilingDriver.hs stack_build_and_test: description: "Build and test the project using Stack" From eb410bf0ecf58ec9320cf72b4d34d6d2de21f878 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 5 Apr 2023 13:58:58 +0200 Subject: [PATCH 194/219] rm ormolu --- liquidhaskell.cabal | 1 - 1 file changed, 1 deletion(-) diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 2e195305de..530c83ff99 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -161,7 +161,6 @@ library , mtl >= 2.1 , optics >= 0.2 , optparse-applicative < 0.18 - , ormolu < 0.5.1 , githash , megaparsec >= 8 , pretty >= 1.1 From fec96f4a1965a653064f7b2cc2277f0417f8d608 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 5 Apr 2023 14:27:59 +0200 Subject: [PATCH 195/219] rm profiling from cabal_900 --- .circleci/config.yml | 5 ----- liquidhaskell.cabal | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 260d2d6e5a..3cae55ff37 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -88,11 +88,6 @@ commands: (liquidhaskell_datadir=$PWD cabal v2-test -j1 --project-file << parameters.project_file >> liquidhaskell:liquidhaskell-parser --flag devel --test-show-details=streaming --test-options="--xml=/tmp/junit/cabal/parser-test-results.xml") || (<>) no_output_timeout: 30m - - run: - name: Test building the profiling driver - command: | - cabal exec -- ghc -hide-package ghc-lib-parser scripts/ProfilingDriver.hs - stack_build_and_test: description: "Build and test the project using Stack" parameters: diff --git a/liquidhaskell.cabal b/liquidhaskell.cabal index 530c83ff99..0008374495 100644 --- a/liquidhaskell.cabal +++ b/liquidhaskell.cabal @@ -161,6 +161,7 @@ library , mtl >= 2.1 , optics >= 0.2 , optparse-applicative < 0.18 + , ormolu , githash , megaparsec >= 8 , pretty >= 1.1 From bcdfc84b4201fb42514f1fb6a9c22ab1604ff556 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 6 Apr 2023 17:17:08 +0200 Subject: [PATCH 196/219] upd relational tests --- .circleci/config.yml | 14 + tests/relational/neg/AppNull.hs | 2 +- tests/relational/neg/Fib.hs | 4 +- tests/relational/neg/FunReft.hs | 2 +- tests/relational/neg/IncrLet.hs | 2 +- tests/relational/neg/Null.hs | 2 +- tests/relational/neg/PolyNull.hs | 4 +- tests/relational/neg/Prims.hs | 2 +- tests/relational/neg/Rec.hs | 2 +- tests/relational/pos/Abs_relToUn.hs | 9 + tests/relational/pos/ApSum.hs | 2 +- tests/relational/pos/AppNull.hs | 4 +- tests/relational/pos/BuiltInFib.hs | 2 +- tests/relational/pos/BuiltInNull.hs | 9 +- tests/relational/pos/Fib.hs | 4 +- tests/relational/pos/FunReft.hs | 2 +- tests/relational/pos/IncrF.hs | 2 +- tests/relational/pos/IncrLet.hs | 6 +- tests/relational/pos/Map.hs | 3 +- tests/relational/pos/Max.hs | 2 +- tests/relational/pos/Null.hs | 5 +- tests/relational/pos/PMonad.hs | 1 + tests/relational/pos/PolyNull.hs | 7 +- tests/relational/pos/Prims.hs | 2 +- tests/relational/pos/R2Dcounting_relToUn.hs | 52 ++++ .../pos/RConstantTimeComparison_relToUn.hs | 260 ++++++++++++++++++ tests/relational/pos/RIncr_relToUn.hs | 54 ++++ tests/relational/pos/RMap_relToUn.hs | 90 ++++++ tests/relational/pos/RVar_relToUn.hs | 20 ++ tests/relational/pos/Rec.hs | 2 +- tests/relational/pos/RecNonFunc.hs | 2 +- tests/relational/pos/SumType.hs | 5 +- tests/relational/pos/TrdOrdPredNonRel.hs | 2 + tests/relational/pos/UnaryVsRelational.hs | 2 +- tests/relational/rtest | 12 +- tests/tests.cabal | 54 +++- 36 files changed, 610 insertions(+), 39 deletions(-) create mode 100644 tests/relational/pos/Abs_relToUn.hs create mode 100644 tests/relational/pos/R2Dcounting_relToUn.hs create mode 100644 tests/relational/pos/RConstantTimeComparison_relToUn.hs create mode 100644 tests/relational/pos/RIncr_relToUn.hs create mode 100644 tests/relational/pos/RMap_relToUn.hs create mode 100644 tests/relational/pos/RVar_relToUn.hs diff --git a/.circleci/config.yml b/.circleci/config.yml index 3cae55ff37..89f6609913 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -80,6 +80,11 @@ commands: command: | mkdir -p /tmp/junit/cabal << parameters.setup_test_extra_steps >> + - run: + name: Test Relational + command: | + LIQUID_CABAL_PROJECT_FILE=<> cabal v2-run --project-file << parameters.project_file >> tests:test-driver -- relational-pos relational-neg || (<>) + no_output_timeout: 30m - run: name: Test command: | @@ -146,6 +151,14 @@ commands: jobs: + relational: + machine: + image: ubuntu-2004:202107-02 + steps: + - relational_tests: + stack_yaml_file: "stack.yaml" + extra_build_flags: "--flag liquidhaskell:devel" + extra_test_flags: " liquid-platform:liquidhaskell " stack_900: machine: image: ubuntu-2004:202107-02 @@ -168,5 +181,6 @@ workflows: version: 2 build_stack_and_cabal: jobs: + - relational - stack_900 - cabal_900 diff --git a/tests/relational/neg/AppNull.hs b/tests/relational/neg/AppNull.hs index c2ab7eb201..ba8485f82a 100644 --- a/tests/relational/neg/AppNull.hs +++ b/tests/relational/neg/AppNull.hs @@ -1,5 +1,5 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module AppNull where import Prelude hiding ( null ) diff --git a/tests/relational/neg/Fib.hs b/tests/relational/neg/Fib.hs index 3291a9aed6..c4cde44381 100644 --- a/tests/relational/neg/Fib.hs +++ b/tests/relational/neg/Fib.hs @@ -1,5 +1,5 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module Fib where data N = Z | S N @@ -16,7 +16,7 @@ leq _ Z = False leq (S n) (S m) = leq n m {-@ relational fib ~ fib :: {n1:_ -> _ ~ n2:_ -> _ - | Fixme.leq n1 n2 :=> r1 < r2 }@-} + | Fib.leq n1 n2 :=> r1 < r2 }@-} diff --git a/tests/relational/neg/FunReft.hs b/tests/relational/neg/FunReft.hs index 978498282c..288cc2c800 100644 --- a/tests/relational/neg/FunReft.hs +++ b/tests/relational/neg/FunReft.hs @@ -1,5 +1,5 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module FunReft where {-@ foo :: { v:(x1:Int -> Int) | x1 /= x1 } @-} foo :: Int -> Int diff --git a/tests/relational/neg/IncrLet.hs b/tests/relational/neg/IncrLet.hs index 5f69c561b7..ef78ee19d4 100644 --- a/tests/relational/neg/IncrLet.hs +++ b/tests/relational/neg/IncrLet.hs @@ -1,5 +1,5 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module IncrLet where incr :: Int -> Int incr = let one = 1 in (+ one) diff --git a/tests/relational/neg/Null.hs b/tests/relational/neg/Null.hs index 78c74f8f29..fc02fdd3c7 100644 --- a/tests/relational/neg/Null.hs +++ b/tests/relational/neg/Null.hs @@ -1,5 +1,5 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module Null where import Prelude hiding ( null ) diff --git a/tests/relational/neg/PolyNull.hs b/tests/relational/neg/PolyNull.hs index c04172a824..289ada15d5 100644 --- a/tests/relational/neg/PolyNull.hs +++ b/tests/relational/neg/PolyNull.hs @@ -1,12 +1,12 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module PolyNull where import Prelude hiding ( null ) data List a = Nil | Cons a (List a) {-@ measure size @-} -{-@ size :: l:List a -> {v:Nat | ((v == 0) <=> (is$Fixme.Nil l)) } @-} +{-@ size :: l:List a -> {v:Nat | ((v == 0) <=> (is$PolyNull.Nil l)) } @-} size :: List a -> Int size Nil = 0 size (Cons _ xs) = 1 + size xs diff --git a/tests/relational/neg/Prims.hs b/tests/relational/neg/Prims.hs index 9b2785b534..a574ce9114 100644 --- a/tests/relational/neg/Prims.hs +++ b/tests/relational/neg/Prims.hs @@ -1,5 +1,5 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module Prims where i :: Int i = 0 diff --git a/tests/relational/neg/Rec.hs b/tests/relational/neg/Rec.hs index dc67d607c2..22b14eca0b 100644 --- a/tests/relational/neg/Rec.hs +++ b/tests/relational/neg/Rec.hs @@ -1,5 +1,5 @@ {-@ LIQUID "--expect-any-error" @-} -module Fixme where +module Rec where f :: Int -> Int f x = if x <= 0 then 0 else 1 + f (x - 1) diff --git a/tests/relational/pos/Abs_relToUn.hs b/tests/relational/pos/Abs_relToUn.hs new file mode 100644 index 0000000000..9ff2b651a5 --- /dev/null +++ b/tests/relational/pos/Abs_relToUn.hs @@ -0,0 +1,9 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module Abs_relToUn (module Abs_relToUn) where + +import Abs +import GHC.Classes +import GHC.Types +import Prelude diff --git a/tests/relational/pos/ApSum.hs b/tests/relational/pos/ApSum.hs index 6d2c78431e..a7e2b94bad 100644 --- a/tests/relational/pos/ApSum.hs +++ b/tests/relational/pos/ApSum.hs @@ -1,4 +1,4 @@ -module Fixme where +module ApSum where apsum :: Int -> Int -> Int apsum n a = if n <= 0 then a else a + n + apsum (n - 1) a diff --git a/tests/relational/pos/AppNull.hs b/tests/relational/pos/AppNull.hs index 690be9748d..13559f6134 100644 --- a/tests/relational/pos/AppNull.hs +++ b/tests/relational/pos/AppNull.hs @@ -1,4 +1,6 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} + +module AppNull where import Prelude hiding ( null ) diff --git a/tests/relational/pos/BuiltInFib.hs b/tests/relational/pos/BuiltInFib.hs index 105f5b70d7..becd8eaba4 100644 --- a/tests/relational/pos/BuiltInFib.hs +++ b/tests/relational/pos/BuiltInFib.hs @@ -1,4 +1,4 @@ -module Fixme where +module BuiltInFib where fib :: Int -> Int fib x | x <= 1 = 1 diff --git a/tests/relational/pos/BuiltInNull.hs b/tests/relational/pos/BuiltInNull.hs index 2060e3af3d..d6648a9309 100644 --- a/tests/relational/pos/BuiltInNull.hs +++ b/tests/relational/pos/BuiltInNull.hs @@ -1,4 +1,7 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module BuiltInNull where {-@ reflect null' @-} null' :: [Int] -> Bool @@ -6,5 +9,5 @@ null' [] = True null' _ = False {-@ relational null' ~ null' :: { l1:_ -> _ - ~ l2:_ -> _ - | len l1 = len l2 :=> Fixme.null' l1 = Fixme.null' l2 }@-} + ~ l2:_ -> _ + | len l1 = len l2 :=> BuiltInNull.null' l1 = BuiltInNull.null' l2 } @-} diff --git a/tests/relational/pos/Fib.hs b/tests/relational/pos/Fib.hs index 94284161b5..eec8161ab1 100644 --- a/tests/relational/pos/Fib.hs +++ b/tests/relational/pos/Fib.hs @@ -1,4 +1,6 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} + +module Fib where data N = Z | S N diff --git a/tests/relational/pos/FunReft.hs b/tests/relational/pos/FunReft.hs index d63128d599..0a3dbecaf8 100644 --- a/tests/relational/pos/FunReft.hs +++ b/tests/relational/pos/FunReft.hs @@ -1,4 +1,4 @@ -module Fixme where +module FunReft where {-@ foo :: { v:(x1:Int -> Int) | x1 == x1 } @-} foo :: Int -> Int diff --git a/tests/relational/pos/IncrF.hs b/tests/relational/pos/IncrF.hs index b3877a858e..2e50da85eb 100644 --- a/tests/relational/pos/IncrF.hs +++ b/tests/relational/pos/IncrF.hs @@ -1,5 +1,5 @@ -module Fixme where +module IncrF where {-@ add :: x:Int -> y:Int -> {v:Int|v = x + y} @-} add :: Int -> Int -> Int diff --git a/tests/relational/pos/IncrLet.hs b/tests/relational/pos/IncrLet.hs index 1312c95fa4..073508c617 100644 --- a/tests/relational/pos/IncrLet.hs +++ b/tests/relational/pos/IncrLet.hs @@ -1,4 +1,6 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} + +module IncrLet where import GHC.Types @@ -14,7 +16,7 @@ incr = plus 1 ~ x2:Int -> Int | x1 < x2 :=> r1 x1 < r2 x2 } @-} --- {-@ relIncrIncr_rtt :: x1:GHC.Types.Int -> x2:{VV : GHC.Types.Int | x1 < x2} -> {VV : () | Fixme.incr x1 < Fixme.incr x2} @-} +-- {-@ relIncrIncr_rtt :: x1:GHC.Types.Int -> x2:{VV : GHC.Types.Int | x1 < x2} -> {VV : () | IncrLet.incr x1 < IncrLet.incr x2} @-} -- relIncrIncr_rtt :: GHC.Types.Int -> GHC.Types.Int -> () -- relIncrIncr_rtt = () (() () ()) (() () ()) diff --git a/tests/relational/pos/Map.hs b/tests/relational/pos/Map.hs index fb3bea7d7f..c08472f5a7 100644 --- a/tests/relational/pos/Map.hs +++ b/tests/relational/pos/Map.hs @@ -1,4 +1,5 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +module Map where import Prelude hiding ( map ) diff --git a/tests/relational/pos/Max.hs b/tests/relational/pos/Max.hs index 80da7d9a07..88a0c4445e 100644 --- a/tests/relational/pos/Max.hs +++ b/tests/relational/pos/Max.hs @@ -1,4 +1,4 @@ -module Fixme where +module Max where max :: Int -> Int -> Int max a b = if a < b then b else a diff --git a/tests/relational/pos/Null.hs b/tests/relational/pos/Null.hs index 296f5ef0a1..68d7774bbf 100644 --- a/tests/relational/pos/Null.hs +++ b/tests/relational/pos/Null.hs @@ -1,4 +1,7 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module Null where import Prelude hiding ( null ) diff --git a/tests/relational/pos/PMonad.hs b/tests/relational/pos/PMonad.hs index 99f0f4c681..6613ab49d8 100644 --- a/tests/relational/pos/PMonad.hs +++ b/tests/relational/pos/PMonad.hs @@ -1,3 +1,4 @@ +{-@ LIQUID "--reflection" @-} {-@ LIQUID "--no-totality" @-} module PMonad where diff --git a/tests/relational/pos/PolyNull.hs b/tests/relational/pos/PolyNull.hs index 64e7063b6a..5767458134 100644 --- a/tests/relational/pos/PolyNull.hs +++ b/tests/relational/pos/PolyNull.hs @@ -1,11 +1,12 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +module PolyNull where import Prelude hiding ( null ) data List a = Nil | Cons a (List a) {-@ measure size @-} -{-@ size :: l:List a -> {v:Nat | ((v == 0) <=> (is$Fixme.Nil l)) } @-} +{-@ size :: l:List a -> {v:Nat | ((v == 0) <=> (is$PolyNull.Nil l)) } @-} size :: List a -> Int size Nil = 0 size (Cons _ xs) = 1 + size xs @@ -17,4 +18,4 @@ null _ = False {-@ relational null ~ null :: { l1:List a -> Bool ~ l2:List b -> Bool - | Fixme.size l1 == Fixme.size l2 :=> r1 l1 == r2 l2 } @-} + | PolyNull.size l1 == PolyNull.size l2 :=> r1 l1 == r2 l2 } @-} diff --git a/tests/relational/pos/Prims.hs b/tests/relational/pos/Prims.hs index 4e075be2c8..268b846472 100644 --- a/tests/relational/pos/Prims.hs +++ b/tests/relational/pos/Prims.hs @@ -1,4 +1,4 @@ -module Fixme where +module Prims where s :: Int s = 0 diff --git a/tests/relational/pos/R2Dcounting_relToUn.hs b/tests/relational/pos/R2Dcounting_relToUn.hs new file mode 100644 index 0000000000..795fe50d57 --- /dev/null +++ b/tests/relational/pos/R2Dcounting_relToUn.hs @@ -0,0 +1,52 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module R2Dcounting_relToUn (module R2Dcounting_relToUn) where + +import GHC.Classes +import GHC.Types +import Language.Haskell.Liquid.ProofCombinators +import R2Dcounting +import RTick +import Prelude + +{- HLINT ignore "Use camelCase" -} +{-@ count2Df1Count2Df2Theorem :: p1:(lq_tmp$db##0:[GHC.Types.Int] -> GHC.Types.Bool) -> p2:(lq_tmp$db##6:[GHC.Types.Int] -> GHC.Types.Bool) -> p1p2Lemma:(lq_tmp$db##0:[GHC.Types.Int] -> lq_tmp$db##6:[GHC.Types.Int] -> lq_tmp$db##0lq_tmp$db##6Lemma:() -> ()) -> e1:GHC.Types.Int -> e2:GHC.Types.Int -> e1e2Lemma:{VV : () | e1 == e2 + && p1 == p2} -> l1:[[GHC.Types.Int]] -> l2:[[GHC.Types.Int]] -> l1l2Lemma:{VV : () | l1 == l2} -> {VV : () | RTick.tcost (R2Dcounting.count2Df1 p1 e1 l1) <= RTick.tcost (R2Dcounting.count2Df2 p2 e2 l2)} @-} +count2Df1Count2Df2Theorem :: ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> [GHC.Types.Int] -> () -> ()) -> GHC.Types.Int -> GHC.Types.Int -> () -> [[GHC.Types.Int]] -> [[GHC.Types.Int]] -> () -> () +count2Df1Count2Df2Theorem p1 p2 p1p2Lemma e1 e2 e1e2Lemma l1 l2 l1l2Lemma = + ( ( ( {- GOAL: RTick.return ~ RTick.return -} + (\_ _ _ -> ()) + ) + 0 + ) + 0 + ) + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 0 + ) + 0 + ) + ( {- GOAL: 0 ~ 0 -} + (const ((const ()) 0)) 0 + ) + ) + +{- BARE CORE +\ _ [Occ=Dead] + _ [Occ=Dead] + _ [Occ=Dead] + _ [Occ=Dead] + _ [Occ=Dead] + _ [Occ=Dead] + _ [Occ=Dead] + _ [Occ=Dead] + _ [Occ=Dead] -> + (src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + (GHC.Types.I# 0#) + (GHC.Types.I# 0#) + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) +-} diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs new file mode 100644 index 0000000000..7a403bfe1a --- /dev/null +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -0,0 +1,260 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module RConstantTimeComparison_relToUn ( module RConstantTimeComparison_relToUn) where +import RTick +import Lists +import Prelude +import Language.Haskell.Liquid.ProofCombinators +import Erasure +import RConstantTimeComparison +import GHC.Types +import GHC.Classes +{- HLINT ignore "Use camelCase" -} +{-@ compCompTheorem :: xs1:[RConstantTimeComparison.Bit] -> xs2:[RConstantTimeComparison.Bit] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> ys1:[RConstantTimeComparison.Bit] -> ys2:[RConstantTimeComparison.Bit] -> ys1ys2Lemma:{VV : () | Lists.length xs1 == Lists.length ys1 + && Lists.length xs1 == Lists.length ys2} -> {VV : () | RTick.tcost (RConstantTimeComparison.comp xs1 ys1) == RTick.tcost (RConstantTimeComparison.comp xs1 ys2)} @-} +compCompTheorem :: [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> () +compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of + [] -> case xs2 of + [] -> ((({- GOAL: RTick.return ~ RTick.return -} + (\_ _ _ -> ())) True) True) ({- GOAL: True ~ True -} + (const ((const ()) True)) True) + (:) x2 xs2 -> {- GOAL: RTick.return True ~ () -} () + (:) x1 xs1 -> case xs2 of + [] -> {- GOAL: () ~ RTick.return True -} () + (:) x2 xs2 -> case ys1 of + [] -> case ys2 of + [] -> case (patError) "relational/pos/RConstantTimeComparison.hs:(33,1)-(35,31)|function comp"# of + (:) y2 ys2 -> {- GOAL: () ~ let ds = (RConstantT (...) -} () + (:) y1 ys1 -> case ys2 of + [] -> {- GOAL: let ds = (RConstantT (...) ~ () -} () + (:) y2 ys2 -> let ds1 = (RConstantTimeComparison.comp xs1) ys1 in + let ds2 = (RConstantTimeComparison.comp xs2) ys2 in + let ds1ds2Lemma = (((((compCompTheorem xs1) xs2) ({- GOAL: xs1 ~ xs2 -} + (const ((const ()) xs1)) xs2)) ys1) ys2) ({- GOAL: ys1 ~ ys2 -} + (const ((const ()) ys1)) ys2) in + let m1 = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m v -> m in + let m2 = case (RConstantTimeComparison.comp xs2) ys2 of + Tick m v -> m in + let m1m2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> {- GOAL: m1 ~ m2 -} + (const ((const ()) m1)) m2 in + let v1 = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v -> v in + let v2 = case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v -> v in + let v1v2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v2 -> {- GOAL: v1 ~ v2 -} + (const ((const ()) v1)) v2 in + (((((({- GOAL: RTick.Tick ~ RTick.Tick -} + (\_ _ _ _ _ _ -> ())) (((+) (case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1)) 1)) (((+) (case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2)) 1)) ((((((({- GOAL: + ~ + -} + (\_ _ _ _ _ _ -> ())) (case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1)) (case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2)) (case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v22 -> m1m2Lemma)) 1) 1) (((({- GOAL: ~ -} + (\_ _ _ -> ())) 1) 1) ({- GOAL: 1 ~ 1 -} + (const ((const ()) 1)) 1)))) ((RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) (case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> v1))) ((RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) (case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> v2))) ((((((({- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} + (\_ _ _ _ _ _ -> ())) (((GHC.Classes.==) x1) y1)) (((GHC.Classes.==) x2) y2)) ((((((({- GOAL: GHC.Classes.== ~ GHC.Classes.== -} + (\_ _ _ _ _ _ -> ())) x1) x2) ({- GOAL: x1 ~ x2 -} + (const ((const ()) x1)) x2)) y1) y2) ({- GOAL: y1 ~ y2 -} + (const ((const ()) y1)) y2))) (case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> v1)) (case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> v2)) (case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v22 -> v1v2Lemma)) + + +{- BARE CORE +\ (xs1 :: [RConstantTimeComparison.Bit]) + (xs2 :: [RConstantTimeComparison.Bit]) + (xs1xs2Lemma :: [RConstantTimeComparison.Bit]) + (ys1 :: [RConstantTimeComparison.Bit]) + (ys2 :: [RConstantTimeComparison.Bit]) + (ys1ys2Lemma :: [RConstantTimeComparison.Bit]) -> + case xs1 of lq_anf$##72057594037927945311 { + [] -> + case xs2 of lq_anf$##72057594037927945312 { + [] -> + (src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + GHC.Types.True + GHC.Types.True + (src<.:0:0> + const (const GHC.Tuple.() GHC.Types.True) GHC.Types.True); + : x2 xs2 -> src<.:0:0> GHC.Tuple.() + }; + : x1 xs1 -> + case xs2 of lq_anf$##72057594037927945312 { + [] -> src<.:0:0> GHC.Tuple.(); + : x2 xs2 -> + case ys1 of lq_anf$##72057594037927945321 { + [] -> + case ys2 of lq_anf$##72057594037927945322 { + [] -> + case Control.Exception.Base.patError + @GHC.Types.LiftedRep + @() + "relational/pos/RConstantTimeComparison.hs:(33,1)-(35,31)|function comp"# + of lq_anf$##72057594037927945351 { + }; + : y2 ys2 -> src<.:0:0> GHC.Tuple.() + }; + : y1 ys1 -> + case ys2 of lq_anf$##72057594037927945322 { + [] -> src<.:0:0> GHC.Tuple.(); + : y2 ys2 -> + let { + ds1 :: RTick.Tick GHC.Types.Bool + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + ds1 = RConstantTimeComparison.comp xs1 ys1 } in + let { + ds2 :: RTick.Tick GHC.Types.Bool + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + ds2 = RConstantTimeComparison.comp xs2 ys2 } in + let { + ds1ds2Lemma :: RTick.Tick GHC.Types.Bool + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] + ds1ds2Lemma + = compCompTheorem + xs1 + xs2 + (src<.:0:0> const (const GHC.Tuple.() xs1) xs2) + ys1 + ys2 + (src<.:0:0> const (const GHC.Tuple.() ys1) ys2) } in + let { + m1 :: GHC.Types.Int + [LclId] + m1 + = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m v -> + m + } } in + let { + m2 :: GHC.Types.Int + [LclId] + m2 + = case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m v -> + m + } } in + let { + m1m2Lemma :: GHC.Types.Int + [LclId] + m1m2Lemma + = case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m1 v1 -> + case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + src<.:0:0> const (const GHC.Tuple.() m1) m2 + } + } } in + let { + v1 :: GHC.Types.Bool + [LclId] + v1 + = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v -> + v + } } in + let { + v2 :: GHC.Types.Bool + [LclId] + v2 + = case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v -> + v + } } in + let { + v1v2Lemma :: GHC.Types.Bool + [LclId] + v1v2Lemma + = case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v1 -> + case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m22 v2 -> + src<.:0:0> const (const GHC.Tuple.() v1) v2 + } + } } in + (src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (GHC.Types.I# 1#)) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (GHC.Types.I# 1#)) + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + m1m2Lemma + } + }) + (GHC.Types.I# 1#) + (GHC.Types.I# 1#) + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#))) + (RConstantTimeComparison.and + (GHC.Classes.== x1 y1) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + })) + (RConstantTimeComparison.and + (GHC.Classes.== x2 y2) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + })) + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (GHC.Classes.== x1 y1) + (GHC.Classes.== x2 y2) + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + x1 + x2 + (src<.:0:0> const (const GHC.Tuple.() x1) x2) + y1 + y2 + (src<.:0:0> const (const GHC.Tuple.() y1) y2)) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + v1v2Lemma + } + })) + } + } + } + } +-} \ No newline at end of file diff --git a/tests/relational/pos/RIncr_relToUn.hs b/tests/relational/pos/RIncr_relToUn.hs new file mode 100644 index 0000000000..7d545e8e80 --- /dev/null +++ b/tests/relational/pos/RIncr_relToUn.hs @@ -0,0 +1,54 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module RIncr_relToUn (module RIncr_relToUn) where + +import GHC.Classes +import GHC.Types +import RIncr +import Prelude + +{- HLINT ignore "Use camelCase" -} +{-@ incrIncrTheorem :: xl:GHC.Types.Int -> xr:GHC.Types.Int -> xlxrLemma:{VV : () | xl < xr} -> {VV : () | RIncr.incr xl < RIncr.incr xr} @-} +incrIncrTheorem :: GHC.Types.Int -> GHC.Types.Int -> () -> () +incrIncrTheorem xl xr xlxrLemma = + ( ( ( ( ( ( {- GOAL: + ~ + -} + (\_ _ _ _ _ _ -> ()) + ) + xl + ) + xr + ) + xlxrLemma + ) + 1 + ) + 1 + ) + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 1 + ) + 1 + ) + ( {- GOAL: 1 ~ 1 -} + (const ((const ()) 1)) 1 + ) + ) + +{- BARE CORE +\ (xl :: GHC.Types.Int) + (xr :: GHC.Types.Int) + (xlxrLemma :: GHC.Types.Int) -> + (src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + xl + xr + xlxrLemma + (GHC.Types.I# 1#) + (GHC.Types.I# 1#) + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#)) +-} diff --git a/tests/relational/pos/RMap_relToUn.hs b/tests/relational/pos/RMap_relToUn.hs new file mode 100644 index 0000000000..c85fc3689a --- /dev/null +++ b/tests/relational/pos/RMap_relToUn.hs @@ -0,0 +1,90 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module RMap_relToUn (module RMap_relToUn) where + +import GHC.Classes +import GHC.Types +import RMap +import Prelude + +{- HLINT ignore "Use camelCase" -} +{-@ mapMapTheorem :: f1:(x1:GHC.Types.Int -> GHC.Types.Int) -> f2:(x2:GHC.Types.Int -> GHC.Types.Int) -> f1f2Lemma:(x1:GHC.Types.Int -> x2:GHC.Types.Int -> x1x2Lemma:() -> ()) -> xs1:[GHC.Types.Int] -> xs2:[GHC.Types.Int] -> xs1xs2Lemma:{VV : () | len xs1 == len xs2} -> {VV : () | len (RMap.map f1 xs1) == len (RMap.map f2 xs2)} @-} +mapMapTheorem :: (GHC.Types.Int -> GHC.Types.Int) -> (GHC.Types.Int -> GHC.Types.Int) -> (GHC.Types.Int -> GHC.Types.Int -> () -> ()) -> [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () +mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of + [] -> case xs2 of + [] -> {- GOAL: [] ~ [] -} () + (:) x2 xs2 -> + {- GOAL: [] ~ ((:) (f2 x2)) ((RMap (...) -} + (const ((const ()) [])) (((:) (f2 x2)) ((RMap.map f2) xs2)) + (:) x1 xs1 -> case xs2 of + [] -> + {- GOAL: ((:) (f1 x1)) ((RMap (...) ~ [] -} + (const ((const ()) (((:) (f1 x1)) ((RMap.map f1) xs1)))) [] + (:) x2 xs2 -> + ( ( ( ( ( ( {- GOAL: : ~ : -} + (\_ _ _ _ _ _ -> ()) + ) + (f1 x1) + ) + (f2 x2) + ) + ( ((f1f2Lemma x1) x2) + ( {- GOAL: x1 ~ x2 -} + (const ((const ()) x1)) x2 + ) + ) + ) + ((RMap.map f1) xs1) + ) + ((RMap.map f2) xs2) + ) + ( (((((mapMapTheorem f1) f2) f1f2Lemma) xs1) xs2) + ( {- GOAL: xs1 ~ xs2 -} + (const ((const ()) xs1)) xs2 + ) + ) + +{- BARE CORE +\ (f1 :: GHC.Types.Int -> GHC.Types.Int) + (f2 :: GHC.Types.Int -> GHC.Types.Int) + (f1f2Lemma :: GHC.Types.Int -> GHC.Types.Int) + (xs1 :: [GHC.Types.Int]) + (xs2 :: [GHC.Types.Int]) + (xs1xs2Lemma :: [GHC.Types.Int]) -> + case xs1 of lq_anf$##72057594037927939941 { + [] -> + case xs2 of lq_anf$##72057594037927939942 { + [] -> src<.:0:0> GHC.Tuple.(); + : x2 xs2 -> + src<.:0:0> + const + (const GHC.Tuple.() GHC.Types.[]) + (GHC.Types.: (f2 x2) (RMap.map f2 xs2)) + }; + : x1 xs1 -> + case xs2 of lq_anf$##72057594037927939942 { + [] -> + src<.:0:0> + const + (const GHC.Tuple.() (GHC.Types.: (f1 x1) (RMap.map f1 xs1))) + GHC.Types.[]; + : x2 xs2 -> + (src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (f1 x1) + (f2 x2) + (f1f2Lemma x1 x2 (src<.:0:0> const (const GHC.Tuple.() x1) x2)) + (RMap.map f1 xs1) + (RMap.map f2 xs2) + (mapMapTheorem + f1 + f2 + f1f2Lemma + xs1 + xs2 + (src<.:0:0> const (const GHC.Tuple.() xs1) xs2)) + } + } +-} diff --git a/tests/relational/pos/RVar_relToUn.hs b/tests/relational/pos/RVar_relToUn.hs new file mode 100644 index 0000000000..d230b63cd4 --- /dev/null +++ b/tests/relational/pos/RVar_relToUn.hs @@ -0,0 +1,20 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module RVar_relToUn (module RVar_relToUn) where + +import GHC.Classes +import GHC.Types +import RVar +import Prelude + +{- HLINT ignore "Use camelCase" -} +{-@ y1Y2Theorem :: {VV : () | RVar.y1 <= RVar.y2} @-} +y1Y2Theorem :: () +y1Y2Theorem = + {- GOAL: RVar.x1 ~ RVar.x2 -} + (const ((const ()) RVar.x1)) RVar.x2 + +{- BARE CORE +src<.:0:0> const (const GHC.Tuple.() RVar.x1) RVar.x2 +-} diff --git a/tests/relational/pos/Rec.hs b/tests/relational/pos/Rec.hs index 2e6ccad8eb..a3d77ffc56 100644 --- a/tests/relational/pos/Rec.hs +++ b/tests/relational/pos/Rec.hs @@ -1,4 +1,4 @@ -module Fixme where +module Rec where f :: Int -> Int f x = if x <= 0 then 0 else 1 + f (x - 1) diff --git a/tests/relational/pos/RecNonFunc.hs b/tests/relational/pos/RecNonFunc.hs index 5af0d131e0..b8f5c7da01 100644 --- a/tests/relational/pos/RecNonFunc.hs +++ b/tests/relational/pos/RecNonFunc.hs @@ -1,6 +1,6 @@ {-@ LIQUID "--no-termination" @-} -module Fixme where +module RecNonFunc where {-@ r :: Nat @-} r :: Int diff --git a/tests/relational/pos/SumType.hs b/tests/relational/pos/SumType.hs index eaf249c04c..db86d5ff68 100644 --- a/tests/relational/pos/SumType.hs +++ b/tests/relational/pos/SumType.hs @@ -1,4 +1,7 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module SumType where data D = A | B | C diff --git a/tests/relational/pos/TrdOrdPredNonRel.hs b/tests/relational/pos/TrdOrdPredNonRel.hs index 7690faf024..c4a0b8c1d5 100644 --- a/tests/relational/pos/TrdOrdPredNonRel.hs +++ b/tests/relational/pos/TrdOrdPredNonRel.hs @@ -1,3 +1,5 @@ +{-@ LIQUID "--reflection" @-} + module TrdOrdPredNonRel where {-@ reflect h @-} diff --git a/tests/relational/pos/UnaryVsRelational.hs b/tests/relational/pos/UnaryVsRelational.hs index 044e2254e6..90241c33f8 100644 --- a/tests/relational/pos/UnaryVsRelational.hs +++ b/tests/relational/pos/UnaryVsRelational.hs @@ -1,4 +1,4 @@ -module Fixme where +module UnaryVsRelational where {-@ reflect abs @-} abs :: Int -> Int diff --git a/tests/relational/rtest b/tests/relational/rtest index fe6a6d9020..721809e6f8 100755 --- a/tests/relational/rtest +++ b/tests/relational/rtest @@ -5,27 +5,29 @@ # $ chmod +x tests/relational/rtest # $ ./tests/relational/rtest +LH="env liquidhaskell_datadir=$PWD cabal v2-exec -- liquidhaskell -q --ple --reflection" + # Return code rc=0 # Test pos -for f in tests/relational/pos/* +for f in tests/relational/pos/*.hs do echo echo $f - if ! liquid $f --ple --reflection --idirs=tests/relational/pos + if ! $LH $f --idirs=tests/relational/pos then rc=1 fi done # Test neg -for f in tests/relational/neg/* +for f in tests/relational/neg/*.hs do echo echo $f - liquid $f --reflection --ple - if ! [[ $(liquid $f --reflection --ple) =~ "LIQUID: UNSAFE" ]] + $LH $f --reflection --ple + if ! [[ $($LH $f --reflection --ple) =~ "LIQUID: UNSAFE" ]] then rc=1 fi diff --git a/tests/tests.cabal b/tests/tests.cabal index ca1b0fdb69..f1c3fd74a4 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2030,18 +2030,55 @@ executable relational-pos buildable: False other-modules: - Abs + Abs_relToUn + , Abs + , AppNull + , ApSum , ApSumAsync , AsynchCase + , BuiltInFib + , BuiltInNull , CheckedImp + , Erasure + , Fib + , FunReft + , IncrF + , IncrLet + , Lists + , Map + , Max + , MutRecSame + , Null + , PMonad + , PolyNull , PredAbs + , Prims + , R2Dcounting + , RConstantTimeComparison + , Rec + , RecNonFunc + , RIncr_relToUn + , RIncr + , RMap_relToUn + , RMap + , RMemAlloc + , RPatError + , RTick + , RVar_relToUn + , RVar , SndOrdPredNonRel + , SubRef1 + , SubRef2 + , SumType + , TrdOrdPredNonRel + , UnaryVsRelational ghc-options: -fplugin=LiquidHaskell -fkeep-going -O0 if flag(measure-timings) ghc-options: -fforce-recomp -ddump-timings -ddump-to-file build-depends: liquid-base , liquid-prelude + , liquid-ghc-prim , liquid-vector , liquidhaskell @@ -2060,14 +2097,27 @@ executable relational-neg other-modules: Abs + , AppNull , ApSum , ApSumAsync , BasePredWf - , CheckedImp + , BuiltInFib , CaseOnRec + , CheckedImp + , Fib , FunBaseWf + , FunReft , HigherOrderWf + , IncrLet + , IndAssm + , Null + , PolyNull + , Prims + , Rec , SndOrdPred + , SndOrdPredNonRel + , SubRef + , SubRel ghc-options: -fplugin=LiquidHaskell -fkeep-going -O0 if flag(measure-timings) From 831d21e3f648e04a5097cb67ca26aa8f82518b02 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 6 Apr 2023 17:23:56 +0200 Subject: [PATCH 197/219] add test relational step --- .circleci/config.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 89f6609913..77bf6abbd3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -128,6 +128,12 @@ commands: paths: - ~/.stack - ./.stack-work + - run: + name: Test Relational + command: | + stack --no-terminal --stack-yaml << parameters.stack_yaml_file >> clean + stack --no-terminal --stack-yaml << parameters.stack_yaml_file >> run test-driver -- relational-pos relational-neg + no_output_timeout: 30m - run: name: Test command: | @@ -151,14 +157,6 @@ commands: jobs: - relational: - machine: - image: ubuntu-2004:202107-02 - steps: - - relational_tests: - stack_yaml_file: "stack.yaml" - extra_build_flags: "--flag liquidhaskell:devel" - extra_test_flags: " liquid-platform:liquidhaskell " stack_900: machine: image: ubuntu-2004:202107-02 @@ -181,6 +179,5 @@ workflows: version: 2 build_stack_and_cabal: jobs: - - relational - stack_900 - cabal_900 From 7586fe127a625a0b4ae0a6f070059ea588e9bfce Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 6 Apr 2023 18:00:00 +0200 Subject: [PATCH 198/219] clean terms in case srcutinee --- .../Haskell/Liquid/Constraint/Relational.hs | 19 +- .../pos/RConstantTimeComparison_relToUn.hs | 253 ++++++++++++------ tests/tests.cabal | 1 + 3 files changed, 190 insertions(+), 83 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index e469326ae4..271eade7ec 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -354,6 +354,8 @@ relTermToUnTerm' m relTerms (Lam x1 e1) (Lam x2 e2) (e1l, e2r) = subRelCopiesWithMapping m e1 x1 e2 x2 relTermToUnTerm' m relTerms (Let (NonRec x1 d1) e1) (Let (NonRec x2 d2) e2) | areCompatible d1 d2 + , not b1 + , not b2 = Let (NonRec x1l d1') $ Let (NonRec x2r d2') $ Let (NonRec relX relD) $ relTermToUnTerm' m (((x1l, x2r), Var relX) : relTerms) e1l e2r where @@ -362,8 +364,8 @@ relTermToUnTerm' m relTerms (Let (NonRec x1 d1) e1) (Let (NonRec x2 d2) e2) (x1l, x2r) = mkRelCopies x1 x2 (e1l, e2r) = subRelCopies e1 x1 e2 x2 rvs = renVars m - (d1', _) = cleanUnTerms rvs d1 - (d2', _) = cleanUnTerms rvs d2 + (d1', b1) = cleanUnTerms rvs d1 + (d2', b2) = cleanUnTerms rvs d2 -- TODO: test recursive and mutually recursive lets relTermToUnTerm' m relTerms (Let (Rec bs1) e1) (Let (Rec bs2) e2) | length bs1 == length bs2 @@ -377,12 +379,13 @@ relTermToUnTerm' m relTerms (Let (Rec bs1) e1) (Let (Rec bs2) e2) relTermsBs = zipWith (\(x1, d1) (x2, d2) -> ((x1, x2), relTermToUnTerm' m relTerms d1 d2)) bs1 bs2 relTerms' = relTermsBs ++ relTerms relBs = zipWith (\(x1, d1) (x2, d2) -> (mkRelLemmaVar x1 x2, relTermToUnTerm' m relTerms' d1 d2)) bs1 bs2 -relTermToUnTerm' m relTerms (Case d1 x1 t1 as1) (Case d2 x2 t2 as2) = - Case d1 x1l t1 $ map +relTermToUnTerm' m relTerms (Case d1 x1 t1 as1) (Case d2 x2 t2 as2) + | not b1, not b2 = + Case d1' x1l t1 $ map (\(Ghc.Alt c1 bs1 e1) -> let bs1l = map (mkCopyWithSuffix relSuffixL) bs1 in ( Ghc.Alt c1 bs1l $ - Case d2 x2r t2 $ map + Case d2' x2r t2 $ map (\(Ghc.Alt c2 bs2 e2) -> let bs2r = map (mkCopyWithSuffix relSuffixR) bs2 e1l = subVarAndTys ((x1, x1l) : zip bs1 bs1l) e1 @@ -392,7 +395,11 @@ relTermToUnTerm' m relTerms (Case d1 x1 t1 as1) (Case d2 x2 t2 as2) = as2 )) as1 - where (x1l, x2r) = mkRelCopies x1 x2 + where + (x1l, x2r) = mkRelCopies x1 x2 + rvs = renVars m + (d1', b1) = cleanUnTerms rvs d1 + (d2', b2) = cleanUnTerms rvs d2 relTermToUnTerm' m _ e1 e2 = traceWhenLoud ("relTermToUnTerm': can't proceed proof generation on e1:\n" ++ F.showpp e1 ++ "\ne2:\n" ++ F.showpp e2) $ Tick (Ghc.SourceNote realSpan info) $ diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs index 7a403bfe1a..4fcf51026c 100644 --- a/tests/relational/pos/RConstantTimeComparison_relToUn.hs +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -1,76 +1,181 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} -module RConstantTimeComparison_relToUn ( module RConstantTimeComparison_relToUn) where -import RTick -import Lists -import Prelude -import Language.Haskell.Liquid.ProofCombinators +module RConstantTimeComparison_relToUn (module RConstantTimeComparison_relToUn) where + import Erasure -import RConstantTimeComparison -import GHC.Types import GHC.Classes +import GHC.Types +import Language.Haskell.Liquid.ProofCombinators +import Lists +import RConstantTimeComparison +import RTick +import Prelude + {- HLINT ignore "Use camelCase" -} {-@ compCompTheorem :: xs1:[RConstantTimeComparison.Bit] -> xs2:[RConstantTimeComparison.Bit] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> ys1:[RConstantTimeComparison.Bit] -> ys2:[RConstantTimeComparison.Bit] -> ys1ys2Lemma:{VV : () | Lists.length xs1 == Lists.length ys1 && Lists.length xs1 == Lists.length ys2} -> {VV : () | RTick.tcost (RConstantTimeComparison.comp xs1 ys1) == RTick.tcost (RConstantTimeComparison.comp xs1 ys2)} @-} compCompTheorem :: [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> () compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of - [] -> case xs2 of - [] -> ((({- GOAL: RTick.return ~ RTick.return -} - (\_ _ _ -> ())) True) True) ({- GOAL: True ~ True -} - (const ((const ()) True)) True) - (:) x2 xs2 -> {- GOAL: RTick.return True ~ () -} () - (:) x1 xs1 -> case xs2 of - [] -> {- GOAL: () ~ RTick.return True -} () - (:) x2 xs2 -> case ys1 of - [] -> case ys2 of - [] -> case (patError) "relational/pos/RConstantTimeComparison.hs:(33,1)-(35,31)|function comp"# of - (:) y2 ys2 -> {- GOAL: () ~ let ds = (RConstantT (...) -} () - (:) y1 ys1 -> case ys2 of - [] -> {- GOAL: let ds = (RConstantT (...) ~ () -} () - (:) y2 ys2 -> let ds1 = (RConstantTimeComparison.comp xs1) ys1 in - let ds2 = (RConstantTimeComparison.comp xs2) ys2 in - let ds1ds2Lemma = (((((compCompTheorem xs1) xs2) ({- GOAL: xs1 ~ xs2 -} - (const ((const ()) xs1)) xs2)) ys1) ys2) ({- GOAL: ys1 ~ ys2 -} - (const ((const ()) ys1)) ys2) in - let m1 = case (RConstantTimeComparison.comp xs1) ys1 of - Tick m v -> m in - let m2 = case (RConstantTimeComparison.comp xs2) ys2 of - Tick m v -> m in - let m1m2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> {- GOAL: m1 ~ m2 -} - (const ((const ()) m1)) m2 in - let v1 = case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v -> v in - let v2 = case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v -> v in - let v1v2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m22 v2 -> {- GOAL: v1 ~ v2 -} - (const ((const ()) v1)) v2 in - (((((({- GOAL: RTick.Tick ~ RTick.Tick -} - (\_ _ _ _ _ _ -> ())) (((+) (case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1)) 1)) (((+) (case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2)) 1)) ((((((({- GOAL: + ~ + -} - (\_ _ _ _ _ _ -> ())) (case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1)) (case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2)) (case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m22 v22 -> m1m2Lemma)) 1) 1) (((({- GOAL: ~ -} - (\_ _ _ -> ())) 1) 1) ({- GOAL: 1 ~ 1 -} - (const ((const ()) 1)) 1)))) ((RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) (case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1))) ((RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) (case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2))) ((((((({- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} - (\_ _ _ _ _ _ -> ())) (((GHC.Classes.==) x1) y1)) (((GHC.Classes.==) x2) y2)) ((((((({- GOAL: GHC.Classes.== ~ GHC.Classes.== -} - (\_ _ _ _ _ _ -> ())) x1) x2) ({- GOAL: x1 ~ x2 -} - (const ((const ()) x1)) x2)) y1) y2) ({- GOAL: y1 ~ y2 -} - (const ((const ()) y1)) y2))) (case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1)) (case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2)) (case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m22 v22 -> v1v2Lemma)) - + [] -> case xs2 of + [] -> + ( ( ( {- GOAL: RTick.return ~ RTick.return -} + (\_ _ _ -> ()) + ) + True + ) + True + ) + ( {- GOAL: True ~ True -} + (const ((const ()) True)) True + ) + (:) x2 xs2 -> {- GOAL: RTick.return True ~ () -} () + (:) x1 xs1 -> case xs2 of + [] -> {- GOAL: () ~ RTick.return True -} () + (:) x2 xs2 -> case ys1 of + [] -> case ys2 of + [] -> {- GOAL: () ~ () -} () + (:) y2 ys2 -> {- GOAL: () ~ let ds = (RConstantT (...) -} () + (:) y1 ys1 -> case ys2 of + [] -> {- GOAL: let ds = (RConstantT (...) ~ () -} () + (:) y2 ys2 -> + let ds1 = (RConstantTimeComparison.comp xs1) ys1 + in let ds2 = (RConstantTimeComparison.comp xs2) ys2 + in let ds1ds2Lemma = + ( ( ( ((compCompTheorem xs1) xs2) + ( {- GOAL: xs1 ~ xs2 -} + (const ((const ()) xs1)) xs2 + ) + ) + ys1 + ) + ys2 + ) + ( {- GOAL: ys1 ~ ys2 -} + (const ((const ()) ys1)) ys2 + ) + in let m1 = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m v -> m + in let m2 = case (RConstantTimeComparison.comp xs2) ys2 of + Tick m v -> m + in let m1m2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> + {- GOAL: m1 ~ m2 -} + (const ((const ()) m1)) m2 + in let v1 = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v -> v + in let v2 = case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v -> v + in let v1v2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v2 -> + {- GOAL: v1 ~ v2 -} + (const ((const ()) v1)) v2 + in ( ( ( ( ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} + (\_ _ _ _ _ _ -> ()) + ) + ( ( (+) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1 + ) + ) + 1 + ) + ) + ( ( (+) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2 + ) + ) + 1 + ) + ) + ( ( ( ( ( ( ( {- GOAL: + ~ + -} + (\_ _ _ _ _ _ -> ()) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1 + ) + ) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2 + ) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v22 -> m1m2Lemma + ) + ) + 1 + ) + 1 + ) + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 1 + ) + 1 + ) + ( {- GOAL: 1 ~ 1 -} + (const ((const ()) 1)) 1 + ) + ) + ) + ) + ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> v1 + ) + ) + ) + ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> v2 + ) + ) + ) + ( ( ( ( ( ( ( {- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} + (\_ _ _ _ _ _ -> ()) + ) + (((GHC.Classes.==) x1) y1) + ) + (((GHC.Classes.==) x2) y2) + ) + ( ( ( ( ( ( ( {- GOAL: GHC.Classes.== ~ GHC.Classes.== -} + (\_ _ _ _ _ _ -> ()) + ) + x1 + ) + x2 + ) + ( {- GOAL: x1 ~ x2 -} + (const ((const ()) x1)) x2 + ) + ) + y1 + ) + y2 + ) + ( {- GOAL: y1 ~ y2 -} + (const ((const ()) y1)) y2 + ) + ) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> v1 + ) + ) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> v2 + ) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v22 -> v1v2Lemma + ) + ) {- BARE CORE \ (xs1 :: [RConstantTimeComparison.Bit]) @@ -79,9 +184,9 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of (ys1 :: [RConstantTimeComparison.Bit]) (ys2 :: [RConstantTimeComparison.Bit]) (ys1ys2Lemma :: [RConstantTimeComparison.Bit]) -> - case xs1 of lq_anf$##72057594037927945311 { + case xs1 of lq_anf$##72057594037927945861 { [] -> - case xs2 of lq_anf$##72057594037927945312 { + case xs2 of lq_anf$##72057594037927945862 { [] -> (src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) GHC.Types.True @@ -91,23 +196,17 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of : x2 xs2 -> src<.:0:0> GHC.Tuple.() }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927945312 { + case xs2 of lq_anf$##72057594037927945862 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> - case ys1 of lq_anf$##72057594037927945321 { + case ys1 of lq_anf$##72057594037927945871 { [] -> - case ys2 of lq_anf$##72057594037927945322 { - [] -> - case Control.Exception.Base.patError - @GHC.Types.LiftedRep - @() - "relational/pos/RConstantTimeComparison.hs:(33,1)-(35,31)|function comp"# - of lq_anf$##72057594037927945351 { - }; + case ys2 of lq_anf$##72057594037927945872 { + [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> src<.:0:0> GHC.Tuple.() }; : y1 ys1 -> - case ys2 of lq_anf$##72057594037927945322 { + case ys2 of lq_anf$##72057594037927945872 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> let { @@ -257,4 +356,4 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of } } } --} \ No newline at end of file +-} diff --git a/tests/tests.cabal b/tests/tests.cabal index f1c3fd74a4..081bf43225 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2054,6 +2054,7 @@ executable relational-pos , PredAbs , Prims , R2Dcounting + , RConstantTimeComparison_relToUn , RConstantTimeComparison , Rec , RecNonFunc From c2e84da742fc5adac12dee378b9b34cdf8f56eac Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 6 Apr 2023 18:14:32 +0200 Subject: [PATCH 199/219] enable no-adt for translations --- .circleci/config.yml | 12 ++- src/Language/Haskell/Liquid/Liquid.hs | 3 +- tests/relational/pos/R2Dcounting.hs | 7 +- tests/relational/pos/R2Dcounting_relToUn.hs | 2 + .../relational/pos/RConstantTimeComparison.hs | 11 ++- .../pos/RConstantTimeComparison_relToUn.hs | 19 ++--- tests/relational/pos/RIncr_relToUn.hs | 2 + tests/relational/pos/RMap_relToUn.hs | 8 +- tests/relational/pos/RMemAlloc.hs | 14 ++-- tests/relational/pos/RMemAlloc_relToUn.hs | 79 +++++++++++++++++++ tests/relational/pos/RVar_relToUn.hs | 2 + 11 files changed, 124 insertions(+), 35 deletions(-) create mode 100644 tests/relational/pos/RMemAlloc_relToUn.hs diff --git a/.circleci/config.yml b/.circleci/config.yml index 77bf6abbd3..31327853ab 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -85,6 +85,11 @@ commands: command: | LIQUID_CABAL_PROJECT_FILE=<> cabal v2-run --project-file << parameters.project_file >> tests:test-driver -- relational-pos relational-neg || (<>) no_output_timeout: 30m + - run: + name: Test Translations + command: | + LIQUID_CABAL_PROJECT_FILE=<> cabal v2-run --project-file << parameters.project_file >> tests:test-driver -- relational-pos relational-neg || (<>) + no_output_timeout: 30m - run: name: Test command: | @@ -135,9 +140,14 @@ commands: stack --no-terminal --stack-yaml << parameters.stack_yaml_file >> run test-driver -- relational-pos relational-neg no_output_timeout: 30m - run: - name: Test + name: Test Translation command: | stack --no-terminal --stack-yaml << parameters.stack_yaml_file >> clean + stack --no-terminal --stack-yaml << parameters.stack_yaml_file >> run test-driver -- relational-pos relational-neg + no_output_timeout: 30m + - run: + name: Test + command: | mkdir -p /tmp/junit/stack stack --no-terminal --stack-yaml << parameters.stack_yaml_file >> run test-driver stack --no-terminal --stack-yaml << parameters.stack_yaml_file >> test tests:tasty diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index f8ab8544eb..f0e6526dcd 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -259,7 +259,8 @@ solveCs cfg tgt cgi info names = do let hintName = takeBaseName tgt ++ "_relToUn" let hintFile = replaceBaseName tgt hintName let flags = "{-@ LIQUID \"--reflection\" @-}\n" - ++ "{-@ LIQUID \"--ple\" @-}\n\n" + ++ "{-@ LIQUID \"--ple\" @-}\n" + ++ "{-@ LIQUID \"--no-adt\" @-}\n\n" let moduleFile = "module " ++ hintName ++ " ( module " ++ hintName ++ ") where\n" let listOfImps = map (\imp -> F.symbolicString imp) (S.toList $ gsAllImps $ giSrc info) diff --git a/tests/relational/pos/R2Dcounting.hs b/tests/relational/pos/R2Dcounting.hs index b7e1a49411..4fb576ef05 100644 --- a/tests/relational/pos/R2Dcounting.hs +++ b/tests/relational/pos/R2Dcounting.hs @@ -26,11 +26,7 @@ import Prelude hiding (return, (>>=), pure, length, (<*>), fmap) --- End --- {-@ reflect count2D @-} -count2D :: (Int -> [Int] -> Tick Int) - -> ([Int] -> Bool) - -> Int - -> [[Int]] - -> Tick Int +count2D :: (Int -> [Int] -> Tick Int) -> ([Int] -> Bool) -> Int -> [[Int]] -> Tick Int count2D _ _ _ [] = return 0 count2D find p x (l:m) = count2D find p x m >>= count2D' (p l) (find x l) @@ -45,7 +41,6 @@ count2Df2 :: ([Int] -> Bool) -> Int -> [[Int]] -> Tick Int count2Df2 _ _ _ = return 0 count2Df2 p x (l:m) = count2Df2 p x m >>= count2D' (p l) (find2 x l) - {-@ reflect count2D' @-} count2D' :: Bool -> Tick Int -> Int -> Tick Int count2D' b c r = if b then fmap (plus r) c else return r diff --git a/tests/relational/pos/R2Dcounting_relToUn.hs b/tests/relational/pos/R2Dcounting_relToUn.hs index 795fe50d57..99f000e8ef 100644 --- a/tests/relational/pos/R2Dcounting_relToUn.hs +++ b/tests/relational/pos/R2Dcounting_relToUn.hs @@ -1,6 +1,8 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + module R2Dcounting_relToUn (module R2Dcounting_relToUn) where import GHC.Classes diff --git a/tests/relational/pos/RConstantTimeComparison.hs b/tests/relational/pos/RConstantTimeComparison.hs index bf6e20bb13..af1053d6b4 100644 --- a/tests/relational/pos/RConstantTimeComparison.hs +++ b/tests/relational/pos/RConstantTimeComparison.hs @@ -14,7 +14,6 @@ import Prelude hiding ( pure, return, and, fmap, length ) import RTick import Language.Haskell.Liquid.ProofCombinators import Lists -import Erasure -- -- Proving a password comparisons function adheres to the @@ -26,8 +25,8 @@ data Bit = Zero | One deriving Eq {-@ reflect comp @-} {-@ comp :: xs:[Bit] - -> { ys:[Bit] | length xs == length ys } - -> { t:Tick Bool | tcost t == length xs } + -> { ys:[Bit] | len xs == len ys } + -> { t:Tick Bool | tcost t == len xs } @-} comp :: [Bit] -> [Bit] -> Tick Bool comp [] _ = return True @@ -39,9 +38,9 @@ comp (x : xs) (y : ys) = let Tick m v = comp xs ys in :: { xs1:[Bit] -> ys1:[Bit] -> t:Tick Bool ~ xs2:[Bit] -> ys2:[Bit] -> t:Tick Bool | !(xs1 = xs2) - :=> !(Lists.length xs1 == Lists.length ys1 && Lists.length xs1 == Lists.length ys2) - :=> RTick.tcost (RConstantTimeComparison.comp xs1 ys1) - == RTick.tcost (RConstantTimeComparison.comp xs1 ys2) } @-} + :=> !(len xs1 == len ys1 && len xs1 == len ys2) + :=> RTick.tcost (r1 xs1 ys1) + == RTick.tcost (r2 xs2 ys2) } @-} --- End --- {- diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs index 4fcf51026c..c709c9e86b 100644 --- a/tests/relational/pos/RConstantTimeComparison_relToUn.hs +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -1,9 +1,10 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + module RConstantTimeComparison_relToUn (module RConstantTimeComparison_relToUn) where -import Erasure import GHC.Classes import GHC.Types import Language.Haskell.Liquid.ProofCombinators @@ -13,8 +14,8 @@ import RTick import Prelude {- HLINT ignore "Use camelCase" -} -{-@ compCompTheorem :: xs1:[RConstantTimeComparison.Bit] -> xs2:[RConstantTimeComparison.Bit] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> ys1:[RConstantTimeComparison.Bit] -> ys2:[RConstantTimeComparison.Bit] -> ys1ys2Lemma:{VV : () | Lists.length xs1 == Lists.length ys1 - && Lists.length xs1 == Lists.length ys2} -> {VV : () | RTick.tcost (RConstantTimeComparison.comp xs1 ys1) == RTick.tcost (RConstantTimeComparison.comp xs1 ys2)} @-} +{-@ compCompTheorem :: xs1:[RConstantTimeComparison.Bit] -> xs2:[RConstantTimeComparison.Bit] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> ys1:[RConstantTimeComparison.Bit] -> ys2:[RConstantTimeComparison.Bit] -> ys1ys2Lemma:{VV : () | len xs1 == len ys1 + && len xs1 == len ys2} -> {VV : () | RTick.tcost (RConstantTimeComparison.comp xs1 ys1) == RTick.tcost (RConstantTimeComparison.comp xs2 ys2)} @-} compCompTheorem :: [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> () compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of [] -> case xs2 of @@ -184,9 +185,9 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of (ys1 :: [RConstantTimeComparison.Bit]) (ys2 :: [RConstantTimeComparison.Bit]) (ys1ys2Lemma :: [RConstantTimeComparison.Bit]) -> - case xs1 of lq_anf$##72057594037927945861 { + case xs1 of lq_anf$##72057594037927946881 { [] -> - case xs2 of lq_anf$##72057594037927945862 { + case xs2 of lq_anf$##72057594037927946882 { [] -> (src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) GHC.Types.True @@ -196,17 +197,17 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of : x2 xs2 -> src<.:0:0> GHC.Tuple.() }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927945862 { + case xs2 of lq_anf$##72057594037927946882 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> - case ys1 of lq_anf$##72057594037927945871 { + case ys1 of lq_anf$##72057594037927946891 { [] -> - case ys2 of lq_anf$##72057594037927945872 { + case ys2 of lq_anf$##72057594037927946892 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> src<.:0:0> GHC.Tuple.() }; : y1 ys1 -> - case ys2 of lq_anf$##72057594037927945872 { + case ys2 of lq_anf$##72057594037927946892 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> let { diff --git a/tests/relational/pos/RIncr_relToUn.hs b/tests/relational/pos/RIncr_relToUn.hs index 7d545e8e80..4108349c22 100644 --- a/tests/relational/pos/RIncr_relToUn.hs +++ b/tests/relational/pos/RIncr_relToUn.hs @@ -1,6 +1,8 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + module RIncr_relToUn (module RIncr_relToUn) where import GHC.Classes diff --git a/tests/relational/pos/RMap_relToUn.hs b/tests/relational/pos/RMap_relToUn.hs index c85fc3689a..6db77b4e85 100644 --- a/tests/relational/pos/RMap_relToUn.hs +++ b/tests/relational/pos/RMap_relToUn.hs @@ -1,6 +1,8 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + module RMap_relToUn (module RMap_relToUn) where import GHC.Classes @@ -52,9 +54,9 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of (xs1 :: [GHC.Types.Int]) (xs2 :: [GHC.Types.Int]) (xs1xs2Lemma :: [GHC.Types.Int]) -> - case xs1 of lq_anf$##72057594037927939941 { + case xs1 of lq_anf$##72057594037927945401 { [] -> - case xs2 of lq_anf$##72057594037927939942 { + case xs2 of lq_anf$##72057594037927945402 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> src<.:0:0> @@ -63,7 +65,7 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of (GHC.Types.: (f2 x2) (RMap.map f2 xs2)) }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927939942 { + case xs2 of lq_anf$##72057594037927945402 { [] -> src<.:0:0> const diff --git a/tests/relational/pos/RMemAlloc.hs b/tests/relational/pos/RMemAlloc.hs index 62c6b99cd3..91485f082f 100644 --- a/tests/relational/pos/RMemAlloc.hs +++ b/tests/relational/pos/RMemAlloc.hs @@ -1,6 +1,6 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} -{- LIQUID "--relational-hints" @-} +{-@ LIQUID "--relational-hints" @-} module RMemAlloc where import RTick @@ -19,14 +19,9 @@ foldl' :: (Int -> Int -> Int) -> Int -> [Int] -> Tick Int foldl' _ z [] = pure z foldl' f z (x : xs) = let w = f z x in w `seq` foldl' f w xs -{-@ relational foldl ~ foldl' :: { f1:(Int -> Int -> Int) -> acc1:Int -> xs1:[Int] -> Tick Int - ~ f2:(Int -> Int -> Int) -> acc2:Int -> xs2:[Int] -> Tick Int - | true :=> f1 = f2 && acc1 = acc2 :=> xs1 = xs2 - :=> true } @-} - {-@ reflect length1 @-} length1 :: [Int] -> Tick Int -length1 = foldl' upd 0 +length1 xs = foldl' upd 0 xs {-@ reflect upd @-} upd :: Int -> Int -> Int @@ -34,12 +29,13 @@ upd x _ = x + 1 {-@ reflect length2 @-} length2 :: [Int] -> Tick Int -length2 = foldl upd 0 +length2 xs = foldl upd 0 xs {-@ relational length1 ~ length2 :: { xs1:[Int] -> Tick Int ~ xs2:[Int] -> Tick Int | xs1 = xs2 - :=> RTick.tcost (RMemAlloc.length2 xs1) - RTick.tcost (RMemAlloc.length1 xs1) = len xs1} @-} + :=> RTick.tcost (RMemAlloc.length2 xs1) + - RTick.tcost (RMemAlloc.length1 xs1) = len xs1} @-} {-@ reflect len @-} {-@ len :: [a] -> Nat @-} diff --git a/tests/relational/pos/RMemAlloc_relToUn.hs b/tests/relational/pos/RMemAlloc_relToUn.hs new file mode 100644 index 0000000000..556e1cde05 --- /dev/null +++ b/tests/relational/pos/RMemAlloc_relToUn.hs @@ -0,0 +1,79 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +{-@ LIQUID "--no-adt" @-} + +module RMemAlloc_relToUn (module RMemAlloc_relToUn) where + +import GHC.Classes +import GHC.Types +import Language.Haskell.Liquid.ProofCombinators +import RMemAlloc +import RTick +import Prelude + +{- HLINT ignore "Use camelCase" -} +{-@ length1Length2Theorem :: xs1:[GHC.Types.Int] -> xs2:[GHC.Types.Int] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> {VV : () | RTick.tcost (RMemAlloc.length2 xs1) - RTick.tcost (RMemAlloc.length1 xs1) == len xs1} @-} +length1Length2Theorem :: [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () +length1Length2Theorem xs1 xs2 xs1xs2Lemma = + ( ( ( ( ( ( ( ( ( {- GOAL: RMemAlloc.foldl' ~ RMemAlloc.foldl -} + (\_ _ _ _ _ _ _ _ _ -> ()) + ) + RMemAlloc.upd + ) + RMemAlloc.upd + ) + ( {- GOAL: RMemAlloc.upd ~ RMemAlloc.upd -} + (\_ _ _ _ _ _ -> ()) + ) + ) + 0 + ) + 0 + ) + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 0 + ) + 0 + ) + ( {- GOAL: 0 ~ 0 -} + (const ((const ()) 0)) 0 + ) + ) + ) + xs1 + ) + xs2 + ) + xs1xs2Lemma + +{- BARE CORE +\ (xs1 :: [GHC.Types.Int]) + (xs2 :: [GHC.Types.Int]) + (xs1xs2Lemma :: [GHC.Types.Int]) -> + (src<.:0:0> + \ (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) -> + GHC.Tuple.()) + RMemAlloc.upd + RMemAlloc.upd + (src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (GHC.Types.I# 0#) + (GHC.Types.I# 0#) + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) + xs1 + xs2 + xs1xs2Lemma +-} diff --git a/tests/relational/pos/RVar_relToUn.hs b/tests/relational/pos/RVar_relToUn.hs index d230b63cd4..57e7f61456 100644 --- a/tests/relational/pos/RVar_relToUn.hs +++ b/tests/relational/pos/RVar_relToUn.hs @@ -1,6 +1,8 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + module RVar_relToUn (module RVar_relToUn) where import GHC.Classes From 6169cea7c08826ae4ee4eb95617f0eeef49520ae Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 6 Apr 2023 18:14:54 +0200 Subject: [PATCH 200/219] rename todo modules --- tests/relational/todo/Ap.hs | 4 +++- tests/relational/todo/AssumeRelational.hs | 2 ++ tests/relational/todo/Bsplit.hs | 3 ++- tests/relational/todo/CaseOnRec.hs | 2 +- tests/relational/todo/DeltaSort.hs | 1 + tests/relational/todo/Example.hs | 1 + tests/relational/todo/FibLet.hs | 1 + tests/relational/todo/Filter.hs | 1 + tests/relational/todo/IncrF.hs | 2 +- tests/relational/todo/IncrHO.hs | 3 ++- tests/relational/todo/IncrVeryHO.hs | 1 + tests/relational/todo/Incr_.hs | 2 +- tests/relational/todo/IsZero.hs | 3 +++ tests/relational/todo/Map.hs | 3 ++- 14 files changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/relational/todo/Ap.hs b/tests/relational/todo/Ap.hs index 66f079fba4..4823b1441e 100644 --- a/tests/relational/todo/Ap.hs +++ b/tests/relational/todo/Ap.hs @@ -1,4 +1,6 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} + +module Ap where {-@ reflect ap @-} ap :: (Int -> Int) -> Int -> Int diff --git a/tests/relational/todo/AssumeRelational.hs b/tests/relational/todo/AssumeRelational.hs index 8b9ad55bee..51113e3377 100644 --- a/tests/relational/todo/AssumeRelational.hs +++ b/tests/relational/todo/AssumeRelational.hs @@ -1,3 +1,5 @@ +{-@ LIQUID "--reflection" @-} + module AssumeRelational where update :: Int -> Int -> Int diff --git a/tests/relational/todo/Bsplit.hs b/tests/relational/todo/Bsplit.hs index c42c88be87..479b416835 100644 --- a/tests/relational/todo/Bsplit.hs +++ b/tests/relational/todo/Bsplit.hs @@ -1,4 +1,5 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +module Bsplit where {-@ data Tick a = T { res :: a, time :: Int} @-} data Tick a = T { res :: a, time :: Int} diff --git a/tests/relational/todo/CaseOnRec.hs b/tests/relational/todo/CaseOnRec.hs index 75ae07ce52..61d8966dba 100644 --- a/tests/relational/todo/CaseOnRec.hs +++ b/tests/relational/todo/CaseOnRec.hs @@ -1,4 +1,4 @@ -module Fixme where +module CaseOnRec where data Parity = Even | Odd diff --git a/tests/relational/todo/DeltaSort.hs b/tests/relational/todo/DeltaSort.hs index 96e377290b..73f485c57d 100644 --- a/tests/relational/todo/DeltaSort.hs +++ b/tests/relational/todo/DeltaSort.hs @@ -1,3 +1,4 @@ +{-@ LIQUID "--reflection" @-} module DeltaSort where import Prelude hiding ( abs diff --git a/tests/relational/todo/Example.hs b/tests/relational/todo/Example.hs index 206d28d5da..c626dfd2de 100644 --- a/tests/relational/todo/Example.hs +++ b/tests/relational/todo/Example.hs @@ -1,3 +1,4 @@ +module Example where foo, bar :: Bool -> Int foo a = if a then 0 else 2 bar b = if b then 1 else 3 diff --git a/tests/relational/todo/FibLet.hs b/tests/relational/todo/FibLet.hs index 5b59be780b..b201fc0282 100644 --- a/tests/relational/todo/FibLet.hs +++ b/tests/relational/todo/FibLet.hs @@ -1,3 +1,4 @@ +{-@ LIQUID "--reflection" @-} module Fixme where data N = Z | S N diff --git a/tests/relational/todo/Filter.hs b/tests/relational/todo/Filter.hs index 4fa5923f91..11aa430401 100644 --- a/tests/relational/todo/Filter.hs +++ b/tests/relational/todo/Filter.hs @@ -1,3 +1,4 @@ +{-@ LIQUID "--reflection" @-} module Filter where {-@ measure d :: a -> a -> Double @-} diff --git a/tests/relational/todo/IncrF.hs b/tests/relational/todo/IncrF.hs index b3024481cb..b73069ecb5 100644 --- a/tests/relational/todo/IncrF.hs +++ b/tests/relational/todo/IncrF.hs @@ -1,4 +1,4 @@ -module Fixme where +module IncrF where {-@ add :: x:Int -> y:Int -> {v:Int|v = x + y} @-} add :: Int -> Int -> Int diff --git a/tests/relational/todo/IncrHO.hs b/tests/relational/todo/IncrHO.hs index b541142600..5bdfc9c01c 100644 --- a/tests/relational/todo/IncrHO.hs +++ b/tests/relational/todo/IncrHO.hs @@ -1,4 +1,5 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +module IncrHO where incr :: Int -> Int incr = (+ 1) diff --git a/tests/relational/todo/IncrVeryHO.hs b/tests/relational/todo/IncrVeryHO.hs index 196c785201..14c65c9cc2 100644 --- a/tests/relational/todo/IncrVeryHO.hs +++ b/tests/relational/todo/IncrVeryHO.hs @@ -1,3 +1,4 @@ +{-@ LIQUID "--reflection" @-} module IncrVeryHO where {-@ reflect incr @-} diff --git a/tests/relational/todo/Incr_.hs b/tests/relational/todo/Incr_.hs index 55b34d6a35..16740780d4 100644 --- a/tests/relational/todo/Incr_.hs +++ b/tests/relational/todo/Incr_.hs @@ -1,4 +1,4 @@ -module Fixme where +module Incr_ where {-@ plus :: a:Int -> b:Int -> {v:Int | v == a + b} @-} plus :: Int -> Int -> Int diff --git a/tests/relational/todo/IsZero.hs b/tests/relational/todo/IsZero.hs index d84618e965..3ef33dfdfa 100644 --- a/tests/relational/todo/IsZero.hs +++ b/tests/relational/todo/IsZero.hs @@ -1,3 +1,6 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + module Fixme where isZero :: Int -> Bool diff --git a/tests/relational/todo/Map.hs b/tests/relational/todo/Map.hs index 5d7465ae33..00b4815f40 100644 --- a/tests/relational/todo/Map.hs +++ b/tests/relational/todo/Map.hs @@ -1,4 +1,5 @@ -module Fixme where +{-@ LIQUID "--reflection" @-} +module Map where import Prelude hiding ( map ) From a86160b471f6ea72a486f8b8e182748c991cf2eb Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 6 Apr 2023 19:42:33 +0200 Subject: [PATCH 201/219] add lemmas --- .../Haskell/Liquid/Constraint/Relational.hs | 14 +++++++------- tests/relational/pos/R2Dcounting_relToUn.hs | 1 - .../pos/RConstantTimeComparison_relToUn.hs | 13 ++++++------- tests/relational/pos/RIncr_relToUn.hs | 1 - tests/relational/pos/RMap_relToUn.hs | 7 +++---- tests/relational/pos/RMemAlloc_relToUn.hs | 1 - tests/relational/pos/RVar_relToUn.hs | 1 - 7 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index 271eade7ec..f70970f9a8 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -324,7 +324,7 @@ relTermToUnTerm' m relTerms (App f1 v1) (App f2 v2) , GM.isEmbeddedDictVar x2 , areCompatible f1 f2 = relTermToUnTerm' m relTerms f1 f2 -relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2) +relTermToUnTerm' m relTerms e1@(App f1 x1) e2@(App f2 x2) | isCommonArg x1 , isCommonArg x2 , areCompatible f1 f2 @@ -332,15 +332,15 @@ relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2) = traceWhenLoud ("relTermToUnTerm App common arg " ++ show x1 ++ " ~ " ++ show x2) $ App (App (App relF x1') x2') relX - -- `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' + `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' where relF = relTermToUnTerm' m relTerms f1 f2 relX = relTermToUnTerm' m relTerms x1 x2 rvs = renVars m (x1', _) = cleanUnTerms rvs x1 (x2', _) = cleanUnTerms rvs x2 - -- (e1', p1) = cleanUnTerms rvs e1 - -- (e2', p2) = cleanUnTerms rvs e2 + (e1', p1) = cleanUnTerms rvs e1 + (e2', p2) = cleanUnTerms rvs e2 relTermToUnTerm' m relTerms (Lam α1 e1) (Lam α2 e2) | Ghc.isTyVar α1, Ghc.isTyVar α2 = relTermToUnTerm' m relTerms e1 e2 @@ -412,9 +412,9 @@ relTermToUnTerm' m _ e1 e2 right = coreToGoal rvs True e2 info = "GOAL: " ++ left ++ " ~ " ++ right --- guardLemma :: Bool -> CoreExpr -> CoreExpr --- guardLemma True _ = Ghc.unitExpr --- guardLemma False e = e +guardLemma :: Bool -> CoreExpr -> CoreExpr +guardLemma True _ = Ghc.unitExpr +guardLemma False e = e {- function to print CoreExpr as strings in order to insert them as goal comments on the output of the proof. diff --git a/tests/relational/pos/R2Dcounting_relToUn.hs b/tests/relational/pos/R2Dcounting_relToUn.hs index 99f000e8ef..658f8f6e8b 100644 --- a/tests/relational/pos/R2Dcounting_relToUn.hs +++ b/tests/relational/pos/R2Dcounting_relToUn.hs @@ -1,6 +1,5 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} - {-@ LIQUID "--no-adt" @-} module R2Dcounting_relToUn (module R2Dcounting_relToUn) where diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs index c709c9e86b..198993ae10 100644 --- a/tests/relational/pos/RConstantTimeComparison_relToUn.hs +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -1,6 +1,5 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} - {-@ LIQUID "--no-adt" @-} module RConstantTimeComparison_relToUn (module RConstantTimeComparison_relToUn) where @@ -185,9 +184,9 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of (ys1 :: [RConstantTimeComparison.Bit]) (ys2 :: [RConstantTimeComparison.Bit]) (ys1ys2Lemma :: [RConstantTimeComparison.Bit]) -> - case xs1 of lq_anf$##72057594037927946881 { + case xs1 of lq_anf$##72057594037927945861 { [] -> - case xs2 of lq_anf$##72057594037927946882 { + case xs2 of lq_anf$##72057594037927945862 { [] -> (src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) GHC.Types.True @@ -197,17 +196,17 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of : x2 xs2 -> src<.:0:0> GHC.Tuple.() }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927946882 { + case xs2 of lq_anf$##72057594037927945862 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> - case ys1 of lq_anf$##72057594037927946891 { + case ys1 of lq_anf$##72057594037927945871 { [] -> - case ys2 of lq_anf$##72057594037927946892 { + case ys2 of lq_anf$##72057594037927945872 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> src<.:0:0> GHC.Tuple.() }; : y1 ys1 -> - case ys2 of lq_anf$##72057594037927946892 { + case ys2 of lq_anf$##72057594037927945872 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> let { diff --git a/tests/relational/pos/RIncr_relToUn.hs b/tests/relational/pos/RIncr_relToUn.hs index 4108349c22..b28ca9fe02 100644 --- a/tests/relational/pos/RIncr_relToUn.hs +++ b/tests/relational/pos/RIncr_relToUn.hs @@ -1,6 +1,5 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} - {-@ LIQUID "--no-adt" @-} module RIncr_relToUn (module RIncr_relToUn) where diff --git a/tests/relational/pos/RMap_relToUn.hs b/tests/relational/pos/RMap_relToUn.hs index 6db77b4e85..a1d54df9bb 100644 --- a/tests/relational/pos/RMap_relToUn.hs +++ b/tests/relational/pos/RMap_relToUn.hs @@ -1,6 +1,5 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} - {-@ LIQUID "--no-adt" @-} module RMap_relToUn (module RMap_relToUn) where @@ -54,9 +53,9 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of (xs1 :: [GHC.Types.Int]) (xs2 :: [GHC.Types.Int]) (xs1xs2Lemma :: [GHC.Types.Int]) -> - case xs1 of lq_anf$##72057594037927945401 { + case xs1 of lq_anf$##72057594037927940231 { [] -> - case xs2 of lq_anf$##72057594037927945402 { + case xs2 of lq_anf$##72057594037927940232 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> src<.:0:0> @@ -65,7 +64,7 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of (GHC.Types.: (f2 x2) (RMap.map f2 xs2)) }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927945402 { + case xs2 of lq_anf$##72057594037927940232 { [] -> src<.:0:0> const diff --git a/tests/relational/pos/RMemAlloc_relToUn.hs b/tests/relational/pos/RMemAlloc_relToUn.hs index 556e1cde05..0d22f59bb6 100644 --- a/tests/relational/pos/RMemAlloc_relToUn.hs +++ b/tests/relational/pos/RMemAlloc_relToUn.hs @@ -1,6 +1,5 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} - {-@ LIQUID "--no-adt" @-} module RMemAlloc_relToUn (module RMemAlloc_relToUn) where diff --git a/tests/relational/pos/RVar_relToUn.hs b/tests/relational/pos/RVar_relToUn.hs index 57e7f61456..a858014201 100644 --- a/tests/relational/pos/RVar_relToUn.hs +++ b/tests/relational/pos/RVar_relToUn.hs @@ -1,6 +1,5 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} - {-@ LIQUID "--no-adt" @-} module RVar_relToUn (module RVar_relToUn) where From c978756425f5d63f3afa159ce0159a6b15ad3880 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 6 Apr 2023 19:42:52 +0200 Subject: [PATCH 202/219] add conditional lemmas on app --- .../Haskell/Liquid/Constraint/Relational.hs | 5 +- tests/relational/pos/R2Dcounting_relToUn.hs | 66 ++- .../pos/RConstantTimeComparison_relToUn.hs | 544 ++++++++++++------ tests/relational/pos/RIncr_relToUn.hs | 84 ++- tests/relational/pos/RMap_relToUn.hs | 108 ++-- tests/relational/pos/RMemAlloc_relToUn.hs | 120 ++-- tests/relational/rtest | 2 +- 7 files changed, 610 insertions(+), 319 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index f70970f9a8..32cc0a4330 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -331,8 +331,11 @@ relTermToUnTerm' m relTerms e1@(App f1 x1) e2@(App f2 x2) , areCompatible x1 x2 = traceWhenLoud ("relTermToUnTerm App common arg " ++ show x1 ++ " ~ " ++ show x2) $ - App (App (App relF x1') x2') relX + if isBaseGhcTy (Ghc.exprType e1) && isBaseGhcTy (Ghc.exprType e2) then + App (App (App relF x1') x2') relX `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' + else + App (App (App relF x1') x2') relX where relF = relTermToUnTerm' m relTerms f1 f2 relX = relTermToUnTerm' m relTerms x1 x2 diff --git a/tests/relational/pos/R2Dcounting_relToUn.hs b/tests/relational/pos/R2Dcounting_relToUn.hs index 658f8f6e8b..1b0b34baae 100644 --- a/tests/relational/pos/R2Dcounting_relToUn.hs +++ b/tests/relational/pos/R2Dcounting_relToUn.hs @@ -16,24 +16,40 @@ import Prelude && p1 == p2} -> l1:[[GHC.Types.Int]] -> l2:[[GHC.Types.Int]] -> l1l2Lemma:{VV : () | l1 == l2} -> {VV : () | RTick.tcost (R2Dcounting.count2Df1 p1 e1 l1) <= RTick.tcost (R2Dcounting.count2Df2 p2 e2 l2)} @-} count2Df1Count2Df2Theorem :: ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> [GHC.Types.Int] -> () -> ()) -> GHC.Types.Int -> GHC.Types.Int -> () -> [[GHC.Types.Int]] -> [[GHC.Types.Int]] -> () -> () count2Df1Count2Df2Theorem p1 p2 p1p2Lemma e1 e2 e1e2Lemma l1 l2 l1l2Lemma = - ( ( ( {- GOAL: RTick.return ~ RTick.return -} - (\_ _ _ -> ()) - ) - 0 - ) - 0 - ) - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 0 + ( const + ( ( const + ( ( ( ( {- GOAL: RTick.return ~ RTick.return -} + (\_ _ _ -> ()) + ) + 0 + ) + 0 + ) + ( ( const + ( ( const + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 0 + ) + 0 + ) + ( {- GOAL: 0 ~ 0 -} + (const ((const ()) 0)) 0 + ) + ) + ) + 0 + ) + ) + 0 + ) + ) ) - 0 + (RTick.return 0) ) - ( {- GOAL: 0 ~ 0 -} - (const ((const ()) 0)) 0 - ) - ) + ) + (RTick.return 0) {- BARE CORE \ _ [Occ=Dead] @@ -45,9 +61,17 @@ count2Df1Count2Df2Theorem p1 p2 p1p2Lemma e1 e2 e1e2Lemma l1 l2 l1l2Lemma = _ [Occ=Dead] _ [Occ=Dead] _ [Occ=Dead] -> - (src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - (GHC.Types.I# 0#) - (GHC.Types.I# 0#) - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) + const + (const + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + (GHC.Types.I# 0#) + (GHC.Types.I# 0#) + (const + (const + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) + (GHC.Types.I# 0#)) + (GHC.Types.I# 0#))) + (RTick.return (GHC.Types.I# 0#))) + (RTick.return (GHC.Types.I# 0#)) -} diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs index 198993ae10..498004c9d6 100644 --- a/tests/relational/pos/RConstantTimeComparison_relToUn.hs +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -19,16 +19,24 @@ compCompTheorem :: [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of [] -> case xs2 of [] -> - ( ( ( {- GOAL: RTick.return ~ RTick.return -} - (\_ _ _ -> ()) + ( const + ( ( const + ( ( ( ( {- GOAL: RTick.return ~ RTick.return -} + (\_ _ _ -> ()) + ) + True + ) + True + ) + ( {- GOAL: True ~ True -} + (const ((const ()) True)) True + ) + ) + ) + (RTick.return True) ) - True - ) - True ) - ( {- GOAL: True ~ True -} - (const ((const ()) True)) True - ) + (RTick.return True) (:) x2 xs2 -> {- GOAL: RTick.return True ~ () -} () (:) x1 xs1 -> case xs2 of [] -> {- GOAL: () ~ RTick.return True -} () @@ -42,18 +50,26 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of let ds1 = (RConstantTimeComparison.comp xs1) ys1 in let ds2 = (RConstantTimeComparison.comp xs2) ys2 in let ds1ds2Lemma = - ( ( ( ((compCompTheorem xs1) xs2) - ( {- GOAL: xs1 ~ xs2 -} - (const ((const ()) xs1)) xs2 - ) + ( const + ( ( const + ( ( ( ( ((compCompTheorem xs1) xs2) + ( {- GOAL: xs1 ~ xs2 -} + (const ((const ()) xs1)) xs2 + ) + ) + ys1 + ) + ys2 + ) + ( {- GOAL: ys1 ~ ys2 -} + (const ((const ()) ys1)) ys2 + ) + ) + ) + ((RConstantTimeComparison.comp xs1) ys1) ) - ys1 - ) - ys2 ) - ( {- GOAL: ys1 ~ ys2 -} - (const ((const ()) ys1)) ys2 - ) + ((RConstantTimeComparison.comp xs2) ys2) in let m1 = case (RConstantTimeComparison.comp xs1) ys1 of Tick m v -> m in let m2 = case (RConstantTimeComparison.comp xs2) ys2 of @@ -72,108 +88,196 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of Tick m22 v2 -> {- GOAL: v1 ~ v2 -} (const ((const ()) v1)) v2 - in ( ( ( ( ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} - (\_ _ _ _ _ _ -> ()) - ) - ( ( (+) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1 + in ( const + ( ( const + ( ( ( ( ( ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} + (\_ _ _ _ _ _ -> ()) + ) + ( ( (+) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1 + ) + ) + 1 + ) + ) + ( ( (+) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2 + ) + ) + 1 + ) ) - ) - 1 - ) - ) - ( ( (+) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2 - ) - ) - 1 - ) - ) - ( ( ( ( ( ( ( {- GOAL: + ~ + -} - (\_ _ _ _ _ _ -> ()) + ( ( const + ( ( const + ( ( ( ( ( ( ( {- GOAL: + ~ + -} + (\_ _ _ _ _ _ -> ()) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1 + ) + ) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2 + ) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v22 -> m1m2Lemma + ) + ) + 1 + ) + 1 + ) + ( ( const + ( ( const + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 1 + ) + 1 + ) + ( {- GOAL: 1 ~ 1 -} + (const ((const ()) 1)) 1 + ) + ) + ) + 1 + ) + ) + 1 + ) + ) + ) + ( ( (+) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1 + ) + ) + 1 + ) + ) + ) + ( ( (+) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2 + ) + ) + 1 + ) ) + ) + ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1 + Tick m1 v1 -> v1 ) ) + ) + ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2 + Tick m2 v2 -> v2 ) ) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m22 v22 -> m1m2Lemma + ) + ( ( const + ( ( const + ( ( ( ( ( ( ( {- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} + (\_ _ _ _ _ _ -> ()) + ) + (((GHC.Classes.==) x1) y1) + ) + (((GHC.Classes.==) x2) y2) + ) + ( ( const + ( ( const + ( ( ( ( ( ( ( {- GOAL: GHC.Classes.== ~ GHC.Classes.== -} + (\_ _ _ _ _ _ -> ()) + ) + x1 + ) + x2 + ) + ( {- GOAL: x1 ~ x2 -} + (const ((const ()) x1)) x2 + ) + ) + y1 + ) + y2 + ) + ( {- GOAL: y1 ~ y2 -} + (const ((const ()) y1)) y2 + ) + ) + ) + (((GHC.Classes.==) x1) y1) + ) + ) + (((GHC.Classes.==) x2) y2) + ) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> v1 + ) + ) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> v2 + ) + ) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of + Tick m22 v22 -> v1v2Lemma + ) + ) + ) + ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> v1 + ) + ) + ) + ) + ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> v2 + ) ) ) - 1 - ) - 1 ) - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 1 + ) + ( ( RTick.Tick + ( ( (+) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> m1 + ) ) 1 ) - ( {- GOAL: 1 ~ 1 -} - (const ((const ()) 1)) 1 + ) + ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) + ( case (RConstantTimeComparison.comp xs1) ys1 of + Tick m1 v1 -> v1 ) ) ) ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1 - ) - ) - ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2 - ) - ) ) - ( ( ( ( ( ( ( {- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} - (\_ _ _ _ _ _ -> ()) + ( ( RTick.Tick + ( ( (+) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> m2 ) - (((GHC.Classes.==) x1) y1) - ) - (((GHC.Classes.==) x2) y2) ) - ( ( ( ( ( ( ( {- GOAL: GHC.Classes.== ~ GHC.Classes.== -} - (\_ _ _ _ _ _ -> ()) - ) - x1 - ) - x2 - ) - ( {- GOAL: x1 ~ x2 -} - (const ((const ()) x1)) x2 - ) - ) - y1 - ) - y2 - ) - ( {- GOAL: y1 ~ y2 -} - (const ((const ()) y1)) y2 - ) - ) - ) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1 - ) - ) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2 + 1 ) ) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m22 v22 -> v1v2Lemma + ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) + ( case (RConstantTimeComparison.comp xs2) ys2 of + Tick m2 v2 -> v2 + ) ) ) @@ -184,29 +288,33 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of (ys1 :: [RConstantTimeComparison.Bit]) (ys2 :: [RConstantTimeComparison.Bit]) (ys1ys2Lemma :: [RConstantTimeComparison.Bit]) -> - case xs1 of lq_anf$##72057594037927945861 { + case xs1 of lq_anf$##72057594037927946261 { [] -> - case xs2 of lq_anf$##72057594037927945862 { + case xs2 of lq_anf$##72057594037927946262 { [] -> - (src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - GHC.Types.True - GHC.Types.True - (src<.:0:0> - const (const GHC.Tuple.() GHC.Types.True) GHC.Types.True); + const + (const + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + GHC.Types.True + GHC.Types.True + (src<.:0:0> + const (const GHC.Tuple.() GHC.Types.True) GHC.Types.True)) + (RTick.return GHC.Types.True)) + (RTick.return GHC.Types.True); : x2 xs2 -> src<.:0:0> GHC.Tuple.() }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927945862 { + case xs2 of lq_anf$##72057594037927946262 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> - case ys1 of lq_anf$##72057594037927945871 { + case ys1 of lq_anf$##72057594037927946271 { [] -> - case ys2 of lq_anf$##72057594037927945872 { + case ys2 of lq_anf$##72057594037927946272 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> src<.:0:0> GHC.Tuple.() }; : y1 ys1 -> - case ys2 of lq_anf$##72057594037927945872 { + case ys2 of lq_anf$##72057594037927946272 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> let { @@ -227,13 +335,17 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] ds1ds2Lemma - = compCompTheorem - xs1 - xs2 - (src<.:0:0> const (const GHC.Tuple.() xs1) xs2) - ys1 - ys2 - (src<.:0:0> const (const GHC.Tuple.() ys1) ys2) } in + = const + (const + (compCompTheorem + xs1 + xs2 + (src<.:0:0> const (const GHC.Tuple.() xs1) xs2) + ys1 + ys2 + (src<.:0:0> const (const GHC.Tuple.() ys1) ys2)) + (RConstantTimeComparison.comp xs1 ys1)) + (RConstantTimeComparison.comp xs2 ys2) } in let { m1 :: GHC.Types.Int [LclId] @@ -282,76 +394,144 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of src<.:0:0> const (const GHC.Tuple.() v1) v2 } } } in - (src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - m1 - }) - (GHC.Types.I# 1#)) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - m2 - }) - (GHC.Types.I# 1#)) - ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - m1 - }) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - m2 - }) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m11 v11 -> - case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m22 v22 -> - m1m2Lemma - } - }) - (GHC.Types.I# 1#) - (GHC.Types.I# 1#) - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#))) - (RConstantTimeComparison.and - (GHC.Classes.== x1 y1) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - v1 - })) - (RConstantTimeComparison.and - (GHC.Classes.== x2 y2) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - v2 - })) - ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (GHC.Classes.== x1 y1) - (GHC.Classes.== x2 y2) + const + (const ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - x1 - x2 - (src<.:0:0> const (const GHC.Tuple.() x1) x2) - y1 - y2 - (src<.:0:0> const (const GHC.Tuple.() y1) y2)) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - v1 - }) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - v2 - }) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m11 v11 -> - case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m22 v22 -> - v1v2Lemma - } - })) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (GHC.Types.I# 1#)) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (GHC.Types.I# 1#)) + (const + (const + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m1 v1 -> + m1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m2 v2 -> + m2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + m1m2Lemma + } + }) + (GHC.Types.I# 1#) + (GHC.Types.I# 1#) + (const + (const + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#)) + (GHC.Types.I# 1#)) + (GHC.Types.I# 1#))) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m1 v1 -> + m1 + }) + (GHC.Types.I# 1#))) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (GHC.Types.I# 1#))) + (RConstantTimeComparison.and + (GHC.Classes.== x1 y1) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + })) + (RConstantTimeComparison.and + (GHC.Classes.== x2 y2) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + })) + (const + (const + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (GHC.Classes.== x1 y1) + (GHC.Classes.== x2 y2) + (const + (const + ((src<.:0:0> + \ (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) -> + GHC.Tuple.()) + x1 + x2 + (src<.:0:0> const (const GHC.Tuple.() x1) x2) + y1 + y2 + (src<.:0:0> const (const GHC.Tuple.() y1) y2)) + (GHC.Classes.== x1 y1)) + (GHC.Classes.== x2 y2)) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m1 v1 -> + v1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m2 v2 -> + v2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + v1v2Lemma + } + })) + (RConstantTimeComparison.and + (GHC.Classes.== x1 y1) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m1 v1 -> + v1 + }))) + (RConstantTimeComparison.and + (GHC.Classes.== x2 y2) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + })))) + (RTick.Tick + (GHC.Num.+ + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (GHC.Types.I# 1#)) + (RConstantTimeComparison.and + (GHC.Classes.== x1 y1) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + })))) + (RTick.Tick + (GHC.Num.+ + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (GHC.Types.I# 1#)) + (RConstantTimeComparison.and + (GHC.Classes.== x2 y2) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + }))) } } } diff --git a/tests/relational/pos/RIncr_relToUn.hs b/tests/relational/pos/RIncr_relToUn.hs index b28ca9fe02..63364f2cc1 100644 --- a/tests/relational/pos/RIncr_relToUn.hs +++ b/tests/relational/pos/RIncr_relToUn.hs @@ -13,43 +13,67 @@ import Prelude {-@ incrIncrTheorem :: xl:GHC.Types.Int -> xr:GHC.Types.Int -> xlxrLemma:{VV : () | xl < xr} -> {VV : () | RIncr.incr xl < RIncr.incr xr} @-} incrIncrTheorem :: GHC.Types.Int -> GHC.Types.Int -> () -> () incrIncrTheorem xl xr xlxrLemma = - ( ( ( ( ( ( {- GOAL: + ~ + -} - (\_ _ _ _ _ _ -> ()) + ( const + ( ( const + ( ( ( ( ( ( ( {- GOAL: + ~ + -} + (\_ _ _ _ _ _ -> ()) + ) + xl + ) + xr + ) + xlxrLemma + ) + 1 + ) + 1 + ) + ( ( const + ( ( const + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 1 + ) + 1 + ) + ( {- GOAL: 1 ~ 1 -} + (const ((const ()) 1)) 1 + ) + ) + ) + 1 + ) + ) + 1 + ) ) - xl - ) - xr ) - xlxrLemma + (((+) xl) 1) ) - 1 - ) - 1 ) - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 1 - ) - 1 - ) - ( {- GOAL: 1 ~ 1 -} - (const ((const ()) 1)) 1 - ) - ) + (((+) xr) 1) {- BARE CORE \ (xl :: GHC.Types.Int) (xr :: GHC.Types.Int) (xlxrLemma :: GHC.Types.Int) -> - (src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - xl - xr - xlxrLemma - (GHC.Types.I# 1#) - (GHC.Types.I# 1#) - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#)) + const + (const + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + xl + xr + xlxrLemma + (GHC.Types.I# 1#) + (GHC.Types.I# 1#) + (const + (const + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#)) + (GHC.Types.I# 1#)) + (GHC.Types.I# 1#))) + (GHC.Num.+ xl (GHC.Types.I# 1#))) + (GHC.Num.+ xr (GHC.Types.I# 1#)) -} diff --git a/tests/relational/pos/RMap_relToUn.hs b/tests/relational/pos/RMap_relToUn.hs index a1d54df9bb..4cf1ea9b3c 100644 --- a/tests/relational/pos/RMap_relToUn.hs +++ b/tests/relational/pos/RMap_relToUn.hs @@ -23,28 +23,52 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of {- GOAL: ((:) (f1 x1)) ((RMap (...) ~ [] -} (const ((const ()) (((:) (f1 x1)) ((RMap.map f1) xs1)))) [] (:) x2 xs2 -> - ( ( ( ( ( ( {- GOAL: : ~ : -} - (\_ _ _ _ _ _ -> ()) + ( const + ( ( const + ( ( ( ( ( ( ( {- GOAL: : ~ : -} + (\_ _ _ _ _ _ -> ()) + ) + (f1 x1) + ) + (f2 x2) + ) + ( ( const + ( ( const + ( ((f1f2Lemma x1) x2) + ( {- GOAL: x1 ~ x2 -} + (const ((const ()) x1)) x2 + ) + ) + ) + (f1 x1) + ) + ) + (f2 x2) + ) + ) + ((RMap.map f1) xs1) + ) + ((RMap.map f2) xs2) + ) + ( ( const + ( ( const + ( (((((mapMapTheorem f1) f2) f1f2Lemma) xs1) xs2) + ( {- GOAL: xs1 ~ xs2 -} + (const ((const ()) xs1)) xs2 + ) + ) + ) + ((RMap.map f1) xs1) + ) + ) + ((RMap.map f2) xs2) + ) ) - (f1 x1) - ) - (f2 x2) ) - ( ((f1f2Lemma x1) x2) - ( {- GOAL: x1 ~ x2 -} - (const ((const ()) x1)) x2 - ) - ) + (((:) (f1 x1)) ((RMap.map f1) xs1)) ) - ((RMap.map f1) xs1) - ) - ((RMap.map f2) xs2) ) - ( (((((mapMapTheorem f1) f2) f1f2Lemma) xs1) xs2) - ( {- GOAL: xs1 ~ xs2 -} - (const ((const ()) xs1)) xs2 - ) - ) + (((:) (f2 x2)) ((RMap.map f2) xs2)) {- BARE CORE \ (f1 :: GHC.Types.Int -> GHC.Types.Int) @@ -53,9 +77,9 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of (xs1 :: [GHC.Types.Int]) (xs2 :: [GHC.Types.Int]) (xs1xs2Lemma :: [GHC.Types.Int]) -> - case xs1 of lq_anf$##72057594037927940231 { + case xs1 of lq_anf$##72057594037927940391 { [] -> - case xs2 of lq_anf$##72057594037927940232 { + case xs2 of lq_anf$##72057594037927940392 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> src<.:0:0> @@ -64,28 +88,40 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of (GHC.Types.: (f2 x2) (RMap.map f2 xs2)) }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927940232 { + case xs2 of lq_anf$##72057594037927940392 { [] -> src<.:0:0> const (const GHC.Tuple.() (GHC.Types.: (f1 x1) (RMap.map f1 xs1))) GHC.Types.[]; : x2 xs2 -> - (src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (f1 x1) - (f2 x2) - (f1f2Lemma x1 x2 (src<.:0:0> const (const GHC.Tuple.() x1) x2)) - (RMap.map f1 xs1) - (RMap.map f2 xs2) - (mapMapTheorem - f1 - f2 - f1f2Lemma - xs1 - xs2 - (src<.:0:0> const (const GHC.Tuple.() xs1) xs2)) + const + (const + ((src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (f1 x1) + (f2 x2) + (const + (const + (f1f2Lemma x1 x2 (src<.:0:0> const (const GHC.Tuple.() x1) x2)) + (f1 x1)) + (f2 x2)) + (RMap.map f1 xs1) + (RMap.map f2 xs2) + (const + (const + (mapMapTheorem + f1 + f2 + f1f2Lemma + xs1 + xs2 + (src<.:0:0> const (const GHC.Tuple.() xs1) xs2)) + (RMap.map f1 xs1)) + (RMap.map f2 xs2))) + (GHC.Types.: (f1 x1) (RMap.map f1 xs1))) + (GHC.Types.: (f2 x2) (RMap.map f2 xs2)) } } -} diff --git a/tests/relational/pos/RMemAlloc_relToUn.hs b/tests/relational/pos/RMemAlloc_relToUn.hs index 0d22f59bb6..13248cb12c 100644 --- a/tests/relational/pos/RMemAlloc_relToUn.hs +++ b/tests/relational/pos/RMemAlloc_relToUn.hs @@ -15,64 +15,88 @@ import Prelude {-@ length1Length2Theorem :: xs1:[GHC.Types.Int] -> xs2:[GHC.Types.Int] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> {VV : () | RTick.tcost (RMemAlloc.length2 xs1) - RTick.tcost (RMemAlloc.length1 xs1) == len xs1} @-} length1Length2Theorem :: [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () length1Length2Theorem xs1 xs2 xs1xs2Lemma = - ( ( ( ( ( ( ( ( ( {- GOAL: RMemAlloc.foldl' ~ RMemAlloc.foldl -} - (\_ _ _ _ _ _ _ _ _ -> ()) + ( const + ( ( const + ( ( ( ( ( ( ( ( ( ( {- GOAL: RMemAlloc.foldl' ~ RMemAlloc.foldl -} + (\_ _ _ _ _ _ _ _ _ -> ()) + ) + RMemAlloc.upd + ) + RMemAlloc.upd + ) + ( {- GOAL: RMemAlloc.upd ~ RMemAlloc.upd -} + (\_ _ _ _ _ _ -> ()) + ) + ) + 0 + ) + 0 + ) + ( ( const + ( ( const + ( ( ( ( {- GOAL: ~ -} + (\_ _ _ -> ()) + ) + 0 + ) + 0 + ) + ( {- GOAL: 0 ~ 0 -} + (const ((const ()) 0)) 0 + ) + ) + ) + 0 + ) + ) + 0 + ) ) - RMemAlloc.upd + xs1 ) - RMemAlloc.upd + xs2 ) - ( {- GOAL: RMemAlloc.upd ~ RMemAlloc.upd -} - (\_ _ _ _ _ _ -> ()) - ) + xs1xs2Lemma ) - 0 - ) - 0 ) - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 0 - ) - 0 - ) - ( {- GOAL: 0 ~ 0 -} - (const ((const ()) 0)) 0 - ) - ) + (((RMemAlloc.foldl' RMemAlloc.upd) 0) xs1) ) - xs1 - ) - xs2 ) - xs1xs2Lemma + (((RMemAlloc.foldl RMemAlloc.upd) 0) xs2) {- BARE CORE \ (xs1 :: [GHC.Types.Int]) (xs2 :: [GHC.Types.Int]) (xs1xs2Lemma :: [GHC.Types.Int]) -> - (src<.:0:0> - \ (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) -> - GHC.Tuple.()) - RMemAlloc.upd - RMemAlloc.upd - (src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (GHC.Types.I# 0#) - (GHC.Types.I# 0#) - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) - xs1 - xs2 - xs1xs2Lemma + const + (const + ((src<.:0:0> + \ (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) + (_ :: ()) -> + GHC.Tuple.()) + RMemAlloc.upd + RMemAlloc.upd + (src<.:0:0> + \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> + GHC.Tuple.()) + (GHC.Types.I# 0#) + (GHC.Types.I# 0#) + (const + (const + ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) + 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) + (GHC.Types.I# 0#)) + (GHC.Types.I# 0#)) + xs1 + xs2 + xs1xs2Lemma) + (RMemAlloc.foldl' RMemAlloc.upd (GHC.Types.I# 0#) xs1)) + (RMemAlloc.foldl RMemAlloc.upd (GHC.Types.I# 0#) xs2) -} diff --git a/tests/relational/rtest b/tests/relational/rtest index 721809e6f8..387c2bee89 100755 --- a/tests/relational/rtest +++ b/tests/relational/rtest @@ -15,7 +15,7 @@ for f in tests/relational/pos/*.hs do echo echo $f - if ! $LH $f --idirs=tests/relational/pos + if ! $LH $f -itests/relational/pos then rc=1 fi From 134018d5c510c97975bbf4cfac830d90c988a724 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 13 Apr 2023 12:15:03 +0100 Subject: [PATCH 203/219] prevent constant folding in translation --- .../Haskell/Liquid/Constraint/Relational.hs | 61 +- src/Language/Haskell/Liquid/Liquid.hs | 2 +- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 9 +- tests/relational/pos/R2Dcounting_relToUn.hs | 72 +- .../pos/RConstantTimeComparison_relToUn.hs | 634 +++++++----------- tests/relational/pos/RIncr_relToUn.hs | 95 ++- tests/relational/pos/RMap_relToUn.hs | 140 ++-- tests/relational/pos/RMemAlloc_relToUn.hs | 136 ++-- tests/relational/pos/RVar_relToUn.hs | 7 +- tests/tests.cabal | 2 + 10 files changed, 448 insertions(+), 710 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index 32cc0a4330..4ff7786ca0 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -324,17 +324,13 @@ relTermToUnTerm' m relTerms (App f1 v1) (App f2 v2) , GM.isEmbeddedDictVar x2 , areCompatible f1 f2 = relTermToUnTerm' m relTerms f1 f2 -relTermToUnTerm' m relTerms e1@(App f1 x1) e2@(App f2 x2) +relTermToUnTerm' m relTerms (App f1 x1) (App f2 x2) | isCommonArg x1 , isCommonArg x2 , areCompatible f1 f2 , areCompatible x1 x2 = traceWhenLoud ("relTermToUnTerm App common arg " ++ show x1 ++ " ~ " ++ show x2) $ - if isBaseGhcTy (Ghc.exprType e1) && isBaseGhcTy (Ghc.exprType e2) then - App (App (App relF x1') x2') relX - `addLemma` guardLemma p1 e1' `addLemma` guardLemma p2 e2' - else App (App (App relF x1') x2') relX where relF = relTermToUnTerm' m relTerms f1 f2 @@ -342,8 +338,6 @@ relTermToUnTerm' m relTerms e1@(App f1 x1) e2@(App f2 x2) rvs = renVars m (x1', _) = cleanUnTerms rvs x1 (x2', _) = cleanUnTerms rvs x2 - (e1', p1) = cleanUnTerms rvs e1 - (e2', p2) = cleanUnTerms rvs e2 relTermToUnTerm' m relTerms (Lam α1 e1) (Lam α2 e2) | Ghc.isTyVar α1, Ghc.isTyVar α2 = relTermToUnTerm' m relTerms e1 e2 @@ -406,7 +400,7 @@ relTermToUnTerm' m relTerms (Case d1 x1 t1 as1) (Case d2 x2 t2 as2) relTermToUnTerm' m _ e1 e2 = traceWhenLoud ("relTermToUnTerm': can't proceed proof generation on e1:\n" ++ F.showpp e1 ++ "\ne2:\n" ++ F.showpp e2) $ Tick (Ghc.SourceNote realSpan info) $ - mkLambdaUnit m e1 e2 (Ghc.exprType e1) (Ghc.exprType e2) + mkLambdaUnit m e1 e2 (Ghc.exprType e1) (Ghc.exprType e2) Ghc.unitExpr 1 where realLoc = Ghc.mkRealSrcLoc (Ghc.mkFastString "") 0 0 realSpan = Ghc.mkRealSrcSpan realLoc realLoc @@ -415,9 +409,9 @@ relTermToUnTerm' m _ e1 e2 right = coreToGoal rvs True e2 info = "GOAL: " ++ left ++ " ~ " ++ right -guardLemma :: Bool -> CoreExpr -> CoreExpr -guardLemma True _ = Ghc.unitExpr -guardLemma False e = e +-- guardLemma :: Bool -> CoreExpr -> CoreExpr +-- guardLemma True _ = Ghc.unitExpr +-- guardLemma False e = e {- function to print CoreExpr as strings in order to insert them as goal comments on the output of the proof. @@ -453,25 +447,24 @@ areCompatibleTy t1 (Ghc.ForAllTy _ t2) = areCompatibleTy t1 t2 areCompatibleTy _ _ = False -mkLambdaUnit :: ArgMapping - -> CoreExpr -> CoreExpr -> Type -> Type -> CoreExpr -mkLambdaUnit m e1 e2 (Ghc.ForAllTy _ t1) (Ghc.ForAllTy _ t2) = - mkLambdaUnit m e1 e2 t1 t2 -mkLambdaUnit m e1 e2 (Ghc.FunTy Ghc.InvisArg _ _ t1) (Ghc.FunTy Ghc.InvisArg _ _ t2) = mkLambdaUnit m e1 e2 t1 t2 -mkLambdaUnit m e1 e2 (Ghc.FunTy Ghc.VisArg _ _ t1) (Ghc.FunTy Ghc.VisArg _ _ t2) - = Lam (GM.stringVar "_" Ghc.unitTy) $ - Lam (GM.stringVar "_" Ghc.unitTy) $ - Lam (GM.stringVar "_" Ghc.unitTy) $ mkLambdaUnit m e1 e2 t1 t2 -mkLambdaUnit _ _ _ t1@Ghc.FunTy{} t2 = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2 -mkLambdaUnit _ _ _ t1 t2@Ghc.FunTy{} = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2 - -mkLambdaUnit m e1 e2 _ _ - | Ghc.FunTy {} <- Ghc.exprType e1 - , Ghc.FunTy {} <- Ghc.exprType e2 = Ghc.unitExpr - | Ghc.ForAllTy {} <- Ghc.exprType e1 - , Ghc.ForAllTy {} <- Ghc.exprType e2 = Ghc.unitExpr - | patError1 || patError2 = Ghc.unitExpr - | otherwise = Ghc.unitExpr `addLemma` cle1 `addLemma` cle2 +mkLambdaUnit :: ArgMapping -> CoreExpr -> CoreExpr -> Type -> Type -> CoreExpr -> Int -> CoreExpr +mkLambdaUnit m e1 e2 (Ghc.ForAllTy _ t1) (Ghc.ForAllTy _ t2) acc i + = mkLambdaUnit m e1 e2 t1 t2 acc i +mkLambdaUnit m e1 e2 (Ghc.FunTy Ghc.InvisArg _ _ t1) (Ghc.FunTy Ghc.InvisArg _ _ t2) acc i + = mkLambdaUnit m e1 e2 t1 t2 acc i +mkLambdaUnit m e1 e2 (Ghc.FunTy Ghc.VisArg _ _ t1) (Ghc.FunTy Ghc.VisArg _ _ t2) acc i + = Lam v1 $ Lam v2 $ Lam relV $ mkLambdaUnit m (App e1 (Var v1)) (App e2 (Var v2)) t1 t2 + (acc `addLemma` Var relV) (i + 2) + where + v1 = GM.stringVar ("x" ++ show i) Ghc.unitTy + v2 = GM.stringVar ("x" ++ show (i + 1)) Ghc.unitTy + relV = mkRelLemmaVar v1 v2 +mkLambdaUnit _ _ _ t1@Ghc.FunTy{} t2 _ _ = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2 +mkLambdaUnit _ _ _ t1 t2@Ghc.FunTy{} _ _ = F.panic $ "relTermToUnTerm: asked to relate unmatching types " ++ F.showpp t1 ++ " " ++ F.showpp t2 + +mkLambdaUnit m e1 e2 _ _ acc _ + | patError1 || patError2 = acc + | otherwise = acc `addLemma` cle1 `addLemma` cle2 where rvs = renVars m (cle1, patError1) = cleanUnTerms rvs e1 @@ -479,10 +472,8 @@ mkLambdaUnit m e1 e2 _ _ -- Generates proof: e ? lm addLemma :: CoreExpr -> CoreExpr -> CoreExpr -addLemma e lm = App (App cnst e) lm - where - cnst = Var $ GM.stringVar "const" Ghc.unitTy - -- q = Var $ GM.stringVar "?" Ghc.unitTy +addLemma e lm = App (App q e) lm + where q = Var $ GM.stringVar "?" Ghc.unitTy cleanUnTerms :: RenVars -> CoreExpr -> (CoreExpr, Bool) cleanUnTerms rvs var@(Var v) @@ -1199,6 +1190,8 @@ relWfError loc e1 e2 t1 t2 p msg relHint :: RenVars -> SpecType -> Ghc.Var -> CoreExpr -> Doc relHint rvs t v e = text "{- HLINT ignore \"Use camelCase\" -}" + $+$ text "{- HLINT ignore \"Use if\" -}" + $+$ text "{- HLINT ignore \"Use section\" -}" $+$ text ("{-@ " ++ name ++ " :: " ++ F.showpp t ++ " @-}") $+$ text (name ++ " :: " ++ removeIdent (toType False t)) $+$ text (coreToHs rvs t v e) diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index f0e6526dcd..acb2de07a5 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -264,7 +264,7 @@ solveCs cfg tgt cgi info names = do let moduleFile = "module " ++ hintName ++ " ( module " ++ hintName ++ ") where\n" let listOfImps = map (\imp -> F.symbolicString imp) (S.toList $ gsAllImps $ giSrc info) - ++ [takeBaseName tgt, "GHC.Types", "GHC.Classes"] + ++ [takeBaseName tgt, "GHC.Types", "GHC.Classes", "Language.Haskell.Liquid.ProofCombinators"] let imports = L.intercalate "\n" $ map ("import " ++) listOfImps {- diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index a23eee3ec1..688281aa72 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -303,12 +303,13 @@ pprintBody' rvs i (Tick _ e) = pprintBody' rvs i e pprintBody' _ _ e = error (" Not yet implemented for e = " ++ show e) -parenVars :: [String] -parenVars = ["+", "-", "*", "/", "%", "?", ":", "++", "==", "/="] +noParenVars :: [String] +noParenVars = ["()"] paren :: CoreExpr -> Bool -> String -> String -paren (Var v) _ res | occStr v `notElem` parenVars = res --- paren (App _ _) True res = res +paren (Var v) _ res | head (occStr v) `elem` ['a'..'z'] = res + | occStr v `elem` noParenVars = res +paren (App _ _) True res = res paren (App (Var i) _) _ res | occStr i == "I#" = res paren Lit{} _ res = res paren _ _ res = "(" ++ res ++ ")" diff --git a/tests/relational/pos/R2Dcounting_relToUn.hs b/tests/relational/pos/R2Dcounting_relToUn.hs index 1b0b34baae..7d45329636 100644 --- a/tests/relational/pos/R2Dcounting_relToUn.hs +++ b/tests/relational/pos/R2Dcounting_relToUn.hs @@ -12,44 +12,26 @@ import RTick import Prelude {- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} {-@ count2Df1Count2Df2Theorem :: p1:(lq_tmp$db##0:[GHC.Types.Int] -> GHC.Types.Bool) -> p2:(lq_tmp$db##6:[GHC.Types.Int] -> GHC.Types.Bool) -> p1p2Lemma:(lq_tmp$db##0:[GHC.Types.Int] -> lq_tmp$db##6:[GHC.Types.Int] -> lq_tmp$db##0lq_tmp$db##6Lemma:() -> ()) -> e1:GHC.Types.Int -> e2:GHC.Types.Int -> e1e2Lemma:{VV : () | e1 == e2 && p1 == p2} -> l1:[[GHC.Types.Int]] -> l2:[[GHC.Types.Int]] -> l1l2Lemma:{VV : () | l1 == l2} -> {VV : () | RTick.tcost (R2Dcounting.count2Df1 p1 e1 l1) <= RTick.tcost (R2Dcounting.count2Df2 p2 e2 l2)} @-} count2Df1Count2Df2Theorem :: ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> [GHC.Types.Int] -> () -> ()) -> GHC.Types.Int -> GHC.Types.Int -> () -> [[GHC.Types.Int]] -> [[GHC.Types.Int]] -> () -> () count2Df1Count2Df2Theorem p1 p2 p1p2Lemma e1 e2 e1e2Lemma l1 l2 l1l2Lemma = - ( const - ( ( const - ( ( ( ( {- GOAL: RTick.return ~ RTick.return -} - (\_ _ _ -> ()) - ) - 0 - ) - 0 - ) - ( ( const - ( ( const - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 0 - ) - 0 - ) - ( {- GOAL: 0 ~ 0 -} - (const ((const ()) 0)) 0 - ) - ) - ) - 0 - ) - ) - 0 - ) - ) - ) - (RTick.return 0) - ) + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) (RTick.return x1)) (RTick.return x2)) ) - (RTick.return 0) + 0 + 0 + ( ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) + ) + 0 + 0 + ( {- GOAL: 0 ~ 0 -} + (?) ((?) () 0) 0 + ) + ) {- BARE CORE \ _ [Occ=Dead] @@ -61,17 +43,15 @@ count2Df1Count2Df2Theorem p1 p2 p1p2Lemma e1 e2 e1e2Lemma l1 l2 l1l2Lemma = _ [Occ=Dead] _ [Occ=Dead] _ [Occ=Dead] -> - const - (const - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - (GHC.Types.I# 0#) - (GHC.Types.I# 0#) - (const - (const - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) - (GHC.Types.I# 0#)) - (GHC.Types.I# 0#))) - (RTick.return (GHC.Types.I# 0#))) - (RTick.return (GHC.Types.I# 0#)) + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.return x1)) + (RTick.return x2)) + (GHC.Types.I# 0#) + (GHC.Types.I# 0#) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 0# 0# (src<.:0:0> ? (? GHC.Tuple.() 0#) 0#)) -} diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs index 498004c9d6..98aeaf95ad 100644 --- a/tests/relational/pos/RConstantTimeComparison_relToUn.hs +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -13,272 +13,145 @@ import RTick import Prelude {- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} {-@ compCompTheorem :: xs1:[RConstantTimeComparison.Bit] -> xs2:[RConstantTimeComparison.Bit] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> ys1:[RConstantTimeComparison.Bit] -> ys2:[RConstantTimeComparison.Bit] -> ys1ys2Lemma:{VV : () | len xs1 == len ys1 && len xs1 == len ys2} -> {VV : () | RTick.tcost (RConstantTimeComparison.comp xs1 ys1) == RTick.tcost (RConstantTimeComparison.comp xs2 ys2)} @-} compCompTheorem :: [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> [RConstantTimeComparison.Bit] -> [RConstantTimeComparison.Bit] -> () -> () compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of [] -> case xs2 of [] -> - ( const - ( ( const - ( ( ( ( {- GOAL: RTick.return ~ RTick.return -} - (\_ _ _ -> ()) - ) - True - ) - True - ) - ( {- GOAL: True ~ True -} - (const ((const ()) True)) True - ) - ) - ) - (RTick.return True) - ) + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) (RTick.return x1)) (RTick.return x2)) ) - (RTick.return True) - (:) x2 xs2 -> {- GOAL: RTick.return True ~ () -} () + (True) + (True) + ( {- GOAL: True ~ True -} + (?) ((?) () (True)) (True) + ) + (:) x2 xs2 -> {- GOAL: RTick.return (True) ~ () -} () (:) x1 xs1 -> case xs2 of - [] -> {- GOAL: () ~ RTick.return True -} () + [] -> {- GOAL: () ~ RTick.return (True) -} () (:) x2 xs2 -> case ys1 of [] -> case ys2 of [] -> {- GOAL: () ~ () -} () - (:) y2 ys2 -> {- GOAL: () ~ let ds = (RConstantT (...) -} () + (:) y2 ys2 -> {- GOAL: () ~ let ds = RConstantTi (...) -} () (:) y1 ys1 -> case ys2 of - [] -> {- GOAL: let ds = (RConstantT (...) ~ () -} () + [] -> {- GOAL: let ds = RConstantTi (...) ~ () -} () (:) y2 ys2 -> - let ds1 = (RConstantTimeComparison.comp xs1) ys1 - in let ds2 = (RConstantTimeComparison.comp xs2) ys2 + let ds1 = RConstantTimeComparison.comp xs1 ys1 + in let ds2 = RConstantTimeComparison.comp xs2 ys2 in let ds1ds2Lemma = - ( const - ( ( const - ( ( ( ( ((compCompTheorem xs1) xs2) - ( {- GOAL: xs1 ~ xs2 -} - (const ((const ()) xs1)) xs2 - ) - ) - ys1 - ) - ys2 - ) - ( {- GOAL: ys1 ~ ys2 -} - (const ((const ()) ys1)) ys2 - ) - ) - ) - ((RConstantTimeComparison.comp xs1) ys1) - ) - ) - ((RConstantTimeComparison.comp xs2) ys2) - in let m1 = case (RConstantTimeComparison.comp xs1) ys1 of + compCompTheorem + xs1 + xs2 + ( {- GOAL: xs1 ~ xs2 -} + (?) ((?) () xs1) xs2 + ) + ys1 + ys2 + ( {- GOAL: ys1 ~ ys2 -} + (?) ((?) () ys1) ys2 + ) + in let m1 = case RConstantTimeComparison.comp xs1 ys1 of Tick m v -> m - in let m2 = case (RConstantTimeComparison.comp xs2) ys2 of + in let m2 = case RConstantTimeComparison.comp xs2 ys2 of Tick m v -> m - in let m1m2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of + in let m1m2Lemma = case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> case RConstantTimeComparison.comp xs2 ys2 of Tick m2 v2 -> {- GOAL: m1 ~ m2 -} - (const ((const ()) m1)) m2 - in let v1 = case (RConstantTimeComparison.comp xs1) ys1 of + (?) ((?) () m1) m2 + in let v1 = case RConstantTimeComparison.comp xs1 ys1 of Tick m1 v -> v - in let v2 = case (RConstantTimeComparison.comp xs2) ys2 of + in let v2 = case RConstantTimeComparison.comp xs2 ys2 of Tick m2 v -> v - in let v1v2Lemma = case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v1 -> case (RConstantTimeComparison.comp xs2) ys2 of + in let v1v2Lemma = case RConstantTimeComparison.comp xs1 ys1 of + Tick m11 v1 -> case RConstantTimeComparison.comp xs2 ys2 of Tick m22 v2 -> {- GOAL: v1 ~ v2 -} - (const ((const ()) v1)) v2 - in ( const - ( ( const - ( ( ( ( ( ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} - (\_ _ _ _ _ _ -> ()) - ) - ( ( (+) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1 - ) - ) - 1 - ) - ) - ( ( (+) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2 - ) - ) - 1 - ) - ) - ( ( const - ( ( const - ( ( ( ( ( ( ( {- GOAL: + ~ + -} - (\_ _ _ _ _ _ -> ()) - ) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1 - ) - ) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2 - ) - ) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m22 v22 -> m1m2Lemma - ) - ) - 1 - ) - 1 - ) - ( ( const - ( ( const - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 1 - ) - 1 - ) - ( {- GOAL: 1 ~ 1 -} - (const ((const ()) 1)) 1 - ) - ) - ) - 1 - ) - ) - 1 - ) - ) - ) - ( ( (+) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1 - ) - ) - 1 - ) - ) - ) - ( ( (+) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2 - ) - ) - 1 - ) - ) - ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1 - ) - ) - ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2 - ) - ) - ) - ( ( const - ( ( const - ( ( ( ( ( ( ( {- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} - (\_ _ _ _ _ _ -> ()) - ) - (((GHC.Classes.==) x1) y1) - ) - (((GHC.Classes.==) x2) y2) - ) - ( ( const - ( ( const - ( ( ( ( ( ( ( {- GOAL: GHC.Classes.== ~ GHC.Classes.== -} - (\_ _ _ _ _ _ -> ()) - ) - x1 - ) - x2 - ) - ( {- GOAL: x1 ~ x2 -} - (const ((const ()) x1)) x2 - ) - ) - y1 - ) - y2 - ) - ( {- GOAL: y1 ~ y2 -} - (const ((const ()) y1)) y2 - ) - ) - ) - (((GHC.Classes.==) x1) y1) - ) - ) - (((GHC.Classes.==) x2) y2) - ) - ) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1 - ) - ) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2 - ) - ) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m11 v11 -> case (RConstantTimeComparison.comp xs2) ys2 of - Tick m22 v22 -> v1v2Lemma - ) - ) - ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1 - ) - ) - ) - ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2 - ) - ) - ) - ) + (?) ((?) () v1) v2 + in ( {- GOAL: RTick.Tick ~ RTick.Tick -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((RTick.Tick) x1 x3)) ((RTick.Tick) x2 x4)) + ) + ( (+) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> m1 ) - ( ( RTick.Tick - ( ( (+) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> m1 - ) - ) - 1 - ) - ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x1) y1)) - ( case (RConstantTimeComparison.comp xs1) ys1 of - Tick m1 v1 -> v1 - ) - ) - ) + 1 + ) + ( (+) + ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> m2 + ) + 1 + ) + ( ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((+) x1 x3)) ((+) x2 x4)) ) - ) - ( ( RTick.Tick - ( ( (+) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> m2 - ) - ) - 1 + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> m1 + ) + ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> m2 + ) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m11 v11 -> case RConstantTimeComparison.comp xs2 ys2 of + Tick m22 v22 -> m1m2Lemma + ) + 1 + 1 + ( ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) ) + 1 + 1 + ( {- GOAL: 1 ~ 1 -} + (?) ((?) () 1) 1 + ) + ) + ) + ( RConstantTimeComparison.and + ((GHC.Classes.==) x1 y1) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> v1 + ) + ) + ( RConstantTimeComparison.and + ((GHC.Classes.==) x2 y2) + ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> v2 + ) + ) + ( ( {- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) (RConstantTimeComparison.and x1 x3)) (RConstantTimeComparison.and x2 x4)) ) - ( (RConstantTimeComparison.and (((GHC.Classes.==) x2) y2)) - ( case (RConstantTimeComparison.comp xs2) ys2 of - Tick m2 v2 -> v2 + ((GHC.Classes.==) x1 y1) + ((GHC.Classes.==) x2 y2) + ( ( {- GOAL: GHC.Classes.== ~ GHC.Classes.== -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((GHC.Classes.==) x1 x3)) ((GHC.Classes.==) x2 x4)) + ) + x1 + x2 + ( {- GOAL: x1 ~ x2 -} + (?) ((?) () x1) x2 + ) + y1 + y2 + ( {- GOAL: y1 ~ y2 -} + (?) ((?) () y1) y2 ) ) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> v1 + ) + ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> v2 + ) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m11 v11 -> case RConstantTimeComparison.comp xs2 ys2 of + Tick m22 v22 -> v1v2Lemma + ) ) {- BARE CORE @@ -288,33 +161,31 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of (ys1 :: [RConstantTimeComparison.Bit]) (ys2 :: [RConstantTimeComparison.Bit]) (ys1ys2Lemma :: [RConstantTimeComparison.Bit]) -> - case xs1 of lq_anf$##72057594037927946261 { + case xs1 of lq_anf$##72057594037927946061 { [] -> - case xs2 of lq_anf$##72057594037927946262 { + case xs2 of lq_anf$##72057594037927946062 { [] -> - const - (const - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - GHC.Types.True - GHC.Types.True - (src<.:0:0> - const (const GHC.Tuple.() GHC.Types.True) GHC.Types.True)) - (RTick.return GHC.Types.True)) - (RTick.return GHC.Types.True); + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.return x1)) + (RTick.return x2)) + GHC.Types.True + GHC.Types.True + (src<.:0:0> ? (? GHC.Tuple.() GHC.Types.True) GHC.Types.True); : x2 xs2 -> src<.:0:0> GHC.Tuple.() }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927946262 { + case xs2 of lq_anf$##72057594037927946062 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> - case ys1 of lq_anf$##72057594037927946271 { + case ys1 of lq_anf$##72057594037927946071 { [] -> - case ys2 of lq_anf$##72057594037927946272 { + case ys2 of lq_anf$##72057594037927946072 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> src<.:0:0> GHC.Tuple.() }; : y1 ys1 -> - case ys2 of lq_anf$##72057594037927946272 { + case ys2 of lq_anf$##72057594037927946072 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> let { @@ -335,17 +206,13 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] ds1ds2Lemma - = const - (const - (compCompTheorem - xs1 - xs2 - (src<.:0:0> const (const GHC.Tuple.() xs1) xs2) - ys1 - ys2 - (src<.:0:0> const (const GHC.Tuple.() ys1) ys2)) - (RConstantTimeComparison.comp xs1 ys1)) - (RConstantTimeComparison.comp xs2 ys2) } in + = compCompTheorem + xs1 + xs2 + (src<.:0:0> ? (? GHC.Tuple.() xs1) xs2) + ys1 + ys2 + (src<.:0:0> ? (? GHC.Tuple.() ys1) ys2) } in let { m1 :: GHC.Types.Int [LclId] @@ -367,7 +234,7 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - src<.:0:0> const (const GHC.Tuple.() m1) m2 + src<.:0:0> ? (? GHC.Tuple.() m1) m2 } } } in let { @@ -391,147 +258,108 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m11 v1 -> case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m22 v2 -> - src<.:0:0> const (const GHC.Tuple.() v1) v2 + src<.:0:0> ? (? GHC.Tuple.() v1) v2 } } } in - const - (const + (src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (RTick.Tick x1 x3)) + (RTick.Tick x2 x4)) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (GHC.Types.I# 1#)) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (GHC.Types.I# 1#)) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + m1m2Lemma + } + }) + (GHC.Types.I# 1#) + (GHC.Types.I# 1#) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 1# 1# (src<.:0:0> ? (? GHC.Tuple.() 1#) 1#))) + (RConstantTimeComparison.and + (GHC.Classes.== x1 y1) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + })) + (RConstantTimeComparison.and + (GHC.Classes.== x2 y2) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + })) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (RConstantTimeComparison.and x1 x3)) + (RConstantTimeComparison.and x2 x4)) + (GHC.Classes.== x1 y1) + (GHC.Classes.== x2 y2) ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - m1 - }) - (GHC.Types.I# 1#)) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - m2 - }) - (GHC.Types.I# 1#)) - (const - (const - ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m1 v1 -> - m1 - }) - (case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m2 v2 -> - m2 - }) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m11 v11 -> - case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m22 v22 -> - m1m2Lemma - } - }) - (GHC.Types.I# 1#) - (GHC.Types.I# 1#) - (const - (const - ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#)) - (GHC.Types.I# 1#)) - (GHC.Types.I# 1#))) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m1 v1 -> - m1 - }) - (GHC.Types.I# 1#))) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - m2 - }) - (GHC.Types.I# 1#))) - (RConstantTimeComparison.and - (GHC.Classes.== x1 y1) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - v1 - })) - (RConstantTimeComparison.and - (GHC.Classes.== x2 y2) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - v2 - })) - (const - (const - ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (GHC.Classes.== x1 y1) - (GHC.Classes.== x2 y2) - (const - (const - ((src<.:0:0> - \ (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) -> - GHC.Tuple.()) - x1 - x2 - (src<.:0:0> const (const GHC.Tuple.() x1) x2) - y1 - y2 - (src<.:0:0> const (const GHC.Tuple.() y1) y2)) - (GHC.Classes.== x1 y1)) - (GHC.Classes.== x2 y2)) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m1 v1 -> - v1 - }) - (case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m2 v2 -> - v2 - }) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m11 v11 -> - case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m22 v22 -> - v1v2Lemma - } - })) - (RConstantTimeComparison.and - (GHC.Classes.== x1 y1) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m1 v1 -> - v1 - }))) - (RConstantTimeComparison.and - (GHC.Classes.== x2 y2) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - v2 - })))) - (RTick.Tick - (GHC.Num.+ - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - m1 - }) - (GHC.Types.I# 1#)) - (RConstantTimeComparison.and - (GHC.Classes.== x1 y1) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - v1 - })))) - (RTick.Tick - (GHC.Num.+ - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - m2 - }) - (GHC.Types.I# 1#)) - (RConstantTimeComparison.and - (GHC.Classes.== x2 y2) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - v2 - }))) + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (GHC.Classes.== x1 x3)) + (GHC.Classes.== x2 x4)) + x1 + x2 + (src<.:0:0> ? (? GHC.Tuple.() x1) x2) + y1 + y2 + (src<.:0:0> ? (? GHC.Tuple.() y1) y2)) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + v1v2Lemma + } + })) } } } diff --git a/tests/relational/pos/RIncr_relToUn.hs b/tests/relational/pos/RIncr_relToUn.hs index 63364f2cc1..fd8d21de98 100644 --- a/tests/relational/pos/RIncr_relToUn.hs +++ b/tests/relational/pos/RIncr_relToUn.hs @@ -6,74 +6,55 @@ module RIncr_relToUn (module RIncr_relToUn) where import GHC.Classes import GHC.Types +import Language.Haskell.Liquid.ProofCombinators import RIncr import Prelude {- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} {-@ incrIncrTheorem :: xl:GHC.Types.Int -> xr:GHC.Types.Int -> xlxrLemma:{VV : () | xl < xr} -> {VV : () | RIncr.incr xl < RIncr.incr xr} @-} incrIncrTheorem :: GHC.Types.Int -> GHC.Types.Int -> () -> () incrIncrTheorem xl xr xlxrLemma = - ( const - ( ( const - ( ( ( ( ( ( ( {- GOAL: + ~ + -} - (\_ _ _ _ _ _ -> ()) - ) - xl - ) - xr - ) - xlxrLemma - ) - 1 - ) - 1 - ) - ( ( const - ( ( const - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 1 - ) - 1 - ) - ( {- GOAL: 1 ~ 1 -} - (const ((const ()) 1)) 1 - ) - ) - ) - 1 - ) - ) - 1 - ) - ) - ) - (((+) xl) 1) - ) + ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((+) x1 x3)) ((+) x2 x4)) ) - (((+) xr) 1) + xl + xr + xlxrLemma + 1 + 1 + ( ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) + ) + 1 + 1 + ( {- GOAL: 1 ~ 1 -} + (?) ((?) () 1) 1 + ) + ) {- BARE CORE \ (xl :: GHC.Types.Int) (xr :: GHC.Types.Int) (xlxrLemma :: GHC.Types.Int) -> - const - (const - ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - xl - xr - xlxrLemma - (GHC.Types.I# 1#) - (GHC.Types.I# 1#) - (const - (const - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 1# 1# (src<.:0:0> const (const GHC.Tuple.() 1#) 1#)) - (GHC.Types.I# 1#)) - (GHC.Types.I# 1#))) - (GHC.Num.+ xl (GHC.Types.I# 1#))) - (GHC.Num.+ xr (GHC.Types.I# 1#)) + (src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + xl + xr + xlxrLemma + (GHC.Types.I# 1#) + (GHC.Types.I# 1#) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 1# 1# (src<.:0:0> ? (? GHC.Tuple.() 1#) 1#)) -} diff --git a/tests/relational/pos/RMap_relToUn.hs b/tests/relational/pos/RMap_relToUn.hs index 4cf1ea9b3c..bcef216bca 100644 --- a/tests/relational/pos/RMap_relToUn.hs +++ b/tests/relational/pos/RMap_relToUn.hs @@ -6,69 +6,52 @@ module RMap_relToUn (module RMap_relToUn) where import GHC.Classes import GHC.Types +import Language.Haskell.Liquid.ProofCombinators import RMap import Prelude {- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} {-@ mapMapTheorem :: f1:(x1:GHC.Types.Int -> GHC.Types.Int) -> f2:(x2:GHC.Types.Int -> GHC.Types.Int) -> f1f2Lemma:(x1:GHC.Types.Int -> x2:GHC.Types.Int -> x1x2Lemma:() -> ()) -> xs1:[GHC.Types.Int] -> xs2:[GHC.Types.Int] -> xs1xs2Lemma:{VV : () | len xs1 == len xs2} -> {VV : () | len (RMap.map f1 xs1) == len (RMap.map f2 xs2)} @-} mapMapTheorem :: (GHC.Types.Int -> GHC.Types.Int) -> (GHC.Types.Int -> GHC.Types.Int) -> (GHC.Types.Int -> GHC.Types.Int -> () -> ()) -> [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of [] -> case xs2 of - [] -> {- GOAL: [] ~ [] -} () + [] -> + {- GOAL: [] ~ [] -} + (?) ((?) () ([])) ([]) (:) x2 xs2 -> - {- GOAL: [] ~ ((:) (f2 x2)) ((RMap (...) -} - (const ((const ()) [])) (((:) (f2 x2)) ((RMap.map f2) xs2)) + {- GOAL: [] ~ (:) (f2 x2) (RMap.ma (...) -} + (?) ((?) () ([])) ((:) (f2 x2) (RMap.map f2 xs2)) (:) x1 xs1 -> case xs2 of [] -> - {- GOAL: ((:) (f1 x1)) ((RMap (...) ~ [] -} - (const ((const ()) (((:) (f1 x1)) ((RMap.map f1) xs1)))) [] + {- GOAL: (:) (f1 x1) (RMap.ma (...) ~ [] -} + (?) ((?) () ((:) (f1 x1) (RMap.map f1 xs1))) ([]) (:) x2 xs2 -> - ( const - ( ( const - ( ( ( ( ( ( ( {- GOAL: : ~ : -} - (\_ _ _ _ _ _ -> ()) - ) - (f1 x1) - ) - (f2 x2) - ) - ( ( const - ( ( const - ( ((f1f2Lemma x1) x2) - ( {- GOAL: x1 ~ x2 -} - (const ((const ()) x1)) x2 - ) - ) - ) - (f1 x1) - ) - ) - (f2 x2) - ) - ) - ((RMap.map f1) xs1) - ) - ((RMap.map f2) xs2) - ) - ( ( const - ( ( const - ( (((((mapMapTheorem f1) f2) f1f2Lemma) xs1) xs2) - ( {- GOAL: xs1 ~ xs2 -} - (const ((const ()) xs1)) xs2 - ) - ) - ) - ((RMap.map f1) xs1) - ) - ) - ((RMap.map f2) xs2) - ) - ) - ) - (((:) (f1 x1)) ((RMap.map f1) xs1)) - ) + ( {- GOAL: : ~ : -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((:) x1 x3)) ((:) x2 x4)) ) - (((:) (f2 x2)) ((RMap.map f2) xs2)) + (f1 x1) + (f2 x2) + ( f1f2Lemma + x1 + x2 + ( {- GOAL: x1 ~ x2 -} + (?) ((?) () x1) x2 + ) + ) + (RMap.map f1 xs1) + (RMap.map f2 xs2) + ( mapMapTheorem + f1 + f2 + f1f2Lemma + xs1 + xs2 + ( {- GOAL: xs1 ~ xs2 -} + (?) ((?) () xs1) xs2 + ) + ) {- BARE CORE \ (f1 :: GHC.Types.Int -> GHC.Types.Int) @@ -77,51 +60,38 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of (xs1 :: [GHC.Types.Int]) (xs2 :: [GHC.Types.Int]) (xs1xs2Lemma :: [GHC.Types.Int]) -> - case xs1 of lq_anf$##72057594037927940391 { + case xs1 of lq_anf$##72057594037927940271 { [] -> - case xs2 of lq_anf$##72057594037927940392 { - [] -> src<.:0:0> GHC.Tuple.(); + case xs2 of lq_anf$##72057594037927940272 { + [] -> src<.:0:0> ? (? GHC.Tuple.() GHC.Types.[]) GHC.Types.[]; : x2 xs2 -> src<.:0:0> - const - (const GHC.Tuple.() GHC.Types.[]) + ? (? GHC.Tuple.() GHC.Types.[]) (GHC.Types.: (f2 x2) (RMap.map f2 xs2)) }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927940392 { + case xs2 of lq_anf$##72057594037927940272 { [] -> src<.:0:0> - const - (const GHC.Tuple.() (GHC.Types.: (f1 x1) (RMap.map f1 xs1))) + ? (? GHC.Tuple.() (GHC.Types.: (f1 x1) (RMap.map f1 xs1))) GHC.Types.[]; : x2 xs2 -> - const - (const - ((src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (f1 x1) - (f2 x2) - (const - (const - (f1f2Lemma x1 x2 (src<.:0:0> const (const GHC.Tuple.() x1) x2)) - (f1 x1)) - (f2 x2)) - (RMap.map f1 xs1) - (RMap.map f2 xs2) - (const - (const - (mapMapTheorem - f1 - f2 - f1f2Lemma - xs1 - xs2 - (src<.:0:0> const (const GHC.Tuple.() xs1) xs2)) - (RMap.map f1 xs1)) - (RMap.map f2 xs2))) - (GHC.Types.: (f1 x1) (RMap.map f1 xs1))) - (GHC.Types.: (f2 x2) (RMap.map f2 xs2)) + (src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (GHC.Types.: x1 x3)) + (GHC.Types.: x2 x4)) + (f1 x1) + (f2 x2) + (f1f2Lemma x1 x2 (src<.:0:0> ? (? GHC.Tuple.() x1) x2)) + (RMap.map f1 xs1) + (RMap.map f2 xs2) + (mapMapTheorem + f1 f2 f1f2Lemma xs1 xs2 (src<.:0:0> ? (? GHC.Tuple.() xs1) xs2)) } } -} diff --git a/tests/relational/pos/RMemAlloc_relToUn.hs b/tests/relational/pos/RMemAlloc_relToUn.hs index 13248cb12c..f111b8f1f7 100644 --- a/tests/relational/pos/RMemAlloc_relToUn.hs +++ b/tests/relational/pos/RMemAlloc_relToUn.hs @@ -12,91 +12,71 @@ import RTick import Prelude {- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} {-@ length1Length2Theorem :: xs1:[GHC.Types.Int] -> xs2:[GHC.Types.Int] -> xs1xs2Lemma:{VV : () | xs1 == xs2} -> {VV : () | RTick.tcost (RMemAlloc.length2 xs1) - RTick.tcost (RMemAlloc.length1 xs1) == len xs1} @-} length1Length2Theorem :: [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () length1Length2Theorem xs1 xs2 xs1xs2Lemma = - ( const - ( ( const - ( ( ( ( ( ( ( ( ( ( {- GOAL: RMemAlloc.foldl' ~ RMemAlloc.foldl -} - (\_ _ _ _ _ _ _ _ _ -> ()) - ) - RMemAlloc.upd - ) - RMemAlloc.upd - ) - ( {- GOAL: RMemAlloc.upd ~ RMemAlloc.upd -} - (\_ _ _ _ _ _ -> ()) - ) - ) - 0 - ) - 0 - ) - ( ( const - ( ( const - ( ( ( ( {- GOAL: ~ -} - (\_ _ _ -> ()) - ) - 0 - ) - 0 - ) - ( {- GOAL: 0 ~ 0 -} - (const ((const ()) 0)) 0 - ) - ) - ) - 0 - ) - ) - 0 - ) - ) - xs1 - ) - xs2 - ) - xs1xs2Lemma - ) - ) - (((RMemAlloc.foldl' RMemAlloc.upd) 0) xs1) - ) + ( {- GOAL: RMemAlloc.foldl' ~ RMemAlloc.foldl -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma x5 x6 x5x6Lemma -> (?) ((?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) x5x6Lemma) (RMemAlloc.foldl' x1 x3 x5)) (RMemAlloc.foldl x2 x4 x6)) ) - (((RMemAlloc.foldl RMemAlloc.upd) 0) xs2) + RMemAlloc.upd + RMemAlloc.upd + ( {- GOAL: RMemAlloc.upd ~ RMemAlloc.upd -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) (RMemAlloc.upd x1 x3)) (RMemAlloc.upd x2 x4)) + ) + 0 + 0 + ( ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) + ) + 0 + 0 + ( {- GOAL: 0 ~ 0 -} + (?) ((?) () 0) 0 + ) + ) + xs1 + xs2 + xs1xs2Lemma {- BARE CORE \ (xs1 :: [GHC.Types.Int]) (xs2 :: [GHC.Types.Int]) (xs1xs2Lemma :: [GHC.Types.Int]) -> - const - (const - ((src<.:0:0> - \ (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) - (_ :: ()) -> - GHC.Tuple.()) - RMemAlloc.upd - RMemAlloc.upd - (src<.:0:0> - \ (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) (_ :: ()) -> - GHC.Tuple.()) - (GHC.Types.I# 0#) - (GHC.Types.I# 0#) - (const - (const - ((src<.:0:0> \ (_ :: ()) (_ :: ()) (_ :: ()) -> GHC.Tuple.()) - 0# 0# (src<.:0:0> const (const GHC.Tuple.() 0#) 0#)) - (GHC.Types.I# 0#)) - (GHC.Types.I# 0#)) - xs1 - xs2 - xs1xs2Lemma) - (RMemAlloc.foldl' RMemAlloc.upd (GHC.Types.I# 0#) xs1)) - (RMemAlloc.foldl RMemAlloc.upd (GHC.Types.I# 0#) xs2) + (src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) + (x5 :: ()) + (x6 :: ()) + (x5x6Lemma :: ()) -> + ? (? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) x5x6Lemma) + (RMemAlloc.foldl' x1 x3 x5)) + (RMemAlloc.foldl x2 x4 x6)) + RMemAlloc.upd + RMemAlloc.upd + (src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (RMemAlloc.upd x1 x3)) + (RMemAlloc.upd x2 x4)) + (GHC.Types.I# 0#) + (GHC.Types.I# 0#) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 0# 0# (src<.:0:0> ? (? GHC.Tuple.() 0#) 0#)) + xs1 + xs2 + xs1xs2Lemma -} diff --git a/tests/relational/pos/RVar_relToUn.hs b/tests/relational/pos/RVar_relToUn.hs index a858014201..cff3c4f395 100644 --- a/tests/relational/pos/RVar_relToUn.hs +++ b/tests/relational/pos/RVar_relToUn.hs @@ -6,16 +6,19 @@ module RVar_relToUn (module RVar_relToUn) where import GHC.Classes import GHC.Types +import Language.Haskell.Liquid.ProofCombinators import RVar import Prelude {- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} {-@ y1Y2Theorem :: {VV : () | RVar.y1 <= RVar.y2} @-} y1Y2Theorem :: () y1Y2Theorem = {- GOAL: RVar.x1 ~ RVar.x2 -} - (const ((const ()) RVar.x1)) RVar.x2 + (?) ((?) () RVar.x1) RVar.x2 {- BARE CORE -src<.:0:0> const (const GHC.Tuple.() RVar.x1) RVar.x2 +src<.:0:0> ? (? GHC.Tuple.() RVar.x1) RVar.x2 -} diff --git a/tests/tests.cabal b/tests/tests.cabal index 081bf43225..101b0e7437 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2053,6 +2053,7 @@ executable relational-pos , PolyNull , PredAbs , Prims + , R2Dcounting_relToUn , R2Dcounting , RConstantTimeComparison_relToUn , RConstantTimeComparison @@ -2062,6 +2063,7 @@ executable relational-pos , RIncr , RMap_relToUn , RMap + , RMemAlloc_relToUn , RMemAlloc , RPatError , RTick From bad8db7c4f6863d88af190a7935bdeb1b9dd2fdf Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 13 Apr 2023 13:41:22 +0100 Subject: [PATCH 204/219] restrict constant folding of let expressions --- .../Haskell/Liquid/Constraint/Relational.hs | 2 +- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 10 +- tests/relational/pos/R2Dcounting_relToUn.hs | 6 +- .../pos/RConstantTimeComparison_relToUn.hs | 517 ++++++++-------- tests/relational/pos/RIncr_relToUn.hs | 6 +- tests/relational/pos/RMap_relToUn.hs | 16 +- tests/relational/pos/RMemAlloc_relToUn.hs | 8 +- tests/relational/pos/RRelationalISort.hs | 90 +++ tests/relational/pos/RRelationalMSort.hs | 69 +++ tests/relational/pos/RSquareAndMultiply.hs | 76 +++ .../pos/RSquareAndMultiply_relToUn.hs | 585 ++++++++++++++++++ tests/relational/pos/RVar_relToUn.hs | 2 +- tests/tests.cabal | 4 +- 13 files changed, 1112 insertions(+), 279 deletions(-) create mode 100644 tests/relational/pos/RRelationalISort.hs create mode 100644 tests/relational/pos/RRelationalMSort.hs create mode 100644 tests/relational/pos/RSquareAndMultiply.hs create mode 100644 tests/relational/pos/RSquareAndMultiply_relToUn.hs diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index 4ff7786ca0..f21b50ada4 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -354,7 +354,7 @@ relTermToUnTerm' m relTerms (Let (NonRec x1 d1) e1) (Let (NonRec x2 d2) e2) , not b1 , not b2 = Let (NonRec x1l d1') $ Let (NonRec x2r d2') $ Let (NonRec relX relD) $ - relTermToUnTerm' m (((x1l, x2r), Var relX) : relTerms) e1l e2r + relTermToUnTerm' m (((x1l, x2r), Var relX) : relTerms) e1l e2r `addLemma` Var relX where relX = mkRelLemmaVar x1l x2r relD = relTermToUnTerm' m relTerms d1 d2 diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 688281aa72..fa5721e922 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -264,7 +264,8 @@ pprintBody' rvs i (App e Type{}) = pprintBody' rvs i e pprintBody' rvs i (App e1 e2) | undesirableVar e1 = pprintBody' rvs i e2 | undesirableVar e2 = pprintBody' rvs i e1 - | otherwise = paren e1 True left ++ " " ++ paren e2 False right + | isOperator e1 = paren e2 False right ++ " " ++ paren e1 False left + | otherwise = paren e1 True left ++ " " ++ paren e2 False right where left = pprintBody' rvs i e1 right = pprintBody' rvs (i+1) e2 @@ -306,9 +307,12 @@ pprintBody' _ _ e = error (" Not yet implemented for e = " ++ show e) noParenVars :: [String] noParenVars = ["()"] +isOperator :: CoreExpr -> Bool +isOperator (Var v) | head (occStr v) `notElem` ['a'..'z'] = True +isOperator _ = False + paren :: CoreExpr -> Bool -> String -> String -paren (Var v) _ res | head (occStr v) `elem` ['a'..'z'] = res - | occStr v `elem` noParenVars = res +paren (Var _) _ res = res paren (App _ _) True res = res paren (App (Var i) _) _ res | occStr i == "I#" = res paren Lit{} _ res = res diff --git a/tests/relational/pos/R2Dcounting_relToUn.hs b/tests/relational/pos/R2Dcounting_relToUn.hs index 7d45329636..67cda7e690 100644 --- a/tests/relational/pos/R2Dcounting_relToUn.hs +++ b/tests/relational/pos/R2Dcounting_relToUn.hs @@ -19,17 +19,17 @@ import Prelude count2Df1Count2Df2Theorem :: ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> GHC.Types.Bool) -> ([GHC.Types.Int] -> [GHC.Types.Int] -> () -> ()) -> GHC.Types.Int -> GHC.Types.Int -> () -> [[GHC.Types.Int]] -> [[GHC.Types.Int]] -> () -> () count2Df1Count2Df2Theorem p1 p2 p1p2Lemma e1 e2 e1e2Lemma l1 l2 l1l2Lemma = ( {- GOAL: RTick.return ~ RTick.return -} - (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) (RTick.return x1)) (RTick.return x2)) + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.return x1)) ? (RTick.return x2)) ) 0 0 ( ( {- GOAL: ~ -} - (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? x1) ? x2) ) 0 0 ( {- GOAL: 0 ~ 0 -} - (?) ((?) () 0) 0 + (() ? 0) ? 0 ) ) diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs index 98aeaf95ad..510fe17c8f 100644 --- a/tests/relational/pos/RConstantTimeComparison_relToUn.hs +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -22,16 +22,16 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of [] -> case xs2 of [] -> ( {- GOAL: RTick.return ~ RTick.return -} - (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) (RTick.return x1)) (RTick.return x2)) + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.return x1)) ? (RTick.return x2)) ) - (True) - (True) + True + True ( {- GOAL: True ~ True -} - (?) ((?) () (True)) (True) + (() ? True) ? True ) - (:) x2 xs2 -> {- GOAL: RTick.return (True) ~ () -} () + (:) x2 xs2 -> {- GOAL: RTick.return True ~ () -} () (:) x1 xs1 -> case xs2 of - [] -> {- GOAL: () ~ RTick.return (True) -} () + [] -> {- GOAL: () ~ RTick.return True -} () (:) x2 xs2 -> case ys1 of [] -> case ys2 of [] -> {- GOAL: () ~ () -} () @@ -46,113 +46,117 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of xs1 xs2 ( {- GOAL: xs1 ~ xs2 -} - (?) ((?) () xs1) xs2 + (() ? xs1) ? xs2 ) ys1 ys2 ( {- GOAL: ys1 ~ ys2 -} - (?) ((?) () ys1) ys2 + (() ? ys1) ? ys2 ) - in let m1 = case RConstantTimeComparison.comp xs1 ys1 of - Tick m v -> m - in let m2 = case RConstantTimeComparison.comp xs2 ys2 of - Tick m v -> m - in let m1m2Lemma = case RConstantTimeComparison.comp xs1 ys1 of - Tick m1 v1 -> case RConstantTimeComparison.comp xs2 ys2 of - Tick m2 v2 -> - {- GOAL: m1 ~ m2 -} - (?) ((?) () m1) m2 - in let v1 = case RConstantTimeComparison.comp xs1 ys1 of - Tick m1 v -> v - in let v2 = case RConstantTimeComparison.comp xs2 ys2 of - Tick m2 v -> v - in let v1v2Lemma = case RConstantTimeComparison.comp xs1 ys1 of - Tick m11 v1 -> case RConstantTimeComparison.comp xs2 ys2 of - Tick m22 v2 -> - {- GOAL: v1 ~ v2 -} - (?) ((?) () v1) v2 - in ( {- GOAL: RTick.Tick ~ RTick.Tick -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((RTick.Tick) x1 x3)) ((RTick.Tick) x2 x4)) - ) - ( (+) - ( case RConstantTimeComparison.comp xs1 ys1 of - Tick m1 v1 -> m1 + in ( let m1 = case RConstantTimeComparison.comp xs1 ys1 of + Tick m v -> m + in let m2 = case RConstantTimeComparison.comp xs2 ys2 of + Tick m v -> m + in let m1m2Lemma = case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> + {- GOAL: m1 ~ m2 -} + (() ? m1) ? m2 + in ( let v1 = case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v -> v + in let v2 = case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v -> v + in let v1v2Lemma = case RConstantTimeComparison.comp xs1 ys1 of + Tick m11 v1 -> case RConstantTimeComparison.comp xs2 ys2 of + Tick m22 v2 -> + {- GOAL: v1 ~ v2 -} + (() ? v1) ? v2 + in ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 RTick.Tick x3)) ? (x2 RTick.Tick x4)) ) - 1 - ) - ( (+) - ( case RConstantTimeComparison.comp xs2 ys2 of - Tick m2 v2 -> m2 - ) - 1 - ) - ( ( {- GOAL: + ~ + -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((+) x1 x3)) ((+) x2 x4)) - ) - ( case RConstantTimeComparison.comp xs1 ys1 of - Tick m1 v1 -> m1 - ) - ( case RConstantTimeComparison.comp xs2 ys2 of - Tick m2 v2 -> m2 - ) - ( case RConstantTimeComparison.comp xs1 ys1 of - Tick m11 v11 -> case RConstantTimeComparison.comp xs2 ys2 of - Tick m22 v22 -> m1m2Lemma - ) - 1 - 1 - ( ( {- GOAL: ~ -} - (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) + ( ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> m1 + ) + + 1 ) - 1 - 1 - ( {- GOAL: 1 ~ 1 -} - (?) ((?) () 1) 1 + ( ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> m2 ) - ) - ) - ( RConstantTimeComparison.and - ((GHC.Classes.==) x1 y1) - ( case RConstantTimeComparison.comp xs1 ys1 of - Tick m1 v1 -> v1 - ) - ) - ( RConstantTimeComparison.and - ((GHC.Classes.==) x2 y2) - ( case RConstantTimeComparison.comp xs2 ys2 of - Tick m2 v2 -> v2 - ) - ) - ( ( {- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) (RConstantTimeComparison.and x1 x3)) (RConstantTimeComparison.and x2 x4)) - ) - ((GHC.Classes.==) x1 y1) - ((GHC.Classes.==) x2 y2) - ( ( {- GOAL: GHC.Classes.== ~ GHC.Classes.== -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((GHC.Classes.==) x1 x3)) ((GHC.Classes.==) x2 x4)) + + 1 ) - x1 - x2 - ( {- GOAL: x1 ~ x2 -} - (?) ((?) () x1) x2 + ( ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 + x3)) ? (x2 + x4)) ) - y1 - y2 - ( {- GOAL: y1 ~ y2 -} - (?) ((?) () y1) y2 + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> m1 + ) + ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> m2 + ) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m11 v11 -> case RConstantTimeComparison.comp xs2 ys2 of + Tick m22 v22 -> m1m2Lemma + ) + 1 + 1 + ( ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? x1) ? x2) + ) + 1 + 1 + ( {- GOAL: 1 ~ 1 -} + (() ? 1) ? 1 + ) + ) + ) + ( RConstantTimeComparison.and + (x1 GHC.Classes.== y1) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> v1 + ) + ) + ( RConstantTimeComparison.and + (x2 GHC.Classes.== y2) + ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> v2 + ) + ) + ( ( {- GOAL: RConstantTimeCompari (...) ~ RConstantTimeCompari (...) -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (RConstantTimeComparison.and x1 x3)) ? (RConstantTimeComparison.and x2 x4)) ) - ) - ( case RConstantTimeComparison.comp xs1 ys1 of - Tick m1 v1 -> v1 - ) - ( case RConstantTimeComparison.comp xs2 ys2 of - Tick m2 v2 -> v2 - ) - ( case RConstantTimeComparison.comp xs1 ys1 of - Tick m11 v11 -> case RConstantTimeComparison.comp xs2 ys2 of - Tick m22 v22 -> v1v2Lemma - ) - ) + (x1 GHC.Classes.== y1) + (x2 GHC.Classes.== y2) + ( ( {- GOAL: GHC.Classes.== ~ GHC.Classes.== -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 GHC.Classes.== x3)) ? (x2 GHC.Classes.== x4)) + ) + x1 + x2 + ( {- GOAL: x1 ~ x2 -} + (() ? x1) ? x2 + ) + y1 + y2 + ( {- GOAL: y1 ~ y2 -} + (() ? y1) ? y2 + ) + ) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m1 v1 -> v1 + ) + ( case RConstantTimeComparison.comp xs2 ys2 of + Tick m2 v2 -> v2 + ) + ( case RConstantTimeComparison.comp xs1 ys1 of + Tick m11 v11 -> case RConstantTimeComparison.comp xs2 ys2 of + Tick m22 v22 -> v1v2Lemma + ) + ) + ) + ? v1v2Lemma + ) + ? m1m2Lemma + ) + ? ds1ds2Lemma {- BARE CORE \ (xs1 :: [RConstantTimeComparison.Bit]) @@ -161,9 +165,9 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of (ys1 :: [RConstantTimeComparison.Bit]) (ys2 :: [RConstantTimeComparison.Bit]) (ys1ys2Lemma :: [RConstantTimeComparison.Bit]) -> - case xs1 of lq_anf$##72057594037927946061 { + case xs1 of lq_anf$##72057594037927948741 { [] -> - case xs2 of lq_anf$##72057594037927946062 { + case xs2 of lq_anf$##72057594037927948742 { [] -> (src<.:0:0> \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> @@ -175,17 +179,17 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of : x2 xs2 -> src<.:0:0> GHC.Tuple.() }; : x1 xs1 -> - case xs2 of lq_anf$##72057594037927946062 { + case xs2 of lq_anf$##72057594037927948742 { [] -> src<.:0:0> GHC.Tuple.(); : x2 xs2 -> - case ys1 of lq_anf$##72057594037927946071 { + case ys1 of lq_anf$##72057594037927948751 { [] -> - case ys2 of lq_anf$##72057594037927946072 { + case ys2 of lq_anf$##72057594037927948752 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> src<.:0:0> GHC.Tuple.() }; : y1 ys1 -> - case ys2 of lq_anf$##72057594037927946072 { + case ys2 of lq_anf$##72057594037927948752 { [] -> src<.:0:0> GHC.Tuple.(); : y2 ys2 -> let { @@ -213,153 +217,156 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of ys1 ys2 (src<.:0:0> ? (? GHC.Tuple.() ys1) ys2) } in - let { - m1 :: GHC.Types.Int - [LclId] - m1 - = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m v -> - m - } } in - let { - m2 :: GHC.Types.Int - [LclId] - m2 - = case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m v -> - m - } } in - let { - m1m2Lemma :: GHC.Types.Int - [LclId] - m1m2Lemma - = case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m1 v1 -> - case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - src<.:0:0> ? (? GHC.Tuple.() m1) m2 - } - } } in - let { - v1 :: GHC.Types.Bool - [LclId] - v1 - = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v -> - v - } } in - let { - v2 :: GHC.Types.Bool - [LclId] - v2 - = case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v -> - v - } } in - let { - v1v2Lemma :: GHC.Types.Bool - [LclId] - v1v2Lemma - = case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m11 v1 -> - case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m22 v2 -> - src<.:0:0> ? (? GHC.Tuple.() v1) v2 - } - } } in - (src<.:0:0> - \ (x1 :: ()) - (x2 :: ()) - (x1x2Lemma :: ()) - (x3 :: ()) - (x4 :: ()) - (x3x4Lemma :: ()) -> - ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (RTick.Tick x1 x3)) - (RTick.Tick x2 x4)) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - m1 - }) - (GHC.Types.I# 1#)) - (GHC.Num.+ - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - m2 - }) - (GHC.Types.I# 1#)) - ((src<.:0:0> - \ (x1 :: ()) - (x2 :: ()) - (x1x2Lemma :: ()) - (x3 :: ()) - (x4 :: ()) - (x3x4Lemma :: ()) -> - ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (GHC.Num.+ x1 x3)) - (GHC.Num.+ x2 x4)) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - m1 - }) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - m2 - }) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m11 v11 -> - case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m22 v22 -> - m1m2Lemma - } - }) - (GHC.Types.I# 1#) - (GHC.Types.I# 1#) - ((src<.:0:0> - \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> - ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) - (GHC.Types.I# x2)) - 1# 1# (src<.:0:0> ? (? GHC.Tuple.() 1#) 1#))) - (RConstantTimeComparison.and - (GHC.Classes.== x1 y1) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - v1 - })) - (RConstantTimeComparison.and - (GHC.Classes.== x2 y2) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - v2 - })) - ((src<.:0:0> - \ (x1 :: ()) - (x2 :: ()) - (x1x2Lemma :: ()) - (x3 :: ()) - (x4 :: ()) - (x3x4Lemma :: ()) -> - ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) - (RConstantTimeComparison.and x1 x3)) - (RConstantTimeComparison.and x2 x4)) - (GHC.Classes.== x1 y1) - (GHC.Classes.== x2 y2) - ((src<.:0:0> - \ (x1 :: ()) - (x2 :: ()) - (x1x2Lemma :: ()) - (x3 :: ()) - (x4 :: ()) - (x3x4Lemma :: ()) -> - ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) - (GHC.Classes.== x1 x3)) - (GHC.Classes.== x2 x4)) - x1 - x2 - (src<.:0:0> ? (? GHC.Tuple.() x1) x2) - y1 - y2 - (src<.:0:0> ? (? GHC.Tuple.() y1) y2)) - (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> - v1 - }) - (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> - v2 - }) - (case RConstantTimeComparison.comp xs1 ys1 of - { RTick.Tick m11 v11 -> - case RConstantTimeComparison.comp xs2 ys2 of - { RTick.Tick m22 v22 -> - v1v2Lemma - } - })) + ? (let { + m1 :: GHC.Types.Int + [LclId] + m1 + = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m v -> + m + } } in + let { + m2 :: GHC.Types.Int + [LclId] + m2 + = case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m v -> + m + } } in + let { + m1m2Lemma :: GHC.Types.Int + [LclId] + m1m2Lemma + = case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m1 v1 -> + case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + src<.:0:0> ? (? GHC.Tuple.() m1) m2 + } + } } in + ? (let { + v1 :: GHC.Types.Bool + [LclId] + v1 + = case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v -> + v + } } in + let { + v2 :: GHC.Types.Bool + [LclId] + v2 + = case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v -> + v + } } in + let { + v1v2Lemma :: GHC.Types.Bool + [LclId] + v1v2Lemma + = case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v1 -> + case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m22 v2 -> + src<.:0:0> ? (? GHC.Tuple.() v1) v2 + } + } } in + ? ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (RTick.Tick x1 x3)) + (RTick.Tick x2 x4)) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (GHC.Types.I# 1#)) + (GHC.Num.+ + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (GHC.Types.I# 1#)) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + m1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + m2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + m1m2Lemma + } + }) + (GHC.Types.I# 1#) + (GHC.Types.I# 1#) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 1# 1# (src<.:0:0> ? (? GHC.Tuple.() 1#) 1#))) + (RConstantTimeComparison.and + (GHC.Classes.== x1 y1) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + })) + (RConstantTimeComparison.and + (GHC.Classes.== x2 y2) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + })) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (RConstantTimeComparison.and x1 x3)) + (RConstantTimeComparison.and x2 x4)) + (GHC.Classes.== x1 y1) + (GHC.Classes.== x2 y2) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (GHC.Classes.== x1 x3)) + (GHC.Classes.== x2 x4)) + x1 + x2 + (src<.:0:0> ? (? GHC.Tuple.() x1) x2) + y1 + y2 + (src<.:0:0> ? (? GHC.Tuple.() y1) y2)) + (case RConstantTimeComparison.comp xs1 ys1 of { RTick.Tick m1 v1 -> + v1 + }) + (case RConstantTimeComparison.comp xs2 ys2 of { RTick.Tick m2 v2 -> + v2 + }) + (case RConstantTimeComparison.comp xs1 ys1 of + { RTick.Tick m11 v11 -> + case RConstantTimeComparison.comp xs2 ys2 of + { RTick.Tick m22 v22 -> + v1v2Lemma + } + }))) + v1v2Lemma) + m1m2Lemma) + ds1ds2Lemma } } } diff --git a/tests/relational/pos/RIncr_relToUn.hs b/tests/relational/pos/RIncr_relToUn.hs index fd8d21de98..3867d633da 100644 --- a/tests/relational/pos/RIncr_relToUn.hs +++ b/tests/relational/pos/RIncr_relToUn.hs @@ -17,7 +17,7 @@ import Prelude incrIncrTheorem :: GHC.Types.Int -> GHC.Types.Int -> () -> () incrIncrTheorem xl xr xlxrLemma = ( {- GOAL: + ~ + -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((+) x1 x3)) ((+) x2 x4)) + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 + x3)) ? (x2 + x4)) ) xl xr @@ -25,12 +25,12 @@ incrIncrTheorem xl xr xlxrLemma = 1 1 ( ( {- GOAL: ~ -} - (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? x1) ? x2) ) 1 1 ( {- GOAL: 1 ~ 1 -} - (?) ((?) () 1) 1 + (() ? 1) ? 1 ) ) diff --git a/tests/relational/pos/RMap_relToUn.hs b/tests/relational/pos/RMap_relToUn.hs index bcef216bca..fb7a4a4cc4 100644 --- a/tests/relational/pos/RMap_relToUn.hs +++ b/tests/relational/pos/RMap_relToUn.hs @@ -19,17 +19,17 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of [] -> case xs2 of [] -> {- GOAL: [] ~ [] -} - (?) ((?) () ([])) ([]) + (() ? []) ? [] (:) x2 xs2 -> - {- GOAL: [] ~ (:) (f2 x2) (RMap.ma (...) -} - (?) ((?) () ([])) ((:) (f2 x2) (RMap.map f2 xs2)) + {- GOAL: [] ~ (f2 x2) : (RMap.map (...) -} + (() ? []) ? ((f2 x2) : (RMap.map f2 xs2)) (:) x1 xs1 -> case xs2 of [] -> - {- GOAL: (:) (f1 x1) (RMap.ma (...) ~ [] -} - (?) ((?) () ((:) (f1 x1) (RMap.map f1 xs1))) ([]) + {- GOAL: (f1 x1) : (RMap.map (...) ~ [] -} + (() ? ((f1 x1) : (RMap.map f1 xs1))) ? [] (:) x2 xs2 -> ( {- GOAL: : ~ : -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) ((:) x1 x3)) ((:) x2 x4)) + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 : x3)) ? (x2 : x4)) ) (f1 x1) (f2 x2) @@ -37,7 +37,7 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of x1 x2 ( {- GOAL: x1 ~ x2 -} - (?) ((?) () x1) x2 + (() ? x1) ? x2 ) ) (RMap.map f1 xs1) @@ -49,7 +49,7 @@ mapMapTheorem f1 f2 f1f2Lemma xs1 xs2 xs1xs2Lemma = case xs1 of xs1 xs2 ( {- GOAL: xs1 ~ xs2 -} - (?) ((?) () xs1) xs2 + (() ? xs1) ? xs2 ) ) diff --git a/tests/relational/pos/RMemAlloc_relToUn.hs b/tests/relational/pos/RMemAlloc_relToUn.hs index f111b8f1f7..5d3eee5e7d 100644 --- a/tests/relational/pos/RMemAlloc_relToUn.hs +++ b/tests/relational/pos/RMemAlloc_relToUn.hs @@ -18,22 +18,22 @@ import Prelude length1Length2Theorem :: [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () length1Length2Theorem xs1 xs2 xs1xs2Lemma = ( {- GOAL: RMemAlloc.foldl' ~ RMemAlloc.foldl -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma x5 x6 x5x6Lemma -> (?) ((?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) x5x6Lemma) (RMemAlloc.foldl' x1 x3 x5)) (RMemAlloc.foldl x2 x4 x6)) + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma x5 x6 x5x6Lemma -> ((((() ? x1x2Lemma) ? x3x4Lemma) ? x5x6Lemma) ? (RMemAlloc.foldl' x1 x3 x5)) ? (RMemAlloc.foldl x2 x4 x6)) ) RMemAlloc.upd RMemAlloc.upd ( {- GOAL: RMemAlloc.upd ~ RMemAlloc.upd -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (?) ((?) ((?) ((?) () x1x2Lemma) x3x4Lemma) (RMemAlloc.upd x1 x3)) (RMemAlloc.upd x2 x4)) + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (RMemAlloc.upd x1 x3)) ? (RMemAlloc.upd x2 x4)) ) 0 0 ( ( {- GOAL: ~ -} - (\x1 x2 x1x2Lemma -> (?) ((?) ((?) () x1x2Lemma) x1) x2) + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? x1) ? x2) ) 0 0 ( {- GOAL: 0 ~ 0 -} - (?) ((?) () 0) 0 + (() ? 0) ? 0 ) ) xs1 diff --git a/tests/relational/pos/RRelationalISort.hs b/tests/relational/pos/RRelationalISort.hs new file mode 100644 index 0000000000..d35c7a8397 --- /dev/null +++ b/tests/relational/pos/RRelationalISort.hs @@ -0,0 +1,90 @@ +{- POPL'17 Radicek et al. -} +{- ISort 16/11/69 -} + +{- LIQUID "--relational-hints" @-} +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple-local" @-} + +module RRelationalISort where +import Prelude hiding (return, (>>=), pure, sort, (<*>), length) +import Lists +{-@ infix : @-} +{-@ infix @-} +import RTick +import Language.Haskell.Liquid.ProofCombinators +import Language.Haskell.Liquid.Bag + +--- Proof --- +{-@ relational isort ~ isort + :: { l1:[a] -> Tick [a] + ~ l2:[a] -> Tick [a] + | !(true) + :=> !(Lists.length l1 = Lists.length l2) + :=> RTick.tcost (r1 l1) - RTick.tcost (r2 l2) + <= RRelationalISort.unsortedDiff l1 l2 } +@-} + +{-@ relational insert ~ insert :: { x1:a -> xs1:[a] -> Tick [a] + ~ x2:a -> xs2:[a] -> Tick [a] + | !(true) + :=> !(true) + :=> !(true) + :=> RTick.tcost (r1 x1 xs1) - RTick.tcost (r2 x2 xs2) + <= RRelationalISort.largerThan x1 xs1 - RRelationalISort.largerThan x2 xs2 } +@-} +--- End --- + +{-@ reflect isort @-} +isort :: Ord a => [a] -> Tick [a] +{-@ isort + :: Ord a => xs:[a] + -> Tick {os:(OList a) | length os == length xs } +@-} +-- && fromList os == fromList xs +isort [] = return [] +isort (x:xs) = isort xs >/= insert x + +{-@ reflect insert @-} +insert :: Ord a => a -> [a] -> Tick [a] +{-@ insert + :: Ord a => x:a -> xs:(OList a) + -> Tick { os:(OList a) | length os == 1 + length xs } +@-} +-- && fromList os == put x (fromList xs) +insert x [] = return [x] +insert x (y:ys) + | x <= y = return (x:y:ys) + | otherwise = let Tick m f = Tick 0 (cons y) in + let Tick n v = insert x ys + in Tick (1 + n + m) (f v) + +-- {-@ assume put :: (Ord k) => k:k -> b:Bag k -> {v:Bag k | v = Map_store b k (1 + (Map_select b k))} @-} +-- put :: (Ord k) => k -> Bag k -> Bag k +-- put k m = M.insert k (1 + get k m) m +-- +-- {-@ assume get :: (Ord k) => k:k -> b:Bag k -> {v:Nat | v = Map_select b k} @-} +-- get :: (Ord k) => k -> Bag k -> Int +-- get k m = M.findWithDefault 0 k m + +-- Tick m f Tick n x = Tick (1 + m + n) (f x) +-- (pure (y:)) insert x ys + +{-@ reflect unsortedDiff @-} +unsortedDiff :: Ord a => [a] -> [a] -> Int +unsortedDiff l1 l2 = unsorted l1 - unsorted l2 + +{-@ reflect sorted @-} +sorted :: Ord a => [a] -> Bool +sorted xs = unsorted xs == 0 + +{-@ reflect unsorted @-} +unsorted :: Ord a => [a] -> Int +unsorted [] = 0 +unsorted (x:xs) = largerThan x xs + unsorted xs + +{-@ reflect largerThan @-} +largerThan :: Ord a => a -> [a] -> Int +largerThan _ [] = 0 +largerThan x (y:ys) + | x <= y = largerThan x ys + | otherwise = 1 + largerThan x ys diff --git a/tests/relational/pos/RRelationalMSort.hs b/tests/relational/pos/RRelationalMSort.hs new file mode 100644 index 0000000000..5d0ba11ac9 --- /dev/null +++ b/tests/relational/pos/RRelationalMSort.hs @@ -0,0 +1,69 @@ +{- Relational MSort 23/25/59 -} + +{-# LANGUAGE FlexibleContexts #-} +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple-local" @-} +{- LIQUID "--smttimeout=20000" @-} + +module RRelationalMSort where + +{-@ infix <*> @-} +{-@ infix : @-} + +import RTick +import Language.Haskell.Liquid.ProofCombinators +import ProofCombinators +import Lists +import Log2 (log, logNat, plusLog) +import PowerOf2 +import Prelude hiding (return, (>>=), pure, length, (<*>), log, take, drop, min) + +--- Proof --- + +{-@ relational msort ~ msort :: { xs1:[a] -> Tick [a] + ~ xs2:[a] -> Tick [a] + | !(true) + :=> !(Lists.length xs1 = Lists.length xs2 && powerOf2 (Lists.length xs1)) + :=> RTick.tcost (r1 xs1) - RTick.tcost (r2 xs2) + <= Lists.length xs1 * (1 + log (RRelationalMSort.differ xs1 xs2)) } @-} + +{-@ relational merge ~ merge :: { xs1:[a] -> ys1:[a] -> Tick [a] + ~ xs2:[a] -> ys2:[a] -> Tick [a] + | !(true) + :=> !(true) + :=> !(true) + :=> RTick.tcost (r1 xs1 ys1) - RTick.tcost (r2 xs2 ys2) + <= Lists.length xs1 + Lists.length ys1 - RRelationalMSort.min (Lists.length xs2) (Lists.length ys2) } @-} +--- End -- + +{-@ reflect differ @-} +{-@ differ :: Ord a => xs:[a] -> ys:{[a] | length xs == length ys } -> Nat @-} +differ :: Ord a => [a] -> [a] -> Int +differ [] [] = 0 +differ (x:xs) (y:ys) + | x == y = differ xs ys + | otherwise = 1 + differ xs ys + +{-@ reflect msort @-} +{-@ msort :: Ord a => xs:[a] -> Tick ({o:OList a | length o == length xs }) / [length xs] @-} +msort :: Ord a => [a] -> Tick [a] +msort [] = return [] +msort [x] = return [x] +msort xs = step 2 (zipWithM merge (msort xs1) (msort xs2)) + where + P xs1 xs2 = split xs + +{-@ reflect merge @-} +{-@ merge :: Ord a => xs:(OList a) -> ys:(OList a) + -> {t:Tick ({o:OList a | length o == length xs + length ys }) | tcost t <= length xs + length ys && min (length xs) (length ys) <= tcost t } + / [length xs + length ys] @-} +merge :: Ord a => [a] -> [a] -> Tick [a] +merge [] ys = return ys +merge xs [] = return xs +merge (x:xs) (y:ys) + | x <= y = pure (cons x) merge xs (y:ys) + | otherwise = pure (cons y) merge (x:xs) ys + +{-@ inline min @-} +min :: Int -> Int -> Int +min x y = if x <= y then x else y \ No newline at end of file diff --git a/tests/relational/pos/RSquareAndMultiply.hs b/tests/relational/pos/RSquareAndMultiply.hs new file mode 100644 index 0000000000..ed838655f5 --- /dev/null +++ b/tests/relational/pos/RSquareAndMultiply.hs @@ -0,0 +1,76 @@ +{- Square And Multiply 13/5/4 -} + +{-@ LIQUID "--relational-hints" @-} +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} +module RSquareAndMultiply where + +{-@ infix <*> @-} +{-@ infix : @-} + +import RTick +import Language.Haskell.Liquid.ProofCombinators +import Lists +import Prelude hiding (return, (>>=), pure, length, (<*>)) + +theorem :: Int -> Int -> [Int] -> [Int] -> Proof +{-@ theorem + :: t:Nat + -> x:Int + -> l1:{[Int] | 0 < length l1} + -> l2:{[Int] | length l1 == length l2 } + -> { tcost (sam t x l1) - tcost (sam t x l2) <= t * (diff l1 l2) } + / [length l1] +@-} +theorem _ _ [_] [_] = () +theorem t x (l1:ls1@(_:_)) (l2:ls2@(_:_)) + | l1 == 0 && l2 == 0 = theorem t x ls1 ls2 + +theorem t x (l1:ls1@(_:_)) (l2:ls2@(_:_)) + | l1 /= 0 && l2 == 0 = theorem t x ls1 ls2 + +theorem t x (l1:ls1@(_:_)) (l2:ls2@(_:_)) + | l1 == 0 && l2 /= 0 = theorem t x ls1 ls2 + +theorem t x (l1:ls1@(_:_)) (l2:ls2@(_:_)) + | l1 /= 0 && l2 /= 0 = theorem t x ls1 ls2 + +{-@ reflect diff @-} +{-@ diff :: l1:[Int] -> l2:{[Int] | length l1 == length l2 } -> Int @-} +diff :: [Int] -> [Int] -> Int +diff [] [] = 0 +diff (x:xs) (y:ys) = (if x == y then 0 else 1) + diff xs ys + +{-@ reflect sam @-} +sam :: Int -> Int -> [Int] -> Tick Int +{-@ sam :: t:Nat -> Int -> bs:{[Int] | 0 < length bs } -> Tick Int @-} +sam _ x [b] = return (if b == 0 then 1 else x) +sam t x (b:bs) | b == 0 = let s = sam t x bs in pure power2 <*> s +sam t x (_:bs) = let s = sam t x bs in s >>= power2Times t x + +--- Proof --- +{- relational sam ~ sam + :: { t1:Nat -> x1:Int -> l1:[Int] -> Tick Int + ~ t2:Nat -> x2:Int -> l2:[Int] -> Tick Int + | !(t1 = t2) + :=> !(x1 = x2) + :=> !(0 < Lists.length l1 && Lists.length l1 = Lists.length l2) + :=> RTick.tcost (r1 t1 x1 l1) + - RTick.tcost (r2 t2 x2 l2) + <= t1 * (RSquareAndMultiply.diff l1 l2) } +@-} + +--- End --- + +{-@ reflect power2Times @-} +{-@ power2Times :: Nat -> Int -> Int -> Tick Int @-} +power2Times :: Int -> Int -> Int -> Tick Int +power2Times t x s = waitN t (multiply x (power2 s)) + +{-@ reflect multiply @-} +multiply :: Int -> Int -> Int +multiply x y = x * y + +{-@ reflect power2 @-} +power2 :: Int -> Int +power2 x = x * x diff --git a/tests/relational/pos/RSquareAndMultiply_relToUn.hs b/tests/relational/pos/RSquareAndMultiply_relToUn.hs new file mode 100644 index 0000000000..cee72a82e0 --- /dev/null +++ b/tests/relational/pos/RSquareAndMultiply_relToUn.hs @@ -0,0 +1,585 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + +module RSquareAndMultiply_relToUn (module RSquareAndMultiply_relToUn) where + +import GHC.Classes +import GHC.Types +import Language.Haskell.Liquid.ProofCombinators +import Lists +import RSquareAndMultiply +import RTick +import Prelude + +{- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} +{-@ samSamTheorem :: t1:{VV##0 : GHC.Types.Int | VV##0 >= 0} -> t2:{VV##0 : GHC.Types.Int | VV##0 >= 0} -> t1t2Lemma:{VV : () | t1 == t2} -> x1:GHC.Types.Int -> x2:GHC.Types.Int -> x1x2Lemma:{VV : () | x1 == x2} -> l1:[GHC.Types.Int] -> l2:[GHC.Types.Int] -> l1l2Lemma:{VV : () | Lists.length l1 == Lists.length l2 + && 0 < Lists.length l1} -> {VV : () | RTick.tcost (RSquareAndMultiply.sam t1 x1 l1) - RTick.tcost (RSquareAndMultiply.sam t2 x2 l2) <= t1 * RSquareAndMultiply.diff l1 l2} @-} +samSamTheorem :: GHC.Types.Int -> GHC.Types.Int -> () -> GHC.Types.Int -> GHC.Types.Int -> () -> [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () +samSamTheorem t1 t2 t1t2Lemma x1 x2 x1x2Lemma l1 l2 l1l2Lemma = case l1 of + [] -> case l2 of + [] -> {- GOAL: () ~ () -} () + (:) b2 ds2 -> {- GOAL: () ~ case ds2 of [] -> RT (...) -} () + (:) b1 ds1 -> case l2 of + [] -> {- GOAL: case ds1 of [] -> RT (...) ~ () -} () + (:) b2 ds2 -> case ds1 of + [] -> case ds2 of + [] -> + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.return x1)) ? (RTick.return x2)) + ) + ( case b1 GHC.Classes.== 0 of + False -> x1 + True -> 1 + ) + ( case b2 GHC.Classes.== 0 of + False -> x2 + True -> 1 + ) + ( case b1 GHC.Classes.== 0 of + False -> case b2 GHC.Classes.== 0 of + False -> x1x2Lemma + True -> + {- GOAL: x1 ~ 1 -} + (() ? x1) ? 1 + True -> case b2 GHC.Classes.== 0 of + False -> + {- GOAL: 1 ~ x2 -} + (() ? 1) ? x2 + True -> + ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? x1) ? x2) + ) + 1 + 1 + ( {- GOAL: 1 ~ 1 -} + (() ? 1) ? 1 + ) + ) + (:) lq_anf72057594037927948272 lq_anf72057594037927948282 -> + {- GOAL: RTick.return (case b (...) ~ case b2 GHC.Classes. (...) -} + ( () + ? ( RTick.return + ( case b1 GHC.Classes.== 0 of + False -> x1 + True -> 1 + ) + ) + ) + ? ( case b2 GHC.Classes.== 0 of + False -> + let s = RSquareAndMultiply.sam t2 x2 ds2 + in (RSquareAndMultiply.sam t2 x2 ds2) RTick.>>= (RSquareAndMultiply.power2Times t2 x2) + True -> + let s = RSquareAndMultiply.sam t2 x2 ds2 + in (RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t2 x2 ds2) + ) + (:) lq_anf72057594037927948271 lq_anf72057594037927948281 -> case ds2 of + [] -> + {- GOAL: case b1 GHC.Classes. (...) ~ RTick.return (case b (...) -} + ( () + ? ( case b1 GHC.Classes.== 0 of + False -> + let s = RSquareAndMultiply.sam t1 x1 ds1 + in (RSquareAndMultiply.sam t1 x1 ds1) RTick.>>= (RSquareAndMultiply.power2Times t1 x1) + True -> + let s = RSquareAndMultiply.sam t1 x1 ds1 + in (RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t1 x1 ds1) + ) + ) + ? ( RTick.return + ( case b2 GHC.Classes.== 0 of + False -> x2 + True -> 1 + ) + ) + (:) lq_anf72057594037927948272 lq_anf72057594037927948282 -> case b1 GHC.Classes.== 0 of + False -> case b2 GHC.Classes.== 0 of + False -> + let s1 = RSquareAndMultiply.sam t1 x1 ds1 + in let s2 = RSquareAndMultiply.sam t2 x2 ds2 + in let s1s2Lemma = + samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + ( {- GOAL: ds1 ~ ds2 -} + (() ? ds1) ? ds2 + ) + in s1s2Lemma + ? ( ( {- GOAL: RTick.>>= ~ RTick.>>= -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 RTick.>>= x3)) ? (x2 RTick.>>= x4)) + ) + (RSquareAndMultiply.sam t1 x1 ds1) + (RSquareAndMultiply.sam t2 x2 ds2) + ( samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + ( {- GOAL: ds1 ~ ds2 -} + (() ? ds1) ? ds2 + ) + ) + (RSquareAndMultiply.power2Times t1 x1) + (RSquareAndMultiply.power2Times t2 x2) + ( ( {- GOAL: RSquareAndMultiply.p (...) ~ RSquareAndMultiply.p (...) -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma x5 x6 x5x6Lemma -> ((((() ? x1x2Lemma) ? x3x4Lemma) ? x5x6Lemma) ? (RSquareAndMultiply.power2Times x1 x3 x5)) ? (RSquareAndMultiply.power2Times x2 x4 x6)) + ) + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ) + ) + True -> + let s1 = RSquareAndMultiply.sam t1 x1 ds1 + in let s2 = RSquareAndMultiply.sam t2 x2 ds2 + in let s1s2Lemma = + samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + ( {- GOAL: ds1 ~ ds2 -} + (() ? ds1) ? ds2 + ) + in s1s2Lemma + ? ( {- GOAL: (RSquareAndMultiply. (...) ~ (RTick.pure RSquareA (...) -} + (() ? ((RSquareAndMultiply.sam t1 x1 ds1) RTick.>>= (RSquareAndMultiply.power2Times t1 x1))) ? ((RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t2 x2 ds2)) + ) + True -> case b2 GHC.Classes.== 0 of + False -> + let s1 = RSquareAndMultiply.sam t1 x1 ds1 + in let s2 = RSquareAndMultiply.sam t2 x2 ds2 + in let s1s2Lemma = + samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + ( {- GOAL: ds1 ~ ds2 -} + (() ? ds1) ? ds2 + ) + in s1s2Lemma + ? ( {- GOAL: (RTick.pure RSquareA (...) ~ (RSquareAndMultiply. (...) -} + (() ? ((RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t1 x1 ds1))) ? ((RSquareAndMultiply.sam t2 x2 ds2) RTick.>>= (RSquareAndMultiply.power2Times t2 x2)) + ) + True -> + let s1 = RSquareAndMultiply.sam t1 x1 ds1 + in let s2 = RSquareAndMultiply.sam t2 x2 ds2 + in let s1s2Lemma = + samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + ( {- GOAL: ds1 ~ ds2 -} + (() ? ds1) ? ds2 + ) + in s1s2Lemma + ? ( ( {- GOAL: RTick.<*> ~ RTick.<*> -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 RTick.<*> x3)) ? (x2 RTick.<*> x4)) + ) + (RTick.pure RSquareAndMultiply.power2) + (RTick.pure RSquareAndMultiply.power2) + ( ( {- GOAL: RTick.pure ~ RTick.pure -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.pure x1)) ? (RTick.pure x2)) + ) + RSquareAndMultiply.power2 + RSquareAndMultiply.power2 + ( {- GOAL: RSquareAndMultiply.p (...) ~ RSquareAndMultiply.p (...) -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RSquareAndMultiply.power2 x1)) ? (RSquareAndMultiply.power2 x2)) + ) + ) + (RSquareAndMultiply.sam t1 x1 ds1) + (RSquareAndMultiply.sam t2 x2 ds2) + ( samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + ( {- GOAL: ds1 ~ ds2 -} + (() ? ds1) ? ds2 + ) + ) + ) + +{- BARE CORE +\ (t1 :: GHC.Types.Int) + (t2 :: GHC.Types.Int) + (t1t2Lemma :: GHC.Types.Int) + (x1 :: GHC.Types.Int) + (x2 :: GHC.Types.Int) + (x1x2Lemma :: GHC.Types.Int) + (l1 :: [GHC.Types.Int]) + (l2 :: [GHC.Types.Int]) + (l1l2Lemma :: [GHC.Types.Int]) -> + case l1 of lq_anf$##72057594037927948101 { + [] -> + case l2 of lq_anf$##72057594037927948102 { + [] -> src<.:0:0> GHC.Tuple.(); + : b2 ds2 -> src<.:0:0> GHC.Tuple.() + }; + : b1 ds1 -> + case l2 of lq_anf$##72057594037927948102 { + [] -> src<.:0:0> GHC.Tuple.(); + : b2 ds2 -> + case ds1 of lq_anf$##72057594037927948141 { + [] -> + case ds2 of lq_anf$##72057594037927948142 { + [] -> + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.return x1)) + (RTick.return x2)) + (case GHC.Classes.== b1 (GHC.Types.I# 0#) + of lq_anf$##7205759403792794824 { + GHC.Types.False -> x1; + GHC.Types.True -> GHC.Types.I# 1# + }) + (case GHC.Classes.== b2 (GHC.Types.I# 0#) + of lq_anf$##7205759403792794824 { + GHC.Types.False -> x2; + GHC.Types.True -> GHC.Types.I# 1# + }) + (case GHC.Classes.== b1 (GHC.Types.I# 0#) + of lq_anf$##72057594037927948241 { + GHC.Types.False -> + case GHC.Classes.== b2 (GHC.Types.I# 0#) + of lq_anf$##72057594037927948242 { + GHC.Types.False -> x1x2Lemma; + GHC.Types.True -> + src<.:0:0> ? (? GHC.Tuple.() x1) (GHC.Types.I# 1#) + }; + GHC.Types.True -> + case GHC.Classes.== b2 (GHC.Types.I# 0#) + of lq_anf$##72057594037927948242 { + GHC.Types.False -> + src<.:0:0> ? (? GHC.Tuple.() (GHC.Types.I# 1#)) x2; + GHC.Types.True -> + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 1# 1# (src<.:0:0> ? (? GHC.Tuple.() 1#) 1#) + } + }); + : lq_anf$##72057594037927948272 lq_anf$##72057594037927948282 -> + src<.:0:0> + ? (? GHC.Tuple.() + (RTick.return + (case GHC.Classes.== b1 (GHC.Types.I# 0#) + of lq_anf$##7205759403792794824 { + GHC.Types.False -> x1; + GHC.Types.True -> GHC.Types.I# 1# + }))) + (case GHC.Classes.== b2 (GHC.Types.I# 0#) + of lq_anf$##7205759403792794818 { + GHC.Types.False -> + let { + s :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s = RSquareAndMultiply.sam t2 x2 ds2 } in + RTick.>>= + (RSquareAndMultiply.sam t2 x2 ds2) + (RSquareAndMultiply.power2Times t2 x2); + GHC.Types.True -> + let { + s :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s = RSquareAndMultiply.sam t2 x2 ds2 } in + RTick.<*> + (RTick.pure RSquareAndMultiply.power2) + (RSquareAndMultiply.sam t2 x2 ds2) + }) + }; + : lq_anf$##72057594037927948271 lq_anf$##72057594037927948281 -> + case ds2 of lq_anf$##72057594037927948142 { + [] -> + src<.:0:0> + ? (? GHC.Tuple.() + (case GHC.Classes.== b1 (GHC.Types.I# 0#) + of lq_anf$##7205759403792794818 { + GHC.Types.False -> + let { + s :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s = RSquareAndMultiply.sam t1 x1 ds1 } in + RTick.>>= + (RSquareAndMultiply.sam t1 x1 ds1) + (RSquareAndMultiply.power2Times t1 x1); + GHC.Types.True -> + let { + s :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s = RSquareAndMultiply.sam t1 x1 ds1 } in + RTick.<*> + (RTick.pure RSquareAndMultiply.power2) + (RSquareAndMultiply.sam t1 x1 ds1) + })) + (RTick.return + (case GHC.Classes.== b2 (GHC.Types.I# 0#) + of lq_anf$##7205759403792794824 { + GHC.Types.False -> x2; + GHC.Types.True -> GHC.Types.I# 1# + })); + : lq_anf$##72057594037927948272 lq_anf$##72057594037927948282 -> + case GHC.Classes.== b1 (GHC.Types.I# 0#) + of lq_anf$##72057594037927948181 { + GHC.Types.False -> + case GHC.Classes.== b2 (GHC.Types.I# 0#) + of lq_anf$##72057594037927948182 { + GHC.Types.False -> + let { + s1 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + let { + s2 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + let { + s1s2Lemma :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1s2Lemma + = samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in + ? s1s2Lemma + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (RTick.>>= x1 x3)) + (RTick.>>= x2 x4)) + (RSquareAndMultiply.sam t1 x1 ds1) + (RSquareAndMultiply.sam t2 x2 ds2) + (samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2)) + (RSquareAndMultiply.power2Times t1 x1) + (RSquareAndMultiply.power2Times t2 x2) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) + (x5 :: ()) + (x6 :: ()) + (x5x6Lemma :: ()) -> + ? (? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) x5x6Lemma) + (RSquareAndMultiply.power2Times x1 x3 x5)) + (RSquareAndMultiply.power2Times x2 x4 x6)) + t1 t2 t1t2Lemma x1 x2 x1x2Lemma)); + GHC.Types.True -> + let { + s1 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + let { + s2 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + let { + s1s2Lemma :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1s2Lemma + = samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in + ? s1s2Lemma + (src<.:0:0> + ? (? GHC.Tuple.() + (RTick.>>= + (RSquareAndMultiply.sam t1 x1 ds1) + (RSquareAndMultiply.power2Times t1 x1))) + (RTick.<*> + (RTick.pure RSquareAndMultiply.power2) + (RSquareAndMultiply.sam t2 x2 ds2))) + }; + GHC.Types.True -> + case GHC.Classes.== b2 (GHC.Types.I# 0#) + of lq_anf$##72057594037927948182 { + GHC.Types.False -> + let { + s1 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + let { + s2 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + let { + s1s2Lemma :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1s2Lemma + = samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in + ? s1s2Lemma + (src<.:0:0> + ? (? GHC.Tuple.() + (RTick.<*> + (RTick.pure RSquareAndMultiply.power2) + (RSquareAndMultiply.sam t1 x1 ds1))) + (RTick.>>= + (RSquareAndMultiply.sam t2 x2 ds2) + (RSquareAndMultiply.power2Times t2 x2))); + GHC.Types.True -> + let { + s1 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + let { + s2 :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + let { + s1s2Lemma :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + s1s2Lemma + = samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in + ? s1s2Lemma + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (RTick.<*> x1 x3)) + (RTick.<*> x2 x4)) + (RTick.pure RSquareAndMultiply.power2) + (RTick.pure RSquareAndMultiply.power2) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.pure x1)) (RTick.pure x2)) + RSquareAndMultiply.power2 + RSquareAndMultiply.power2 + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (RSquareAndMultiply.power2 x1)) + (RSquareAndMultiply.power2 x2))) + (RSquareAndMultiply.sam t1 x1 ds1) + (RSquareAndMultiply.sam t2 x2 ds2) + (samSamTheorem + t1 + t2 + t1t2Lemma + x1 + x2 + x1x2Lemma + ds1 + ds2 + (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2))) + } + } + } + } + } + } +-} diff --git a/tests/relational/pos/RVar_relToUn.hs b/tests/relational/pos/RVar_relToUn.hs index cff3c4f395..db21e54a2f 100644 --- a/tests/relational/pos/RVar_relToUn.hs +++ b/tests/relational/pos/RVar_relToUn.hs @@ -17,7 +17,7 @@ import Prelude y1Y2Theorem :: () y1Y2Theorem = {- GOAL: RVar.x1 ~ RVar.x2 -} - (?) ((?) () RVar.x1) RVar.x2 + (() ? RVar.x1) ? RVar.x2 {- BARE CORE src<.:0:0> ? (? GHC.Tuple.() RVar.x1) RVar.x2 diff --git a/tests/tests.cabal b/tests/tests.cabal index 101b0e7437..707b4c3ed0 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2053,7 +2053,7 @@ executable relational-pos , PolyNull , PredAbs , Prims - , R2Dcounting_relToUn + , R2Dcounting_relToUn , R2Dcounting , RConstantTimeComparison_relToUn , RConstantTimeComparison @@ -2066,6 +2066,8 @@ executable relational-pos , RMemAlloc_relToUn , RMemAlloc , RPatError + , RSquareAndMultiply_relToUn + , RSquareAndMultiply , RTick , RVar_relToUn , RVar From d0ab69e1ec8b25c9694a4f0f7bf1c9d68250ab36 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Thu, 13 Apr 2023 15:43:38 +0100 Subject: [PATCH 205/219] print infix operators --- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 5 ++++- tests/relational/pos/RConstantTimeComparison_relToUn.hs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index fa5721e922..586959d977 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -307,8 +307,11 @@ pprintBody' _ _ e = error (" Not yet implemented for e = " ++ show e) noParenVars :: [String] noParenVars = ["()"] +letters :: String +letters = ['a'..'z'] ++ ['A'..'Z'] + isOperator :: CoreExpr -> Bool -isOperator (Var v) | head (occStr v) `notElem` ['a'..'z'] = True +isOperator (Var v) | head (occStr v) `notElem` letters = True isOperator _ = False paren :: CoreExpr -> Bool -> String -> String diff --git a/tests/relational/pos/RConstantTimeComparison_relToUn.hs b/tests/relational/pos/RConstantTimeComparison_relToUn.hs index 510fe17c8f..53289fe2e6 100644 --- a/tests/relational/pos/RConstantTimeComparison_relToUn.hs +++ b/tests/relational/pos/RConstantTimeComparison_relToUn.hs @@ -72,7 +72,7 @@ compCompTheorem xs1 xs2 xs1xs2Lemma ys1 ys2 ys1ys2Lemma = case xs1 of {- GOAL: v1 ~ v2 -} (() ? v1) ? v2 in ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 RTick.Tick x3)) ? (x2 RTick.Tick x4)) + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (RTick.Tick x1 x3)) ? (RTick.Tick x2 x4)) ) ( ( case RConstantTimeComparison.comp xs1 ys1 of Tick m1 v1 -> m1 From 024477b0c1fbca565b5bde807b87e2fb9cc7b928 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 18 Apr 2023 12:30:54 +0200 Subject: [PATCH 206/219] add RRelationalMSort_relToUn test --- tests/relational/pos/Log2.hs | 66 + tests/relational/pos/PowerOf2.hs | 61 + tests/relational/pos/ProofCombinators.hs | 19 + tests/relational/pos/RRelationalMSort.hs | 58 +- .../pos/RRelationalMSort_relToUn.hs | 1197 +++++++++++++++++ tests/tests.cabal | 7 +- 6 files changed, 1381 insertions(+), 27 deletions(-) create mode 100644 tests/relational/pos/Log2.hs create mode 100644 tests/relational/pos/PowerOf2.hs create mode 100644 tests/relational/pos/ProofCombinators.hs create mode 100644 tests/relational/pos/RRelationalMSort_relToUn.hs diff --git a/tests/relational/pos/Log2.hs b/tests/relational/pos/Log2.hs new file mode 100644 index 0000000000..3c452207c3 --- /dev/null +++ b/tests/relational/pos/Log2.hs @@ -0,0 +1,66 @@ +module Log2 (module Log2) where + +import Language.Haskell.Liquid.ProofCombinators (Proof) + +assumption :: Proof +assumption = () +-- +-- Define an abstract measure called 'log' +-- LH knows nothing about its implementation +-- +{-@ measure log :: a -> a @-} + +-- +-- log_2 rounded to the nearest integer +-- +{-@ assume log :: x:Int -> {v:Int | v == log x } @-} +log :: Int -> Int +log x = round (logBase 2 (fromIntegral x :: Double)) + + +-- +-- Assume that log_2 1 == 0 +-- +{-@ assume logOne :: { log 1 == 0 } @-} +logOne :: Proof +logOne = assumption +-- +-- Assume that log_2 == 1 +-- +{-@ assume logTwo :: { log 2 == 1 } @-} +logTwo :: Proof +logTwo = assumption + + +{-@ assume logNat :: x:{ Int | 0 <= x } -> { 0 <= log x } @-} +logNat :: Int -> Proof +logNat _ = assumption + +{-@ assume logPos :: x:{ Int | 1 < x } -> { 0 < log x } @-} +logPos :: Int -> Proof +logPos _ = assumption + +-- +-- Log ratio law: log_b (x / y) == log_b x - log_b y +-- +{-@ assume logDiv :: x:Int -> y:Int -> {log (x / y) = log x - log y } @-} +logDiv :: Int -> Int -> Proof +logDiv _ _ = assumption + +-- +-- Log ratio law: log_b (x + y) == log_b x + log_b (1+y/x) +-- +{-@ assume logPlus :: x:Int -> y:Int -> {log (x + y) = log x + log (1 + y/x) } @-} +logPlus :: Int -> Int -> Proof +logPlus _ _ = assumption + +plusLog :: Int -> Int -> Int -> Proof +{-@ assume plusLog :: d1:Int -> d2:Int -> d:{Int | 0 < d && d == d1 + d2 } + -> { log d1 + log d2 <= 2 * (log d)} @-} +plusLog _ _ _ = () +{- + log d1 + log d2 +== log (d - d2) + log (d - d1) +== 2 * log d + log (1 - d2/d) + log (1 - d1/d) +<= 2 * log d +-} \ No newline at end of file diff --git a/tests/relational/pos/PowerOf2.hs b/tests/relational/pos/PowerOf2.hs new file mode 100644 index 0000000000..39db01166d --- /dev/null +++ b/tests/relational/pos/PowerOf2.hs @@ -0,0 +1,61 @@ + +{-@ LIQUID "--reflection" @-} + +module PowerOf2 where + +import Language.Haskell.Liquid.ProofCombinators (Proof) + +assumption :: Proof +assumption = () + +-- +-- Define an abstract measure called 'powerOf2' +-- LH knows nothing about its implementation +-- +{-@ measure powerOf2 :: Int -> Bool @-} + +-- +-- Multiplication/division identity law: 2 * (x / 2) == x +-- +{-@ assume timesDiv :: x:{ Int | powerOf2 x } -> { 2 * (x / 2) == x } @-} +timesDiv :: Int -> Proof +timesDiv _ = assumption + +-- +-- Assume that if x is a power of 2 then x / 2 is a power of 2 +-- +{-@ assume powerOf2Div2 :: x:{ Int | powerOf2 x } -> { powerOf2 (x / 2) } @-} +powerOf2Div2 :: Int -> Proof +powerOf2Div2 _ = assumption + +-- +-- Assume that if x is a power of 2 then (x - x / 2) is a power of 2 +-- +{-@ assume powerOf2Div2' :: x:{ Int | powerOf2 x } -> { powerOf2 (x - (x / 2)) } @-} +powerOf2Div2' :: Int -> Proof +powerOf2Div2' _ = assumption + + + +{-@ assume powerOfIsEven :: x:{ Int | powerOf2 x } -> { (x mod 2 == 0) && (2 <= x => (x / 2 < x) && powerOf2 (x / 2)) } @-} +powerOfIsEven :: Int -> Proof +powerOfIsEven _ = assumption +------------------------------------------------------------------------------- + +-- +-- 2^x +-- +{-@ reflect twoToPower @-} +{-@ twoToPower :: Nat -> Nat @-} +twoToPower :: Int -> Int +twoToPower 0 = 1 +twoToPower n = 2 * twoToPower (n - 1) + + +-- Some math assumptions +distributeDiv :: Int -> Int -> Int -> Proof +{-@ assume distributeDiv + :: n:{Int | powerOf2 n} + -> x:Int -> y:Int + -> {(n/2 * (x + 2 * y)) == n * (x/2 + y )} @-} +distributeDiv _ _ _ = () \ No newline at end of file diff --git a/tests/relational/pos/ProofCombinators.hs b/tests/relational/pos/ProofCombinators.hs new file mode 100644 index 0000000000..6045b9f903 --- /dev/null +++ b/tests/relational/pos/ProofCombinators.hs @@ -0,0 +1,19 @@ +module ProofCombinators where + +assert :: Bool -> () +{-@ assert :: b:{Bool | b} -> {b} @-} +assert _ = () + +assume :: Bool -> () +{-@ assume assume :: b:Bool -> {b} @-} +assume _ = () + +infixl 3 =*= +{-@ (=*=) :: x:Int -> y:{Int | y == x} -> {v:Int | v == x && v == y} @-} +(=*=) :: Int -> Int -> Int +_ =*= y = y + +infixl 3 =<*= +{-@ (=<*=) :: x:Int -> y:{Int | x <= y } -> {v:Int | v == y} @-} +(=<*=) :: Int -> Int -> Int +_ =<*= y = y diff --git a/tests/relational/pos/RRelationalMSort.hs b/tests/relational/pos/RRelationalMSort.hs index 5d0ba11ac9..f0a53c398c 100644 --- a/tests/relational/pos/RRelationalMSort.hs +++ b/tests/relational/pos/RRelationalMSort.hs @@ -2,7 +2,8 @@ {-# LANGUAGE FlexibleContexts #-} {-@ LIQUID "--reflection" @-} -{-@ LIQUID "--ple-local" @-} +{-@ LIQUID "--ple" @-} +{-@ LIQUID "--relational-hints" @-} {- LIQUID "--smttimeout=20000" @-} module RRelationalMSort where @@ -16,53 +17,58 @@ import ProofCombinators import Lists import Log2 (log, logNat, plusLog) import PowerOf2 -import Prelude hiding (return, (>>=), pure, length, (<*>), log, take, drop, min) +import Prelude hiding (return, (>>=), pure, length, (<*>), log, take, drop, min, fst, snd) --- Proof --- -{-@ relational msort ~ msort :: { xs1:[a] -> Tick [a] - ~ xs2:[a] -> Tick [a] - | !(true) - :=> !(Lists.length xs1 = Lists.length xs2 && powerOf2 (Lists.length xs1)) - :=> RTick.tcost (r1 xs1) - RTick.tcost (r2 xs2) +{- relational msort ~ msort :: { xs1:[Int] -> Tick [Int] + ~ xs2:[Int] -> Tick [Int] + | !(Lists.length xs1 = Lists.length xs2 && powerOf2 (Lists.length xs1)) + :=> Lists.length xs1 = Lists.length (RTick.tval (r1 xs1)) + && Lists.length xs2 = Lists.length (RTick.tval (r2 xs2)) + && RTick.tcost (r1 xs1) - RTick.tcost (r2 xs2) <= Lists.length xs1 * (1 + log (RRelationalMSort.differ xs1 xs2)) } @-} -{-@ relational merge ~ merge :: { xs1:[a] -> ys1:[a] -> Tick [a] - ~ xs2:[a] -> ys2:[a] -> Tick [a] - | !(true) - :=> !(true) - :=> !(true) - :=> RTick.tcost (r1 xs1 ys1) - RTick.tcost (r2 xs2 ys2) - <= Lists.length xs1 + Lists.length ys1 - RRelationalMSort.min (Lists.length xs2) (Lists.length ys2) } @-} + --- End -- {-@ reflect differ @-} -{-@ differ :: Ord a => xs:[a] -> ys:{[a] | length xs == length ys } -> Nat @-} -differ :: Ord a => [a] -> [a] -> Int +{-@ differ :: xs:[Int] -> { ys:[Int] | length xs == length ys } -> Nat @-} +differ :: [Int] -> [Int] -> Int differ [] [] = 0 differ (x:xs) (y:ys) | x == y = differ xs ys | otherwise = 1 + differ xs ys {-@ reflect msort @-} -{-@ msort :: Ord a => xs:[a] -> Tick ({o:OList a | length o == length xs }) / [length xs] @-} -msort :: Ord a => [a] -> Tick [a] +{- msort :: xs:[Int] -> Tick ({o:List Int | length o == length xs }) / [length xs] @-} +{-@ msort :: xs:[Int] -> { t:Tick (List Int) | length (tval t) == length xs } / [length xs] @-} +msort :: [Int] -> Tick [Int] msort [] = return [] msort [x] = return [x] -msort xs = step 2 (zipWithM merge (msort xs1) (msort xs2)) +-- msort xs = step 2 (zipWithM merge (msort ls) (msort rs)) +msort xs = step (2 + lt + rt) (merge ls' rs') where - P xs1 xs2 = split xs + Tick lt ls' = msort (left s) + Tick rt rs' = msort (right s) + s = split xs {-@ reflect merge @-} -{-@ merge :: Ord a => xs:(OList a) -> ys:(OList a) - -> {t:Tick ({o:OList a | length o == length xs + length ys }) | tcost t <= length xs + length ys && min (length xs) (length ys) <= tcost t } +{- merge :: xs:(List Int) -> ys:(List Int) + -> {t:Tick ({o:List Int | length o == length xs + length ys }) | tcost t <= length xs + length ys && min (length xs) (length ys) <= tcost t } + / [length xs + length ys] @-} +{-@ merge :: xs:(List Int) -> ys:(List Int) + -> {t:Tick (List Int) | length (tval t) == length xs + length ys + && tcost t <= length xs + length ys + && min (length xs) (length ys) <= tcost t } / [length xs + length ys] @-} -merge :: Ord a => [a] -> [a] -> Tick [a] +merge :: [Int] -> [Int] -> Tick [Int] merge [] ys = return ys merge xs [] = return xs -merge (x:xs) (y:ys) - | x <= y = pure (cons x) merge xs (y:ys) - | otherwise = pure (cons y) merge (x:xs) ys +merge (x:xs) (y:ys) | x <= y = Tick (t + 1) (cons x m) + where Tick t m = merge xs (y:ys) +merge (x:xs) (y:ys) = Tick (t + 1) (cons y m) + where Tick t m = merge (x:xs) ys {-@ inline min @-} min :: Int -> Int -> Int diff --git a/tests/relational/pos/RRelationalMSort_relToUn.hs b/tests/relational/pos/RRelationalMSort_relToUn.hs new file mode 100644 index 0000000000..de0641cd82 --- /dev/null +++ b/tests/relational/pos/RRelationalMSort_relToUn.hs @@ -0,0 +1,1197 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + +module RRelationalMSort_relToUn (module RRelationalMSort_relToUn) where + +import GHC.Classes +import GHC.Types +import Language.Haskell.Liquid.ProofCombinators +import Lists +import Log2 +import PowerOf2 +import ProofCombinators +import RRelationalMSort +import RTick +import Prelude + +{- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} +{-@ msortMsortTheorem :: xs1:[GHC.Types.Int] -> xs2:[GHC.Types.Int] -> xs1xs2Lemma:{VV : () | powerOf2 (Lists.length xs1) + && Lists.length xs1 == Lists.length xs2} -> {VV : () | Lists.length xs1 == Lists.length (RTick.tval (RRelationalMSort.msort xs1)) + && Lists.length xs2 == Lists.length (RTick.tval (RRelationalMSort.msort xs2)) + && RTick.tcost (RRelationalMSort.msort xs1) - RTick.tcost (RRelationalMSort.msort xs2) <= Lists.length xs1 * (1 + log (RRelationalMSort.differ xs1 xs2))} @-} +msortMsortTheorem :: [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () +msortMsortTheorem xs1 xs2 xs1xs2Lemma = case xs1 of + [] -> case xs2 of + [] -> + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.return x1)) ? (RTick.return x2)) + ) + [] + [] + ( {- GOAL: [] ~ [] -} + (() ? []) ? [] + ) + (:) x2 ds2 -> + {- GOAL: RTick.return [] ~ case ds2 of [] -> RT (...) -} + (() ? (RTick.return [])) + ? ( case ds2 of + [] -> RTick.return (x2 : []) + (:) lq_anf7205759403792793662 lq_anf7205759403792793663 -> + let s = Lists.split xs2 + in let ds = RRelationalMSort.msort (Lists.right (Lists.split xs2)) + in let rt = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rt + in let rs' = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rs' + in let ds = RRelationalMSort.msort (Lists.left (Lists.split xs2)) + in let lt = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> lt + in let ls' = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> ls' + in RTick.step + ( ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> lt + ) + ) + + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rt + ) + ) + ( RRelationalMSort.merge + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> ls' + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rs' + ) + ) + ) + (:) x1 ds1 -> case xs2 of + [] -> + {- GOAL: case ds1 of [] -> RT (...) ~ RTick.return [] -} + ( () + ? ( case ds1 of + [] -> RTick.return (x1 : []) + (:) lq_anf7205759403792793662 lq_anf7205759403792793663 -> + let s = Lists.split xs1 + in let ds = RRelationalMSort.msort (Lists.right (Lists.split xs1)) + in let rt = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rt + in let rs' = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rs' + in let ds = RRelationalMSort.msort (Lists.left (Lists.split xs1)) + in let lt = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> lt + in let ls' = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> ls' + in RTick.step + ( ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> lt + ) + ) + + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rt + ) + ) + ( RRelationalMSort.merge + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> ls' + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rs' + ) + ) + ) + ) + ? (RTick.return []) + (:) x2 ds2 -> case ds1 of + [] -> case ds2 of + [] -> + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.return x1)) ? (RTick.return x2)) + ) + (x1 : []) + (x2 : []) + ( ( {- GOAL: : ~ : -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 : x3)) ? (x2 : x4)) + ) + x1 + x2 + ( {- GOAL: x1 ~ x2 -} + (() ? x1) ? x2 + ) + [] + [] + ( {- GOAL: [] ~ [] -} + (() ? []) ? [] + ) + ) + (:) lq_anf72057594037927936622 lq_anf72057594037927936632 -> + {- GOAL: RTick.return (x1 : [ (...) ~ let s = Lists.split (...) -} + (() ? (RTick.return (x1 : []))) + ? ( let s = Lists.split xs2 + in let ds = RRelationalMSort.msort (Lists.right (Lists.split xs2)) + in let rt = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rt + in let rs' = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rs' + in let ds = RRelationalMSort.msort (Lists.left (Lists.split xs2)) + in let lt = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> lt + in let ls' = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> ls' + in RTick.step + ( ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> lt + ) + ) + + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rt + ) + ) + ( RRelationalMSort.merge + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> ls' + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rs' + ) + ) + ) + (:) lq_anf72057594037927936621 lq_anf72057594037927936631 -> case ds2 of + [] -> + {- GOAL: let s = Lists.split (...) ~ RTick.return (x2 : [ (...) -} + ( () + ? ( let s = Lists.split xs1 + in let ds = RRelationalMSort.msort (Lists.right (Lists.split xs1)) + in let rt = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rt + in let rs' = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rs' + in let ds = RRelationalMSort.msort (Lists.left (Lists.split xs1)) + in let lt = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> lt + in let ls' = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> ls' + in RTick.step + ( ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> lt + ) + ) + + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rt + ) + ) + ( RRelationalMSort.merge + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> ls' + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rs' + ) + ) + ) + ) + ? (RTick.return (x2 : [])) + (:) lq_anf72057594037927936622 lq_anf72057594037927936632 -> + let s1 = Lists.split xs1 + in let s2 = Lists.split xs2 + in let s1s2Lemma = + ( {- GOAL: Lists.split ~ Lists.split -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (Lists.split x1)) ? (Lists.split x2)) + ) + xs1 + xs2 + xs1xs2Lemma + in ( let ds1 = RRelationalMSort.msort (Lists.right (Lists.split xs1)) + in let ds2 = RRelationalMSort.msort (Lists.right (Lists.split xs2)) + in let ds1ds2Lemma = + msortMsortTheorem + (Lists.right (Lists.split xs1)) + (Lists.right (Lists.split xs2)) + ( ( {- GOAL: Lists.right ~ Lists.right -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (Lists.right x1)) ? (Lists.right x2)) + ) + (Lists.split xs1) + (Lists.split xs2) + ( ( {- GOAL: Lists.split ~ Lists.split -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (Lists.split x1)) ? (Lists.split x2)) + ) + xs1 + xs2 + xs1xs2Lemma + ) + ) + in ( let rt1 = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt rs' -> rt + in let rt2 = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt rs' -> rt + in let rt1rt2Lemma = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt1 rs'1 -> case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt2 rs'2 -> + {- GOAL: rt1 ~ rt2 -} + (() ? rt1) ? rt2 + in ( let rs'1 = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt1 rs' -> rs' + in let rs'2 = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt2 rs' -> rs' + in let rs'1rs'2Lemma = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt11 rs'1 -> case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt22 rs'2 -> + {- GOAL: rs'1 ~ rs'2 -} + (() ? rs'1) ? rs'2 + in ( let ds1 = RRelationalMSort.msort (Lists.left (Lists.split xs1)) + in let ds2 = RRelationalMSort.msort (Lists.left (Lists.split xs2)) + in let ds1ds2Lemma = + msortMsortTheorem + (Lists.left (Lists.split xs1)) + (Lists.left (Lists.split xs2)) + ( ( {- GOAL: Lists.left ~ Lists.left -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (Lists.left x1)) ? (Lists.left x2)) + ) + (Lists.split xs1) + (Lists.split xs2) + ( ( {- GOAL: Lists.split ~ Lists.split -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (Lists.split x1)) ? (Lists.split x2)) + ) + xs1 + xs2 + xs1xs2Lemma + ) + ) + in ( let lt1 = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt ls' -> lt + in let lt2 = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt ls' -> lt + in let lt1lt2Lemma = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt1 ls'1 -> case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt2 ls'2 -> + {- GOAL: lt1 ~ lt2 -} + (() ? lt1) ? lt2 + in ( let ls'1 = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt1 ls' -> ls' + in let ls'2 = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt2 ls' -> ls' + in let ls'1ls'2Lemma = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt11 ls'1 -> case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt22 ls'2 -> + {- GOAL: ls'1 ~ ls'2 -} + (() ? ls'1) ? ls'2 + in ( ( {- GOAL: RTick.step ~ RTick.step -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (RTick.step x1 x3)) ? (RTick.step x2 x4)) + ) + ( ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt1 ls'1 -> lt1 + ) + ) + + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt1 rs'1 -> rt1 + ) + ) + ( ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt2 ls'2 -> lt2 + ) + ) + + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt2 rs'2 -> rt2 + ) + ) + ( ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 + x3)) ? (x2 + x4)) + ) + ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt1 ls'1 -> lt1 + ) + ) + ( 2 + + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt2 ls'2 -> lt2 + ) + ) + ( ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 + x3)) ? (x2 + x4)) + ) + 2 + 2 + ( ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? x1) ? x2) + ) + 2 + 2 + ( {- GOAL: 2 ~ 2 -} + (() ? 2) ? 2 + ) + ) + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt1 ls'1 -> lt1 + ) + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt2 ls'2 -> lt2 + ) + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt11 ls'11 -> case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt22 ls'22 -> lt1lt2Lemma + ) + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt1 rs'1 -> rt1 + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt2 rs'2 -> rt2 + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt11 rs'11 -> case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt22 rs'22 -> rt1rt2Lemma + ) + ) + ( RRelationalMSort.merge + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt1 ls'1 -> ls'1 + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt1 rs'1 -> rs'1 + ) + ) + ( RRelationalMSort.merge + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt2 ls'2 -> ls'2 + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt2 rs'2 -> rs'2 + ) + ) + ( ( {- GOAL: RRelationalMSort.mer (...) ~ RRelationalMSort.mer (...) -} + (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (RRelationalMSort.merge x1 x3)) ? (RRelationalMSort.merge x2 x4)) + ) + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt1 ls'1 -> ls'1 + ) + ( case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt2 ls'2 -> ls'2 + ) + ( case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + Tick lt11 ls'11 -> case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + Tick lt22 ls'22 -> ls'1ls'2Lemma + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt1 rs'1 -> rs'1 + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt2 rs'2 -> rs'2 + ) + ( case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + Tick rt11 rs'11 -> case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + Tick rt22 rs'22 -> rs'1rs'2Lemma + ) + ) + ) + ? ls'1ls'2Lemma + ) + ? lt1lt2Lemma + ) + ? ds1ds2Lemma + ) + ? rs'1rs'2Lemma + ) + ? rt1rt2Lemma + ) + ? ds1ds2Lemma + ) + ? s1s2Lemma + +{- BARE CORE +\ (xs1 :: [GHC.Types.Int]) + (xs2 :: [GHC.Types.Int]) + (xs1xs2Lemma :: [GHC.Types.Int]) -> + case xs1 of lq_anf$##72057594037927936501 { + [] -> + case xs2 of lq_anf$##72057594037927936502 { + [] -> + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.return x1)) + (RTick.return x2)) + GHC.Types.[] + GHC.Types.[] + (src<.:0:0> ? (? GHC.Tuple.() GHC.Types.[]) GHC.Types.[]); + : x2 ds2 -> + src<.:0:0> + ? (? GHC.Tuple.() (RTick.return GHC.Types.[])) + (case ds2 of lq_anf$##7205759403792793652 { + [] -> RTick.return (GHC.Types.: x2 GHC.Types.[]); + : lq_anf$##7205759403792793662 lq_anf$##7205759403792793663 -> + let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs2 } in + let { + ds_d1U5 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U5 + = RRelationalMSort.msort (Lists.right (Lists.split xs2)) } in + let { + rt :: GHC.Types.Int + [LclId] + rt + = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rt + } } in + let { + rs' :: [GHC.Types.Int] + [LclId] + rs' + = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rs' + } } in + let { + ds_d1U4 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U4 + = RRelationalMSort.msort (Lists.left (Lists.split xs2)) } in + let { + lt :: GHC.Types.Int + [LclId] + lt + = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + lt + } } in + let { + ls' :: [GHC.Types.Int] + [LclId] + ls' + = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + ls' + } } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + lt + })) + (case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rt + })) + (RRelationalMSort.merge + (case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + ls' + }) + (case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rs' + })) + }) + }; + : x1 ds1 -> + case xs2 of lq_anf$##72057594037927936502 { + [] -> + src<.:0:0> + ? (? GHC.Tuple.() + (case ds1 of lq_anf$##7205759403792793652 { + [] -> RTick.return (GHC.Types.: x1 GHC.Types.[]); + : lq_anf$##7205759403792793662 lq_anf$##7205759403792793663 -> + let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs1 } in + let { + ds_d1U5 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U5 + = RRelationalMSort.msort (Lists.right (Lists.split xs1)) } in + let { + rt :: GHC.Types.Int + [LclId] + rt + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rt + } } in + let { + rs' :: [GHC.Types.Int] + [LclId] + rs' + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rs' + } } in + let { + ds_d1U4 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U4 + = RRelationalMSort.msort (Lists.left (Lists.split xs1)) } in + let { + lt :: GHC.Types.Int + [LclId] + lt + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + lt + } } in + let { + ls' :: [GHC.Types.Int] + [LclId] + ls' + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + ls' + } } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + lt + })) + (case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rt + })) + (RRelationalMSort.merge + (case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + ls' + }) + (case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rs' + })) + })) + (RTick.return GHC.Types.[]); + : x2 ds2 -> + case ds1 of lq_anf$##72057594037927936521 { + [] -> + case ds2 of lq_anf$##72057594037927936522 { + [] -> + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.return x1)) + (RTick.return x2)) + (GHC.Types.: x1 GHC.Types.[]) + (GHC.Types.: x2 GHC.Types.[]) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (GHC.Types.: x1 x3)) + (GHC.Types.: x2 x4)) + x1 + x2 + (src<.:0:0> ? (? GHC.Tuple.() x1) x2) + GHC.Types.[] + GHC.Types.[] + (src<.:0:0> ? (? GHC.Tuple.() GHC.Types.[]) GHC.Types.[])); + : lq_anf$##72057594037927936622 lq_anf$##72057594037927936632 -> + src<.:0:0> + ? (? GHC.Tuple.() (RTick.return (GHC.Types.: x1 GHC.Types.[]))) + (let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs2 } in + let { + ds_d1U5 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U5 + = RRelationalMSort.msort (Lists.right (Lists.split xs2)) } in + let { + rt :: GHC.Types.Int + [LclId] + rt + = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rt + } } in + let { + rs' :: [GHC.Types.Int] + [LclId] + rs' + = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rs' + } } in + let { + ds_d1U4 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U4 + = RRelationalMSort.msort (Lists.left (Lists.split xs2)) } in + let { + lt :: GHC.Types.Int + [LclId] + lt + = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + lt + } } in + let { + ls' :: [GHC.Types.Int] + [LclId] + ls' + = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + ls' + } } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + lt + })) + (case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rt + })) + (RRelationalMSort.merge + (case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + ls' + }) + (case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rs' + }))) + }; + : lq_anf$##72057594037927936621 lq_anf$##72057594037927936631 -> + case ds2 of lq_anf$##72057594037927936522 { + [] -> + src<.:0:0> + ? (? GHC.Tuple.() + (let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs1 } in + let { + ds_d1U5 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U5 + = RRelationalMSort.msort (Lists.right (Lists.split xs1)) } in + let { + rt :: GHC.Types.Int + [LclId] + rt + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rt + } } in + let { + rs' :: [GHC.Types.Int] + [LclId] + rs' + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rs' + } } in + let { + ds_d1U4 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1U4 + = RRelationalMSort.msort (Lists.left (Lists.split xs1)) } in + let { + lt :: GHC.Types.Int + [LclId] + lt + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + lt + } } in + let { + ls' :: [GHC.Types.Int] + [LclId] + ls' + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + ls' + } } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + lt + })) + (case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rt + })) + (RRelationalMSort.merge + (case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + ls' + }) + (case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rs' + })))) + (RTick.return (GHC.Types.: x2 GHC.Types.[])); + : lq_anf$##72057594037927936622 lq_anf$##72057594037927936632 -> + let { + s1 :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s1 = Lists.split xs1 } in + let { + s2 :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s2 = Lists.split xs2 } in + let { + s1s2Lemma :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s1s2Lemma + = (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (Lists.split x1)) (Lists.split x2)) + xs1 xs2 xs1xs2Lemma } in + ? (let { + ds1 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds1 = RRelationalMSort.msort (Lists.right (Lists.split xs1)) } in + let { + ds2 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds2 = RRelationalMSort.msort (Lists.right (Lists.split xs2)) } in + let { + ds1ds2Lemma :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds1ds2Lemma + = msortMsortTheorem + (Lists.right (Lists.split xs1)) + (Lists.right (Lists.split xs2)) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (Lists.right x1)) (Lists.right x2)) + (Lists.split xs1) + (Lists.split xs2) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (Lists.split x1)) + (Lists.split x2)) + xs1 xs2 xs1xs2Lemma)) } in + ? (let { + rt1 :: GHC.Types.Int + [LclId] + rt1 + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt rs' -> + rt + } } in + let { + rt2 :: GHC.Types.Int + [LclId] + rt2 + = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt rs' -> + rt + } } in + let { + rt1rt2Lemma :: GHC.Types.Int + [LclId] + rt1rt2Lemma + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt1 rs'1 -> + case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt2 rs'2 -> + src<.:0:0> ? (? GHC.Tuple.() rt1) rt2 + } + } } in + ? (let { + rs'1 :: [GHC.Types.Int] + [LclId] + rs'1 + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt1 rs' -> + rs' + } } in + let { + rs'2 :: [GHC.Types.Int] + [LclId] + rs'2 + = case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt2 rs' -> + rs' + } } in + let { + rs'1rs'2Lemma :: [GHC.Types.Int] + [LclId] + rs'1rs'2Lemma + = case RRelationalMSort.msort (Lists.right (Lists.split xs1)) of + { RTick.Tick rt11 rs'1 -> + case RRelationalMSort.msort (Lists.right (Lists.split xs2)) of + { RTick.Tick rt22 rs'2 -> + src<.:0:0> ? (? GHC.Tuple.() rs'1) rs'2 + } + } } in + ? (let { + ds1 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds1 = RRelationalMSort.msort (Lists.left (Lists.split xs1)) } in + let { + ds2 :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds2 = RRelationalMSort.msort (Lists.left (Lists.split xs2)) } in + let { + ds1ds2Lemma :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds1ds2Lemma + = msortMsortTheorem + (Lists.left (Lists.split xs1)) + (Lists.left (Lists.split xs2)) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (Lists.left x1)) + (Lists.left x2)) + (Lists.split xs1) + (Lists.split xs2) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) (Lists.split x1)) + (Lists.split x2)) + xs1 xs2 xs1xs2Lemma)) } in + ? (let { + lt1 :: GHC.Types.Int + [LclId] + lt1 + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt ls' -> + lt + } } in + let { + lt2 :: GHC.Types.Int + [LclId] + lt2 + = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt ls' -> + lt + } } in + let { + lt1lt2Lemma :: GHC.Types.Int + [LclId] + lt1lt2Lemma + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) of + { RTick.Tick lt1 ls'1 -> + case RRelationalMSort.msort (Lists.left (Lists.split xs2)) of + { RTick.Tick lt2 ls'2 -> + src<.:0:0> ? (? GHC.Tuple.() lt1) lt2 + } + } } in + ? (let { + ls'1 :: [GHC.Types.Int] + [LclId] + ls'1 + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt1 ls' -> + ls' + } } in + let { + ls'2 :: [GHC.Types.Int] + [LclId] + ls'2 + = case RRelationalMSort.msort (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt2 ls' -> + ls' + } } in + let { + ls'1ls'2Lemma :: [GHC.Types.Int] + [LclId] + ls'1ls'2Lemma + = case RRelationalMSort.msort (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt11 ls'1 -> + case RRelationalMSort.msort (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt22 ls'2 -> + src<.:0:0> ? (? GHC.Tuple.() ls'1) ls'2 + } + } } in + ? ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (RTick.step x1 x3)) + (RTick.step x2 x4)) + (GHC.Num.+ + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt1 ls'1 -> + lt1 + })) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs1)) + of + { RTick.Tick rt1 rs'1 -> + rt1 + })) + (GHC.Num.+ + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt2 ls'2 -> + lt2 + })) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs2)) + of + { RTick.Tick rt2 rs'2 -> + rt2 + })) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt1 ls'1 -> + lt1 + })) + (GHC.Num.+ + (GHC.Types.I# 2#) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt2 ls'2 -> + lt2 + })) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + (GHC.Types.I# 2#) + (GHC.Types.I# 2#) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma) + (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 2# 2# (src<.:0:0> ? (? GHC.Tuple.() 2#) 2#)) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt1 ls'1 -> + lt1 + }) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt2 ls'2 -> + lt2 + }) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt11 ls'11 -> + case RRelationalMSort.msort + (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt22 ls'22 -> + lt1lt2Lemma + } + })) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs1)) + of + { RTick.Tick rt1 rs'1 -> + rt1 + }) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs2)) + of + { RTick.Tick rt2 rs'2 -> + rt2 + }) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs1)) + of + { RTick.Tick rt11 rs'11 -> + case RRelationalMSort.msort + (Lists.right (Lists.split xs2)) + of + { RTick.Tick rt22 rs'22 -> + rt1rt2Lemma + } + })) + (RRelationalMSort.merge + (case RRelationalMSort.msort + (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt1 ls'1 -> + ls'1 + }) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs1)) + of + { RTick.Tick rt1 rs'1 -> + rs'1 + })) + (RRelationalMSort.merge + (case RRelationalMSort.msort + (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt2 ls'2 -> + ls'2 + }) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs2)) + of + { RTick.Tick rt2 rs'2 -> + rs'2 + })) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) + (RRelationalMSort.merge x1 x3)) + (RRelationalMSort.merge x2 x4)) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt1 ls'1 -> + ls'1 + }) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt2 ls'2 -> + ls'2 + }) + (case RRelationalMSort.msort + (Lists.left (Lists.split xs1)) + of + { RTick.Tick lt11 ls'11 -> + case RRelationalMSort.msort + (Lists.left (Lists.split xs2)) + of + { RTick.Tick lt22 ls'22 -> + ls'1ls'2Lemma + } + }) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs1)) + of + { RTick.Tick rt1 rs'1 -> + rs'1 + }) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs2)) + of + { RTick.Tick rt2 rs'2 -> + rs'2 + }) + (case RRelationalMSort.msort + (Lists.right (Lists.split xs1)) + of + { RTick.Tick rt11 rs'11 -> + case RRelationalMSort.msort + (Lists.right (Lists.split xs2)) + of + { RTick.Tick rt22 rs'22 -> + rs'1rs'2Lemma + } + }))) + ls'1ls'2Lemma) + lt1lt2Lemma) + ds1ds2Lemma) + rs'1rs'2Lemma) + rt1rt2Lemma) + ds1ds2Lemma) + s1s2Lemma + } + } + } + } +-} diff --git a/tests/tests.cabal b/tests/tests.cabal index 707b4c3ed0..c81c605273 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2045,15 +2045,18 @@ executable relational-pos , IncrF , IncrLet , Lists + , Log2 , Map , Max , MutRecSame , Null , PMonad , PolyNull + , PowerOf2 , PredAbs , Prims - , R2Dcounting_relToUn + , ProofCombinators + , R2Dcounting_relToUn , R2Dcounting , RConstantTimeComparison_relToUn , RConstantTimeComparison @@ -2066,6 +2069,8 @@ executable relational-pos , RMemAlloc_relToUn , RMemAlloc , RPatError + , RRelationalMSort_relToUn + , RRelationalMSort , RSquareAndMultiply_relToUn , RSquareAndMultiply , RTick From 55a5bde109237450b3fdae2071eeb58aeddf7ad8 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 25 Apr 2023 13:17:40 +0200 Subject: [PATCH 207/219] fix square and mul --- .../Haskell/Liquid/Constraint/Relational.hs | 5 +- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 37 +- tests/relational/pos/RSquareAndMultiply.hs | 28 +- .../pos/RSquareAndMultiply_relToUn.hs | 1214 ++++++++++++----- 4 files changed, 878 insertions(+), 406 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index f21b50ada4..a768b2955c 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -659,7 +659,8 @@ consRelCheck unary γ ψ l1@(Let (NonRec x1 d1) e1) l2@(Let (NonRec x2 d2) e2) t let binders = vs1 ++ vs2 ++ concatMap (fst . vargs) ts1 ++ concatMap (fst . vargs) ts2 let qs' = traceWhenLoud ("Let qs: " ++ F.showpp qs) qs let (ho, fo) = L.partition (containsVars binders) qs' - γ''' <- γ'' `addPreds` map (F.subst rs2xs) fo + let fo' = map (F.subst rs2xs) fo + γ''' <- γ'' `addPreds` traceWhenLoud ("Let fos: " ++ F.showpp fo') fo' let ψ' = ψ ++ map (\qq -> toRel (evar1, evar2, s1, s2, qq)) ho consRelCheck unary γ''' ψ' e1' e2' t1 t2 p where @@ -1098,7 +1099,7 @@ mkRelCopies x1 x2 = (mkCopyWithSuffix relSuffixL x1, mkCopyWithSuffix relSuffixR mkCopyWithName :: String -> Var -> Var mkCopyWithName s v = traceWhenLoud ("mkCopyWithName: produced an occ name " ++ Ghc.getOccString (varName v')) v' -- where v' = GM.stringVar s (Ghc.exprType (Var v)) - where v' = Ghc.setVarName v $ Ghc.mkInternalName (Ghc.getUnique v) (Ghc.mkVarOcc s) (Ghc.getSrcSpan v) + where v' = Ghc.setVarName v $ Ghc.mkSystemName (Ghc.getUnique v) (Ghc.mkVarOcc s) mkCopyWithSuffix :: String -> Var -> Var mkCopyWithSuffix s v = mkCopyWithName (Ghc.getOccString v ++ s) v diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 586959d977..60d99fac69 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -88,13 +88,13 @@ fromAnf' (Lam b e) bnds in (Lam b e', bnds') fromAnf' (Let (NonRec rb lb) e) bnds - | elem '#' (show rb) = let (lb', bnds') = fromAnf' lb bnds - in fromAnf' e ((rb, lb') : bnds') - - | otherwise = (Let (NonRec rb lb') e', binds'') + | "lq_anf" == take 6 (show rb) + = fromAnf' e ((rb, lb') : bnds') + | otherwise + = (Let (NonRec rb lb') e', bnds'') where - (lb', bnds') = fromAnf' lb bnds - (e', binds'') = fromAnf' e ((rb, lb') : bnds') + (lb', bnds') = fromAnf' lb bnds + (e', bnds'') = fromAnf' e bnds' fromAnf' (Let (Rec {}) _) _ = error " By construction, no recursive bindings in let expression. " @@ -211,14 +211,14 @@ handleVar :: RenVars -> Var -> String handleVar vars v | isTyConName name = "{- TyConName -}" | isTyVarName name = "{- TyVar -}" - | isSystemName name = getSysName vars name --- ++ "{- SysName -}" + | isSystemName name = getSysName vars v + -- ++ "{- SysName -}" | isWiredInName name = getLocalName name --- ++ "{- WiredInName -}" - | isInternalName name = getSysName vars name --- ++ "{- Internal -}" + -- ++ "{- WiredInName -}" + | isInternalName name = getSysName vars v + -- ++ "{- Internal -}" | isExternalName name = getExternalName name --- ++ "{- external name -}" + -- ++ "{- external name -}" | otherwise = "{- Not properly handled -}" ++ show (getOccString name) where @@ -228,12 +228,15 @@ handleVar vars v occStr :: Var -> String occStr = getOccString . varName -getSysName :: RenVars -> Name -> String -getSysName vars n - | elem occ vars = occ - | otherwise = filter (not . (`elem` "$#")) occ +getSysName :: RenVars -> Var -> String +getSysName vars v + | occ `elem` vars = occ + -- | "Lemma" == drop (length occ - 5) occ = occ + -- ++ "{- in renvars -}" + | otherwise = filter (`notElem` "$#") $ show v + -- ++ "{- not in renvars -}" where - occ = getOccString n + occ = getOccString (varName v) {- Should not be done here, but function used to check if is an undesirable variable or not (I#) -} diff --git a/tests/relational/pos/RSquareAndMultiply.hs b/tests/relational/pos/RSquareAndMultiply.hs index ed838655f5..53a2235c0b 100644 --- a/tests/relational/pos/RSquareAndMultiply.hs +++ b/tests/relational/pos/RSquareAndMultiply.hs @@ -10,17 +10,16 @@ module RSquareAndMultiply where import RTick import Language.Haskell.Liquid.ProofCombinators -import Lists -import Prelude hiding (return, (>>=), pure, length, (<*>)) +import Prelude hiding (return, (>>=), pure, (<*>)) theorem :: Int -> Int -> [Int] -> [Int] -> Proof {-@ theorem :: t:Nat -> x:Int - -> l1:{[Int] | 0 < length l1} - -> l2:{[Int] | length l1 == length l2 } + -> l1:{[Int] | 0 < len l1} + -> l2:{[Int] | len l1 == len l2 } -> { tcost (sam t x l1) - tcost (sam t x l2) <= t * (diff l1 l2) } - / [length l1] + / [len l1] @-} theorem _ _ [_] [_] = () theorem t x (l1:ls1@(_:_)) (l2:ls2@(_:_)) @@ -36,30 +35,33 @@ theorem t x (l1:ls1@(_:_)) (l2:ls2@(_:_)) | l1 /= 0 && l2 /= 0 = theorem t x ls1 ls2 {-@ reflect diff @-} -{-@ diff :: l1:[Int] -> l2:{[Int] | length l1 == length l2 } -> Int @-} +{-@ diff :: l1:[Int] -> l2:{[Int] | len l1 == len l2 } -> Int @-} diff :: [Int] -> [Int] -> Int diff [] [] = 0 diff (x:xs) (y:ys) = (if x == y then 0 else 1) + diff xs ys {-@ reflect sam @-} sam :: Int -> Int -> [Int] -> Tick Int -{-@ sam :: t:Nat -> Int -> bs:{[Int] | 0 < length bs } -> Tick Int @-} +{-@ sam :: t:Nat -> Int -> bs:{[Int] | 0 < len bs } -> Tick Int @-} sam _ x [b] = return (if b == 0 then 1 else x) -sam t x (b:bs) | b == 0 = let s = sam t x bs in pure power2 <*> s -sam t x (_:bs) = let s = sam t x bs in s >>= power2Times t x - +sam t x (b:bs) = if b == 0 + then let Tick m v = sam t x bs + in pure power2 <*> Tick m v + else let Tick m v = sam t x bs + Tick n u = power2Times t x v + in Tick (m + n) u + --- Proof --- -{- relational sam ~ sam +{-@ relational sam ~ sam :: { t1:Nat -> x1:Int -> l1:[Int] -> Tick Int ~ t2:Nat -> x2:Int -> l2:[Int] -> Tick Int | !(t1 = t2) :=> !(x1 = x2) - :=> !(0 < Lists.length l1 && Lists.length l1 = Lists.length l2) + :=> !(0 < len l1 && len l1 = len l2) :=> RTick.tcost (r1 t1 x1 l1) - RTick.tcost (r2 t2 x2 l2) <= t1 * (RSquareAndMultiply.diff l1 l2) } @-} - --- End --- {-@ reflect power2Times @-} diff --git a/tests/relational/pos/RSquareAndMultiply_relToUn.hs b/tests/relational/pos/RSquareAndMultiply_relToUn.hs index cee72a82e0..e326df8b39 100644 --- a/tests/relational/pos/RSquareAndMultiply_relToUn.hs +++ b/tests/relational/pos/RSquareAndMultiply_relToUn.hs @@ -7,7 +7,6 @@ module RSquareAndMultiply_relToUn (module RSquareAndMultiply_relToUn) where import GHC.Classes import GHC.Types import Language.Haskell.Liquid.ProofCombinators -import Lists import RSquareAndMultiply import RTick import Prelude @@ -15,42 +14,42 @@ import Prelude {- HLINT ignore "Use camelCase" -} {- HLINT ignore "Use if" -} {- HLINT ignore "Use section" -} -{-@ samSamTheorem :: t1:{VV##0 : GHC.Types.Int | VV##0 >= 0} -> t2:{VV##0 : GHC.Types.Int | VV##0 >= 0} -> t1t2Lemma:{VV : () | t1 == t2} -> x1:GHC.Types.Int -> x2:GHC.Types.Int -> x1x2Lemma:{VV : () | x1 == x2} -> l1:[GHC.Types.Int] -> l2:[GHC.Types.Int] -> l1l2Lemma:{VV : () | Lists.length l1 == Lists.length l2 - && 0 < Lists.length l1} -> {VV : () | RTick.tcost (RSquareAndMultiply.sam t1 x1 l1) - RTick.tcost (RSquareAndMultiply.sam t2 x2 l2) <= t1 * RSquareAndMultiply.diff l1 l2} @-} +{-@ samSamTheorem :: t1:{VV##0 : GHC.Types.Int | VV##0 >= 0} -> t2:{VV##0 : GHC.Types.Int | VV##0 >= 0} -> t1t2Lemma:{VV : () | t1 == t2} -> x1:GHC.Types.Int -> x2:GHC.Types.Int -> x1x2Lemma:{VV : () | x1 == x2} -> l1:[GHC.Types.Int] -> l2:[GHC.Types.Int] -> l1l2Lemma:{VV : () | len l1 == len l2 + && 0 < len l1} -> {VV : () | RTick.tcost (RSquareAndMultiply.sam t1 x1 l1) - RTick.tcost (RSquareAndMultiply.sam t2 x2 l2) <= t1 * RSquareAndMultiply.diff l1 l2} @-} samSamTheorem :: GHC.Types.Int -> GHC.Types.Int -> () -> GHC.Types.Int -> GHC.Types.Int -> () -> [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () -samSamTheorem t1 t2 t1t2Lemma x1 x2 x1x2Lemma l1 l2 l1l2Lemma = case l1 of +samSamTheorem t1 t2 t1t2Lemma_d1TX x1 x2 x1x2Lemma_aVq l1 l2 l1l2Lemma_d1TY = case l1 of [] -> case l2 of [] -> {- GOAL: () ~ () -} () - (:) b2 ds2 -> {- GOAL: () ~ case ds2 of [] -> RT (...) -} () - (:) b1 ds1 -> case l2 of - [] -> {- GOAL: case ds1 of [] -> RT (...) ~ () -} () - (:) b2 ds2 -> case ds1 of - [] -> case ds2 of + (:) b2_aVr ds2_d1Uc -> {- GOAL: () ~ case ds2_d1Uc of [] (...) -} () + (:) b1_aVr ds1_d1Uc -> case l2 of + [] -> {- GOAL: case ds1_d1Uc of [] (...) ~ () -} () + (:) b2_aVr ds2_d1Uc -> case ds1_d1Uc of + [] -> case ds2_d1Uc of [] -> ( {- GOAL: RTick.return ~ RTick.return -} - (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.return x1)) ? (RTick.return x2)) + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.return x1)) ? (RTick.return x2)) ) - ( case b1 GHC.Classes.== 0 of + ( case b1_aVr GHC.Classes.== 0 of False -> x1 True -> 1 ) - ( case b2 GHC.Classes.== 0 of + ( case b2_aVr GHC.Classes.== 0 of False -> x2 True -> 1 ) - ( case b1 GHC.Classes.== 0 of - False -> case b2 GHC.Classes.== 0 of - False -> x1x2Lemma + ( case b1_aVr GHC.Classes.== 0 of + False -> case b2_aVr GHC.Classes.== 0 of + False -> x1x2Lemma_aVq True -> - {- GOAL: x1 ~ 1 -} + {- GOAL: x1_aVq ~ 1 -} (() ? x1) ? 1 - True -> case b2 GHC.Classes.== 0 of + True -> case b2_aVr GHC.Classes.== 0 of False -> - {- GOAL: 1 ~ x2 -} + {- GOAL: 1 ~ x2_aVq -} (() ? 1) ? x2 True -> ( {- GOAL: ~ -} - (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? x1) ? x2) + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? x1) ? x2) ) 1 1 @@ -58,524 +57,991 @@ samSamTheorem t1 t2 t1t2Lemma x1 x2 x1x2Lemma l1 l2 l1l2Lemma = case l1 of (() ? 1) ? 1 ) ) - (:) lq_anf72057594037927948272 lq_anf72057594037927948282 -> - {- GOAL: RTick.return (case b (...) ~ case b2 GHC.Classes. (...) -} + (:) lq_anf72057594037927936832_d1l lq_anf72057594037927936842_d1m -> + {- GOAL: RTick.return (case b (...) ~ case b2_aVr GHC.Clas (...) -} ( () ? ( RTick.return - ( case b1 GHC.Classes.== 0 of + ( case b1_aVr GHC.Classes.== 0 of False -> x1 True -> 1 ) ) ) - ? ( case b2 GHC.Classes.== 0 of + ? ( case b2_aVr GHC.Classes.== 0 of False -> - let s = RSquareAndMultiply.sam t2 x2 ds2 - in (RSquareAndMultiply.sam t2 x2 ds2) RTick.>>= (RSquareAndMultiply.power2Times t2 x2) + let ds_d1Ub = RSquareAndMultiply.sam t2 x2 ds2_d1Uc + in let m = case ds_d1Ub of + Tick m v -> m + in let v = case ds_d1Ub of + Tick m v -> v + in let ds_d1Ua = RSquareAndMultiply.power2Times t2 x2 v + in let n = case ds_d1Ua of + Tick n u -> n + in let u = case ds_d1Ua of + Tick n u -> u + in RTick.Tick (m + n) u True -> - let s = RSquareAndMultiply.sam t2 x2 ds2 - in (RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t2 x2 ds2) + let ds_d1U7 = RSquareAndMultiply.sam t2 x2 ds2_d1Uc + in let m = case ds_d1U7 of + Tick m v -> m + in let v = case ds_d1U7 of + Tick m v -> v + in (RTick.pure RSquareAndMultiply.power2) RTick.<*> (RTick.Tick m v) ) - (:) lq_anf72057594037927948271 lq_anf72057594037927948281 -> case ds2 of + (:) lq_anf72057594037927936831_d1l lq_anf72057594037927936841_d1m -> case ds2_d1Uc of [] -> - {- GOAL: case b1 GHC.Classes. (...) ~ RTick.return (case b (...) -} + {- GOAL: case b1_aVr GHC.Clas (...) ~ RTick.return (case b (...) -} ( () - ? ( case b1 GHC.Classes.== 0 of + ? ( case b1_aVr GHC.Classes.== 0 of False -> - let s = RSquareAndMultiply.sam t1 x1 ds1 - in (RSquareAndMultiply.sam t1 x1 ds1) RTick.>>= (RSquareAndMultiply.power2Times t1 x1) + let ds_d1Ub = RSquareAndMultiply.sam t1 x1 ds1_d1Uc + in let m = case ds_d1Ub of + Tick m v -> m + in let v = case ds_d1Ub of + Tick m v -> v + in let ds_d1Ua = RSquareAndMultiply.power2Times t1 x1 v + in let n = case ds_d1Ua of + Tick n u -> n + in let u = case ds_d1Ua of + Tick n u -> u + in RTick.Tick (m + n) u True -> - let s = RSquareAndMultiply.sam t1 x1 ds1 - in (RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t1 x1 ds1) + let ds_d1U7 = RSquareAndMultiply.sam t1 x1 ds1_d1Uc + in let m = case ds_d1U7 of + Tick m v -> m + in let v = case ds_d1U7 of + Tick m v -> v + in (RTick.pure RSquareAndMultiply.power2) RTick.<*> (RTick.Tick m v) ) ) ? ( RTick.return - ( case b2 GHC.Classes.== 0 of + ( case b2_aVr GHC.Classes.== 0 of False -> x2 True -> 1 ) ) - (:) lq_anf72057594037927948272 lq_anf72057594037927948282 -> case b1 GHC.Classes.== 0 of - False -> case b2 GHC.Classes.== 0 of + (:) lq_anf72057594037927936832_d1l lq_anf72057594037927936842_d1m -> case b1_aVr GHC.Classes.== 0 of + False -> case b2_aVr GHC.Classes.== 0 of False -> - let s1 = RSquareAndMultiply.sam t1 x1 ds1 - in let s2 = RSquareAndMultiply.sam t2 x2 ds2 - in let s1s2Lemma = + let ds1_d1Ub = RSquareAndMultiply.sam t1 x1 ds1_d1Uc + in let ds2_d1Ub = RSquareAndMultiply.sam t2 x2 ds2_d1Uc + in let ds1ds2Lemma_d1Ub = samSamTheorem t1 t2 - t1t2Lemma + t1t2Lemma_d1TX x1 x2 - x1x2Lemma - ds1 - ds2 - ( {- GOAL: ds1 ~ ds2 -} - (() ? ds1) ? ds2 - ) - in s1s2Lemma - ? ( ( {- GOAL: RTick.>>= ~ RTick.>>= -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 RTick.>>= x3)) ? (x2 RTick.>>= x4)) - ) - (RSquareAndMultiply.sam t1 x1 ds1) - (RSquareAndMultiply.sam t2 x2 ds2) - ( samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - ( {- GOAL: ds1 ~ ds2 -} - (() ? ds1) ? ds2 - ) - ) - (RSquareAndMultiply.power2Times t1 x1) - (RSquareAndMultiply.power2Times t2 x2) - ( ( {- GOAL: RSquareAndMultiply.p (...) ~ RSquareAndMultiply.p (...) -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma x5 x6 x5x6Lemma -> ((((() ? x1x2Lemma) ? x3x4Lemma) ? x5x6Lemma) ? (RSquareAndMultiply.power2Times x1 x3 x5)) ? (RSquareAndMultiply.power2Times x2 x4 x6)) - ) - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ) + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + ( {- GOAL: ds1_d1Uc ~ ds2_d1Uc -} + (() ? ds1_d1Uc) ? ds2_d1Uc ) + in ( let m1_aXk = case ds1_d1Ub of + Tick m v -> m + in let m2_aXk = case ds2_d1Ub of + Tick m v -> m + in let m1m2Lemma_aXk = case ds1_d1Ub of + Tick m1_aXk v1_aXl -> case ds2_d1Ub of + Tick m2_aXk v2_aXl -> + {- GOAL: m1_aXk ~ m2_aXk -} + (() ? m1_aXk) ? m2_aXk + in ( let v1_aXl = case ds1_d1Ub of + Tick m1_aXk v -> v + in let v2_aXl = case ds2_d1Ub of + Tick m2_aXk v -> v + in let v1v2Lemma_aXl = case ds1_d1Ub of + Tick m11_aXk v1_aXl -> case ds2_d1Ub of + Tick m22_aXk v2_aXl -> + {- GOAL: v1_aXl ~ v2_aXl -} + (() ? v1_aXl) ? v2_aXl + in ( let ds1_d1Ua = RSquareAndMultiply.power2Times t1 x1 v1_aXl + in let ds2_d1Ua = RSquareAndMultiply.power2Times t2 x2 v2_aXl + in let ds1ds2Lemma_d1Ua = + ( {- GOAL: RSquareAndMultiply.p (...) ~ RSquareAndMultiply.p (...) -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp x5 x6 x5x6Lemma_xp -> ((((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? x5x6Lemma_xp) ? (RSquareAndMultiply.power2Times x1 x3 x5)) ? (RSquareAndMultiply.power2Times x2 x4 x6)) + ) + t1 + t2 + t1t2Lemma_d1TX + x1 + x2 + x1x2Lemma_aVq + v1_aXl + v2_aXl + v1v2Lemma_aXl + in ( let n1_aXr = case ds1_d1Ua of + Tick n u -> n + in let n2_aXr = case ds2_d1Ua of + Tick n u -> n + in let n1n2Lemma_aXr = case ds1_d1Ua of + Tick n1_aXr u1_aXs -> case ds2_d1Ua of + Tick n2_aXr u2_aXs -> + {- GOAL: n1_aXr ~ n2_aXr -} + (() ? n1_aXr) ? n2_aXr + in ( let u1_aXs = case ds1_d1Ua of + Tick n1_aXr u -> u + in let u2_aXs = case ds2_d1Ua of + Tick n2_aXr u -> u + in let u1u2Lemma_aXs = case ds1_d1Ua of + Tick n11_aXr u1_aXs -> case ds2_d1Ua of + Tick n22_aXr u2_aXs -> + {- GOAL: u1_aXs ~ u2_aXs -} + (() ? u1_aXs) ? u2_aXs + in ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (RTick.Tick x1 x3)) ? (RTick.Tick x2 x4)) + ) + (m1_aXk + n1_aXr) + (m2_aXk + n2_aXr) + ( ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 + x3)) ? (x2 + x4)) + ) + m1_aXk + m2_aXk + m1m2Lemma_aXk + n1_aXr + n2_aXr + n1n2Lemma_aXr + ) + u1_aXs + u2_aXs + u1u2Lemma_aXs + ) + ? u1u2Lemma_aXs + ) + ? n1n2Lemma_aXr + ) + ? ds1ds2Lemma_d1Ua + ) + ? v1v2Lemma_aXl + ) + ? m1m2Lemma_aXk + ) + ? ds1ds2Lemma_d1Ub True -> - let s1 = RSquareAndMultiply.sam t1 x1 ds1 - in let s2 = RSquareAndMultiply.sam t2 x2 ds2 - in let s1s2Lemma = + let ds1_d1Ub = RSquareAndMultiply.sam t1 x1 ds1_d1Uc + in let ds2_d1U7 = RSquareAndMultiply.sam t2 x2 ds2_d1Uc + in let ds1ds2Lemma_d1Ub = samSamTheorem t1 t2 - t1t2Lemma + t1t2Lemma_d1TX x1 x2 - x1x2Lemma - ds1 - ds2 - ( {- GOAL: ds1 ~ ds2 -} - (() ? ds1) ? ds2 - ) - in s1s2Lemma - ? ( {- GOAL: (RSquareAndMultiply. (...) ~ (RTick.pure RSquareA (...) -} - (() ? ((RSquareAndMultiply.sam t1 x1 ds1) RTick.>>= (RSquareAndMultiply.power2Times t1 x1))) ? ((RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t2 x2 ds2)) + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + ( {- GOAL: ds1_d1Uc ~ ds2_d1Uc -} + (() ? ds1_d1Uc) ? ds2_d1Uc ) - True -> case b2 GHC.Classes.== 0 of + in ( let m1_aXk = case ds1_d1Ub of + Tick m v -> m + in let m2_aX7 = case ds2_d1U7 of + Tick m v -> m + in let m1m2Lemma_aXk = case ds1_d1Ub of + Tick m1_aXk v1_aXl -> case ds2_d1U7 of + Tick m2_aX7 v2_aX8 -> + {- GOAL: m1_aXk ~ m2_aX7 -} + (() ? m1_aXk) ? m2_aX7 + in ( let v1_aXl = case ds1_d1Ub of + Tick m1_aXk v -> v + in let v2_aX8 = case ds2_d1U7 of + Tick m2_aX7 v -> v + in let v1v2Lemma_aXl = case ds1_d1Ub of + Tick m11_aXk v1_aXl -> case ds2_d1U7 of + Tick m22_aX7 v2_aX8 -> + {- GOAL: v1_aXl ~ v2_aX8 -} + (() ? v1_aXl) ? v2_aX8 + in ( {- GOAL: let ds_d1Ua = RSquar (...) ~ (RTick.pure RSquareA (...) -} + ( () + ? ( let ds_d1Ua = RSquareAndMultiply.power2Times t1 x1 v1_aXl + in let n = case ds_d1Ua of + Tick n u -> n + in let u = case ds_d1Ua of + Tick n u -> u + in RTick.Tick (m1_aXk + n) u + ) + ) + ? ((RTick.pure RSquareAndMultiply.power2) RTick.<*> (RTick.Tick m2_aX7 v2_aX8)) + ) + ? v1v2Lemma_aXl + ) + ? m1m2Lemma_aXk + ) + ? ds1ds2Lemma_d1Ub + True -> case b2_aVr GHC.Classes.== 0 of False -> - let s1 = RSquareAndMultiply.sam t1 x1 ds1 - in let s2 = RSquareAndMultiply.sam t2 x2 ds2 - in let s1s2Lemma = + let ds1_d1U7 = RSquareAndMultiply.sam t1 x1 ds1_d1Uc + in let ds2_d1Ub = RSquareAndMultiply.sam t2 x2 ds2_d1Uc + in let ds1ds2Lemma_d1U7 = samSamTheorem t1 t2 - t1t2Lemma + t1t2Lemma_d1TX x1 x2 - x1x2Lemma - ds1 - ds2 - ( {- GOAL: ds1 ~ ds2 -} - (() ? ds1) ? ds2 - ) - in s1s2Lemma - ? ( {- GOAL: (RTick.pure RSquareA (...) ~ (RSquareAndMultiply. (...) -} - (() ? ((RTick.pure RSquareAndMultiply.power2) RTick.<*> (RSquareAndMultiply.sam t1 x1 ds1))) ? ((RSquareAndMultiply.sam t2 x2 ds2) RTick.>>= (RSquareAndMultiply.power2Times t2 x2)) + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + ( {- GOAL: ds1_d1Uc ~ ds2_d1Uc -} + (() ? ds1_d1Uc) ? ds2_d1Uc ) + in ( let m1_aX7 = case ds1_d1U7 of + Tick m v -> m + in let m2_aXk = case ds2_d1Ub of + Tick m v -> m + in let m1m2Lemma_aX7 = case ds1_d1U7 of + Tick m1_aX7 v1_aX8 -> case ds2_d1Ub of + Tick m2_aXk v2_aXl -> + {- GOAL: m1_aX7 ~ m2_aXk -} + (() ? m1_aX7) ? m2_aXk + in ( let v1_aX8 = case ds1_d1U7 of + Tick m1_aX7 v -> v + in let v2_aXl = case ds2_d1Ub of + Tick m2_aXk v -> v + in let v1v2Lemma_aX8 = case ds1_d1U7 of + Tick m11_aX7 v1_aX8 -> case ds2_d1Ub of + Tick m22_aXk v2_aXl -> + {- GOAL: v1_aX8 ~ v2_aXl -} + (() ? v1_aX8) ? v2_aXl + in ( {- GOAL: (RTick.pure RSquareA (...) ~ let ds_d1Ua = RSquar (...) -} + (() ? ((RTick.pure RSquareAndMultiply.power2) RTick.<*> (RTick.Tick m1_aX7 v1_aX8))) + ? ( let ds_d1Ua = RSquareAndMultiply.power2Times t2 x2 v2_aXl + in let n = case ds_d1Ua of + Tick n u -> n + in let u = case ds_d1Ua of + Tick n u -> u + in RTick.Tick (m2_aXk + n) u + ) + ) + ? v1v2Lemma_aX8 + ) + ? m1m2Lemma_aX7 + ) + ? ds1ds2Lemma_d1U7 True -> - let s1 = RSquareAndMultiply.sam t1 x1 ds1 - in let s2 = RSquareAndMultiply.sam t2 x2 ds2 - in let s1s2Lemma = + let ds1_d1U7 = RSquareAndMultiply.sam t1 x1 ds1_d1Uc + in let ds2_d1U7 = RSquareAndMultiply.sam t2 x2 ds2_d1Uc + in let ds1ds2Lemma_d1U7 = samSamTheorem t1 t2 - t1t2Lemma + t1t2Lemma_d1TX x1 x2 - x1x2Lemma - ds1 - ds2 - ( {- GOAL: ds1 ~ ds2 -} - (() ? ds1) ? ds2 - ) - in s1s2Lemma - ? ( ( {- GOAL: RTick.<*> ~ RTick.<*> -} - (\x1 x2 x1x2Lemma x3 x4 x3x4Lemma -> (((() ? x1x2Lemma) ? x3x4Lemma) ? (x1 RTick.<*> x3)) ? (x2 RTick.<*> x4)) - ) - (RTick.pure RSquareAndMultiply.power2) - (RTick.pure RSquareAndMultiply.power2) - ( ( {- GOAL: RTick.pure ~ RTick.pure -} - (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RTick.pure x1)) ? (RTick.pure x2)) - ) - RSquareAndMultiply.power2 - RSquareAndMultiply.power2 - ( {- GOAL: RSquareAndMultiply.p (...) ~ RSquareAndMultiply.p (...) -} - (\x1 x2 x1x2Lemma -> ((() ? x1x2Lemma) ? (RSquareAndMultiply.power2 x1)) ? (RSquareAndMultiply.power2 x2)) - ) - ) - (RSquareAndMultiply.sam t1 x1 ds1) - (RSquareAndMultiply.sam t2 x2 ds2) - ( samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - ( {- GOAL: ds1 ~ ds2 -} - (() ? ds1) ? ds2 - ) - ) + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + ( {- GOAL: ds1_d1Uc ~ ds2_d1Uc -} + (() ? ds1_d1Uc) ? ds2_d1Uc ) + in ( let m1_aX7 = case ds1_d1U7 of + Tick m v -> m + in let m2_aX7 = case ds2_d1U7 of + Tick m v -> m + in let m1m2Lemma_aX7 = case ds1_d1U7 of + Tick m1_aX7 v1_aX8 -> case ds2_d1U7 of + Tick m2_aX7 v2_aX8 -> + {- GOAL: m1_aX7 ~ m2_aX7 -} + (() ? m1_aX7) ? m2_aX7 + in ( let v1_aX8 = case ds1_d1U7 of + Tick m1_aX7 v -> v + in let v2_aX8 = case ds2_d1U7 of + Tick m2_aX7 v -> v + in let v1v2Lemma_aX8 = case ds1_d1U7 of + Tick m11_aX7 v1_aX8 -> case ds2_d1U7 of + Tick m22_aX7 v2_aX8 -> + {- GOAL: v1_aX8 ~ v2_aX8 -} + (() ? v1_aX8) ? v2_aX8 + in ( ( {- GOAL: RTick.<*> ~ RTick.<*> -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 RTick.<*> x3)) ? (x2 RTick.<*> x4)) + ) + (RTick.pure RSquareAndMultiply.power2) + (RTick.pure RSquareAndMultiply.power2) + ( ( {- GOAL: RTick.pure ~ RTick.pure -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.pure x1)) ? (RTick.pure x2)) + ) + RSquareAndMultiply.power2 + RSquareAndMultiply.power2 + ( {- GOAL: RSquareAndMultiply.p (...) ~ RSquareAndMultiply.p (...) -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RSquareAndMultiply.power2 x1)) ? (RSquareAndMultiply.power2 x2)) + ) + ) + (RTick.Tick m1_aX7 v1_aX8) + (RTick.Tick m2_aX7 v2_aX8) + ( ( {- GOAL: RTick.Tick ~ RTick.Tick -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (RTick.Tick x1 x3)) ? (RTick.Tick x2 x4)) + ) + m1_aX7 + m2_aX7 + m1m2Lemma_aX7 + v1_aX8 + v2_aX8 + v1v2Lemma_aX8 + ) + ) + ? v1v2Lemma_aX8 + ) + ? m1m2Lemma_aX7 + ) + ? ds1ds2Lemma_d1U7 {- BARE CORE -\ (t1 :: GHC.Types.Int) - (t2 :: GHC.Types.Int) - (t1t2Lemma :: GHC.Types.Int) - (x1 :: GHC.Types.Int) - (x2 :: GHC.Types.Int) - (x1x2Lemma :: GHC.Types.Int) - (l1 :: [GHC.Types.Int]) - (l2 :: [GHC.Types.Int]) - (l1l2Lemma :: [GHC.Types.Int]) -> - case l1 of lq_anf$##72057594037927948101 { +\ (t1_d1TX :: GHC.Types.Int) + (t2_d1TX :: GHC.Types.Int) + (t1t2Lemma_d1TX :: GHC.Types.Int) + (x1_aVq :: GHC.Types.Int) + (x2_aVq :: GHC.Types.Int) + (x1x2Lemma_aVq :: GHC.Types.Int) + (l1_d1TY :: [GHC.Types.Int]) + (l2_d1TY :: [GHC.Types.Int]) + (l1l2Lemma_d1TY :: [GHC.Types.Int]) -> + case l1_d1TY of lq_anf$##72057594037927936651_d13 { [] -> - case l2 of lq_anf$##72057594037927948102 { + case l2_d1TY of lq_anf$##72057594037927936652_d13 { [] -> src<.:0:0> GHC.Tuple.(); - : b2 ds2 -> src<.:0:0> GHC.Tuple.() + : b2_aVr ds2_d1Uc -> src<.:0:0> GHC.Tuple.() }; - : b1 ds1 -> - case l2 of lq_anf$##72057594037927948102 { + : b1_aVr ds1_d1Uc -> + case l2_d1TY of lq_anf$##72057594037927936652_d13 { [] -> src<.:0:0> GHC.Tuple.(); - : b2 ds2 -> - case ds1 of lq_anf$##72057594037927948141 { + : b2_aVr ds2_d1Uc -> + case ds1_d1Uc of lq_anf$##72057594037927936691_d17 { [] -> - case ds2 of lq_anf$##72057594037927948142 { + case ds2_d1Uc of lq_anf$##72057594037927936692_d17 { [] -> (src<.:0:0> - \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> - ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.return x1)) + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.return x1)) (RTick.return x2)) - (case GHC.Classes.== b1 (GHC.Types.I# 0#) - of lq_anf$##7205759403792794824 { - GHC.Types.False -> x1; + (case GHC.Classes.== b1_aVr (GHC.Types.I# 0#) + of lq_anf$##7205759403792793680 { + GHC.Types.False -> x1_aVq; GHC.Types.True -> GHC.Types.I# 1# }) - (case GHC.Classes.== b2 (GHC.Types.I# 0#) - of lq_anf$##7205759403792794824 { - GHC.Types.False -> x2; + (case GHC.Classes.== b2_aVr (GHC.Types.I# 0#) + of lq_anf$##7205759403792793680 { + GHC.Types.False -> x2_aVq; GHC.Types.True -> GHC.Types.I# 1# }) - (case GHC.Classes.== b1 (GHC.Types.I# 0#) - of lq_anf$##72057594037927948241 { + (case GHC.Classes.== b1_aVr (GHC.Types.I# 0#) + of lq_anf$##72057594037927936801_d1i { GHC.Types.False -> - case GHC.Classes.== b2 (GHC.Types.I# 0#) - of lq_anf$##72057594037927948242 { - GHC.Types.False -> x1x2Lemma; + case GHC.Classes.== b2_aVr (GHC.Types.I# 0#) + of lq_anf$##72057594037927936802_d1i { + GHC.Types.False -> x1x2Lemma_aVq; GHC.Types.True -> - src<.:0:0> ? (? GHC.Tuple.() x1) (GHC.Types.I# 1#) + src<.:0:0> ? (? GHC.Tuple.() x1_aVq) (GHC.Types.I# 1#) }; GHC.Types.True -> - case GHC.Classes.== b2 (GHC.Types.I# 0#) - of lq_anf$##72057594037927948242 { + case GHC.Classes.== b2_aVr (GHC.Types.I# 0#) + of lq_anf$##72057594037927936802_d1i { GHC.Types.False -> - src<.:0:0> ? (? GHC.Tuple.() (GHC.Types.I# 1#)) x2; + src<.:0:0> ? (? GHC.Tuple.() (GHC.Types.I# 1#)) x2_aVq; GHC.Types.True -> (src<.:0:0> - \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> - ? (? (? GHC.Tuple.() x1x2Lemma) (GHC.Types.I# x1)) + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (GHC.Types.I# x1)) (GHC.Types.I# x2)) 1# 1# (src<.:0:0> ? (? GHC.Tuple.() 1#) 1#) } }); - : lq_anf$##72057594037927948272 lq_anf$##72057594037927948282 -> + : lq_anf$##72057594037927936832_d1l + lq_anf$##72057594037927936842_d1m -> src<.:0:0> ? (? GHC.Tuple.() (RTick.return - (case GHC.Classes.== b1 (GHC.Types.I# 0#) - of lq_anf$##7205759403792794824 { - GHC.Types.False -> x1; + (case GHC.Classes.== b1_aVr (GHC.Types.I# 0#) + of lq_anf$##7205759403792793680 { + GHC.Types.False -> x1_aVq; GHC.Types.True -> GHC.Types.I# 1# }))) - (case GHC.Classes.== b2 (GHC.Types.I# 0#) - of lq_anf$##7205759403792794818 { + (case GHC.Classes.== b2_aVr (GHC.Types.I# 0#) + of lq_anf$##7205759403792793673 { GHC.Types.False -> let { - s :: RTick.Tick GHC.Types.Int + ds_d1Ub :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1Ub = RSquareAndMultiply.sam t2_d1TX x2_aVq ds2_d1Uc } in + let { + m :: GHC.Types.Int + [LclId] + m = case ds_d1Ub of { RTick.Tick m v -> m } } in + let { + v :: GHC.Types.Int + [LclId] + v = case ds_d1Ub of { RTick.Tick m v -> v } } in + let { + ds_d1Ua :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s = RSquareAndMultiply.sam t2 x2 ds2 } in - RTick.>>= - (RSquareAndMultiply.sam t2 x2 ds2) - (RSquareAndMultiply.power2Times t2 x2); + ds_d1Ua = RSquareAndMultiply.power2Times t2_d1TX x2_aVq v } in + let { + n :: GHC.Types.Int + [LclId] + n = case ds_d1Ua of { RTick.Tick n u -> n } } in + let { + u :: GHC.Types.Int + [LclId] + u = case ds_d1Ua of { RTick.Tick n u -> u } } in + RTick.Tick (GHC.Num.+ m n) u; GHC.Types.True -> let { - s :: RTick.Tick GHC.Types.Int + ds_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s = RSquareAndMultiply.sam t2 x2 ds2 } in - RTick.<*> - (RTick.pure RSquareAndMultiply.power2) - (RSquareAndMultiply.sam t2 x2 ds2) + ds_d1U7 = RSquareAndMultiply.sam t2_d1TX x2_aVq ds2_d1Uc } in + let { + m :: GHC.Types.Int + [LclId] + m = case ds_d1U7 of { RTick.Tick m v -> m } } in + let { + v :: GHC.Types.Int + [LclId] + v = case ds_d1U7 of { RTick.Tick m v -> v } } in + RTick.<*> (RTick.pure RSquareAndMultiply.power2) (RTick.Tick m v) }) }; - : lq_anf$##72057594037927948271 lq_anf$##72057594037927948281 -> - case ds2 of lq_anf$##72057594037927948142 { + : lq_anf$##72057594037927936831_d1l + lq_anf$##72057594037927936841_d1m -> + case ds2_d1Uc of lq_anf$##72057594037927936692_d17 { [] -> src<.:0:0> ? (? GHC.Tuple.() - (case GHC.Classes.== b1 (GHC.Types.I# 0#) - of lq_anf$##7205759403792794818 { + (case GHC.Classes.== b1_aVr (GHC.Types.I# 0#) + of lq_anf$##7205759403792793673 { GHC.Types.False -> let { - s :: RTick.Tick GHC.Types.Int + ds_d1Ub :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s = RSquareAndMultiply.sam t1 x1 ds1 } in - RTick.>>= - (RSquareAndMultiply.sam t1 x1 ds1) - (RSquareAndMultiply.power2Times t1 x1); + ds_d1Ub = RSquareAndMultiply.sam t1_d1TX x1_aVq ds1_d1Uc } in + let { + m :: GHC.Types.Int + [LclId] + m = case ds_d1Ub of { RTick.Tick m v -> m } } in + let { + v :: GHC.Types.Int + [LclId] + v = case ds_d1Ub of { RTick.Tick m v -> v } } in + let { + ds_d1Ua :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + ds_d1Ua = RSquareAndMultiply.power2Times t1_d1TX x1_aVq v } in + let { + n :: GHC.Types.Int + [LclId] + n = case ds_d1Ua of { RTick.Tick n u -> n } } in + let { + u :: GHC.Types.Int + [LclId] + u = case ds_d1Ua of { RTick.Tick n u -> u } } in + RTick.Tick (GHC.Num.+ m n) u; GHC.Types.True -> let { - s :: RTick.Tick GHC.Types.Int + ds_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s = RSquareAndMultiply.sam t1 x1 ds1 } in - RTick.<*> - (RTick.pure RSquareAndMultiply.power2) - (RSquareAndMultiply.sam t1 x1 ds1) + ds_d1U7 = RSquareAndMultiply.sam t1_d1TX x1_aVq ds1_d1Uc } in + let { + m :: GHC.Types.Int + [LclId] + m = case ds_d1U7 of { RTick.Tick m v -> m } } in + let { + v :: GHC.Types.Int + [LclId] + v = case ds_d1U7 of { RTick.Tick m v -> v } } in + RTick.<*> (RTick.pure RSquareAndMultiply.power2) (RTick.Tick m v) })) (RTick.return - (case GHC.Classes.== b2 (GHC.Types.I# 0#) - of lq_anf$##7205759403792794824 { - GHC.Types.False -> x2; + (case GHC.Classes.== b2_aVr (GHC.Types.I# 0#) + of lq_anf$##7205759403792793680 { + GHC.Types.False -> x2_aVq; GHC.Types.True -> GHC.Types.I# 1# })); - : lq_anf$##72057594037927948272 lq_anf$##72057594037927948282 -> - case GHC.Classes.== b1 (GHC.Types.I# 0#) - of lq_anf$##72057594037927948181 { + : lq_anf$##72057594037927936832_d1l + lq_anf$##72057594037927936842_d1m -> + case GHC.Classes.== b1_aVr (GHC.Types.I# 0#) + of lq_anf$##72057594037927936731_d1b { GHC.Types.False -> - case GHC.Classes.== b2 (GHC.Types.I# 0#) - of lq_anf$##72057594037927948182 { + case GHC.Classes.== b2_aVr (GHC.Types.I# 0#) + of lq_anf$##72057594037927936732_d1b { GHC.Types.False -> let { - s1 :: RTick.Tick GHC.Types.Int + ds1_d1Ub :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + ds1_d1Ub = RSquareAndMultiply.sam t1_d1TX x1_aVq ds1_d1Uc } in let { - s2 :: RTick.Tick GHC.Types.Int + ds2_d1Ub :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + ds2_d1Ub = RSquareAndMultiply.sam t2_d1TX x2_aVq ds2_d1Uc } in let { - s1s2Lemma :: RTick.Tick GHC.Types.Int + ds1ds2Lemma_d1Ub :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1s2Lemma - = samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in - ? s1s2Lemma - ((src<.:0:0> - \ (x1 :: ()) - (x2 :: ()) - (x1x2Lemma :: ()) - (x3 :: ()) - (x4 :: ()) - (x3x4Lemma :: ()) -> - ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (RTick.>>= x1 x3)) - (RTick.>>= x2 x4)) - (RSquareAndMultiply.sam t1 x1 ds1) - (RSquareAndMultiply.sam t2 x2 ds2) - (samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2)) - (RSquareAndMultiply.power2Times t1 x1) - (RSquareAndMultiply.power2Times t2 x2) - ((src<.:0:0> - \ (x1 :: ()) - (x2 :: ()) - (x1x2Lemma :: ()) - (x3 :: ()) - (x4 :: ()) - (x3x4Lemma :: ()) - (x5 :: ()) - (x6 :: ()) - (x5x6Lemma :: ()) -> - ? (? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) x5x6Lemma) - (RSquareAndMultiply.power2Times x1 x3 x5)) - (RSquareAndMultiply.power2Times x2 x4 x6)) - t1 t2 t1t2Lemma x1 x2 x1x2Lemma)); + ds1ds2Lemma_d1Ub + = samSamTheorem_rxR + t1_d1TX + t2_d1TX + t1t2Lemma_d1TX + x1_aVq + x2_aVq + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + (src<.:0:0> ? (? GHC.Tuple.() ds1_d1Uc) ds2_d1Uc) } in + ? (let { + m1_aXk :: GHC.Types.Int + [LclId] + m1_aXk = case ds1_d1Ub of { RTick.Tick m v -> m } } in + let { + m2_aXk :: GHC.Types.Int + [LclId] + m2_aXk = case ds2_d1Ub of { RTick.Tick m v -> m } } in + let { + m1m2Lemma_aXk :: GHC.Types.Int + [LclId] + m1m2Lemma_aXk + = case ds1_d1Ub of { RTick.Tick m1_aXk v1_aXl -> + case ds2_d1Ub of { RTick.Tick m2_aXk v2_aXl -> + src<.:0:0> ? (? GHC.Tuple.() m1_aXk) m2_aXk + } + } } in + ? (let { + v1_aXl :: GHC.Types.Int + [LclId] + v1_aXl = case ds1_d1Ub of { RTick.Tick m1_aXk v -> v } } in + let { + v2_aXl :: GHC.Types.Int + [LclId] + v2_aXl = case ds2_d1Ub of { RTick.Tick m2_aXk v -> v } } in + let { + v1v2Lemma_aXl :: GHC.Types.Int + [LclId] + v1v2Lemma_aXl + = case ds1_d1Ub of { RTick.Tick m11_aXk v1_aXl -> + case ds2_d1Ub of { RTick.Tick m22_aXk v2_aXl -> + src<.:0:0> ? (? GHC.Tuple.() v1_aXl) v2_aXl + } + } } in + ? (let { + ds1_d1Ua :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, + ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds1_d1Ua + = RSquareAndMultiply.power2Times t1_d1TX x1_aVq v1_aXl } in + let { + ds2_d1Ua :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, + ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds2_d1Ua + = RSquareAndMultiply.power2Times t2_d1TX x2_aVq v2_aXl } in + let { + ds1ds2Lemma_d1Ua :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, + ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds1ds2Lemma_d1Ua + = (src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) + (x5 :: ()) + (x6 :: ()) + (x5x6Lemma_xp :: ()) -> + ? (? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + x5x6Lemma_xp) + (RSquareAndMultiply.power2Times x1 x3 x5)) + (RSquareAndMultiply.power2Times x2 x4 x6)) + t1_d1TX + t2_d1TX + t1t2Lemma_d1TX + x1_aVq + x2_aVq + x1x2Lemma_aVq + v1_aXl + v2_aXl + v1v2Lemma_aXl } in + ? (let { + n1_aXr :: GHC.Types.Int + [LclId] + n1_aXr = case ds1_d1Ua of { RTick.Tick n u -> n } } in + let { + n2_aXr :: GHC.Types.Int + [LclId] + n2_aXr = case ds2_d1Ua of { RTick.Tick n u -> n } } in + let { + n1n2Lemma_aXr :: GHC.Types.Int + [LclId] + n1n2Lemma_aXr + = case ds1_d1Ua of { RTick.Tick n1_aXr u1_aXs -> + case ds2_d1Ua of { RTick.Tick n2_aXr u2_aXs -> + src<.:0:0> ? (? GHC.Tuple.() n1_aXr) n2_aXr + } + } } in + ? (let { + u1_aXs :: GHC.Types.Int + [LclId] + u1_aXs + = case ds1_d1Ua of { RTick.Tick n1_aXr u -> u } } in + let { + u2_aXs :: GHC.Types.Int + [LclId] + u2_aXs + = case ds2_d1Ua of { RTick.Tick n2_aXr u -> u } } in + let { + u1u2Lemma_aXs :: GHC.Types.Int + [LclId] + u1u2Lemma_aXs + = case ds1_d1Ua of { RTick.Tick n11_aXr u1_aXs -> + case ds2_d1Ua of { RTick.Tick n22_aXr u2_aXs -> + src<.:0:0> ? (? GHC.Tuple.() u1_aXs) u2_aXs + } + } } in + ? ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (RTick.Tick x1 x3)) + (RTick.Tick x2 x4)) + (GHC.Num.+ m1_aXk n1_aXr) + (GHC.Num.+ m2_aXk n2_aXr) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) + x3x4Lemma_xp) + (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + m1_aXk + m2_aXk + m1m2Lemma_aXk + n1_aXr + n2_aXr + n1n2Lemma_aXr) + u1_aXs + u2_aXs + u1u2Lemma_aXs) + u1u2Lemma_aXs) + n1n2Lemma_aXr) + ds1ds2Lemma_d1Ua) + v1v2Lemma_aXl) + m1m2Lemma_aXk) + ds1ds2Lemma_d1Ub; GHC.Types.True -> let { - s1 :: RTick.Tick GHC.Types.Int + ds1_d1Ub :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + ds1_d1Ub = RSquareAndMultiply.sam t1_d1TX x1_aVq ds1_d1Uc } in let { - s2 :: RTick.Tick GHC.Types.Int + ds2_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + ds2_d1U7 = RSquareAndMultiply.sam t2_d1TX x2_aVq ds2_d1Uc } in let { - s1s2Lemma :: RTick.Tick GHC.Types.Int + ds1ds2Lemma_d1Ub :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1s2Lemma - = samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in - ? s1s2Lemma - (src<.:0:0> - ? (? GHC.Tuple.() - (RTick.>>= - (RSquareAndMultiply.sam t1 x1 ds1) - (RSquareAndMultiply.power2Times t1 x1))) - (RTick.<*> - (RTick.pure RSquareAndMultiply.power2) - (RSquareAndMultiply.sam t2 x2 ds2))) + ds1ds2Lemma_d1Ub + = samSamTheorem_rxR + t1_d1TX + t2_d1TX + t1t2Lemma_d1TX + x1_aVq + x2_aVq + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + (src<.:0:0> ? (? GHC.Tuple.() ds1_d1Uc) ds2_d1Uc) } in + ? (let { + m1_aXk :: GHC.Types.Int + [LclId] + m1_aXk = case ds1_d1Ub of { RTick.Tick m v -> m } } in + let { + m2_aX7 :: GHC.Types.Int + [LclId] + m2_aX7 = case ds2_d1U7 of { RTick.Tick m v -> m } } in + let { + m1m2Lemma_aXk :: GHC.Types.Int + [LclId] + m1m2Lemma_aXk + = case ds1_d1Ub of { RTick.Tick m1_aXk v1_aXl -> + case ds2_d1U7 of { RTick.Tick m2_aX7 v2_aX8 -> + src<.:0:0> ? (? GHC.Tuple.() m1_aXk) m2_aX7 + } + } } in + ? (let { + v1_aXl :: GHC.Types.Int + [LclId] + v1_aXl = case ds1_d1Ub of { RTick.Tick m1_aXk v -> v } } in + let { + v2_aX8 :: GHC.Types.Int + [LclId] + v2_aX8 = case ds2_d1U7 of { RTick.Tick m2_aX7 v -> v } } in + let { + v1v2Lemma_aXl :: GHC.Types.Int + [LclId] + v1v2Lemma_aXl + = case ds1_d1Ub of { RTick.Tick m11_aXk v1_aXl -> + case ds2_d1U7 of { RTick.Tick m22_aX7 v2_aX8 -> + src<.:0:0> ? (? GHC.Tuple.() v1_aXl) v2_aX8 + } + } } in + ? (src<.:0:0> + ? (? GHC.Tuple.() + (let { + ds_d1Ua :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, + ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds_d1Ua + = RSquareAndMultiply.power2Times + t1_d1TX x1_aVq v1_aXl } in + let { + n :: GHC.Types.Int + [LclId] + n = case ds_d1Ua of { RTick.Tick n u -> n } } in + let { + u :: GHC.Types.Int + [LclId] + u = case ds_d1Ua of { RTick.Tick n u -> u } } in + RTick.Tick (GHC.Num.+ m1_aXk n) u)) + (RTick.<*> + (RTick.pure RSquareAndMultiply.power2) + (RTick.Tick m2_aX7 v2_aX8))) + v1v2Lemma_aXl) + m1m2Lemma_aXk) + ds1ds2Lemma_d1Ub }; GHC.Types.True -> - case GHC.Classes.== b2 (GHC.Types.I# 0#) - of lq_anf$##72057594037927948182 { + case GHC.Classes.== b2_aVr (GHC.Types.I# 0#) + of lq_anf$##72057594037927936732_d1b { GHC.Types.False -> let { - s1 :: RTick.Tick GHC.Types.Int + ds1_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + ds1_d1U7 = RSquareAndMultiply.sam t1_d1TX x1_aVq ds1_d1Uc } in let { - s2 :: RTick.Tick GHC.Types.Int + ds2_d1Ub :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + ds2_d1Ub = RSquareAndMultiply.sam t2_d1TX x2_aVq ds2_d1Uc } in let { - s1s2Lemma :: RTick.Tick GHC.Types.Int + ds1ds2Lemma_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1s2Lemma - = samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in - ? s1s2Lemma - (src<.:0:0> - ? (? GHC.Tuple.() - (RTick.<*> - (RTick.pure RSquareAndMultiply.power2) - (RSquareAndMultiply.sam t1 x1 ds1))) - (RTick.>>= - (RSquareAndMultiply.sam t2 x2 ds2) - (RSquareAndMultiply.power2Times t2 x2))); + ds1ds2Lemma_d1U7 + = samSamTheorem_rxR + t1_d1TX + t2_d1TX + t1t2Lemma_d1TX + x1_aVq + x2_aVq + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + (src<.:0:0> ? (? GHC.Tuple.() ds1_d1Uc) ds2_d1Uc) } in + ? (let { + m1_aX7 :: GHC.Types.Int + [LclId] + m1_aX7 = case ds1_d1U7 of { RTick.Tick m v -> m } } in + let { + m2_aXk :: GHC.Types.Int + [LclId] + m2_aXk = case ds2_d1Ub of { RTick.Tick m v -> m } } in + let { + m1m2Lemma_aX7 :: GHC.Types.Int + [LclId] + m1m2Lemma_aX7 + = case ds1_d1U7 of { RTick.Tick m1_aX7 v1_aX8 -> + case ds2_d1Ub of { RTick.Tick m2_aXk v2_aXl -> + src<.:0:0> ? (? GHC.Tuple.() m1_aX7) m2_aXk + } + } } in + ? (let { + v1_aX8 :: GHC.Types.Int + [LclId] + v1_aX8 = case ds1_d1U7 of { RTick.Tick m1_aX7 v -> v } } in + let { + v2_aXl :: GHC.Types.Int + [LclId] + v2_aXl = case ds2_d1Ub of { RTick.Tick m2_aXk v -> v } } in + let { + v1v2Lemma_aX8 :: GHC.Types.Int + [LclId] + v1v2Lemma_aX8 + = case ds1_d1U7 of { RTick.Tick m11_aX7 v1_aX8 -> + case ds2_d1Ub of { RTick.Tick m22_aXk v2_aXl -> + src<.:0:0> ? (? GHC.Tuple.() v1_aX8) v2_aXl + } + } } in + ? (src<.:0:0> + ? (? GHC.Tuple.() + (RTick.<*> + (RTick.pure RSquareAndMultiply.power2) + (RTick.Tick m1_aX7 v1_aX8))) + (let { + ds_d1Ua :: RTick.Tick GHC.Types.Int + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, + ConLike=False, WorkFree=False, Expandable=False, + Guidance=IF_ARGS [] 40 0}] + ds_d1Ua + = RSquareAndMultiply.power2Times + t2_d1TX x2_aVq v2_aXl } in + let { + n :: GHC.Types.Int + [LclId] + n = case ds_d1Ua of { RTick.Tick n u -> n } } in + let { + u :: GHC.Types.Int + [LclId] + u = case ds_d1Ua of { RTick.Tick n u -> u } } in + RTick.Tick (GHC.Num.+ m2_aXk n) u)) + v1v2Lemma_aX8) + m1m2Lemma_aX7) + ds1ds2Lemma_d1U7; GHC.Types.True -> let { - s1 :: RTick.Tick GHC.Types.Int + ds1_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1 = RSquareAndMultiply.sam t1 x1 ds1 } in + ds1_d1U7 = RSquareAndMultiply.sam t1_d1TX x1_aVq ds1_d1Uc } in let { - s2 :: RTick.Tick GHC.Types.Int + ds2_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s2 = RSquareAndMultiply.sam t2 x2 ds2 } in + ds2_d1U7 = RSquareAndMultiply.sam t2_d1TX x2_aVq ds2_d1Uc } in let { - s1s2Lemma :: RTick.Tick GHC.Types.Int + ds1ds2Lemma_d1U7 :: RTick.Tick GHC.Types.Int [LclId, Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] - s1s2Lemma - = samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2) } in - ? s1s2Lemma - ((src<.:0:0> - \ (x1 :: ()) - (x2 :: ()) - (x1x2Lemma :: ()) - (x3 :: ()) - (x4 :: ()) - (x3x4Lemma :: ()) -> - ? (? (? (? GHC.Tuple.() x1x2Lemma) x3x4Lemma) (RTick.<*> x1 x3)) - (RTick.<*> x2 x4)) - (RTick.pure RSquareAndMultiply.power2) - (RTick.pure RSquareAndMultiply.power2) - ((src<.:0:0> - \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> - ? (? (? GHC.Tuple.() x1x2Lemma) (RTick.pure x1)) (RTick.pure x2)) - RSquareAndMultiply.power2 - RSquareAndMultiply.power2 - (src<.:0:0> - \ (x1 :: ()) (x2 :: ()) (x1x2Lemma :: ()) -> - ? (? (? GHC.Tuple.() x1x2Lemma) (RSquareAndMultiply.power2 x1)) - (RSquareAndMultiply.power2 x2))) - (RSquareAndMultiply.sam t1 x1 ds1) - (RSquareAndMultiply.sam t2 x2 ds2) - (samSamTheorem - t1 - t2 - t1t2Lemma - x1 - x2 - x1x2Lemma - ds1 - ds2 - (src<.:0:0> ? (? GHC.Tuple.() ds1) ds2))) + ds1ds2Lemma_d1U7 + = samSamTheorem_rxR + t1_d1TX + t2_d1TX + t1t2Lemma_d1TX + x1_aVq + x2_aVq + x1x2Lemma_aVq + ds1_d1Uc + ds2_d1Uc + (src<.:0:0> ? (? GHC.Tuple.() ds1_d1Uc) ds2_d1Uc) } in + ? (let { + m1_aX7 :: GHC.Types.Int + [LclId] + m1_aX7 = case ds1_d1U7 of { RTick.Tick m v -> m } } in + let { + m2_aX7 :: GHC.Types.Int + [LclId] + m2_aX7 = case ds2_d1U7 of { RTick.Tick m v -> m } } in + let { + m1m2Lemma_aX7 :: GHC.Types.Int + [LclId] + m1m2Lemma_aX7 + = case ds1_d1U7 of { RTick.Tick m1_aX7 v1_aX8 -> + case ds2_d1U7 of { RTick.Tick m2_aX7 v2_aX8 -> + src<.:0:0> ? (? GHC.Tuple.() m1_aX7) m2_aX7 + } + } } in + ? (let { + v1_aX8 :: GHC.Types.Int + [LclId] + v1_aX8 = case ds1_d1U7 of { RTick.Tick m1_aX7 v -> v } } in + let { + v2_aX8 :: GHC.Types.Int + [LclId] + v2_aX8 = case ds2_d1U7 of { RTick.Tick m2_aX7 v -> v } } in + let { + v1v2Lemma_aX8 :: GHC.Types.Int + [LclId] + v1v2Lemma_aX8 + = case ds1_d1U7 of { RTick.Tick m11_aX7 v1_aX8 -> + case ds2_d1U7 of { RTick.Tick m22_aX7 v2_aX8 -> + src<.:0:0> ? (? GHC.Tuple.() v1_aX8) v2_aX8 + } + } } in + ? ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (RTick.<*> x1 x3)) + (RTick.<*> x2 x4)) + (RTick.pure RSquareAndMultiply.power2) + (RTick.pure RSquareAndMultiply.power2) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.pure x1)) + (RTick.pure x2)) + RSquareAndMultiply.power2 + RSquareAndMultiply.power2 + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) + (RSquareAndMultiply.power2 x1)) + (RSquareAndMultiply.power2 x2))) + (RTick.Tick m1_aX7 v1_aX8) + (RTick.Tick m2_aX7 v2_aX8) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (RTick.Tick x1 x3)) + (RTick.Tick x2 x4)) + m1_aX7 m2_aX7 m1m2Lemma_aX7 v1_aX8 v2_aX8 v1v2Lemma_aX8)) + v1v2Lemma_aX8) + m1m2Lemma_aX7) + ds1ds2Lemma_d1U7 } } } From a602136bcef2c1cd65b9dc1c96ca53f1ede61c99 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 25 Apr 2023 13:36:41 +0200 Subject: [PATCH 208/219] rm relational m sort from tests --- tests/tests.cabal | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/tests.cabal b/tests/tests.cabal index c81c605273..a2f4b7ed2c 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2069,8 +2069,6 @@ executable relational-pos , RMemAlloc_relToUn , RMemAlloc , RPatError - , RRelationalMSort_relToUn - , RRelationalMSort , RSquareAndMultiply_relToUn , RSquareAndMultiply , RTick From 119116326eeb5d77940da55a93085890d69c18d5 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 25 Apr 2023 16:05:26 +0200 Subject: [PATCH 209/219] enable fast flag --- src/Language/Haskell/Liquid/Liquid.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index acb2de07a5..69ffcbe0ef 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -260,6 +260,7 @@ solveCs cfg tgt cgi info names = do let hintFile = replaceBaseName tgt hintName let flags = "{-@ LIQUID \"--reflection\" @-}\n" ++ "{-@ LIQUID \"--ple\" @-}\n" + ++ "{-@ LIQUID \"--fast\" @-}\n" ++ "{-@ LIQUID \"--no-adt\" @-}\n\n" let moduleFile = "module " ++ hintName ++ " ( module " ++ hintName ++ ") where\n" let listOfImps = map (\imp -> F.symbolicString imp) From ecf953c052a2ade0f89e91aa22f8e8e05caaeac6 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 25 Apr 2023 16:06:20 +0200 Subject: [PATCH 210/219] add completed relational msort translation --- tests/relational/pos/RRelationalMSort.hs | 10 +- .../pos/RRelationalMSort_relToUn_completed.hs | 587 ++++++++++++++++++ tests/tests.cabal | 2 + 3 files changed, 593 insertions(+), 6 deletions(-) create mode 100644 tests/relational/pos/RRelationalMSort_relToUn_completed.hs diff --git a/tests/relational/pos/RRelationalMSort.hs b/tests/relational/pos/RRelationalMSort.hs index f0a53c398c..2127bf0d0d 100644 --- a/tests/relational/pos/RRelationalMSort.hs +++ b/tests/relational/pos/RRelationalMSort.hs @@ -24,9 +24,7 @@ import Prelude hiding (return, (>>=), pure, length, (<*>), log, take, drop, min, {- relational msort ~ msort :: { xs1:[Int] -> Tick [Int] ~ xs2:[Int] -> Tick [Int] | !(Lists.length xs1 = Lists.length xs2 && powerOf2 (Lists.length xs1)) - :=> Lists.length xs1 = Lists.length (RTick.tval (r1 xs1)) - && Lists.length xs2 = Lists.length (RTick.tval (r2 xs2)) - && RTick.tcost (r1 xs1) - RTick.tcost (r2 xs2) + :=> RTick.tcost (r1 xs1) - RTick.tcost (r2 xs2) <= Lists.length xs1 * (1 + log (RRelationalMSort.differ xs1 xs2)) } @-} @@ -47,10 +45,10 @@ msort :: [Int] -> Tick [Int] msort [] = return [] msort [x] = return [x] -- msort xs = step 2 (zipWithM merge (msort ls) (msort rs)) -msort xs = step (2 + lt + rt) (merge ls' rs') +msort xs = step (2 + tcost l + tcost r) (merge (tval l) (tval r)) where - Tick lt ls' = msort (left s) - Tick rt rs' = msort (right s) + l = msort (left s) + r = msort (right s) s = split xs {-@ reflect merge @-} diff --git a/tests/relational/pos/RRelationalMSort_relToUn_completed.hs b/tests/relational/pos/RRelationalMSort_relToUn_completed.hs new file mode 100644 index 0000000000..9767e57a8b --- /dev/null +++ b/tests/relational/pos/RRelationalMSort_relToUn_completed.hs @@ -0,0 +1,587 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} +{-@ LIQUID "--fast" @-} +module RRelationalMSort_relToUn_completed where + +import GHC.Classes +import GHC.Types +import Language.Haskell.Liquid.ProofCombinators +import Lists +import Log2 +import PowerOf2 +import ProofCombinators +import RRelationalMSort +import RTick +import Prelude hiding (length, take, drop, log) + + +{- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} +{-@ msortMsortTheorem :: xs1:[GHC.Types.Int] -> xs2:[GHC.Types.Int] -> xs1xs2Lemma:{VV : () | powerOf2 (Lists.length xs1) + && Lists.length xs1 == Lists.length xs2} -> {VV : () | RTick.tcost (RRelationalMSort.msort xs1) - RTick.tcost (RRelationalMSort.msort xs2) <= Lists.length xs1 * (1 + log (RRelationalMSort.differ xs1 xs2))} / [length xs1] @-} +msortMsortTheorem :: [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () +msortMsortTheorem xs1 xs2 xs1xs2Lemma_d1TS = case xs1 of + [] -> case xs2 of + [] -> + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.return x1)) ? (RTick.return x2)) + ) + [] + [] + ( {- GOAL: [] ~ [] -} + (() ? []) ? [] + ) + (:) x2_a10c ds2_d1U1 -> + {- GOAL: RTick.return [] ~ case ds2_d1U1 of [] (...) -} + (() ? (RTick.return [])) + ? ( case ds2_d1U1 of + [] -> RTick.return (x2_a10c : []) + (:) lq_anf7205759403792793666 lq_anf7205759403792793667 -> + let s = Lists.split xs2 + in let r = RRelationalMSort.msort (Lists.right s) + in let l = RRelationalMSort.msort (Lists.left s) + in RTick.step ((2 + (RTick.tcost l)) + (RTick.tcost r)) (RRelationalMSort.merge (RTick.tval l) (RTick.tval r)) + ) + (:) x1_a10c ds1_d1U1 -> case xs2 of + [] -> + {- GOAL: case ds1_d1U1 of [] (...) ~ RTick.return [] -} + ( () + ? ( case ds1_d1U1 of + [] -> RTick.return (x1_a10c : []) + (:) lq_anf7205759403792793666 lq_anf7205759403792793667 -> + let s = Lists.split xs1 + in let r = RRelationalMSort.msort (Lists.right s) + in let l = RRelationalMSort.msort (Lists.left s) + in RTick.step ((2 + (RTick.tcost l)) + (RTick.tcost r)) (RRelationalMSort.merge (RTick.tval l) (RTick.tval r)) + ) + ) + ? (RTick.return []) + (:) x2_a10c ds2_d1U1 -> case ds1_d1U1 of + [] -> case ds2_d1U1 of + [] -> + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.return x1)) ? (RTick.return x2)) + ) + (x1_a10c : []) + (x2_a10c : []) + ( ( {- GOAL: : ~ : -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 : x3)) ? (x2 : x4)) + ) + x1_a10c + x2_a10c + ( {- GOAL: x1_a10c ~ x2_a10c -} + (() ? x1_a10c) ? x2_a10c + ) + [] + [] + ( {- GOAL: [] ~ [] -} + (() ? []) ? [] + ) + ) ? logNat (differ [x1_a10c] [x2_a10c]) + (:) lq_anf72057594037927936662_d14 lq_anf72057594037927936672_d15 -> + {- GOAL: RTick.return (x1_a10 (...) ~ let s = Lists.split (...) -} + (() ? (RTick.return (x1_a10c : []))) + ? ( let s = Lists.split xs2 + in let r = RRelationalMSort.msort (Lists.right s) + in let l = RRelationalMSort.msort (Lists.left s) + in RTick.step ((2 + (RTick.tcost l)) + (RTick.tcost r)) (RRelationalMSort.merge (RTick.tval l) (RTick.tval r)) + ) + (:) lq_anf72057594037927936661_d14 lq_anf72057594037927936671_d15 -> case ds2_d1U1 of + [] -> + {- GOAL: let s = Lists.split (...) ~ RTick.return (x2_a10 (...) -} + ( () + ? ( let s = Lists.split xs1 + in let r = RRelationalMSort.msort (Lists.right s) + in let l = RRelationalMSort.msort (Lists.left s) + in RTick.step ((2 + (RTick.tcost l)) + (RTick.tcost r)) (RRelationalMSort.merge (RTick.tval l) (RTick.tval r)) + ) + ) + ? (RTick.return (x2_a10c : [])) + (:) lq_anf72057594037927936662_d14 lq_anf72057594037927936672_d15 -> if 0 == differ xs1 xs2 then theoremSameLists xs1 xs2 else + let s1_a10g = Lists.split xs1 + in let s2_a10g = Lists.split xs2 + in let s1s2Lemma_a10g = + ( {- GOAL: Lists.split ~ Lists.split -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (Lists.split x1)) ? (Lists.split x2)) + ) + xs1 + xs2 + xs1xs2Lemma_d1TS + in ( let r1_a10f = RRelationalMSort.msort (Lists.right s1_a10g) + in let r2_a10f = RRelationalMSort.msort (Lists.right s2_a10g) + lxs1 = (Lists.left s1_a10g) + rxs1 = (Lists.right s1_a10g) + lxs2 = (Lists.left s2_a10g) + rxs2 = (Lists.right s2_a10g) + in let r1r2Lemma_a10f = + assert (length xs1 >= 2) + ? assert (length xs2 >= 2) + ? powerOfIsEven n + ? assert (length (Lists.right s1_a10g) == length xs1 `div` 2) + ? assert (length (Lists.right s2_a10g) == length xs2 `div` 2) + ? msortMsortTheorem + (Lists.right s1_a10g) + (Lists.right s2_a10g) + ( ( {- GOAL: Lists.right ~ Lists.right -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (Lists.right x1)) ? (Lists.right x2)) + ) + s1_a10g + s2_a10g + s1s2Lemma_a10g + ) + ? splitDiffer n2 xs1 xs2 + ? plusLog (differ lxs1 lxs2) (differ rxs1 rxs2) (differ xs1 xs2) + in ( let l1_a10e = RRelationalMSort.msort (Lists.left s1_a10g) + in let l2_a10e = RRelationalMSort.msort (Lists.left s2_a10g) + in let l1l2Lemma_a10e = + msortMsortTheorem + (Lists.left s1_a10g) + (Lists.left s2_a10g) + ( ( {- GOAL: Lists.left ~ Lists.left -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (Lists.left x1)) ? (Lists.left x2)) + ) + s1_a10g + s2_a10g + s1s2Lemma_a10g + ) + in ( ( {- GOAL: RTick.step ~ RTick.step -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (RTick.step x1 x3)) ? (RTick.step x2 x4)) + ) + ((2 + (RTick.tcost l1_a10e)) + (RTick.tcost r1_a10f)) + ((2 + (RTick.tcost l2_a10e)) + (RTick.tcost r2_a10f)) + ( ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 + x3)) ? (x2 + x4)) + ) + (2 + (RTick.tcost l1_a10e)) + (2 + (RTick.tcost l2_a10e)) + ( ( {- GOAL: + ~ + -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 + x3)) ? (x2 + x4)) + ) + 2 + 2 + ( ( {- GOAL: ~ -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? x1) ? x2) + ) + 2 + 2 + ( {- GOAL: 2 ~ 2 -} + (() ? 2) ? 2 + ) + ) + (RTick.tcost l1_a10e) + (RTick.tcost l2_a10e) + ( ( {- GOAL: RTick.tcost ~ RTick.tcost -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.tcost x1)) ? (RTick.tcost x2)) + ) + l1_a10e + l2_a10e + l1l2Lemma_a10e + ) + ) + (RTick.tcost r1_a10f) + (RTick.tcost r2_a10f) + ( ( {- GOAL: RTick.tcost ~ RTick.tcost -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.tcost x1)) ? (RTick.tcost x2)) + ) + r1_a10f + r2_a10f + r1r2Lemma_a10f + ) + ) + (RRelationalMSort.merge (RTick.tval l1_a10e) (RTick.tval r1_a10f)) + (RRelationalMSort.merge (RTick.tval l2_a10e) (RTick.tval r2_a10f)) + ( ( {- GOAL: RRelationalMSort.mer (...) ~ RRelationalMSort.mer (...) -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (RRelationalMSort.merge x1 x3)) ? (RRelationalMSort.merge x2 x4)) + ) + (RTick.tval l1_a10e) + (RTick.tval l2_a10e) + ( ( {- GOAL: RTick.tval ~ RTick.tval -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.tval x1)) ? (RTick.tval x2)) + ) + l1_a10e + l2_a10e + l1l2Lemma_a10e + ) + (RTick.tval r1_a10f) + (RTick.tval r2_a10f) + ( ( {- GOAL: RTick.tval ~ RTick.tval -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.tval x1)) ? (RTick.tval x2)) + ) + r1_a10f + r2_a10f + r1r2Lemma_a10f + ) + ) + ) + ? l1l2Lemma_a10e + ) + ? r1r2Lemma_a10f + ) + ? s1s2Lemma_a10g + ? distributeDiv n 3 (log (differ xs1 xs2)) + where + n = length xs1 + n2 = length xs1 `div` 2 + +{-@ assume theoremSameLists + :: xs:[Int] + -> ys:{[Int] | length xs = length ys && powerOf2 (length xs) + && (differ xs ys == 0) } + -> { tcost (msort xs) - tcost (msort ys) + <= length xs * (1 + log (differ xs ys))} + @-} +theoremSameLists :: [Int] -> [Int] -> Proof +theoremSameLists _ _ = () + +{-@ ple splitDiffer @-} +splitDiffer :: Int -> [Int] -> [Int] -> Proof +{-@ splitDiffer :: n:Nat + -> xs:{[Int] | n <= length xs } + -> ys:{[Int] | n <= length ys && length xs == length ys } + -> { differ xs ys == differ (take n xs) (take n ys) + + differ (drop n xs) (drop n ys) } +@-} +splitDiffer _ [] [] = () +splitDiffer _ [] (_:_) = () +splitDiffer _ (_:_) [] = () +splitDiffer 0 _ _ = () -- NV: based on the definitions of take drop take 0 = [] and drop 0 xs = xs only when you are not in the list empty case +splitDiffer n (x:xs) (y:ys) + = differ (x:xs) (y:ys) + ? splitDiffer (n-1) xs ys + === differ (take n (x:xs)) (take n (y:ys)) + differ (drop n (x:xs)) (drop n (y:ys)) + *** QED + + +{- BARE CORE +\ (xs1_d1TS :: [GHC.Types.Int]) + (xs2_d1TS :: [GHC.Types.Int]) + (xs1xs2Lemma_d1TS :: [GHC.Types.Int]) -> + case xs1_d1TS of lq_anf$##72057594037927936501_dO { + [] -> + case xs2_d1TS of lq_anf$##72057594037927936502_dO { + [] -> + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.return x1)) + (RTick.return x2)) + GHC.Types.[] + GHC.Types.[] + (src<.:0:0> ? (? GHC.Tuple.() GHC.Types.[]) GHC.Types.[]); + : x2_a10c ds2_d1U1 -> + src<.:0:0> + ? (? GHC.Tuple.() (RTick.return GHC.Types.[])) + (case ds2_d1U1 of lq_anf$##7205759403792793652 { + [] -> RTick.return (GHC.Types.: x2_a10c GHC.Types.[]); + : lq_anf$##7205759403792793666 lq_anf$##7205759403792793667 -> + let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs2_d1TS } in + let { + r :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + r = RRelationalMSort.msort (Lists.right s) } in + let { + l :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + l = RRelationalMSort.msort (Lists.left s) } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l)) (RTick.tcost r)) + (RRelationalMSort.merge (RTick.tval l) (RTick.tval r)) + }) + }; + : x1_a10c ds1_d1U1 -> + case xs2_d1TS of lq_anf$##72057594037927936502_dO { + [] -> + src<.:0:0> + ? (? GHC.Tuple.() + (case ds1_d1U1 of lq_anf$##7205759403792793652 { + [] -> RTick.return (GHC.Types.: x1_a10c GHC.Types.[]); + : lq_anf$##7205759403792793666 lq_anf$##7205759403792793667 -> + let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs1_d1TS } in + let { + r :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + r = RRelationalMSort.msort (Lists.right s) } in + let { + l :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + l = RRelationalMSort.msort (Lists.left s) } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l)) (RTick.tcost r)) + (RRelationalMSort.merge (RTick.tval l) (RTick.tval r)) + })) + (RTick.return GHC.Types.[]); + : x2_a10c ds2_d1U1 -> + case ds1_d1U1 of lq_anf$##72057594037927936521_dQ { + [] -> + case ds2_d1U1 of lq_anf$##72057594037927936522_dQ { + [] -> + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.return x1)) + (RTick.return x2)) + (GHC.Types.: x1_a10c GHC.Types.[]) + (GHC.Types.: x2_a10c GHC.Types.[]) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (GHC.Types.: x1 x3)) + (GHC.Types.: x2 x4)) + x1_a10c + x2_a10c + (src<.:0:0> ? (? GHC.Tuple.() x1_a10c) x2_a10c) + GHC.Types.[] + GHC.Types.[] + (src<.:0:0> ? (? GHC.Tuple.() GHC.Types.[]) GHC.Types.[])); + : lq_anf$##72057594037927936662_d14 + lq_anf$##72057594037927936672_d15 -> + src<.:0:0> + ? (? GHC.Tuple.() + (RTick.return (GHC.Types.: x1_a10c GHC.Types.[]))) + (let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs2_d1TS } in + let { + r :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + r = RRelationalMSort.msort (Lists.right s) } in + let { + l :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + l = RRelationalMSort.msort (Lists.left s) } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l)) (RTick.tcost r)) + (RRelationalMSort.merge (RTick.tval l) (RTick.tval r))) + }; + : lq_anf$##72057594037927936661_d14 + lq_anf$##72057594037927936671_d15 -> + case ds2_d1U1 of lq_anf$##72057594037927936522_dQ { + [] -> + src<.:0:0> + ? (? GHC.Tuple.() + (let { + s :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s = Lists.split xs1_d1TS } in + let { + r :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + r = RRelationalMSort.msort (Lists.right s) } in + let { + l :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + l = RRelationalMSort.msort (Lists.left s) } in + RTick.step + (GHC.Num.+ + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l)) (RTick.tcost r)) + (RRelationalMSort.merge (RTick.tval l) (RTick.tval r)))) + (RTick.return (GHC.Types.: x2_a10c GHC.Types.[])); + : lq_anf$##72057594037927936662_d14 + lq_anf$##72057594037927936672_d15 -> + let { + s1_a10g :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s1_a10g = Lists.split xs1_d1TS } in + let { + s2_a10g :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s2_a10g = Lists.split xs2_d1TS } in + let { + s1s2Lemma_a10g :: Lists.P [GHC.Types.Int] [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] + s1s2Lemma_a10g + = (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (Lists.split x1)) + (Lists.split x2)) + xs1_d1TS xs2_d1TS xs1xs2Lemma_d1TS } in + ? (let { + r1_a10f :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + r1_a10f = RRelationalMSort.msort (Lists.right s1_a10g) } in + let { + r2_a10f :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + r2_a10f = RRelationalMSort.msort (Lists.right s2_a10g) } in + let { + r1r2Lemma_a10f :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + r1r2Lemma_a10f + = msortMsortTheorem_rKO + (Lists.right s1_a10g) + (Lists.right s2_a10g) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (Lists.right x1)) + (Lists.right x2)) + s1_a10g s2_a10g s1s2Lemma_a10g) } in + ? (let { + l1_a10e :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + l1_a10e = RRelationalMSort.msort (Lists.left s1_a10g) } in + let { + l2_a10e :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + l2_a10e = RRelationalMSort.msort (Lists.left s2_a10g) } in + let { + l1l2Lemma_a10e :: RTick.Tick [GHC.Types.Int] + [LclId, + Unf=Unf{Src=, TopLvl=False, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 0}] + l1l2Lemma_a10e + = msortMsortTheorem_rKO + (Lists.left s1_a10g) + (Lists.left s2_a10g) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (Lists.left x1)) + (Lists.left x2)) + s1_a10g s2_a10g s1s2Lemma_a10g) } in + ? ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (RTick.step x1 x3)) + (RTick.step x2 x4)) + (GHC.Num.+ + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l1_a10e)) + (RTick.tcost r1_a10f)) + (GHC.Num.+ + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l2_a10e)) + (RTick.tcost r2_a10f)) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l1_a10e)) + (GHC.Num.+ (GHC.Types.I# 2#) (RTick.tcost l2_a10e)) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (GHC.Num.+ x1 x3)) + (GHC.Num.+ x2 x4)) + (GHC.Types.I# 2#) + (GHC.Types.I# 2#) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (GHC.Types.I# x1)) + (GHC.Types.I# x2)) + 2# 2# (src<.:0:0> ? (? GHC.Tuple.() 2#) 2#)) + (RTick.tcost l1_a10e) + (RTick.tcost l2_a10e) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.tcost x1)) + (RTick.tcost x2)) + l1_a10e l2_a10e l1l2Lemma_a10e)) + (RTick.tcost r1_a10f) + (RTick.tcost r2_a10f) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.tcost x1)) + (RTick.tcost x2)) + r1_a10f r2_a10f r1r2Lemma_a10f)) + (RRelationalMSort.merge (RTick.tval l1_a10e) (RTick.tval r1_a10f)) + (RRelationalMSort.merge (RTick.tval l2_a10e) (RTick.tval r2_a10f)) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (RRelationalMSort.merge x1 x3)) + (RRelationalMSort.merge x2 x4)) + (RTick.tval l1_a10e) + (RTick.tval l2_a10e) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.tval x1)) + (RTick.tval x2)) + l1_a10e l2_a10e l1l2Lemma_a10e) + (RTick.tval r1_a10f) + (RTick.tval r2_a10f) + ((src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.tval x1)) + (RTick.tval x2)) + r1_a10f r2_a10f r1r2Lemma_a10f))) + l1l2Lemma_a10e) + r1r2Lemma_a10f) + s1s2Lemma_a10g + } + } + } + } +-} diff --git a/tests/tests.cabal b/tests/tests.cabal index a2f4b7ed2c..628e0e9057 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2069,6 +2069,8 @@ executable relational-pos , RMemAlloc_relToUn , RMemAlloc , RPatError + , RRelationalMSort_relToUn_completed + , RRelationalMSort , RSquareAndMultiply_relToUn , RSquareAndMultiply , RTick From b196ac1cf4c5fff50537a19401653b7937ea66be Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 25 Apr 2023 16:22:29 +0200 Subject: [PATCH 211/219] add record fields in split --- tests/relational/pos/Lists.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/relational/pos/Lists.hs b/tests/relational/pos/Lists.hs index ddcdc28e33..f9dc3fbdbc 100644 --- a/tests/relational/pos/Lists.hs +++ b/tests/relational/pos/Lists.hs @@ -21,6 +21,7 @@ import Language.Haskell.Liquid.ProofCombinators import Erasure {-@ type OList a = [a]<{\h x -> h <= x }> @-} +{-@ type List a = [a] @-} -- -- Some functions on lists. Throughout this file the cost model is the number @@ -172,7 +173,7 @@ dropLE_erase n (x : xs) *** QED -data P a b = P a b +data P a b = P { left :: a, right :: b} {-@ data P a b

b -> Bool> = P {left :: a, rigth :: b

}@-} {-@ reflect split @-} split :: [a] -> P [a] [a] @@ -186,6 +187,5 @@ split :: [a] -> P [a] [a] => (length l == length x / 2 && length r == length x / 2))}> [a] [a] @-} - split xs = P (take n xs) (drop n xs) where n = length xs `div` 2 \ No newline at end of file From a780ba2c26d92d9550ccb3c0583bc83cd1029155 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 25 Apr 2023 16:42:53 +0200 Subject: [PATCH 212/219] fix typo --- tests/relational/pos/Lists.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/relational/pos/Lists.hs b/tests/relational/pos/Lists.hs index f9dc3fbdbc..cad59eedf3 100644 --- a/tests/relational/pos/Lists.hs +++ b/tests/relational/pos/Lists.hs @@ -174,7 +174,7 @@ dropLE_erase n (x : xs) data P a b = P { left :: a, right :: b} -{-@ data P a b

b -> Bool> = P {left :: a, rigth :: b

}@-} +{-@ data P a b

b -> Bool> = P {left :: a, right :: b

}@-} {-@ reflect split @-} split :: [a] -> P [a] [a] {-@ split From efffa12d442095438fb804cff646ef5d791a5aa8 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 25 Apr 2023 17:25:03 +0200 Subject: [PATCH 213/219] rm abstract reft signature from split --- tests/relational/pos/Lists.hs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/relational/pos/Lists.hs b/tests/relational/pos/Lists.hs index cad59eedf3..7c9bfdd0aa 100644 --- a/tests/relational/pos/Lists.hs +++ b/tests/relational/pos/Lists.hs @@ -177,7 +177,7 @@ data P a b = P { left :: a, right :: b} {-@ data P a b

b -> Bool> = P {left :: a, right :: b

}@-} {-@ reflect split @-} split :: [a] -> P [a] [a] -{-@ split +{- split :: x:[a] -> P <{\l r -> (2 <= length x => @@ -187,5 +187,11 @@ split :: [a] -> P [a] [a] => (length l == length x / 2 && length r == length x / 2))}> [a] [a] @-} +{-@ split :: x:[a] + -> {p:P [a] [a] + | (2 <= length x => (length (left p) < length x && length (right p) < length x)) + && length (left p) + length (right p) == length x + && (((length x) mod 2 == 0 ) + => (length (left p) == length x / 2 && length (right p) == length x / 2))} @-} split xs = P (take n xs) (drop n xs) where n = length xs `div` 2 \ No newline at end of file From 4e2570524517e7e7da906ffb70e84a4b46680de9 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 2 May 2023 18:40:08 +0200 Subject: [PATCH 214/219] remove --fast flag --- src/Language/Haskell/Liquid/Liquid.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Language/Haskell/Liquid/Liquid.hs b/src/Language/Haskell/Liquid/Liquid.hs index 69ffcbe0ef..acb2de07a5 100644 --- a/src/Language/Haskell/Liquid/Liquid.hs +++ b/src/Language/Haskell/Liquid/Liquid.hs @@ -260,7 +260,6 @@ solveCs cfg tgt cgi info names = do let hintFile = replaceBaseName tgt hintName let flags = "{-@ LIQUID \"--reflection\" @-}\n" ++ "{-@ LIQUID \"--ple\" @-}\n" - ++ "{-@ LIQUID \"--fast\" @-}\n" ++ "{-@ LIQUID \"--no-adt\" @-}\n\n" let moduleFile = "module " ++ hintName ++ " ( module " ++ hintName ++ ") where\n" let listOfImps = map (\imp -> F.symbolicString imp) From 1da1d7be79408425ad23d0558cadd47bc20a2f1b Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 2 May 2023 22:46:02 +0200 Subject: [PATCH 215/219] add isort completed --- tests/relational/pos/RRelationalISort.hs | 142 ++++++++++++++---- .../pos/RRelationalISort_relToUn_completed.hs | 139 +++++++++++++++++ tests/tests.cabal | 2 + 3 files changed, 255 insertions(+), 28 deletions(-) create mode 100644 tests/relational/pos/RRelationalISort_relToUn_completed.hs diff --git a/tests/relational/pos/RRelationalISort.hs b/tests/relational/pos/RRelationalISort.hs index d35c7a8397..013c99858a 100644 --- a/tests/relational/pos/RRelationalISort.hs +++ b/tests/relational/pos/RRelationalISort.hs @@ -1,12 +1,13 @@ {- POPL'17 Radicek et al. -} {- ISort 16/11/69 -} -{- LIQUID "--relational-hints" @-} +{-@ LIQUID "--relational-hints" @-} +{- LIQUID "--relational" @-} {-@ LIQUID "--reflection" @-} -{-@ LIQUID "--ple-local" @-} +{-@ LIQUID "--ple" @-} module RRelationalISort where -import Prelude hiding (return, (>>=), pure, sort, (<*>), length) +import Prelude hiding (return, (>>=), pure, (<*>), length) import Lists {-@ infix : @-} {-@ infix @-} @@ -15,42 +16,138 @@ import Language.Haskell.Liquid.ProofCombinators import Language.Haskell.Liquid.Bag --- Proof --- -{-@ relational isort ~ isort - :: { l1:[a] -> Tick [a] - ~ l2:[a] -> Tick [a] - | !(true) - :=> !(Lists.length l1 = Lists.length l2) - :=> RTick.tcost (r1 l1) - RTick.tcost (r2 l2) +{-@ assume relational isort ~ isort + :: { l1:[Int] -> Tick [Int] + ~ l2:[Int] -> Tick [Int] + | !(Lists.length l1 = Lists.length l2) + :=> RTick.tcost (r1 l1) - RTick.tcost (r2 l2) <= RRelationalISort.unsortedDiff l1 l2 } @-} -{-@ relational insert ~ insert :: { x1:a -> xs1:[a] -> Tick [a] - ~ x2:a -> xs2:[a] -> Tick [a] +{- assume relational isort ~ isort by translation isortIsortTheorem @-} + +{- relational insert ~ insert :: { x1:Int -> xs1:[Int] -> Tick [Int] + ~ x2:Int -> xs2:[Int] -> Tick [Int] | !(true) - :=> !(true) :=> !(true) :=> RTick.tcost (r1 x1 xs1) - RTick.tcost (r2 x2 xs2) <= RRelationalISort.largerThan x1 xs1 - RRelationalISort.largerThan x2 xs2 } @-} --- End --- +--- Proof --- +{-@ ple theorem @-} +theorem :: [Int] -> [Int] -> Proof +{-@ theorem :: l1:[Int] -> l2:{[Int] | length l1 == length l2} + -> { tcost (isort l1) - tcost (isort l2) <= unsortedDiff l1 l2 } @-} +theorem [] [] + = () +theorem (x1:xs1) (x2:xs2) + = theorem xs1 xs2 + ? lemma x1 (getISortVal xs1) + ? lemma_preservation x1 xs1 + ? lemma x2 (getISortVal xs2) + ? lemma_preservation x2 xs2 + +{-@ ple lemma @-} +lemma :: Ord a => a -> [a] -> Proof +{-@ lemma + :: Ord a => x:a + -> xs:(OList a) + -> { tcost (insert x xs) == largerThan x xs } +@-} +lemma _ [] = () +lemma x (y:ys) + | x <= y + = lemma1 x (castLEqCons x y ys) + | otherwise + = lemma x ys + +castLEqCons :: a -> a -> [a] -> [a] +{-@ castLEqCons :: x:a -> y':{a | x <= y'} -> ys':(OList {v:a | y' <= v }) -> {o:OList {v:a | x <= v } | o == y':ys'} @-} +castLEqCons _ y' ys' = y':ys' + +getISortVal :: [Int] -> [Int] +{-@ getISortVal :: xs:[Int] -> {o:OList Int | length o == length xs && o == tval (isort xs)} @-} +getISortVal xs = tval (isort xs) + +{-@ ple lemma1 @-} +lemma1 :: Ord a => a -> [a] -> Proof +{-@ lemma1 :: Ord a => x:a -> xs:(OList {v:a | x <= v}) -> {largerThan x xs == 0 } @-} +lemma1 _ [] = () +lemma1 x (_:xs) = lemma1 x xs + +{-@ ple lemma_preservation @-} +lemma_preservation :: Int -> [Int] -> Proof +{-@ lemma_preservation + :: x:Int + -> xs:[Int] + -> {largerThan x xs == largerThan x (tval (isort xs))} + / [length xs] +@-} +lemma_preservation _ [] = () +lemma_preservation x (y:ys) + | x <= y = preservation_insert x y (getISortVal ys) + ? lemma_preservation x ys + +lemma_preservation x (y:ys) + = preservation_insert x y (getISortVal ys) ? lemma_preservation x ys + + +{-@ ple preservation_insert @-} +preservation_insert :: Ord a => a -> a -> [a] -> Proof +{-@ preservation_insert :: Ord a => x:a -> y:a -> ys:(OList a) + -> { largerThan x (y:ys) == largerThan x (tval (insert y ys)) } @-} +preservation_insert _ _ [] = () +preservation_insert x y (z:zs) + | y <= z + = largerThan x (tval (insert y (z:zs))) + === largerThan x (tval (return (y:z:zs))) + === largerThan x (y:z:zs) + *** QED +preservation_insert x y (z:zs) + | not (y <= z) && (x <= z) + = largerThan x (tval (insert y (z:zs))) + ==! largerThan x (tval ((pure (z:)) insert y zs)) + ==! largerThan x ((tval (pure (z:))) (tval (insert y zs))) + ==! largerThan x (z:(tval (insert y zs))) + ==! largerThan x (tval (insert y zs)) + ? preservation_insert x y zs + ==! largerThan x (y:zs) + ==! (if x <= y then largerThan x zs else 1 + largerThan x zs) + ==! (if x <= y then largerThan x (z:zs) else 1 + largerThan x (z:zs)) + ==! largerThan x (y:z:zs) + *** QED + | otherwise + = largerThan x (tval (insert y (z:zs))) + ==! largerThan x (tval ((pure (z:)) insert y zs)) + ==! largerThan x ((tval (pure (z:))) (tval (insert y zs))) + ==! largerThan x (z:(tval (insert y zs))) + ==! 1 + largerThan x (tval (insert y zs)) + ? preservation_insert x y zs + ==! 1 + largerThan x (y:zs) + ==! 1 + (if x <= y then largerThan x zs else 1 + largerThan x zs) + ==! (if x <= y then largerThan x (z:zs) else 1 + largerThan x (z:zs)) + ==! largerThan x (y:z:zs) + *** QED + +--- End --- {-@ reflect isort @-} -isort :: Ord a => [a] -> Tick [a] +isort :: [Int] -> Tick [Int] {-@ isort - :: Ord a => xs:[a] - -> Tick {os:(OList a) | length os == length xs } + :: xs:[Int] + -> Tick {os:(OList Int) | length os == length xs } @-} --- && fromList os == fromList xs isort [] = return [] isort (x:xs) = isort xs >/= insert x + {-@ reflect insert @-} insert :: Ord a => a -> [a] -> Tick [a] {-@ insert :: Ord a => x:a -> xs:(OList a) -> Tick { os:(OList a) | length os == 1 + length xs } @-} --- && fromList os == put x (fromList xs) insert x [] = return [x] insert x (y:ys) | x <= y = return (x:y:ys) @@ -58,17 +155,6 @@ insert x (y:ys) let Tick n v = insert x ys in Tick (1 + n + m) (f v) --- {-@ assume put :: (Ord k) => k:k -> b:Bag k -> {v:Bag k | v = Map_store b k (1 + (Map_select b k))} @-} --- put :: (Ord k) => k -> Bag k -> Bag k --- put k m = M.insert k (1 + get k m) m --- --- {-@ assume get :: (Ord k) => k:k -> b:Bag k -> {v:Nat | v = Map_select b k} @-} --- get :: (Ord k) => k -> Bag k -> Int --- get k m = M.findWithDefault 0 k m - --- Tick m f Tick n x = Tick (1 + m + n) (f x) --- (pure (y:)) insert x ys - {-@ reflect unsortedDiff @-} unsortedDiff :: Ord a => [a] -> [a] -> Int unsortedDiff l1 l2 = unsorted l1 - unsorted l2 diff --git a/tests/relational/pos/RRelationalISort_relToUn_completed.hs b/tests/relational/pos/RRelationalISort_relToUn_completed.hs new file mode 100644 index 0000000000..4fdf616514 --- /dev/null +++ b/tests/relational/pos/RRelationalISort_relToUn_completed.hs @@ -0,0 +1,139 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} +{-@ LIQUID "--fast" @-} +{-@ LIQUID "--no-adt" @-} + +module RRelationalISort_relToUn (module RRelationalISort_relToUn) where + +import GHC.Classes +import GHC.Types +import Language.Haskell.Liquid.Bag +import Language.Haskell.Liquid.ProofCombinators +import Lists +import RRelationalISort +import RTick +import Prelude + +{- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} +{-@ isortIsortTheorem :: l1:[GHC.Types.Int] -> l2:[GHC.Types.Int] -> l1l2Lemma:{VV : () | Lists.length l1 == Lists.length l2} -> {VV : () | RTick.tcost (RRelationalISort.isort l1) - RTick.tcost (RRelationalISort.isort l2) <= RRelationalISort.unsortedDiff l1 l2} @-} +isortIsortTheorem :: [GHC.Types.Int] -> [GHC.Types.Int] -> () -> () +isortIsortTheorem l1 l2 l1l2Lemma_d2et = case l1 of + [] -> case l2 of + [] -> + ( {- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.return x1)) ? (RTick.return x2)) + ) + [] + [] + ( {- GOAL: [] ~ [] -} + (() ? []) ? [] + ) + (:) x2_a1cV xs2_a1cW -> + {- GOAL: RTick.return [] ~ (RRelationalISort.is (...) -} + (() ? (RTick.return [])) ? ((RRelationalISort.isort xs2_a1cW) RTick.>/= (RRelationalISort.insert x2_a1cV)) + (:) x1_a1cV xs1_a1cW -> case l2 of + [] -> + {- GOAL: (RRelationalISort.is (...) ~ RTick.return [] -} + (() ? ((RRelationalISort.isort xs1_a1cW) RTick.>/= (RRelationalISort.insert x1_a1cV))) ? (RTick.return []) + (:) x2_a1cV xs2_a1cW -> + + + let ds1_d1Ul = RRelationalISort.isort xs1_a1cW + in + ( {- GOAL: RTick.>/= ~ RTick.>/= -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 RTick.>/= x3)) ? (x2 RTick.>/= x4) + ? let x1 = x1_a1cV + xs1 = xs1_a1cW + x2 = x2_a1cV + xs2 = xs2_a1cW in (lemma x1 (getISortVal xs1) + ? lemma_preservation x1 xs1 + ? lemma x2 (getISortVal xs2) + ? lemma_preservation x2 xs2)) + ) + (RRelationalISort.isort xs1_a1cW) + (RRelationalISort.isort xs2_a1cW) + ( isortIsortTheorem + xs1_a1cW + xs2_a1cW + ( {- GOAL: xs1_a1cW ~ xs2_a1cW -} + (() ? xs1_a1cW) ? xs2_a1cW + ) + ) + (RRelationalISort.insert x1_a1cV) + (RRelationalISort.insert x2_a1cV) + ( ( {- GOAL: RRelationalISort.ins (...) ~ RRelationalISort.ins (...) -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (RRelationalISort.insert x1 x3)) ? (RRelationalISort.insert x2 x4)) + ) + x1_a1cV + x2_a1cV + ( {- GOAL: x1_a1cV ~ x2_a1cV -} + (() ? x1_a1cV) ? x2_a1cV + ) + ) + +{- BARE CORE +\ (l1_d2et :: [GHC.Types.Int]) + (l2_d2et :: [GHC.Types.Int]) + (l1l2Lemma_d2et :: [GHC.Types.Int]) -> + case l1_d2et of lq_anf$##72057594037927937761_d2Q { + [] -> + case l2_d2et of lq_anf$##72057594037927937762_d2Q { + [] -> + (src<.:0:0> + \ (x1 :: ()) (x2 :: ()) (x1x2Lemma_xp :: ()) -> + ? (? (? GHC.Tuple.() x1x2Lemma_xp) (RTick.return x1)) + (RTick.return x2)) + GHC.Types.[] + GHC.Types.[] + (src<.:0:0> ? (? GHC.Tuple.() GHC.Types.[]) GHC.Types.[]); + : x2_a1cV xs2_a1cW -> + src<.:0:0> + ? (? GHC.Tuple.() (RTick.return GHC.Types.[])) + (RTick.>/= + (RRelationalISort.isort xs2_a1cW) + (RRelationalISort.insert x2_a1cV)) + }; + : x1_a1cV xs1_a1cW -> + case l2_d2et of lq_anf$##72057594037927937762_d2Q { + [] -> + src<.:0:0> + ? (? GHC.Tuple.() + (RTick.>/= + (RRelationalISort.isort xs1_a1cW) + (RRelationalISort.insert x1_a1cV))) + (RTick.return GHC.Types.[]); + : x2_a1cV xs2_a1cW -> + (src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (RTick.>/= x1 x3)) + (RTick.>/= x2 x4)) + (RRelationalISort.isort xs1_a1cW) + (RRelationalISort.isort xs2_a1cW) + (isortIsortTheorem_rEF + xs1_a1cW + xs2_a1cW + (src<.:0:0> ? (? GHC.Tuple.() xs1_a1cW) xs2_a1cW)) + (RRelationalISort.insert x1_a1cV) + (RRelationalISort.insert x2_a1cV) + ((src<.:0:0> + \ (x1 :: ()) + (x2 :: ()) + (x1x2Lemma_xp :: ()) + (x3 :: ()) + (x4 :: ()) + (x3x4Lemma_xp :: ()) -> + ? (? (? (? GHC.Tuple.() x1x2Lemma_xp) x3x4Lemma_xp) + (RRelationalISort.insert x1 x3)) + (RRelationalISort.insert x2 x4)) + x1_a1cV x2_a1cV (src<.:0:0> ? (? GHC.Tuple.() x1_a1cV) x2_a1cV)) + } + } +-} diff --git a/tests/tests.cabal b/tests/tests.cabal index 628e0e9057..59162fd4e8 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2069,6 +2069,8 @@ executable relational-pos , RMemAlloc_relToUn , RMemAlloc , RPatError + , RRelationalISort_relToUn_completed + , RRelationalISort , RRelationalMSort_relToUn_completed , RRelationalMSort , RSquareAndMultiply_relToUn From c4bddddda55c0bdb311818f566370368138538ab Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 2 May 2023 23:03:41 +0200 Subject: [PATCH 216/219] change module name --- tests/relational/pos/RRelationalISort_relToUn_completed.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/relational/pos/RRelationalISort_relToUn_completed.hs b/tests/relational/pos/RRelationalISort_relToUn_completed.hs index 4fdf616514..153322f0ff 100644 --- a/tests/relational/pos/RRelationalISort_relToUn_completed.hs +++ b/tests/relational/pos/RRelationalISort_relToUn_completed.hs @@ -3,7 +3,7 @@ {-@ LIQUID "--fast" @-} {-@ LIQUID "--no-adt" @-} -module RRelationalISort_relToUn (module RRelationalISort_relToUn) where +module RRelationalISort_relToUn_completed where import GHC.Classes import GHC.Types From 775cfc1913b7d41ca9ac73192c3a7a69afaa8c6e Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 3 May 2023 12:20:06 +0200 Subject: [PATCH 217/219] rm fast from RRelationalISort completed --- tests/relational/pos/RRelationalISort_relToUn_completed.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/relational/pos/RRelationalISort_relToUn_completed.hs b/tests/relational/pos/RRelationalISort_relToUn_completed.hs index 153322f0ff..cb167a0949 100644 --- a/tests/relational/pos/RRelationalISort_relToUn_completed.hs +++ b/tests/relational/pos/RRelationalISort_relToUn_completed.hs @@ -1,6 +1,6 @@ {-@ LIQUID "--reflection" @-} {-@ LIQUID "--ple" @-} -{-@ LIQUID "--fast" @-} +{- LIQUID "--fast" @-} {-@ LIQUID "--no-adt" @-} module RRelationalISort_relToUn_completed where From ff6bb2b638a1ef911eaf134106ad7ce4a787bb61 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Wed, 3 May 2023 13:36:25 +0200 Subject: [PATCH 218/219] remove ghc core --- src/Language/Haskell/Liquid/Constraint/Relational.hs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Language/Haskell/Liquid/Constraint/Relational.hs b/src/Language/Haskell/Liquid/Constraint/Relational.hs index a768b2955c..550602011f 100644 --- a/src/Language/Haskell/Liquid/Constraint/Relational.hs +++ b/src/Language/Haskell/Liquid/Constraint/Relational.hs @@ -865,8 +865,8 @@ consRelSynthApp unary γ ψ ft1@(RFun v1 _ s1 t1 r1) ft2@(RFun v2 _ s2 t2 r2) ps F.subst $ F.mkSubst [(v1, F.EVar $ F.symbol x1), (v2, F.EVar $ F.symbol x2)] return (subst t1, subst t2, map subst qs) -consRelSynthApp _ _ _ RFun{} RFun{} ps d1@(Var _) d2@(Var _) - = F.panic $ "consRelSynthApp: multiple rel sigs not supported " ++ F.showpp (ps, d1, d2) +consRelSynthApp _ _ _ ft1@RFun{} ft2@RFun{} ps d1@(Var _) d2@(Var _) + = F.panic $ "consRelSynthApp: multiple rel sigs not supported " ++ F.showpp (ft1, ft2, ps, d1, d2) consRelSynthApp _ _ _ RFun{} RFun{} _ d1 d2 = F.panic $ "consRelSynthApp: expected application to variables, got" ++ F.showpp (d1, d2) consRelSynthApp _ _ _ t1 t2 p d1 d2 = @@ -1196,10 +1196,10 @@ relHint rvs t v e = text "{- HLINT ignore \"Use camelCase\" -}" $+$ text ("{-@ " ++ name ++ " :: " ++ F.showpp t ++ " @-}") $+$ text (name ++ " :: " ++ removeIdent (toType False t)) $+$ text (coreToHs rvs t v e) - $+$ text "" - $+$ text "{- BARE CORE" - $+$ text (show e) - $+$ text "-}" + -- $+$ text "" + -- $+$ text "{- BARE CORE" + -- $+$ text (show e) + -- $+$ text "-}" where name = Ghc.occNameString $ Ghc.getOccName v removeIdent :: Type -> String From 5bf51c9b59a23aedece37dc07da99f2ff54aba61 Mon Sep 17 00:00:00 2001 From: Lisa Vasilenko Date: Tue, 16 May 2023 11:49:50 +0100 Subject: [PATCH 219/219] complete binarycounters proof --- src/Language/Haskell/Liquid/Synthesize/GHC.hs | 22 +++- tests/relational/pos/RBinaryCounters.hs | 109 ++++++++++++++++++ .../pos/RBinaryCounters_relToUn_completed.hs | 104 +++++++++++++++++ tests/tests.cabal | 2 + 4 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 tests/relational/pos/RBinaryCounters.hs create mode 100644 tests/relational/pos/RBinaryCounters_relToUn_completed.hs diff --git a/src/Language/Haskell/Liquid/Synthesize/GHC.hs b/src/Language/Haskell/Liquid/Synthesize/GHC.hs index 60d99fac69..08e3384e0c 100644 --- a/src/Language/Haskell/Liquid/Synthesize/GHC.hs +++ b/src/Language/Haskell/Liquid/Synthesize/GHC.hs @@ -342,8 +342,26 @@ pprintAlts rvs i (GHC.Alt (DataAlt dataCon) vs e) ++ " -> " newIndent = length elCase -pprintAlts _ _ _ = - error " Pretty printing for pattern match on datatypes. " +pprintAlts rvs i (GHC.Alt (LitAlt literal) vs e) + = "\n" ++ indent i + ++ elCase + ++ pprintBody' rvs (i + newIndent) e + where + elCase = showSDocUnsafe (ppr literal) + ++ concatMap (\v -> " " ++ handleVar rvs v) vs + ++ " -> " + newIndent = length elCase + +pprintAlts rvs i (GHC.Alt DEFAULT vs e) + = "\n" ++ indent i + ++ elCase + ++ pprintBody' rvs (i + newIndent) e + where + elCase = "_" + ++ concatMap (\v -> " " ++ handleVar rvs v) vs + ++ " -> " + newIndent = length elCase + diff --git a/tests/relational/pos/RBinaryCounters.hs b/tests/relational/pos/RBinaryCounters.hs new file mode 100644 index 0000000000..c1e7e0c70c --- /dev/null +++ b/tests/relational/pos/RBinaryCounters.hs @@ -0,0 +1,109 @@ +{- Counters 26/21/21 -} + +-- +-- Liquidate your assets: reasoning about resource usage in Liquid Haskell.s +-- + +{-@ LIQUID "--relational-hints" @-} +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} + +module RBinaryCounters (module RBinaryCounters) where + +import Prelude hiding (return, (>>=), pure, length) +import RTick +import Language.Haskell.Liquid.ProofCombinators +import Lists + +-- +-- Comparing bit flips using relational cost analysis. +-- + +{-@ reflect tt @-} +{-@ tt :: n:Nat -> { zs:[{ v:Bool | v == True }] | n == Lists.length zs } @-} +tt :: Int -> [Bool] +tt 0 = [] +tt n = True : tt (n - 1) + +{-@ reflect ff @-} +{-@ ff :: n:Nat -> { zs:[{ v:Bool | v == False }] | n == Lists.length zs } @-} +ff :: Int -> [Bool] +ff 0 = [] +ff n = False : ff (n - 1) + +dualTTFF :: Int -> Proof +{-@ dualTTFF :: l:Nat -> { dual (ff l) (tt l) } @-} +dualTTFF 0 = () +dualTTFF i = dualTTFF (i - 1) + +{-@ reflect dual @-} +{-@ dual + :: xs:[Bool] + -> { ys:[Bool] | Lists.length xs == Lists.length ys } + -> Bool +@-} +dual :: [Bool] -> [Bool] -> Bool +dual [] [] = True +dual (x : xs) (y : ys) = x /= y && dual xs ys +dual _ _ = True + +{-@ reflect incrN @-} +{-@ incrN :: Nat -> [Bool] -> Tick [Bool] @-} +incrN :: Int -> [Bool] -> Tick [Bool] +incrN 0 xs = return xs +incrN n xs = incr xs >>= incrN (n - 1) + +--- Proof --- +{- relational incr ~ decr :: { xs1:[Bool] -> Tick [Bool] + ~ xs2:[Bool] -> Tick [Bool] + | Lists.length xs1 = Lists.length xs2 && RBinaryCounters.dual xs1 xs2 + :=> RTick.tcost (r1 xs1) = RTick.tcost (r2 xs2) + && RBinaryCounters.dual (RTick.tval (r1 xs1)) (RTick.tval (r2 xs2)) } @-} + +{- relational incrN ~ decrN :: { n1:Nat -> xs1:[Bool] -> Tick [Bool] + ~ n2:Nat -> xs2:[Bool] -> Tick [Bool] + | n1 = n2 :=> Lists.length xs1 = Lists.length xs2 && RBinaryCounters.dual xs1 xs2 + :=> RTick.tcost (r1 n1 xs1) = RTick.tcost (r2 n2 xs2) + && RBinaryCounters.dual (RTick.tval (r1 n1 xs1)) (RTick.tval (r2 n2 xs2)) } @-} + +{- relational incrNff ~ decrNtt + :: { n1: Nat -> m1: Nat -> Tick [Bool] + ~ n2: Nat -> m2: Nat -> Tick [Bool] + | n1 = n2 :=> m1 = m2 :=> RTick.tcost (r1 n1 m1) == RTick.tcost (r2 n2 m2) } @-} +--- End --- + +{-@ reflect decrNtt @-} +{-@ decrNtt :: Nat -> Nat -> Tick [Bool] @-} +decrNtt :: Int -> Int -> Tick [Bool] +decrNtt n m = decrN n (tt m) + +{-@ reflect incrNff @-} +{-@ incrNff :: Nat -> Nat -> Tick [Bool] @-} +incrNff :: Int -> Int -> Tick [Bool] +incrNff n m = incrN n (ff m) + +{-@ reflect incr @-} +{-@ incr + :: xs:[Bool] + -> Tick { zs:[Bool] | Lists.length zs == Lists.length xs } +@-} +incr :: [Bool] -> Tick [Bool] +incr [] = return [] +incr (False:xs) = pure (cons True) pure xs +incr (True:xs) = pure (cons False) incr xs + +{-@ reflect decrN @-} +{-@ decrN :: Nat -> [Bool] -> Tick [Bool] @-} +decrN :: Int -> [Bool] -> Tick [Bool] +decrN 0 xs = return xs +decrN n xs = decr xs >>= decrN (n - 1) + +{-@ reflect decr @-} +{-@ decr + :: xs:[Bool] + -> Tick { zs:[Bool] | Lists.length xs == Lists.length zs } +@-} +decr :: [Bool] -> Tick [Bool] +decr [] = return [] +decr (False : xs) = pure (cons True) decr xs +decr (True : xs) = pure (cons False) pure xs diff --git a/tests/relational/pos/RBinaryCounters_relToUn_completed.hs b/tests/relational/pos/RBinaryCounters_relToUn_completed.hs new file mode 100644 index 0000000000..6dc76b6730 --- /dev/null +++ b/tests/relational/pos/RBinaryCounters_relToUn_completed.hs @@ -0,0 +1,104 @@ +{-@ LIQUID "--reflection" @-} +{-@ LIQUID "--ple" @-} +{-@ LIQUID "--no-adt" @-} + +module RBinaryCounters_relToUn_completed where +import RTick +import Lists +import Prelude +import Language.Haskell.Liquid.ProofCombinators +import RBinaryCounters +import GHC.Types +import GHC.Classes +import Language.Haskell.Liquid.ProofCombinators +{- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} +{-@ incrNffDecrNttTheorem :: n1:{VV0 : GHC.Types.Int | VV0 >= 0} -> n2:{VV0 : GHC.Types.Int | VV0 >= 0} -> n1n2Lemma:{VV : () | n1 == n2} -> m1:{VV0 : GHC.Types.Int | VV0 >= 0} -> m2:{VV0 : GHC.Types.Int | VV0 >= 0} -> m1m2Lemma:{VV : () | m1 == m2} -> {VV : () | RTick.tcost (RBinaryCounters.incrNff n1 m1) == RTick.tcost (RBinaryCounters.decrNtt n2 m2)} @-} +incrNffDecrNttTheorem + :: GHC.Types.Int + -> GHC.Types.Int + -> () + -> GHC.Types.Int + -> GHC.Types.Int + -> () + -> () +incrNffDecrNttTheorem n1 n2 n1n2Lemma_a1g2 m1 m2 m1m2Lemma_a1g3 = + incrNDecrNTheorem n1 n2 n1n2Lemma_a1g2 (ff m1) (tt m2) (dualTTFF m1 ? m1m2Lemma_a1g3) + +{- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} +{-@ incrNDecrNTheorem :: n1:{VV0 : GHC.Types.Int | VV0 >= 0} -> n2:{VV0 : GHC.Types.Int | VV0 >= 0} -> n1n2Lemma:{VV : () | n1 == n2} -> xs1:[GHC.Types.Bool] -> xs2:[GHC.Types.Bool] -> xs1xs2Lemma:{VV : () | RBinaryCounters.dual xs1 xs2 + && Lists.length xs1 == Lists.length xs2} -> {VV : () | RBinaryCounters.dual (RTick.tval (RBinaryCounters.incrN n1 xs1)) (RTick.tval (RBinaryCounters.decrN n2 xs2)) + && RTick.tcost (RBinaryCounters.incrN n1 xs1) == RTick.tcost (RBinaryCounters.decrN n2 xs2)} @-} +incrNDecrNTheorem :: GHC.Types.Int -> GHC.Types.Int -> () -> [GHC.Types.Bool] -> [GHC.Types.Bool] -> () -> () +incrNDecrNTheorem n1 n2 n1n2Lemma_d21P xs1 xs2 xs1xs2Lemma_a1fX = case n1 of + 0 -> case n2 of + 0 -> ({- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.return x1)) ? (RTick.return x2))) xs1 xs2 xs1xs2Lemma_a1fX + _ -> {- GOAL: RTick.return xs1_a1f (...) ~ (RBinaryCounters.dec (...) -} + (() ? (RTick.return xs1)) ? ((RBinaryCounters.decr xs2) RTick.>>= (RBinaryCounters.decrN (n2 - 1))) + + _ -> case n2 of + 0 -> {- GOAL: (RBinaryCounters.inc (...) ~ RTick.return xs2_a1g (...) -} + (() ? ((RBinaryCounters.incr xs1) RTick.>>= (RBinaryCounters.incrN (n1 - 1)))) ? (RTick.return xs2) + _ -> incrNDecrNTheorem (n1 - 1) (n2 - 1) n1n2Lemma_d21P (tval (incr xs1)) (tval (decr xs2)) (incrDecrTheorem xs1 xs2 xs1xs2Lemma_a1fX) + ? ({- GOAL: RTick.>>= ~ RTick.>>= -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 RTick.>>= x3)) ? (x2 RTick.>>= x4))) (RBinaryCounters.incr xs1) (RBinaryCounters.decr xs2) (({- GOAL: RBinaryCounters.incr ~ RBinaryCounters.decr -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RBinaryCounters.incr x1)) ? (RBinaryCounters.decr x2) ? incrDecrTheorem x1 x2 x1x2Lemma_xp)) xs1 xs2 xs1xs2Lemma_a1fX) (RBinaryCounters.incrN (n1 - 1)) (RBinaryCounters.decrN (n2 - 1)) (incrNDecrNTheorem (n1 - 1) (n2 - 1) (({- GOAL: - ~ - -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 - x3)) ? (x2 - x4))) n1 n2 n1n2Lemma_d21P 1 1 (({- GOAL: ~ -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? x1) ? x2)) 1 1 ({- GOAL: 1 ~ 1 -} + (() ? 1) ? 1)))) + +{- HLINT ignore "Use camelCase" -} +{- HLINT ignore "Use if" -} +{- HLINT ignore "Use section" -} +{-@ incrDecrTheorem :: xs1:[GHC.Types.Bool] -> xs2:[GHC.Types.Bool] -> xs1xs2Lemma:{VV : () | RBinaryCounters.dual xs1 xs2 + && Lists.length xs1 == Lists.length xs2} -> {VV : () | RBinaryCounters.dual (RTick.tval (RBinaryCounters.incr xs1)) (RTick.tval (RBinaryCounters.decr xs2)) + && RTick.tcost (RBinaryCounters.incr xs1) == RTick.tcost (RBinaryCounters.decr xs2)} @-} +incrDecrTheorem :: [GHC.Types.Bool] -> [GHC.Types.Bool] -> () -> () +incrDecrTheorem xs1 xs2 xs1xs2Lemma_d21J = case xs1 of + [] -> case xs2 of + [] -> ({- GOAL: RTick.return ~ RTick.return -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.return x1)) ? (RTick.return x2))) [] [] ({- GOAL: [] ~ [] -} + (() ? []) ? []) + (:) ds2_d21C xs2 -> {- GOAL: RTick.return [] ~ case ds2_d21C of Fal (...) -} + (() ? (RTick.return [])) ? (case ds2_d21C of + False -> (RTick.pure (Lists.cons True)) RTick. (RBinaryCounters.decr xs2) + True -> (RTick.pure (Lists.cons False)) RTick. (RTick.pure xs2)) + (:) ds1_d21O xs1 -> case xs2 of + [] -> {- GOAL: case ds1_d21O of Fal (...) ~ RTick.return [] -} + (() ? (case ds1_d21O of + False -> (RTick.pure (Lists.cons True)) RTick. (RTick.pure xs1) + True -> (RTick.pure (Lists.cons False)) RTick. (RBinaryCounters.incr xs1))) ? (RTick.return []) + (:) ds2_d21C xs2 -> case ds1_d21O of + False -> case ds2_d21C of + False -> ({- GOAL: RTick. ~ RTick. -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 RTick. x3)) ? (x2 RTick. x4))) (RTick.pure (Lists.cons True)) (RTick.pure (Lists.cons True)) (({- GOAL: RTick.pure ~ RTick.pure -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.pure x1)) ? (RTick.pure x2))) (Lists.cons True) (Lists.cons True) (({- GOAL: Lists.cons ~ Lists.cons -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (Lists.cons x1 x3)) ? (Lists.cons x2 x4))) True True ({- GOAL: True ~ True -} + (() ? True) ? True))) (RTick.pure xs1) (RBinaryCounters.decr xs2) (({- GOAL: RTick.pure ~ RBinaryCounters.decr -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.pure x1)) ? (RBinaryCounters.decr x2))) xs1 xs2 ({- GOAL: xs1_a1g4 ~ xs2_a1g9 -} + (() ? xs1) ? xs2)) + True -> ({- GOAL: RTick. ~ RTick. -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 RTick. x3)) ? (x2 RTick. x4))) (RTick.pure (Lists.cons True)) (RTick.pure (Lists.cons False)) (({- GOAL: RTick.pure ~ RTick.pure -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.pure x1)) ? (RTick.pure x2))) (Lists.cons True) (Lists.cons False) (({- GOAL: Lists.cons ~ Lists.cons -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (Lists.cons x1 x3)) ? (Lists.cons x2 x4))) True False ({- GOAL: True ~ False -} + (() ? True) ? False))) (RTick.pure xs1) (RTick.pure xs2) (({- GOAL: RTick.pure ~ RTick.pure -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.pure x1)) ? (RTick.pure x2))) xs1 xs2 ({- GOAL: xs1_a1g4 ~ xs2_a1g9 -} + (() ? xs1) ? xs2)) + True -> case ds2_d21C of + False -> ({- GOAL: RTick. ~ RTick. -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 RTick. x3)) ? (x2 RTick. x4))) (RTick.pure (Lists.cons False)) (RTick.pure (Lists.cons True)) (({- GOAL: RTick.pure ~ RTick.pure -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.pure x1)) ? (RTick.pure x2))) (Lists.cons False) (Lists.cons True) (({- GOAL: Lists.cons ~ Lists.cons -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (Lists.cons x1 x3)) ? (Lists.cons x2 x4))) False True ({- GOAL: False ~ True -} + (() ? False) ? True))) (RBinaryCounters.incr xs1) (RBinaryCounters.decr xs2) (incrDecrTheorem xs1 xs2 ({- GOAL: xs1_a1g4 ~ xs2_a1g9 -} + (() ? xs1) ? xs2)) + True -> ({- GOAL: RTick. ~ RTick. -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (x1 RTick. x3)) ? (x2 RTick. x4))) (RTick.pure (Lists.cons False)) (RTick.pure (Lists.cons False)) (({- GOAL: RTick.pure ~ RTick.pure -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RTick.pure x1)) ? (RTick.pure x2))) (Lists.cons False) (Lists.cons False) (({- GOAL: Lists.cons ~ Lists.cons -} + (\x1 x2 x1x2Lemma_xp x3 x4 x3x4Lemma_xp -> (((() ? x1x2Lemma_xp) ? x3x4Lemma_xp) ? (Lists.cons x1 x3)) ? (Lists.cons x2 x4))) False False ({- GOAL: False ~ False -} + (() ? False) ? False))) (RBinaryCounters.incr xs1) (RTick.pure xs2) (({- GOAL: RBinaryCounters.incr ~ RTick.pure -} + (\x1 x2 x1x2Lemma_xp -> ((() ? x1x2Lemma_xp) ? (RBinaryCounters.incr x1)) ? (RTick.pure x2))) xs1 xs2 ({- GOAL: xs1_a1g4 ~ xs2_a1g9 -} + (() ? xs1) ? xs2)) diff --git a/tests/tests.cabal b/tests/tests.cabal index 59162fd4e8..5b54137b86 100644 --- a/tests/tests.cabal +++ b/tests/tests.cabal @@ -2058,6 +2058,8 @@ executable relational-pos , ProofCombinators , R2Dcounting_relToUn , R2Dcounting + , RBinaryCounters_relToUn_completed + , RBinaryCounters , RConstantTimeComparison_relToUn , RConstantTimeComparison , Rec