@@ -16,6 +16,10 @@ module Kore.Builtin.Bool (
1616 unifyBoolOr ,
1717 unifyBoolNot ,
1818 matchBool ,
19+ matchBools ,
20+ matchUnifyBoolAnd ,
21+ matchUnifyBoolOr ,
22+ matchUnifyBoolNot ,
1923
2024 -- * Keys
2125 orKey ,
@@ -29,9 +33,6 @@ module Kore.Builtin.Bool (
2933 orElseKey ,
3034) where
3135
32- import Control.Error (
33- MaybeT ,
34- )
3536import qualified Control.Monad as Monad
3637import Data.Functor.Const
3738import qualified Data.HashMap.Strict as HashMap
@@ -55,6 +56,7 @@ import Kore.Internal.Pattern (
5556import qualified Kore.Internal.Pattern as Pattern
5657import Kore.Internal.Symbol
5758import Kore.Internal.TermLike
59+ import Kore.Rewriting.RewritingVariable
5860import Kore.Step.Simplification.Simplify (
5961 BuiltinAndAxiomSimplifier ,
6062 TermSimplifier ,
@@ -163,48 +165,88 @@ builtinFunctions =
163165 xor a b = (a && not b) || (not a && b)
164166 implies a b = not a || b
165167
166- -- | Unification of @BOOL.Bool@ values.
168+ data UnifyBool = UnifyBool
169+ { bool1 , bool2 :: ! InternalBool
170+ }
171+
172+ {- | Matches
173+
174+ @
175+ \\equals{_, _}(\\dv{Bool}(_), \\dv{Bool}(_))
176+ @
177+
178+ and
179+
180+ @
181+ \\and{_}(\\dv{Bool}(_), \\dv{Bool}(_))
182+ @
183+ -}
184+ matchBools ::
185+ TermLike RewritingVariableName ->
186+ TermLike RewritingVariableName ->
187+ Maybe UnifyBool
188+ matchBools first second
189+ | InternalBool_ bool1 <- first
190+ , InternalBool_ bool2 <- second =
191+ Just UnifyBool {bool1, bool2}
192+ | otherwise = Nothing
193+ {-# INLINE matchBools #-}
194+
195+ -- | When bool values are equal, returns first term; otherwise returns bottom.
167196unifyBool ::
168- forall variable unifier .
169- InternalVariable variable =>
197+ forall unifier .
170198 MonadUnify unifier =>
171- TermLike variable ->
172- TermLike variable ->
173- MaybeT unifier (Pattern variable )
174- unifyBool a b =
175- worker a b <|> worker b a
199+ TermLike RewritingVariableName ->
200+ TermLike RewritingVariableName ->
201+ UnifyBool ->
202+ unifier (Pattern RewritingVariableName )
203+ unifyBool termLike1 termLike2 unifyData
204+ | bool1 == bool2 =
205+ return (Pattern. fromTermLike termLike1)
206+ | otherwise =
207+ Unify. explainAndReturnBottom
208+ " different Bool domain values"
209+ termLike1
210+ termLike2
176211 where
177- worker termLike1 termLike2
178- | Just value1 <- matchBool termLike1
179- , Just value2 <- matchBool termLike2 =
180- lift $
181- if value1 == value2
182- then return (Pattern. fromTermLike termLike1)
183- else
184- Unify. explainAndReturnBottom
185- " different Bool domain values"
186- termLike1
187- termLike2
188- worker _ _ = empty
212+ UnifyBool {bool1, bool2} = unifyData
213+
214+ {- | Matches
215+
216+ @
217+ \\equals{_, _}(\\dv{Bool}("true"), andBool(_,_))
218+ @
219+
220+ and
221+
222+ @
223+ \\and{_}(\\dv{Bool}("true"), andBool(_,_))
224+ @
225+ -}
226+ matchUnifyBoolAnd ::
227+ TermLike RewritingVariableName ->
228+ TermLike RewritingVariableName ->
229+ Maybe BoolAnd
230+ matchUnifyBoolAnd first second
231+ | Just True <- matchBool first
232+ , Just boolAnd <- matchBoolAnd second
233+ , isFunctionPattern second =
234+ Just boolAnd
235+ | otherwise =
236+ Nothing
237+ {-# INLINE matchUnifyBoolAnd #-}
189238
190239unifyBoolAnd ::
191- forall variable unifier .
192- InternalVariable variable =>
240+ forall unifier .
193241 MonadUnify unifier =>
194- TermSimplifier variable unifier ->
195- TermLike variable ->
196- TermLike variable ->
197- MaybeT unifier (Pattern variable )
198- unifyBoolAnd unifyChildren a b =
199- worker a b <|> worker b a
242+ TermSimplifier RewritingVariableName unifier ->
243+ TermLike RewritingVariableName ->
244+ BoolAnd ->
245+ unifier (Pattern RewritingVariableName )
246+ unifyBoolAnd unifyChildren term boolAnd =
247+ unifyBothWith unifyChildren term operand1 operand2
200248 where
201- worker termLike1 termLike2
202- | Just value1 <- matchBool termLike1
203- , value1
204- , Just BoolAnd {operand1, operand2} <- matchBoolAnd termLike2
205- , isFunctionPattern termLike2 =
206- unifyBothWith unifyChildren termLike1 operand1 operand2
207- worker _ _ = empty
249+ BoolAnd {operand1, operand2} = boolAnd
208250
209251{- | Takes a (function-like) pattern and unifies it against two other patterns.
210252 Returns the original pattern and the conditions resulting from unification.
@@ -221,8 +263,8 @@ unifyBothWith ::
221263 TermLike variable ->
222264 -- | first term to be unified with the base term
223265 TermLike variable ->
224- MaybeT unifier (Pattern variable )
225- unifyBothWith unify termLike1 operand1 operand2 = lift $ do
266+ unifier (Pattern variable )
267+ unifyBothWith unify termLike1 operand1 operand2 = do
226268 unification1 <- unify' termLike1 operand1
227269 unification2 <- unify' termLike1 operand2
228270 let conditions = unification1 <> unification2
@@ -231,44 +273,83 @@ unifyBothWith unify termLike1 operand1 operand2 = lift $ do
231273 unify' term1 term2 =
232274 Pattern. withoutTerm <$> unify term1 term2
233275
276+ {- | Matches
277+
278+ @
279+ \\equals{_, _}(\\dv{Bool}("false"), boolOr(_,_))
280+ @
281+
282+ and
283+
284+ @
285+ \\and{_}(\\dv{Bool}("false"), boolOr(_,_))
286+ @
287+ -}
288+ matchUnifyBoolOr ::
289+ TermLike RewritingVariableName ->
290+ TermLike RewritingVariableName ->
291+ Maybe BoolOr
292+ matchUnifyBoolOr first second
293+ | Just False <- matchBool first
294+ , Just boolOr <- matchBoolOr second
295+ , isFunctionPattern second =
296+ Just boolOr
297+ | otherwise = Nothing
298+ {-# INLINE matchUnifyBoolOr #-}
299+
234300unifyBoolOr ::
235- forall variable unifier .
236- InternalVariable variable =>
301+ forall unifier .
237302 MonadUnify unifier =>
238- TermSimplifier variable unifier ->
239- TermLike variable ->
240- TermLike variable ->
241- MaybeT unifier (Pattern variable )
242- unifyBoolOr unifyChildren a b =
243- worker a b <|> worker b a
303+ TermSimplifier RewritingVariableName unifier ->
304+ TermLike RewritingVariableName ->
305+ BoolOr ->
306+ unifier (Pattern RewritingVariableName )
307+ unifyBoolOr unifyChildren termLike boolOr =
308+ unifyBothWith unifyChildren termLike operand1 operand2
244309 where
245- worker termLike1 termLike2
246- | Just value1 <- matchBool termLike1
247- , not value1
248- , Just BoolOr {operand1, operand2} <- matchBoolOr termLike2
249- , isFunctionPattern termLike2 =
250- unifyBothWith unifyChildren termLike1 operand1 operand2
251- worker _ _ = empty
310+ BoolOr {operand1, operand2} = boolOr
311+
312+ data UnifyBoolNot = UnifyBoolNot
313+ { boolNot :: BoolNot
314+ , value :: Bool
315+ }
316+
317+ {- | Matches
318+
319+ @
320+ \\equals{_, _}(notBool(_), \\dv{Bool}(_))
321+ @
322+
323+ and
324+
325+ @
326+ \\and{_}(notBool(_), \\dv{Bool}(_))
327+ @
328+ -}
329+ matchUnifyBoolNot ::
330+ TermLike RewritingVariableName ->
331+ TermLike RewritingVariableName ->
332+ Maybe UnifyBoolNot
333+ matchUnifyBoolNot first second
334+ | Just boolNot <- matchBoolNot first
335+ , isFunctionPattern first
336+ , Just value <- matchBool second =
337+ Just $ UnifyBoolNot boolNot value
338+ | otherwise = Nothing
339+ {-# INLINE matchUnifyBoolNot #-}
252340
253341unifyBoolNot ::
254- forall variable unifier .
255- InternalVariable variable =>
256- MonadUnify unifier =>
257- TermSimplifier variable unifier ->
258- TermLike variable ->
259- TermLike variable ->
260- MaybeT unifier (Pattern variable )
261- unifyBoolNot unifyChildren a b =
262- worker a b <|> worker b a
342+ forall unifier .
343+ TermSimplifier RewritingVariableName unifier ->
344+ TermLike RewritingVariableName ->
345+ UnifyBoolNot ->
346+ unifier (Pattern RewritingVariableName )
347+ unifyBoolNot unifyChildren term unifyData =
348+ let notValue = asInternal (termLikeSort term) (not value)
349+ in unifyChildren notValue operand
263350 where
264- worker termLike1 boolTerm
265- | Just BoolNot {operand} <- matchBoolNot termLike1
266- , isFunctionPattern termLike1
267- , Just value <- matchBool boolTerm =
268- lift $ do
269- let notValue = asInternal (termLikeSort boolTerm) (not value)
270- unifyChildren notValue operand
271- worker _ _ = empty
351+ UnifyBoolNot {boolNot, value} = unifyData
352+ BoolNot {operand} = boolNot
272353
273354-- | Match a @BOOL.Bool@ builtin value.
274355matchBool :: TermLike variable -> Maybe Bool
@@ -277,41 +358,41 @@ matchBool (InternalBool_ InternalBool{internalBoolValue}) =
277358matchBool _ = Nothing
278359
279360-- | The @BOOL.and@ hooked symbol applied to @term@-type arguments.
280- data BoolAnd term = BoolAnd
361+ data BoolAnd = BoolAnd
281362 { symbol :: ! Symbol
282- , operand1 , operand2 :: ! term
363+ , operand1 , operand2 :: ! ( TermLike RewritingVariableName )
283364 }
284365
285366-- | Match the @BOOL.and@ hooked symbol.
286- matchBoolAnd :: TermLike variable -> Maybe ( BoolAnd ( TermLike variable ))
367+ matchBoolAnd :: TermLike RewritingVariableName -> Maybe BoolAnd
287368matchBoolAnd (App_ symbol [operand1, operand2]) = do
288369 hook2 <- (getHook . symbolHook) symbol
289370 Monad. guard (hook2 == andKey)
290371 return BoolAnd {symbol, operand1, operand2}
291372matchBoolAnd _ = Nothing
292373
293374-- | The @BOOL.or@ hooked symbol applied to @term@-type arguments.
294- data BoolOr term = BoolOr
375+ data BoolOr = BoolOr
295376 { symbol :: ! Symbol
296- , operand1 , operand2 :: ! term
377+ , operand1 , operand2 :: ! ( TermLike RewritingVariableName )
297378 }
298379
299380-- | Match the @BOOL.or@ hooked symbol.
300- matchBoolOr :: TermLike variable -> Maybe ( BoolOr ( TermLike variable ))
381+ matchBoolOr :: TermLike RewritingVariableName -> Maybe BoolOr
301382matchBoolOr (App_ symbol [operand1, operand2]) = do
302383 hook2 <- (getHook . symbolHook) symbol
303384 Monad. guard (hook2 == orKey)
304385 return BoolOr {symbol, operand1, operand2}
305386matchBoolOr _ = Nothing
306387
307388-- | The @BOOL.not@ hooked symbol applied to a @term@-type argument.
308- data BoolNot term = BoolNot
389+ data BoolNot = BoolNot
309390 { symbol :: ! Symbol
310- , operand :: ! term
391+ , operand :: ! ( TermLike RewritingVariableName )
311392 }
312393
313394-- | Match the @BOOL.not@ hooked symbol.
314- matchBoolNot :: TermLike variable -> Maybe ( BoolNot ( TermLike variable ))
395+ matchBoolNot :: TermLike RewritingVariableName -> Maybe BoolNot
315396matchBoolNot (App_ symbol [operand]) = do
316397 hook2 <- (getHook . symbolHook) symbol
317398 Monad. guard (hook2 == notKey)
0 commit comments