@@ -191,51 +191,45 @@ rewriteStep cutLabels terminalLabels pat = do
191
191
processGroups rest >>= \ case
192
192
RewriteStuck {} -> pure $ RewriteTrivial pat
193
193
other -> pure other
194
- AppliedRules (RewriteGroupApplicationData {ruleApplicationData = [] }) ->
195
- -- not applicable rules in this group, try other groups
196
- -- TODO check that remainder is trivial, abort otherwise
194
+ AppliedRules (RewriteGroupApplicationData {ruleApplicationData = [] , remainderPrediate }) -> do
195
+ -- no applicable rules in this group, try other groups
196
+ assertRemainderUnsat [] remainderPrediate
197
197
processGroups rest
198
198
AppliedRules
199
199
( RewriteGroupApplicationData
200
200
{ ruleApplicationData = [(rule, applied@ RewriteRuleAppliedData {})]
201
- , remainderPrediate = groupRemainderPrediate
201
+ , remainderPrediate
202
202
}
203
- )
203
+ ) -> do
204
+ -- a non-trivial remainder with a single applicable rule is
205
+ -- an indication if semantics incompleteness: abort
206
+ assertRemainderUnsat [rule] remainderPrediate
204
207
-- only one rule applies, see if it's special and return an appropriate result
205
- | not (Set. null groupRemainderPrediate) && not (any isFalse groupRemainderPrediate) -> do
206
- -- a non-trivial remainder with a single applicable rule is
207
- -- an indication if semantics incompleteness: abort
208
- -- TODO refactor remainder check into a function and reuse below
209
- solver <- getSolver
210
- satRes <- SMT. isSat solver (Set. toList $ pat. constraints <> groupRemainderPrediate) pat. substitution
211
- throw $
212
- RewriteRemainderPredicate [rule] satRes . coerce . foldl1 AndTerm $
213
- map coerce . Set. toList $
214
- groupRemainderPrediate
215
- | labelOf rule `elem` cutLabels ->
216
- pure $ RewriteCutPoint (labelOf rule) (uniqueId rule) pat applied. rewritten
217
- | labelOf rule `elem` terminalLabels ->
218
- pure $ RewriteTerminal (labelOf rule) (uniqueId rule) applied. rewritten
219
- | otherwise ->
220
- pure $ RewriteFinished (Just $ ruleLabelOrLocT rule) (Just $ uniqueId rule) applied. rewritten
208
+ if
209
+ | labelOf rule `elem` cutLabels ->
210
+ pure $ RewriteCutPoint (labelOf rule) (uniqueId rule) pat applied. rewritten
211
+ | labelOf rule `elem` terminalLabels ->
212
+ pure $ RewriteTerminal (labelOf rule) (uniqueId rule) applied. rewritten
213
+ | otherwise ->
214
+ pure $ RewriteFinished (Just $ ruleLabelOrLocT rule) (Just $ uniqueId rule) applied. rewritten
221
215
AppliedRules
222
- (RewriteGroupApplicationData {ruleApplicationData = xs, remainderPrediate = groupRemainderPrediate }) -> do
216
+ (RewriteGroupApplicationData {ruleApplicationData = xs, remainderPrediate}) -> do
223
217
-- multiple rules apply, analyse branching and remainders
224
- isSatRemainder groupRemainderPrediate >>= \ case
218
+ isSatRemainder remainderPrediate >>= \ case
225
219
SMT. IsUnsat -> do
226
220
-- the remainder condition is unsatisfiable: no need to consider the remainder branch.
227
- logRemainder (map fst xs) SMT. IsUnsat groupRemainderPrediate
221
+ logRemainder (map fst xs) SMT. IsUnsat remainderPrediate
228
222
pure $ mkBranch pat xs
229
223
satRes@ (SMT. IsSat {}) -> do
230
224
-- the remainder condition is satisfiable.
231
225
-- TODO construct the remainder branch and consider it.
232
226
-- To construct the "remainder pattern",
233
227
-- we add the remainder condition to the predicates of pat
234
- throwRemainder (map fst xs) satRes groupRemainderPrediate
228
+ throwRemainder (map fst xs) satRes remainderPrediate
235
229
satRes@ SMT. IsUnknown {} -> do
236
230
-- solver cannot solve the remainder
237
231
-- TODO descend into the remainder branch anyway
238
- throwRemainder (map fst xs) satRes groupRemainderPrediate
232
+ throwRemainder (map fst xs) satRes remainderPrediate
239
233
240
234
labelOf = fromMaybe " " . (. ruleLabel) . (. attributes)
241
235
ruleLabelOrLocT = renderOneLineText . ruleLabelOrLoc
@@ -253,6 +247,14 @@ rewriteStep cutLabels terminalLabels pat = do
253
247
)
254
248
leafs
255
249
250
+ -- check the remainder predicate for satisfiablity. Do nothing if unsat, abort rewriting otherwise
251
+ assertRemainderUnsat ::
252
+ LoggerMIO io => [RewriteRule " Rewrite" ] -> Set. Set Predicate -> RewriteT io ()
253
+ assertRemainderUnsat rules remainderPrediate =
254
+ isSatRemainder remainderPrediate >>= \ case
255
+ SMT. IsUnsat -> pure ()
256
+ otherSatRes -> throwRemainder rules otherSatRes remainderPrediate
257
+
256
258
-- check the remainder predicate for satisfiability under the pre-branch pattern's constraints
257
259
isSatRemainder :: LoggerMIO io => Set. Set Predicate -> RewriteT io (SMT. IsSatResult () )
258
260
isSatRemainder remainderPredicate =
@@ -262,7 +264,7 @@ rewriteStep cutLabels terminalLabels pat = do
262
264
solver <- getSolver
263
265
SMT. isSat solver (Set. toList $ pat. constraints <> remainderPredicate) pat. substitution
264
266
265
- -- abort rewriting by throwing a remainder predicate as an exception, to be caught and processed in @ performRewrite@
267
+ -- abort rewriting by throwing a remainder predicate as an exception, to be caught and processed in performRewrite
266
268
throwRemainder ::
267
269
LoggerMIO io => [RewriteRule " Rewrite" ] -> SMT. IsSatResult () -> Set. Set Predicate -> RewriteT io a
268
270
throwRemainder rules satResult remainderPredicate =
0 commit comments