@@ -550,8 +550,7 @@ flattenExpr = go []
550
550
-- TODO: handle errors properly
551
551
reachable :: App m => SolverGroup -> Expr End -> m ([SMT2 ], Expr End )
552
552
reachable solvers e = do
553
- conf <- readConfig
554
- res <- liftIO $ go conf [] e
553
+ res <- go [] e
555
554
pure $ second (fromMaybe (internalError " no reachable paths found" )) res
556
555
where
557
556
{-
@@ -560,24 +559,23 @@ reachable solvers e = do
560
559
If reachable return the expr wrapped in a Just. If not return Nothing.
561
560
When walking back up the tree drop unreachable subbranches.
562
561
-}
563
- go :: Config - > [Prop ] -> Expr End -> IO ([SMT2 ], Maybe (Expr End ))
564
- go conf pcs = \ case
562
+ go :: ( App m , MonadUnliftIO m ) = > [Prop ] -> Expr End -> m ([SMT2 ], Maybe (Expr End ))
563
+ go pcs = \ case
565
564
ITE c t f -> do
566
- (tres, fres) <- concurrently
567
- (go conf (PEq (Lit 1 ) c : pcs) t)
568
- (go conf (PEq (Lit 0 ) c : pcs) f)
565
+ (tres, fres) <- withRunInIO $ \ env -> concurrently
566
+ (env $ go (PEq (Lit 1 ) c : pcs) t)
567
+ (env $ go (PEq (Lit 0 ) c : pcs) f)
569
568
let subexpr = case (snd tres, snd fres) of
570
569
(Just t', Just f') -> Just $ ITE c t' f'
571
570
(Just t', Nothing ) -> Just t'
572
571
(Nothing , Just f') -> Just f'
573
572
(Nothing , Nothing ) -> Nothing
574
573
pure (fst tres <> fst fres, subexpr)
575
574
leaf -> do
576
- let query = assertProps conf pcs
577
- res <- checkSat solvers query
575
+ (res, smt2) <- checkSatWithProps solvers pcs
578
576
case res of
579
- Sat _ -> pure ([getNonError query ], Just leaf)
580
- Unsat -> pure ([getNonError query ], Nothing )
577
+ Sat _ -> pure ([getNonError smt2 ], Just leaf)
578
+ Unsat -> pure ([getNonError smt2 ], Nothing )
581
579
r -> internalError $ " Invalid solver result: " <> show r
582
580
583
581
-- | Extract constraints stored in Expr End nodes
@@ -766,35 +764,32 @@ equivalenceCheck' solvers branchesA branchesB = do
766
764
-- the solver if we can determine unsatisfiability from the cache already
767
765
-- the last element of the returned tuple indicates whether the cache was
768
766
-- used or not
769
- check :: Config - > UnsatCache -> ( Set Prop ) -> IO (EquivResult , Bool )
770
- check conf knownUnsat props = do
771
- let smt = assertProps conf ( Set. toList props)
772
- ku <- readTVarIO knownUnsat
773
- res <- if subsetAny props ku
774
- then pure ( True , Unsat )
775
- else ( fmap (( False ),) (checkSat solvers smt) )
767
+ check :: App m = > UnsatCache -> Set Prop -> m (EquivResult , Bool )
768
+ check knownUnsat props = do
769
+ ku <- liftIO $ readTVarIO knownUnsat
770
+ res <- if subsetAny props ku then pure ( True , Unsat )
771
+ else do
772
+ (res, _) <- checkSatWithProps solvers $ Set. toList props
773
+ pure ( False , res )
776
774
case res of
777
775
(_, Sat x) -> pure (Cex x, False )
778
- (quick, Unsat ) ->
779
- case quick of
780
- True -> pure (Qed () , quick)
781
- False -> do
782
- -- nb: we might end up with duplicates here due to a
783
- -- potential race, but it doesn't matter for correctness
784
- atomically $ readTVar knownUnsat >>= writeTVar knownUnsat . (props : )
785
- pure (Qed () , False )
776
+ (True , Unsat ) -> pure (Qed () , True )
777
+ (False , Unsat ) -> do
778
+ -- nb: we might end up with duplicates here due to a
779
+ -- potential race, but it doesn't matter for correctness
780
+ liftIO $ atomically $ readTVar knownUnsat >>= writeTVar knownUnsat . (props : )
781
+ pure (Qed () , False )
786
782
(_, EVM.Solvers. Unknown _) -> pure (EVM.SymExec. Unknown () , False )
787
783
(_, EVM.Solvers. Error txt) -> pure (EVM.SymExec. Error txt, False )
788
784
789
785
-- Allows us to run it in parallel. Note that this (seems to) run it
790
786
-- from left-to-right, and with a max of K threads. This is in contrast to
791
787
-- mapConcurrently which would spawn as many threads as there are jobs, and
792
788
-- run them in a random order. We ordered them correctly, though so that'd be bad
793
- checkAll :: App m => [(Set Prop )] -> UnsatCache -> Int -> m [(EquivResult , Bool )]
794
- checkAll input cache numproc = do
795
- conf <- readConfig
796
- wrap <- liftIO $ pool numproc
797
- liftIO $ parMapIO (wrap . (check conf cache)) input
789
+ checkAll :: (App m , MonadUnliftIO m ) => [(Set Prop )] -> UnsatCache -> Int -> m [(EquivResult , Bool )]
790
+ checkAll input cache numproc = withRunInIO $ \ env -> do
791
+ wrap <- pool numproc
792
+ parMapIO (\ e -> wrap (env $ check cache e)) input
798
793
799
794
800
795
-- Takes two branches and returns a set of props that will need to be
0 commit comments