Skip to content

Commit

Permalink
Merge pull request #2483 from clayrat/cvc5-set-bag
Browse files Browse the repository at this point in the history
Update to use conditional elaboration
  • Loading branch information
nikivazou authored Mar 5, 2025
2 parents 192b876 + fc7443e commit 008891a
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 97 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "liquid-fixpoint"]
path = liquid-fixpoint
url = https://github.com/ucsd-progsys/liquid-fixpoint.git
url = https://github.com/ucsd-progsys/liquid-fixpoint.git
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
side effect of this change is that LH can now pick up names in scope using import aliases
in most places (but see [#2481](https://github.com/ucsd-progsys/liquidhaskell/issues/2481)).
- Allow to link Haskell definitions with logical primitives via `define` declarations [#2463](https://github.com/ucsd-progsys/liquidhaskell/pull/2463).
- CVC5 solver is now supported for all logical theories, including Sets/Bags [#2483](https://github.com/ucsd-progsys/liquidhaskell/pull/2483)

## 0.9.10.1 (2024-08-21)

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ For example:

$ cabal build tests:unit-neg --ghc-options=-fplugin-opt=LiquidHaskell:--no-termination

Or your favorite number of threads, depending on cores etc.
Another useful option is to change the underlying solver:

$ cabal build tests:unit-pos --ghc-options=-fplugin-opt=LiquidHaskell:--smtsolver=cvc5

You can also modify the number of used threads, depending on cores etc.

You can directly extend and run the tests by modifying the files in

Expand Down
7 changes: 3 additions & 4 deletions docs/mkDocs/docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,16 +359,15 @@ to run a given file with full-checking, add the pragma:

**Options:** `smtsolver`

By default, LiquidHaskell uses the SMTLIB2 interface for Z3.
By default, LiquidHaskell uses the SMTLIB2 interface for [Z3](https://github.com/Z3Prover/z3).

To run a different solver (supporting SMTLIB2) do:

$ liquid --smtsolver=NAME foo.hs

Currently, LiquidHaskell supports
Currently, LiquidHaskell additionally supports

+ [CVC4](http://cvc4.cs.stanford.edu/web/)
+ [MathSat](http://mathsat.fbk.eu/download.html )
+ [CVC5](https://cvc5.github.io/)

To use these solvers, you must install the corresponding binaries
from the above web-pages into your `PATH`.
Expand Down
4 changes: 2 additions & 2 deletions liquid-prelude/src/Language/Haskell/Liquid/Bag.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ data Bag a = Bag { toMap :: M.Map a Int } deriving Eq
empty :: Bag k
empty = Bag M.empty

{-@ assume get :: (Ord k) => k:k -> b:Bag k -> {v:Nat | v = Bag_count b k} @-}
{-@ define get k b = (Bag_count b k) @-}
{-@ assume get :: (Ord k) => k:k -> b:Bag k -> {v:Nat | v = Bag_count k b} @-}
{-@ define get k b = (Bag_count k b) @-}
get :: (Ord k) => k -> Bag k -> Int
get k b = M.findWithDefault 0 k (toMap b)

Expand Down
161 changes: 91 additions & 70 deletions liquidhaskell-boot/src/Language/Haskell/Liquid/Bare/Check.hs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import Data.Maybe (isJust, catMaybes, fromMaybe, isNothi
import qualified Data.HashSet as S
import qualified Data.HashMap.Strict as M
import Debug.Trace (trace)
import Control.Monad.Reader

import Language.Fixpoint.Types hiding (panic, mkQual)
import qualified Language.Fixpoint.Types.Config as FC
import Language.Fixpoint.SortCheck
Expand All @@ -29,6 +31,7 @@ import Language.Haskell.Liquid.Types.RTypeOp
import Language.Haskell.Liquid.Types.Specs
import Language.Haskell.Liquid.Types.Types
import Language.Haskell.Liquid.UX.Config
import Language.Fixpoint.Types.Config (ElabFlags)


--------------------------------------------------------------------------------
Expand Down Expand Up @@ -76,11 +79,12 @@ alsQualifiers :: TargetInfo -> SEnv Sort -> [Qualifier]
--------------------------------------------------------------------------------
alsQualifiers info lEnv
= [ q | a <- gsRTAliases . gsQual . giSpec $ info
, q <- refTypeQuals lEnv (loc a) tce (rtBody (val a))
, q <- refTypeQuals lEnv ef (loc a) tce (rtBody (val a))
, length (qParams q) <= k + 1
, validQual lEnv q
]
where
ef = maybe (FC.ElabFlags False) FC.solverFlags . smtsolver . getConfig $ info
k = maxQualParams info
tce = gsTcEmbeds . gsName . giSpec $ info

Expand All @@ -97,12 +101,13 @@ sigQualifiers :: TargetInfo -> SEnv Sort -> [Qualifier]
sigQualifiers info lEnv
= [ q | (x, t) <- specBinders info
, not (x `S.member` S.fromList (specAxiomVars info))
, q <- refTypeQuals lEnv (getSourcePos x) tce (val t)
, q <- refTypeQuals lEnv ef (getSourcePos x) tce (val t)
-- NOTE: large qualifiers are VERY expensive, so we only mine
-- qualifiers up to a given size, controlled with --max-params
, length (qParams q) <= k + 1
]
where
ef = maybe (FC.ElabFlags False) FC.solverFlags . smtsolver . getConfig $ info
k = maxQualParams info
tce = gsTcEmbeds . gsName . giSpec $ info

Expand Down Expand Up @@ -139,11 +144,11 @@ specAxiomVars = gsReflects . gsRefl . giSpec

-- TODO: rewrite using foldReft'
--------------------------------------------------------------------------------
refTypeQuals :: SEnv Sort -> SourcePos -> TCEmb TyCon -> SpecType -> [Qualifier]
refTypeQuals :: SEnv Sort -> ElabFlags -> SourcePos -> TCEmb TyCon -> SpecType -> [Qualifier]
--------------------------------------------------------------------------------
refTypeQuals lEnv l tce t0 = go emptySEnv t0
refTypeQuals lEnv ef l tce t0 = go emptySEnv t0
where
scrape = refTopQuals lEnv l tce t0
scrape = refTopQuals lEnv ef l tce t0
add x t γ = insertSEnv x (rTypeSort tce t) γ
goBind x t γ t' = go (add x t γ) t'
go γ t@(RVar _ _) = scrape γ t
Expand All @@ -164,19 +169,20 @@ refTypeQuals lEnv l tce t0 = go emptySEnv t0

refTopQuals :: (PPrint t, Reftable t, SubsTy RTyVar RSort t, Reftable (RTProp RTyCon RTyVar (UReft t)))
=> SEnv Sort
-> ElabFlags
-> SourcePos
-> TCEmb TyCon
-> RType RTyCon RTyVar r
-> SEnv Sort
-> RRType (UReft t)
-> [Qualifier]
refTopQuals lEnv l tce t0 γ rrt
refTopQuals lEnv ef 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
, notracepp ("refTopQuals: " ++ showpp pa)
$ isNothing $ checkSorted (srcSpan l) (insertSEnv v so γ') pa
$ isNothing $ runReader (checkSorted (srcSpan l) (insertSEnv v so γ') pa) ef
]
++
[ mkP s e | let (MkUReft _ (Pr ps)) = fromMaybe (msg rrt) $ stripRTypeBase rrt
Expand Down
5 changes: 5 additions & 0 deletions liquidhaskell-boot/src/Language/Haskell/Liquid/Misc.hs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ zipWithDef _ [] ys = ys
zipWithDef f (x:xs) (y:ys) = f x y : zipWithDef f xs ys


foldMapM :: (Monoid b, Monad m, Foldable f) => (a -> m b) -> f a -> m b
foldMapM f xs = foldr step return xs mempty
where
step x r z = f x >>= \y -> r $! z `mappend` y

--------------------------------------------------------------------------------
-- Originally part of Fixpoint's Misc:
--------------------------------------------------------------------------------
Expand Down
19 changes: 11 additions & 8 deletions liquidhaskell-boot/src/Language/Haskell/Liquid/WiredIn.hs
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,7 @@ wiredTheorySortedSyms =
]
where
wiredTheorySyms =
[ "Bag_count"
, "Bag_empty"
, "Bag_inter_min"
, "Bag_sng"
, "Bag_sub"
, "Bag_union"
, "Bag_union_max"

[ "Map_default"
, "Map_select"
, "Map_store"

Expand All @@ -117,6 +110,16 @@ wiredTheorySortedSyms =
, "Set_empty"
, "Set_mem"
, "Set_sub"
, "Set_add"
, "Set_com"

, "Bag_count"
, "Bag_empty"
, "Bag_inter_min"
, "Bag_sng"
, "Bag_sub"
, "Bag_union"
, "Bag_union_max"

, "strLen"
]
Expand Down
11 changes: 8 additions & 3 deletions tests/tests.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ executable benchmark-bytestring
-- TODO-REBARE
-- Data.ByteString.T
, Data.ByteString
-- TODO disable this test when running with CVC5
, Data.ByteString.Lazy
, Data.ByteString.LazyZip

Expand Down Expand Up @@ -1252,7 +1253,8 @@ executable unit-neg
, LogNegTest
, Mapreduce
, Mapreduce_tiny
, Maps
-- TODO reenable after fixing apply generation
-- , Maps
, Maybe
, MaybeMonad
, Meas0
Expand Down Expand Up @@ -1418,7 +1420,8 @@ executable unit-pos-1
, Mapreduce_bare
, MapReduceVerified
, Maps1
, Maps
-- TODO reenable after fixing apply generation
-- , Maps
, MapTvCrash
, MaskError
, Maybe000
Expand Down Expand Up @@ -2522,12 +2525,14 @@ executable ple-pos
, NegNormalForm
, NNFPiotr
, PadLeft
-- TODO disable this test when running with CVC5
, Permutations
, Ple0
, PleORM
, Ple_sum
, PolySetFoo
, PolySetBar
-- TODO reenable after fixing apply generation
-- , PolySetBar
, ReflectDefault
, RegexpDerivative
, RosePLEDiv
Expand Down

0 comments on commit 008891a

Please sign in to comment.