@@ -13,47 +13,62 @@ Portability : portable
1313
1414module Kore.Internal.MultiOr
1515 ( MultiOr (.. )
16- , crossProductGeneric
17- , crossProductGenericF
18- , extractPatterns
16+ , bottom
1917 , filterOr
2018 , flatten
21- , flattenGeneric
22- , fullCrossProduct
19+ , distributeAnd
20+ , distributeApplication
2321 , gather
2422 , observeAllT
23+ , observeAll
2524 , make
2625 , merge
2726 , mergeAll
2827 , singleton
2928 , map
29+ , traverse
3030 -- * Re-exports
3131 , Alternative (.. )
3232 ) where
3333
3434import Prelude.Kore hiding
3535 ( map
36+ , traverse
3637 )
3738
3839import Control.DeepSeq
3940 ( NFData
4041 )
42+ import qualified Control.Lens as Lens
43+ import qualified Data.Foldable as Foldable
44+ import Data.Generics.Product
45+ ( field
46+ )
4147import Data.List
4248 ( foldl'
4349 )
4450import qualified Data.Set as Set
51+ import qualified Data.Traversable as Traversable
4552import qualified Generics.SOP as SOP
4653import GHC.Exts
4754 ( IsList
4855 )
4956import qualified GHC.Generics as GHC
5057
5158import Kore.Debug
59+ import Kore.Internal.MultiAnd
60+ ( MultiAnd
61+ )
62+ import qualified Kore.Internal.MultiAnd as MultiAnd
63+ import Kore.Syntax.Application
64+ ( Application (.. )
65+ )
5266import Kore.TopBottom
5367 ( TopBottom (.. )
5468 )
5569import Logic
56- ( LogicT
70+ ( Logic
71+ , LogicT
5772 , MonadLogic
5873 )
5974import qualified Logic
@@ -73,17 +88,12 @@ patterns.
7388-}
7489newtype MultiOr child = MultiOr { getMultiOr :: [child ] }
7590 deriving
76- ( Alternative
77- , Applicative
78- , Eq
91+ ( Eq
7992 , Foldable
80- , Functor
8193 , GHC. Generic
8294 , IsList
83- , Monad
8495 , Ord
8596 , Show
86- , Traversable
8797 )
8898
8999instance SOP. Generic (MultiOr child )
@@ -119,6 +129,9 @@ instance (Ord child, TopBottom child) => From [child] (MultiOr child) where
119129instance From (MultiOr child ) [child ] where
120130 from = getMultiOr
121131
132+ bottom :: MultiOr term
133+ bottom = MultiOr []
134+
122135{-| 'OrBool' is an some sort of Bool data type used when evaluating things
123136inside a 'MultiOr'.
124137-}
@@ -172,54 +185,37 @@ singleton term
172185 | isBottom term = MultiOr []
173186 | otherwise = MultiOr [term]
174187
175- {-| 'extractPatterns' instantiates 'getMultiOr' at 'Pattern'.
176-
177- It returns the patterns inside an @\or@.
178- -}
179- extractPatterns
180- :: MultiOr term
181- -> [term ]
182- extractPatterns = getMultiOr
183-
184- {-| 'fullCrossProduct' distributes all the elements in a list of or, making
185- all possible tuples. Each of these tuples will be an element of the resulting
186- or. This is useful when, say, distributing 'And' or 'Application' patterns
187- over 'Or'.
188-
189- As an example,
190-
191- @
192- fullCrossProduct
193- [ make [a1, a2]
194- , make [b1, b2]
195- , make [c1, c2]
196- ]
197- @
198-
199- will produce something equivalent to
200-
201- @
202- makeGeneric
203- [ [a1, b1, c1]
204- , [a1, b1, c2]
205- , [a1, b2, c1]
206- , [a1, b2, c2]
207- , [a2, b1, c1]
208- , [a2, b1, c2]
209- , [a2, b2, c1]
210- , [a2, b2, c2]
211- ]
212- @
213-
214- -}
215- fullCrossProduct
216- :: [MultiOr term ]
217- -> MultiOr [term ]
218- fullCrossProduct [] = MultiOr [[] ]
219- fullCrossProduct ors =
220- foldr (crossProductGeneric (:) ) lastOrsWithLists (init ors)
188+ distributeAnd
189+ :: Ord term
190+ => TopBottom term
191+ => MultiAnd (MultiOr term )
192+ -> MultiOr (MultiAnd term )
193+ distributeAnd =
194+ foldr (crossProductGeneric and') (singleton MultiAnd. top)
221195 where
222- lastOrsWithLists = fmap (: [] ) (last ors)
196+ and' term ma =
197+ term : MultiAnd. extractPatterns ma & MultiAnd. make
198+
199+ distributeApplication
200+ :: Ord head
201+ => Ord term
202+ => TopBottom term
203+ => Application head (MultiOr term )
204+ -> MultiOr (Application head term )
205+ distributeApplication
206+ Application
207+ { applicationSymbolOrAlias
208+ , applicationChildren
209+ }
210+ =
211+ foldr
212+ (crossProductGeneric applyTo)
213+ (singleton application)
214+ applicationChildren
215+ where
216+ applyTo term = Lens. over (field @ " applicationChildren" ) (term : )
217+ application =
218+ Application { applicationSymbolOrAlias, applicationChildren = [] }
223219
224220{-| 'flatten' transforms a MultiOr (MultiOr term)
225221into a (MultiOr term) by or-ing all the inner elements.
@@ -308,18 +304,6 @@ flattenGeneric
308304flattenGeneric (MultiOr [] ) = MultiOr []
309305flattenGeneric (MultiOr ors) = foldr1 mergeGeneric ors
310306
311- {-| The same as 'crossProductGeneric' except that it works under an
312- applicative thing.
313- -}
314- crossProductGenericF
315- :: Applicative f
316- => (child1 -> child2 -> f child3 )
317- -> MultiOr child1
318- -> MultiOr child2
319- -> f (MultiOr child3 )
320- crossProductGenericF joiner (MultiOr first) (MultiOr second) =
321- MultiOr <$> sequenceA (joiner <$> first <*> second)
322-
323307{-| 'crossProductGeneric' makes all pairs between the elements of two ors,
324308then applies the given function to the result.
325309
@@ -346,12 +330,14 @@ makeGeneric
346330
347331-}
348332crossProductGeneric
349- :: (child1 -> child2 -> child3 )
333+ :: Ord child3
334+ => TopBottom child3
335+ => (child1 -> child2 -> child3 )
350336 -> MultiOr child1
351337 -> MultiOr child2
352338 -> MultiOr child3
353339crossProductGeneric joiner (MultiOr first) (MultiOr second) =
354- MultiOr $ joiner <$> first <*> second
340+ make $ joiner <$> first <*> second
355341
356342gather :: (Ord a , TopBottom a , MonadLogic m ) => m a -> m (MultiOr a )
357343gather act = make <$> Logic. gather act
@@ -361,10 +347,26 @@ observeAllT :: (Ord a, TopBottom a, Monad m) => LogicT m a -> m (MultiOr a)
361347observeAllT act = make <$> Logic. observeAllT act
362348{-# INLINE observeAllT #-}
363349
350+ observeAll :: (Ord a , TopBottom a ) => Logic a -> MultiOr a
351+ observeAll = make . Logic. observeAll
352+ {-# INLINE observeAll #-}
353+
364354map
365355 :: Ord child2
366356 => TopBottom child2
367357 => (child1 -> child2 )
368358 -> MultiOr child1
369359 -> MultiOr child2
370- map f = make . fmap f . extractPatterns
360+ map f = make . fmap f . Foldable. toList
361+ {-# INLINE map #-}
362+
363+ -- | Warning: 'traverse' should not be used with 'LogicT'.
364+ traverse
365+ :: Ord child2
366+ => TopBottom child2
367+ => Applicative f
368+ => (child1 -> f child2 )
369+ -> MultiOr child1
370+ -> f (MultiOr child2 )
371+ traverse f = fmap make . Traversable. traverse f . Foldable. toList
372+ {-# INLINE traverse #-}
0 commit comments