Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check consistency of constraints before evaluating a pattern #4013

Closed
wants to merge 25 commits into from

Conversation

geo2a
Copy link
Collaborator

@geo2a geo2a commented Aug 1, 2024

Fixes #4012

@geo2a geo2a force-pushed the georgy/evaluate-pattern-pruning branch from cf8aa7c to f0ce5de Compare August 1, 2024 16:19
@geo2a
Copy link
Collaborator Author

geo2a commented Aug 2, 2024

KEMV performance at 5cb20aa and FEATURE_SERVER_OPTS="--no-fallback-simplify --no-post-exec-simplify"

| Test                                                                                      | georgy-evaluate-pattern-prunin time | master-e4bd3aadc time | (georgy-evaluate-pattern-prunin/master-e4bd3aadc) time
|-------------------------------------------------------------------------------------------|-------------------------------------|-----------------------|--------------------------------------------------------
| examples/sum-to-n-foundry-spec.k                                                          | 73.48                               | 107.5                 | 0.6835348837209303
| examples/sum-to-n-spec.k                                                                  | 64.17                               | 90.6                  | 0.7082781456953643
| mcd/cat-exhaustiveness-spec.k                                                             | 98.82                               | 137.5                 | 0.718690909090909
| mcd/vow-fess-fail-rough-spec.k                                                            | 104.41                              | 139.66                | 0.7476013174853214
| mcd/vow-flog-fail-rough-spec.k                                                            | 118.63                              | 153.77                | 0.7714768810561227
| erc20/ds/transferFrom-failure-1-b-spec.k                                                  | 117.7                               | 144.21                | 0.8161708619374523
| erc20/ds/transferFrom-failure-2-b-spec.k                                                  | 82.13                               | 99.14                 | 0.8284244502723421
| mcd/dstoken-approve-fail-rough-spec.k                                                     | 85.53                               | 101.39                | 0.8435743169937864
| erc20/ds/transfer-failure-1-b-spec.k                                                      | 79.36                               | 92.58                 | 0.8572045798228559
| mcd/flopper-tick-pass-rough-spec.k                                                        | 193.42                              | 225.57                | 0.8574721815844305
| mcd/flopper-dent-guy-same-pass-rough-spec.k                                               | 816.19                              | 947.89                | 0.8610598276171286
| mcd/flopper-dent-guy-diff-tic-not-0-pass-rough-spec.k                                     | 889.12                              | 1031.15               | 0.862260582844397
| erc20/hkg/transferFrom-failure-1-spec.k                                                   | 78.17                               | 90.08                 | 0.867784191829485
| erc20/ds/transferFrom-failure-1-c-spec.k                                                  | 97.65                               | 112.2                 | 0.8703208556149733
| examples/erc721-spec.md                                                                   | 152.14                              | 173.7                 | 0.8758779504893495
| benchmarks/ecrecoverloop00-sig1-invalid-spec.k                                            | 95.71                               | 108.62                | 0.8811452771128705
| erc20/hkg/transferFrom-failure-2-spec.k                                                   | 76.96                               | 86.88                 | 0.8858195211786372
| mcd/functional-spec.k                                                                     | 515.75                              | 573.51                | 0.8992868476574079
| mcd/flopper-file-pass-rough-spec.k                                                        | 424.62                              | 469.55                | 0.9043126397614737
| kontrol/test-owneruponlytest-testincrementasowner-0-spec.k                                | 70.48                               | 77.74                 | 0.9066117828659636
| benchmarks/functional-spec.k                                                              | 385.91                              | 422.64                | 0.9130938860495931
| mcd/pot-join-pass-rough-spec.k                                                            | 221.09                              | 241.57                | 0.9152212609181604
| erc20/hkg/transfer-failure-1-spec.k                                                       | 59.91                               | 65.42                 | 0.9157749923570773
| kontrol/test-arithmetictest-test_wmul_weakly_increasing_positive-uint256-uint256-0-spec.k | 68.73                               | 74.88                 | 0.9178685897435899
| mcd/flapper-yank-pass-rough-spec.k                                                        | 180.66                              | 196.79                | 0.9180344529701713
| examples/solidity-code-spec.md                                                            | 109.26                              | 118.95                | 0.9185372005044137
| erc20/hkg/transfer-failure-2-spec.k                                                       | 60.17                               | 65.41                 | 0.9198899250879071
| kontrol/test-arithmetictest-test_wdiv_rounding-uint256-uint256-0-spec.k                   | 55.97                               | 60.46                 | 0.9257360238174
| erc20/ds/transferFrom-failure-2-a-spec.k                                                  | 71.14                               | 76.71                 | 0.9273888671620389
| mcd/end-subuu-pass-spec.k                                                                 | 57.14                               | 61.06                 | 0.9358008516213561
| erc20/ds/transfer-failure-1-a-spec.k                                                      | 66.9                                | 71.43                 | 0.9365812683746325
| kontrol/test-countertest-testincrement-0-spec.k                                           | 93.35                               | 99.38                 | 0.9393238076071644
| kontrol/test-expectcalltest-testexpectregularcall-0-spec.k                                | 50.87                               | 53.98                 | 0.9423860689144128
| mcd/flopper-kick-pass-rough-spec.k                                                        | 127.76                              | 135.57                | 0.9423913845245999
| kontrol/test-expectreverttest-testfail_expectrevert_false-0-spec.k                        | 67.53                               | 71.22                 | 0.9481887110362258
| mcd/end-cash-pass-rough-spec.k                                                            | 208.53                              | 219.01                | 0.9521483037304234
| erc20/ds/transfer-failure-2-a-spec.k                                                      | 67.91                               | 71.19                 | 0.9539261132181486
| erc20/ds/transferFrom-failure-1-a-spec.k                                                  | 83.52                               | 87.15                 | 0.9583476764199654
| kontrol/test-allowchangestest-testfailallowchangestostorage-0-spec.k                      | 72.95                               | 75.81                 | 0.9622741063184277
| kontrol/test-emitcontracttest-testexpectemitdonotcheckdata-0-spec.k                       | 53.71                               | 51.88                 | 1.0352737085582113
| benchmarks/ecrecover00-sigvalid-spec.k                                                    | 62.2                                | 59.99                 | 1.036839473245541
| erc20/ds/transferFrom-failure-1-d-spec.k                                                  | 63.92                               | 61.49                 | 1.0395186209139697
| mcd/flipper-ttl-pass-spec.k                                                               | 57.53                               | 55.29                 | 1.0405136552722012
| benchmarks/ecrecover00-siginvalid-spec.k                                                  | 59.0                                | 56.57                 | 1.0429556301926817
| examples/storage-spec.md                                                                  | 95.17                               | 91.21                 | 1.0434162920732377
| mcd/dai-symbol-pass-spec.k                                                                | 56.2                                | 53.8                  | 1.0446096654275094
| benchmarks/ecrecoverloop02-sigs-valid-spec.k                                              | 124.92                              | 119.4                 | 1.0462311557788944
| benchmarks/ecrecoverloop02-sig1-invalid-spec.k                                            | 119.52                              | 114.1                 | 1.0475021910604734
| benchmarks/requires01-a0gt0-spec.k                                                        | 50.63                               | 48.22                 | 1.04997926171713
| benchmarks/dynamicarray00-spec.k                                                          | 52.17                               | 49.66                 | 1.050543697140556
| benchmarks/storagevar01-spec.k                                                            | 50.55                               | 47.85                 | 1.056426332288401
| erc20/hkg/balanceOf-spec.k                                                                | 51.9                                | 48.98                 | 1.059616169865251
| mcd/cat-file-addr-pass-rough-spec.k                                                       | 61.55                               | 57.95                 | 1.0621225194132873
| erc20/ds/balanceOf-spec.k                                                                 | 52.26                               | 49.17                 | 1.062843197071385
| benchmarks/overflow00-overflow-spec.k                                                     | 49.9                                | 46.93                 | 1.0632857447261879
| erc20/ds/allowance-spec.k                                                                 | 55.75                               | 52.4                  | 1.0639312977099238
| benchmarks/ecrecoverloop02-sig0-invalid-spec.k                                            | 98.69                               | 92.7                  | 1.0646170442286946
| benchmarks/structarg00-spec.k                                                             | 55.3                                | 51.9                  | 1.0655105973025047
| benchmarks/keccak00-spec.k                                                                | 59.04                               | 55.24                 | 1.0687907313540912
| erc20/ds/approve-failure-spec.k                                                           | 52.03                               | 48.66                 | 1.0692560624743117
| erc20/ds/totalSupply-spec.k                                                               | 50.37                               | 47.09                 | 1.069653854321512
| examples/erc20-spec.md                                                                    | 170.12                              | 158.53                | 1.0731091906894594
| benchmarks/encodepacked-keccak01-spec.k                                                   | 54.3                                | 50.52                 | 1.0748218527315914
| erc20/hkg/approve-spec.k                                                                  | 54.12                               | 50.31                 | 1.075730471079308
| erc20/hkg/transferFrom-success-2-spec.k                                                   | 63.68                               | 59.03                 | 1.078773504997459
| erc20/hkg/transfer-success-1-spec.k                                                       | 57.77                               | 53.34                 | 1.0830521184851893
| erc20/hkg/transferFrom-success-1-spec.k                                                   | 68.98                               | 63.57                 | 1.0851030360232814
| benchmarks/staticloop00-a0lt10-spec.k                                                     | 55.41                               | 50.98                 | 1.0868968222832482
| erc20/ds/transfer-failure-2-b-spec.k                                                      | 54.87                               | 50.38                 | 1.0891226677252877
| benchmarks/encode-keccak00-spec.k                                                         | 59.4                                | 54.43                 | 1.09130993937167
| benchmarks/ecrecoverloop00-sig0-invalid-spec.k                                            | 69.58                               | 63.74                 | 1.0916222152494508
| erc20/ds/transfer-failure-1-c-spec.k                                                      | 56.99                               | 51.98                 | 1.096383224317045
| erc20/ds/approve-success-spec.k                                                           | 61.43                               | 55.55                 | 1.1058505850585059
| benchmarks/ecrecoverloop00-sigs-valid-spec.k                                              | 79.16                               | 71.53                 | 1.1066685306864252
| erc20/hkg/transfer-success-2-spec.k                                                       | 58.07                               | 52.33                 | 1.1096885151920506
| erc20/ds/transfer-success-1-spec.k                                                        | 69.88                               | 60.86                 | 1.1482090042720998
| benchmarks/structarg01-spec.k                                                             | 71.77                               | 61.54                 | 1.166233344166396
| erc20/ds/transferFrom-success-2-spec.k                                                    | 75.62                               | 64.64                 | 1.1698638613861387
| erc20/ds/transferFrom-success-1-spec.k                                                    | 82.27                               | 69.73                 | 1.1798365122615802
| erc20/ds/transfer-success-2-spec.k                                                        | 70.34                               | 58.96                 | 1.1930122116689281
| TOTAL                                                                                     | 9109.810000000001                   | 9794.299999999997     | 0.930113433323464

@geo2a geo2a force-pushed the georgy/evaluate-pattern-pruning branch from 5cb20aa to 1a34695 Compare August 5, 2024 07:29
@geo2a geo2a force-pushed the georgy/evaluate-pattern-pruning branch from 22162c0 to 2483a57 Compare August 5, 2024 12:06
@geo2a geo2a force-pushed the georgy/evaluate-pattern-pruning branch from 8c9f9d9 to 985fcbc Compare August 5, 2024 14:37
@geo2a geo2a force-pushed the georgy/evaluate-pattern-pruning branch from 985fcbc to 7f7d667 Compare August 5, 2024 14:38
@geo2a geo2a marked this pull request as ready for review August 5, 2024 15:09
@geo2a geo2a requested a review from jberthold August 5, 2024 15:09
Comment on lines +195 to +211
failBecauseUnknown ::
forall io.
Log.LoggerMIO io =>
Set Predicate ->
ExceptT SMTError (SMT io) Bool
failBecauseUnknown psToCheck =
smtRun GetReasonUnknown >>= \case
Unknown reason -> do
Log.withContext Log.CtxAbort $
Log.logMessage $
"Returned Unknown. Reason: " <> fromMaybe "UNKNOWN" reason
throwE $ SMTSolverUnknown reason mempty psToCheck
other -> do
let msg = "Unexpected result while calling ':reason-unknown': " <> show other
Log.withContext Log.CtxAbort $ Log.logMessage $ Text.pack msg
throwSMT' msg

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I previously made it so that we call GetReasonUnknown whenever we get an Unknown result from the solver. Hence we should never need to call GetReasonUnknown explicitly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry should have made this explicit in the type... I think we should change Response to:

data Response' reason
    = Success -- for command_
    | Sat
    | Unsat
    | Unknown reason
    | Values [(SExpr, Value)]
    | Error BS.ByteString
    deriving stock (Eq, Ord, Show)

type Response = Response' Text
type ResponseMay = Response' (Maybe Text)

s.t.

runCmd :: forall cmd io. (SMTEncode cmd, LoggerMIO io) => cmd -> SMT io Response
runCmd c = runCmdMaybe c >>= \case
    Unknown Nothing -> pure $ Unknown"Could not determine reason when running GetReasonUnknown"
    Unknown (Just reason) -> pure $ Unknown reason
    Success -> pure Success
    Sat -> pure Sat
    Unsat -> pure Unsat
    Values vs -> pure $ Values vs
    Error e -> pure $ Error e

    
    where
        runCmdMaybe :: forall cmd'. SMTEncode cmd' => cmd' -> SMT io ResponseMay
        runCmdMaybe cmd = do
            let cmdBS = encode cmd
            ctxt <- SMT get
            case ctxt.mbSolver of
                Nothing -> pure $ Unknown (Just "server started without SMT solver")
                Just solverRef -> do
                    whenJust ctxt.mbTranscriptHandle $ \h -> do
                        whenJust (comment cmd) $ \c ->
                            liftIO (BS.hPutBuilder h c)
                        liftIO (BS.hPutBuilder h $ cmdBS <> "\n")
                    output <- (liftIO $ readIORef solverRef) >>= \solver -> run_ cmd solver cmdBS
                    let result = readResponse output
                    whenJust ctxt.mbTranscriptHandle $
                        liftIO . flip BS.hPutStrLn (BS.pack $ "; " <> show output <> ", parsed as " <> show result <> "\n")
                    case result of
                        Error{} -> do
                            logMessage $
                                "SMT solver reports: " <> pack (show result)
                            pure result
                        Unknown Nothing ->
                            runCmdMaybe GetReasonUnknown >>= \case
                                unknownWithReason@(Unknown (Just _)) -> pure unknownWithReason
                                _ -> pure result
                        _ -> pure result

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree we should resolve this. The underlying ambiguity is that we use Response at low level as well as high level.
We could maybe even have ResponseSolver = Response' () instead of the optionality in ResponseMay, and make the GetReasonUnknown call in runCmd instead of runCmdMay.

Comment on lines -250 to +270
let mkTraces duration
let mkTraces durationLog
| Just True <- req.logTiming =
Just [ProcessingTime (Just Booster) duration]
Just [ProcessingTime (Just Booster) durationLog]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

o/t ...maybe we should just remove all code for log-timing...
What I am using is the proxy-level timing log, not this level underneath.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've prepared a separate PR that removes "log-timing" and "log-fallbacks": #4015

Comment on lines 467 to 501
withContext CtxConstraint
. withContext CtxDetail
. withTermContext (coerce $ collapseAndBools pat.constraints)
$ pure ()
consistent <- withContext CtxConstraint $ SMT.isSat solver pat.constraints
withContext CtxConstraint $ do
logMessage $
"Constraints consistency check returns: " <> show consistent

case consistent of
Right False -> do
-- the constraints are unsatisfiable, which means that the patten is Bottom
throw . SideConditionFalse . collapseAndBools $ pat.constraints
Left SMT.SMTSolverUnknown{} -> do
-- unlikely case of an Unknown response to a consistency check.
-- continue to preserver the old behaviour.
withContext CtxConstraint . logWarn . Text.pack $
"Constraints consistency UNKNOWN: " <> show consistent
continue
Left other ->
-- fail hard on SMT error other than @SMT.SMTSolverUnknown@
liftIO $ Exception.throw other
Right True -> do
-- constraints are consistent, continue
continue
where
continue = do
newTerm <- withTermContext term $ evaluateTerm' BottomUp term `catch_` keepTopLevelResults
-- after evaluating the term, evaluate all (existing and
-- newly-acquired) constraints, once
traverse_ simplifyAssumedPredicate . predicates =<< getState
-- this may yield additional new constraints, left unevaluated
evaluatedConstraints <- predicates <$> getState
pure Pattern{constraints = evaluatedConstraints, term = newTerm, ceilConditions}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is debatable whether we should give the SMT solver the original (unevaluated) pat.constraints here.
As discussed, we should (eventually) keep the originals around but they might contain unevaluated function calls that the solver would abstract over. AFAICT it is still a sound approximation, though, the solver might just not recognise existing contradictions because it abstracts them away.

And a few stylistic things to note:

  • (minor) code mixes record-dot (pat.constraints) and field pun match (pat{term, ceilConditions} access
  • the continue construction is unnecessary if we anyway throw exceptions or just go on with a warning
  • Repeated withContext CtxConstraint could be gathered
Suggested change
withContext CtxConstraint
. withContext CtxDetail
. withTermContext (coerce $ collapseAndBools pat.constraints)
$ pure ()
consistent <- withContext CtxConstraint $ SMT.isSat solver pat.constraints
withContext CtxConstraint $ do
logMessage $
"Constraints consistency check returns: " <> show consistent
case consistent of
Right False -> do
-- the constraints are unsatisfiable, which means that the patten is Bottom
throw . SideConditionFalse . collapseAndBools $ pat.constraints
Left SMT.SMTSolverUnknown{} -> do
-- unlikely case of an Unknown response to a consistency check.
-- continue to preserver the old behaviour.
withContext CtxConstraint . logWarn . Text.pack $
"Constraints consistency UNKNOWN: " <> show consistent
continue
Left other ->
-- fail hard on SMT error other than @SMT.SMTSolverUnknown@
liftIO $ Exception.throw other
Right True -> do
-- constraints are consistent, continue
continue
where
continue = do
newTerm <- withTermContext term $ evaluateTerm' BottomUp term `catch_` keepTopLevelResults
-- after evaluating the term, evaluate all (existing and
-- newly-acquired) constraints, once
traverse_ simplifyAssumedPredicate . predicates =<< getState
-- this may yield additional new constraints, left unevaluated
evaluatedConstraints <- predicates <$> getState
pure Pattern{constraints = evaluatedConstraints, term = newTerm, ceilConditions}
withContext CtxConstraint $ do
consistent <-
withContext CtxDetail . withTermContext (coerce $ collapseAndBools pat.constraints) $
SMT.isSat solver pat.constraints
logMessage $ "Constraints consistency check returns: " <> show consistent
case consistent of
Right False -> do
-- the constraints are unsatisfiable, which means that the patten is Bottom
throw . SideConditionFalse . collapseAndBools $ pat.constraints
Left SMT.SMTSolverUnknown{} -> do
-- unlikely case of an Unknown response to a consistency check.
-- continue to preserver the old behaviour.
logWarn . Text.pack $ "Constraints consistency UNKNOWN: " <> show consistent
Left other ->
-- fail hard on SMT error other than @SMT.SMTSolverUnknown@
liftIO $ Exception.throw other
Right True -> -- constraints are consistent, continue
pure ()
newTerm <- withTermContext term $ evaluateTerm' BottomUp term `catch_` keepTopLevelResults
-- after evaluating the term, evaluate all (existing and
-- newly-acquired) constraints, once
traverse_ simplifyAssumedPredicate . predicates =<< getState
-- this may yield additional new constraints, left unevaluated
evaluatedConstraints <- predicates <$> getState
pure Pattern{constraints = evaluatedConstraints, term = newTerm, ceilConditions}

Copy link
Collaborator Author

@geo2a geo2a Aug 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • after discussing in the daily meeting, we have decided to proceed with checking the constrains as is
  • I've introduced some stylistic corrections --- thanks!

Comment on lines +137 to +139
-- | This function defines the strategy to increment the timeout when retrying a solver query
updateOptionsOnRetry :: SMTOptions -> SMTOptions
updateOptionsOnRetry opts = opts{timeout = 2 * opts.timeout, retryLimit = ((-) 1) <$> opts.retryLimit}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to locate the option change for retries in a separate function.
Maybe we can make this monadic so that we can log the change (see other comment below).

Also, I just recognise that opts.retryLimit is optional, maybe it should always have a non-negative value?

Comment on lines +195 to +211
failBecauseUnknown ::
forall io.
Log.LoggerMIO io =>
Set Predicate ->
ExceptT SMTError (SMT io) Bool
failBecauseUnknown psToCheck =
smtRun GetReasonUnknown >>= \case
Unknown reason -> do
Log.withContext Log.CtxAbort $
Log.logMessage $
"Returned Unknown. Reason: " <> fromMaybe "UNKNOWN" reason
throwE $ SMTSolverUnknown reason mempty psToCheck
other -> do
let msg = "Unexpected result while calling ':reason-unknown': " <> show other
Log.withContext Log.CtxAbort $ Log.logMessage $ Text.pack msg
throwSMT' msg

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree we should resolve this. The underlying ambiguity is that we use Response at low level as well as high level.
We could maybe even have ResponseSolver = Response' () instead of the optionality in ResponseMay, and make the GetReasonUnknown call in runCmd instead of runCmdMay.

solve smtGiven sexprsToCheck transState
_ -> failBecauseUnknown reasonUnknown

_ -> failBecauseUnknown psToCheck >> pure Nothing -- Nothing is unreachable and is here to make the type checker happy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing is unreachable

Instead, failBecauseUnknown could have a flexible return type ExceptT SMTError (SMT io) a because it will anyway never return any a thing. If we keep failBecauseUnknown, that is...

Comment on lines +564 to +565
lift $ hardResetSolver (updateOptionsOnRetry opts)
Log.logMessage ("Retrying with higher timeout" :: Text)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should maybe add the same logMessage to the checkPredicates retry code path. Or rather make updateOptionsOnRetry emit the log message?

@@ -1,6 +1,7 @@
{"context":["proxy"],"message":"Loading definition from resources/log-simplify-json.kore, main module \"IMP-VERIFICATION\""}
{"context":["proxy"],"message":"Starting RPC server"}
{"context":["proxy"],"message":"Processing request 4"}
{"context":[{"request":"4"},"booster","execute",{"term":"bd7c50d"},{"term":"4a36bb8"},{"hook":"INT.le"},"failure"],"message":"Hook returned no result"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a second log change (removal of a similar line, same inner-most term but different outer ones) that CI is currently failing on.

"depth": 1,
"depth": 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name is not quite right any more (the state is not rewritten).
The difference to the other test is that a rewrite b -> d would be possible, so maybe vacuous-not-rewritten ?

@@ -107,6 +107,7 @@ feature_shell "cd kevm-pyk && poetry run pytest src/tests/integration/test_prove
mkdir -p $SCRIPT_DIR/logs

# use special options if given, but restore KORE_RPC_OPTS afterwards
FEATURE_SERVER_OPTS=${FEATURE_SERVER_OPTS:-''}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@geo2a geo2a force-pushed the georgy/evaluate-pattern-pruning branch from b0276d4 to 575428c Compare August 6, 2024 14:36
@geo2a
Copy link
Collaborator Author

geo2a commented Aug 9, 2024

Closed in favor of #4020

@geo2a geo2a closed this Aug 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make the "simplify" endpoint in Booster evaluate inconsisten predicates and patterns to #Bottom
3 participants