@@ -48,14 +48,20 @@ import Booster.Log
48
48
import Booster.Pattern.ApplyEquations qualified as ApplyEquations
49
49
import Booster.Pattern.Base (Pattern (.. ), Sort (SortApp ), Term , Variable )
50
50
import Booster.Pattern.Base qualified as Pattern
51
+ import Booster.Pattern.Bool (pattern TrueBool )
52
+ import Booster.Pattern.Match (FailReason (.. ), MatchResult (.. ), MatchType (.. ), matchTerms )
51
53
import Booster.Pattern.Rewrite (
52
54
RewriteFailed (.. ),
53
55
RewriteResult (.. ),
54
56
RewriteTrace (.. ),
55
57
performRewrite ,
56
58
)
57
- import Booster.Pattern.Util (sortOfPattern , substituteInPredicate , substituteInTerm )
58
- import Booster.Prettyprinter (renderText )
59
+ import Booster.Pattern.Util (
60
+ sortOfPattern ,
61
+ substituteInPredicate ,
62
+ substituteInTerm ,
63
+ )
64
+ import Booster.Prettyprinter (renderDefault , renderText )
59
65
import Booster.SMT.Base qualified as SMT
60
66
import Booster.SMT.Interface qualified as SMT
61
67
import Booster.Syntax.Json (KoreJson (.. ), addHeader , prettyPattern , sortOfJson )
@@ -73,7 +79,11 @@ import Booster.Syntax.Json.Internalise (
73
79
import Booster.Syntax.ParsedKore (parseKoreModule )
74
80
import Booster.Syntax.ParsedKore.Base hiding (ParsedModule )
75
81
import Booster.Syntax.ParsedKore.Base qualified as ParsedModule (ParsedModule (.. ))
76
- import Booster.Syntax.ParsedKore.Internalise (addToDefinitions , definitionErrorToRpcError )
82
+ import Booster.Syntax.ParsedKore.Internalise (
83
+ addToDefinitions ,
84
+ definitionErrorToRpcError ,
85
+ extractExistentials ,
86
+ )
77
87
import Booster.Util (Flag (.. ), constructorName )
78
88
import Kore.JsonRpc.Error qualified as RpcError
79
89
import Kore.JsonRpc.Server (ErrorObj (.. ), JsonRpcHandler (.. ), Respond )
@@ -455,11 +465,87 @@ respond stateVar =
455
465
{ satisfiable = RpcTypes. Sat
456
466
, substitution
457
467
}
468
+ RpcTypes. Implies req -> withModule req. _module $ \ (def, mLlvmLibrary, mSMTOptions) -> Booster.Log. withContext " implies" $ do
469
+ -- internalise given constrained term
470
+ let internalised =
471
+ runExcept . internalisePattern DisallowAlias CheckSubsorts Nothing def . fst . extractExistentials
472
+
473
+ case (internalised req. antecedent. term, internalised req. consequent. term) of
474
+ (Left patternError, _) -> do
475
+ Log. logDebug $ " Error internalising antecedent" <> Text. pack (show patternError)
476
+ pure $
477
+ Left $
478
+ RpcError. backendError $
479
+ RpcError. CouldNotVerifyPattern
480
+ [ patternErrorToRpcError patternError
481
+ ]
482
+ (_, Left patternError) -> do
483
+ Log. logDebug $ " Error internalising consequent" <> Text. pack (show patternError)
484
+ pure $
485
+ Left $
486
+ RpcError. backendError $
487
+ RpcError. CouldNotVerifyPattern
488
+ [ patternErrorToRpcError patternError
489
+ ]
490
+ (Right (patL, substitutionL, unsupportedL), Right (patR, substitutionR, unsupportedR)) -> do
491
+ unless (null unsupportedL && null unsupportedR) $ do
492
+ Log. logWarnNS
493
+ " booster"
494
+ " Implies: aborting due to unsupported predicate parts"
495
+ unless (null unsupportedL) $
496
+ Log. logOtherNS
497
+ " booster"
498
+ (Log. LevelOther " ErrorDetails" )
499
+ (Text. unlines $ map prettyPattern unsupportedL)
500
+ unless (null unsupportedR) $
501
+ Log. logOtherNS
502
+ " booster"
503
+ (Log. LevelOther " ErrorDetails" )
504
+ (Text. unlines $ map prettyPattern unsupportedR)
505
+ let
506
+ -- apply the given substitution before doing anything else
507
+ substPatL =
508
+ Pattern
509
+ { term = substituteInTerm substitutionL patL. term
510
+ , constraints = Set. map (substituteInPredicate substitutionL) patL. constraints
511
+ , ceilConditions = patL. ceilConditions
512
+ }
513
+ substPatR =
514
+ Pattern
515
+ { term = substituteInTerm substitutionR patR. term
516
+ , constraints = Set. map (substituteInPredicate substitutionR) patR. constraints
517
+ , ceilConditions = patR. ceilConditions
518
+ }
519
+
520
+ case matchTerms Booster.Pattern.Match. Implies def substPatR. term substPatL. term of
521
+ MatchFailed (SubsortingError sortError) ->
522
+ pure . Left . RpcError. backendError . RpcError. ImplicationCheckError . RpcError. ErrorOnly . pack $
523
+ show sortError
524
+ MatchFailed {} ->
525
+ doesNotImply (sortOfPattern substPatL) req. antecedent. term req. consequent. term
526
+ MatchIndeterminate remainder ->
527
+ pure . Left . RpcError. backendError . RpcError. ImplicationCheckError . RpcError. ErrorOnly . pack $
528
+ " match remainder: "
529
+ <> renderDefault (pretty remainder)
530
+ MatchSuccess subst -> do
531
+ let filteredConsequentPreds =
532
+ Set. map (substituteInPredicate subst) substPatR. constraints `Set.difference` substPatL. constraints
533
+ doTracing = Flag False
534
+ solver <- traverse (SMT. initSolver def) mSMTOptions
535
+
536
+ if null filteredConsequentPreds
537
+ then implies (sortOfPattern substPatL) req. antecedent. term req. consequent. term subst
538
+ else
539
+ ApplyEquations. evaluateConstraints doTracing def mLlvmLibrary solver mempty filteredConsequentPreds >>= \ case
540
+ (Right newPreds, _) ->
541
+ if all (== Pattern. Predicate TrueBool ) newPreds
542
+ then implies (sortOfPattern substPatL) req. antecedent. term req. consequent. term subst
543
+ else pure . Left . RpcError. backendError $ RpcError. Aborted " unknown constrains"
544
+ (Left other, _) ->
545
+ pure . Left . RpcError. backendError $ RpcError. Aborted (Text. pack . constructorName $ other)
458
546
459
547
-- this case is only reachable if the cancel appeared as part of a batch request
460
548
RpcTypes. Cancel -> pure $ Left RpcError. cancelUnsupportedInBatchMode
461
- -- using "Method does not exist" error code
462
- _ -> pure $ Left RpcError. notImplemented
463
549
where
464
550
withModule ::
465
551
Maybe Text ->
@@ -474,6 +560,39 @@ respond stateVar =
474
560
Nothing -> pure $ Left $ RpcError. backendError $ RpcError. CouldNotFindModule mainName
475
561
Just d -> action (d, state. mLlvmLibrary, state. mSMTOptions)
476
562
563
+ doesNotImply s l r =
564
+ pure $
565
+ Right $
566
+ RpcTypes. Implies
567
+ RpcTypes. ImpliesResult
568
+ { implication = addHeader $ Syntax. KJImplies (externaliseSort s) l r
569
+ , valid = False
570
+ , condition = Nothing
571
+ , logs = Nothing
572
+ }
573
+
574
+ implies s' l r subst =
575
+ let s = externaliseSort s'
576
+ in pure $
577
+ Right $
578
+ RpcTypes. Implies
579
+ RpcTypes. ImpliesResult
580
+ { implication = addHeader $ Syntax. KJImplies s l r
581
+ , valid = True
582
+ , condition =
583
+ Just
584
+ RpcTypes. Condition
585
+ { predicate = addHeader $ Syntax. KJTop s
586
+ , substitution =
587
+ addHeader
588
+ $ (\ xs -> if null xs then Syntax. KJTop s else Syntax. KJAnd s xs)
589
+ . map (uncurry $ externaliseSubstitution s)
590
+ . Map. toList
591
+ $ subst
592
+ }
593
+ , logs = Nothing
594
+ }
595
+
477
596
handleSmtError :: JsonRpcHandler
478
597
handleSmtError = JsonRpcHandler $ \ case
479
598
SMT. GeneralSMTError err -> runtimeError " problem" err
@@ -764,7 +883,7 @@ mkLogRewriteTrace
764
883
| logSuccessfulRewrites ->
765
884
Just $
766
885
singleton $
767
- Rewrite
886
+ Kore.JsonRpc.Types.Log. Rewrite
768
887
{ result =
769
888
Success
770
889
{ rewrittenTerm = Nothing
@@ -778,7 +897,7 @@ mkLogRewriteTrace
778
897
| logFailedRewrites ->
779
898
Just $
780
899
singleton $
781
- Rewrite
900
+ Kore.JsonRpc.Types.Log. Rewrite
782
901
{ result = case reason of
783
902
NoApplicableRules {} -> Failure {reason = " No applicable rules found" , _ruleId = Nothing }
784
903
TermIndexIsNone {} -> Failure {reason = " Term index is None for term" , _ruleId = Nothing }
0 commit comments