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

Georgy/refactor check requires #4035

Merged
merged 3 commits into from
Aug 15, 2024
Merged

Conversation

geo2a
Copy link
Collaborator

@geo2a geo2a commented Aug 14, 2024

Refactor applyRule and applyEquation to check requires/ensures in separate functions.

This will make reviewing #4022 easier.

@geo2a geo2a force-pushed the georgy/refactor-check-requires branch from ab8bd3e to c78d8bb Compare August 14, 2024 10:21
@geo2a geo2a marked this pull request as ready for review August 14, 2024 10:21
@geo2a geo2a requested review from goodlyrottenapple and jberthold and removed request for goodlyrottenapple August 14, 2024 10:21
-- can proceed
pure ()
-- check required constraints from lhs.
-- Reaction on false/indeterminate is varies depending on the equation's type (function/simplification),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
-- Reaction on false/indeterminate is varies depending on the equation's type (function/simplification),
-- Reaction on false/indeterminate varies depending on the equation's type (function/simplification),

Comment on lines +420 to +485
checkRequires ::
Substitution -> RewriteRuleAppT (RewriteT io) ()
checkRequires matchingSubst = do
ModifiersRep (_ :: FromModifiersT mods => Proxy mods) <- getPrettyModifiers
-- apply substitution to rule requires
let ruleRequires =
concatMap (splitBoolPredicates . coerce . substituteInTerm matchingSubst . coerce) rule.requires

-- filter out any predicates known to be _syntactically_ present in the known prior
toCheck <- lift $ filterOutKnownConstraints pat.constraints ruleRequires

-- simplify the constraints (one by one in isolation). Stop if false, abort rewrite if indeterminate.
unclearRequires <-
catMaybes <$> mapM (checkConstraint id notAppliedIfBottom pat.constraints) toCheck

-- unclear conditions may have been simplified and
-- could now be syntactically present in the path constraints, filter again
stillUnclear <- lift $ filterOutKnownConstraints pat.constraints unclearRequires

-- check unclear requires-clauses in the context of known constraints (priorKnowledge)
solver <- lift $ RewriteT $ (.smtSolver) <$> ask
let smtUnclear = do
withContext CtxConstraint . withContext CtxAbort . logMessage $
WithJsonMessage (object ["conditions" .= (externaliseTerm . coerce <$> stillUnclear)]) $
renderOneLineText $
"Uncertain about condition(s) in a rule:"
<+> (hsep . punctuate comma . map (pretty' @mods) $ stillUnclear)
failRewrite $
RuleConditionUnclear rule . coerce . foldl1 AndTerm $
map coerce stillUnclear
SMT.checkPredicates solver pat.constraints mempty (Set.fromList stillUnclear) >>= \case
SMT.IsUnknown{} ->
smtUnclear -- abort rewrite if a solver result was Unknown
SMT.IsInvalid -> do
-- requires is actually false given the prior
withContext CtxFailure $ logMessage ("Required clauses evaluated to #Bottom." :: Text)
RewriteRuleAppT $ pure NotApplied
SMT.IsValid ->
pure () -- can proceed
checkEnsures ::
Substitution -> RewriteRuleAppT (RewriteT io) [Predicate]
checkEnsures matchingSubst = do
-- apply substitution to rule requires
let ruleEnsures =
concatMap (splitBoolPredicates . coerce . substituteInTerm matchingSubst . coerce) $
Set.toList rule.ensures
newConstraints <-
catMaybes <$> mapM (checkConstraint id trivialIfBottom pat.constraints) ruleEnsures

-- check all new constraints together with the known side constraints
solver <- lift $ RewriteT $ (.smtSolver) <$> ask
(lift $ SMT.checkPredicates solver pat.constraints mempty (Set.fromList newConstraints)) >>= \case
SMT.IsInvalid -> do
withContext CtxSuccess $ logMessage ("New constraints evaluated to #Bottom." :: Text)
RewriteRuleAppT $ pure Trivial
_other ->
pure ()

-- if a new constraint is going to be added, the equation cache is invalid
unless (null newConstraints) $ do
withContextFor Equations . logMessage $
("New path condition ensured, invalidating cache" :: Text)

lift . RewriteT . lift . modify $ \s -> s{equations = mempty}
pure newConstraints

Copy link
Contributor

Choose a reason for hiding this comment

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

can this be subsumed by the ApplyEquations version?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We may find the common denominator, but I'm reluctant to do it as #4022 will change checkRequires in ApplyEquations significantly, and I do not think we want to allow rewrite rules with syntactic requires clauses.

@rv-jenkins rv-jenkins merged commit 3d7e91d into master Aug 15, 2024
6 checks passed
@rv-jenkins rv-jenkins deleted the georgy/refactor-check-requires branch August 15, 2024 12:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants