Skip to content

Commit 830d8c3

Browse files
authored
Hotfix indeterminate match for supersort function under injection (#4135)
Improves #4117 and removes temporary workaround #4133 The injection matcher was biased towards variable matching before, and returned a `Fail` prematurely if this failed. The new preference is to check for unevaluated functions that return a supersort first (to return indeterminate), before trying to match a rule variable with supersort. If the source sorts are unrelated, the match can immediately fail.
1 parent aa2aeb9 commit 830d8c3

4 files changed

Lines changed: 47 additions & 138 deletions

File tree

booster/library/Booster/Pattern/ApplyEquations.hs

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -844,27 +844,6 @@ applyEquations theory handler term = do
844844
)
845845
err
846846

847-
{- | A sort predicate equation is characterised by the following:
848-
* Its lhs is a function application (of a symbol starting with 'Lblis', not checked)
849-
* function argument is a singleton K sequence
850-
* containing an injection of a Variable into the 'KItem' sort
851-
* rhs is a boolean
852-
* requires and ensures are both empty (i.e., plain "true" DVs)
853-
* the rule has no location information
854-
-}
855-
isSortPredicate :: RewriteRule tag -> Bool
856-
isSortPredicate rule
857-
| SymbolApplication _funSym [] [arg] <- rule.lhs
858-
, KSeq sort (Var v) <- arg -- implicitly: Injection sort KItem (Var v)
859-
, v.variableSort == sort
860-
, (rule.rhs == TrueBool || rule.rhs == FalseBool)
861-
, [Predicate TrueBool] <- rule.requires -- , null rule.requires
862-
, [Predicate TrueBool] <- rule.ensures -- , null rule.ensures
863-
, UNKNOWN <- sourceRef rule.attributes =
864-
True
865-
| otherwise =
866-
False
867-
868847
applyEquation ::
869848
forall io tag.
870849
LoggerMIO io =>
@@ -873,20 +852,6 @@ applyEquation ::
873852
EquationT
874853
io
875854
(Either ((EquationT io () -> EquationT io ()) -> EquationT io (), ApplyEquationFailure) Term)
876-
applyEquation (FunctionApplication _sym [] [term]) rule
877-
| isSortPredicate rule
878-
, KSeq _ (FunctionApplication _ _ _) <- term =
879-
-- sort predicates only match on a sort injection, unevaluated
880-
-- function applications may create false negatives
881-
pure $
882-
Left
883-
( \ctxt ->
884-
ctxt $
885-
withTermContext term $
886-
withContext CtxWarn $
887-
logMessage ("Refusing to apply sort predicate rule to an unevaluated term" :: Text)
888-
, IndeterminateMatch
889-
)
890855
applyEquation term rule =
891856
runExceptT $
892857
getPrettyModifiers >>= \case

booster/library/Booster/Pattern/Match.hs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ matchInj ::
330330
Term ->
331331
StateT MatchState (Except MatchResult) ()
332332
matchInj
333-
matchType
333+
_matchType
334334
source1
335335
target1
336336
trm1
@@ -341,28 +341,44 @@ matchInj
341341
failWith (DifferentSorts (Injection source1 target1 trm1) (Injection source2 target2 trm2))
342342
| source1 == source2 = do
343343
enqueueRegularProblem trm1 trm2
344-
| Var v <- trm1 = do
345-
-- variable in pattern, check source sorts and bind
344+
matchInj
345+
matchType
346+
source1
347+
target1
348+
trm1
349+
source2
350+
target2
351+
trm2 =
352+
do
346353
subsorts <- gets mSubsorts
347-
isSubsort <-
354+
s1IsSubsort <-
355+
lift . withExcept (MatchFailed . SubsortingError) $
356+
checkSubsort subsorts source1 source2
357+
s2IsSubsort <-
348358
lift . withExcept (MatchFailed . SubsortingError) $
349359
checkSubsort subsorts source2 source1
350-
if isSubsort
351-
then bindVariable matchType v (Injection source2 source1 trm2)
352-
else failWith (DifferentSorts trm1 trm2)
353-
| FunctionApplication{} <- trm2 = do
360+
-- cases below require a subsort relation (and source1 ==
361+
-- source2 is already handled)
362+
unless (s1IsSubsort || s2IsSubsort) $
363+
failWith (DifferentSorts trm1 trm2)
354364
-- Functions may have a more general sort than the actual result.
355365
-- This means we cannot simply fail the rewrite: the match is
356366
-- indeterminate if the function result is.
357-
subsorts <- gets mSubsorts
358-
isSubsort <- -- rule requires a more specific sort?
359-
lift . withExcept (MatchFailed . SubsortingError) $
360-
checkSubsort subsorts source1 source2
361-
if isSubsort
362-
then addIndeterminate trm1 trm2
363-
else failWith (DifferentSorts (Injection source1 target1 trm1) (Injection source2 target2 trm2))
364-
| otherwise =
365-
failWith (DifferentSorts (Injection source1 target1 trm1) (Injection source2 target2 trm2))
367+
case (s1IsSubsort, trm2) of
368+
(True, FunctionApplication{}) ->
369+
addIndeterminate trm1 trm2
370+
_ -> do
371+
-- If the rule has a variable with a supersort of the
372+
-- subject, trm2 can be bound with a suitable injection
373+
case (s2IsSubsort, trm1) of
374+
(True, Var v) ->
375+
bindVariable matchType v (Injection source2 source1 trm2)
376+
_ ->
377+
-- truly different sorts, safe to just fail
378+
failWith $
379+
DifferentSorts
380+
(Injection source1 target1 trm1)
381+
(Injection source2 target2 trm2)
366382
{-# INLINE matchInj #-}
367383

368384
----- Symbol Applications

0 commit comments

Comments
 (0)