@@ -1308,44 +1308,17 @@ impl<C: Context> Forest<C> {
1308
1308
/// abstraction function to yield the canonical form that will be
1309
1309
/// used to pick a table. Typically, this abstraction has no
1310
1310
/// effect, and hence we are simply returning the canonical form
1311
- /// of `subgoal`, but if the subgoal is getting too big, we may
1312
- /// truncate the goal to ensure termination.
1313
- ///
1314
- /// This technique is described in the SA paper.
1311
+ /// of `subgoal`; but if the subgoal is getting too big, we return
1312
+ /// `None`, which causes the subgoal to flounder.
1315
1313
fn abstract_positive_literal (
1316
1314
& mut self ,
1317
1315
infer : & mut dyn InferenceTable < C > ,
1318
1316
subgoal : & C :: GoalInEnvironment ,
1319
1317
) -> Option < ( C :: UCanonicalGoalInEnvironment , C :: UniverseMap ) > {
1320
- // Subgoal abstraction: Rather than looking up the table for
1321
- // `selected_goal` directly, first apply the truncation
1322
- // function. This may introduce fresh variables, making the
1323
- // goal that we are looking up more general, and forcing us to
1324
- // reuse an existing table. For example, if we had a selected
1325
- // goal of
1326
- //
1327
- // // Vec<Vec<Vec<Vec<i32>>>>: Sized
1328
- //
1329
- // we might now produce a truncated goal of
1330
- //
1331
- // // Vec<Vec<?T>>: Sized
1332
- //
1333
- // Obviously, the answer we are looking for -- if it exists -- will be
1334
- // found amongst the answers of this new, truncated goal.
1335
- //
1336
- // Subtle point: Note that the **selected goal** remains
1337
- // unchanged and will be carried over into the "pending
1338
- // clause" for the positive link on the new subgoal. This
1339
- // means that if our new, truncated subgoal produces
1340
- // irrelevant answers (e.g., `Vec<Vec<u32>>: Sized`), they
1341
- // will fail to unify with our selected goal, producing no
1342
- // resolvent.
1343
-
1344
- if infer. truncate_goal ( subgoal) . is_some ( ) {
1345
- return None ;
1318
+ match infer. truncate_goal ( subgoal) {
1319
+ Some ( _) => None ,
1320
+ None => Some ( infer. fully_canonicalize_goal ( subgoal) ) ,
1346
1321
}
1347
-
1348
- return Some ( infer. fully_canonicalize_goal ( subgoal) ) ;
1349
1322
}
1350
1323
1351
1324
/// Given a selected negative subgoal, the subgoal is "inverted"
@@ -1399,63 +1372,10 @@ impl<C: Context> Forest<C> {
1399
1372
// affect completeness when it comes to subgoal abstraction.
1400
1373
let inverted_subgoal = infer. invert_goal ( subgoal) ?;
1401
1374
1402
- // DIVERGENCE
1403
- //
1404
- // If the negative subgoal has grown so large that we would have
1405
- // to truncate it, we currently just abort the computation
1406
- // entirely. This is not necessary -- the SA paper makes no
1407
- // such distinction, for example, and applies truncation equally
1408
- // for positive/negative literals. However, there are some complications
1409
- // that arise that I do not wish to deal with right now.
1410
- //
1411
- // Let's work through an example to show you what I
1412
- // mean. Imagine we have this (negative) selected literal;
1413
- // hence `selected_subgoal` will just be the inner part:
1414
- //
1415
- // // not { Vec<Vec<Vec<Vec<i32>>>>: Sized }
1416
- // // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1417
- // // `selected_goal`
1418
- //
1419
- // (In this case, the `inverted_subgoal` would be the same,
1420
- // since there are no free universal variables.)
1421
- //
1422
- // If truncation **doesn't apply**, we would go and lookup the
1423
- // table for the selected goal (`Vec<Vec<..>>: Sized`) and see
1424
- // whether it has any answers. If it does, and they are
1425
- // definite, then this negative literal is false. We don't
1426
- // really care even how many answers there are and so forth
1427
- // (if the goal is ground, as in this case, there can be at
1428
- // most one definite answer, but if there are universals, then
1429
- // the inverted goal would have variables; even so, a single
1430
- // definite answer suffices to show that the `not { .. }` goal
1431
- // is false).
1432
- //
1433
- // Truncation muddies the water, because the table may
1434
- // generate answers that are not relevant to our original,
1435
- // untruncated literal. Suppose that we truncate the selected
1436
- // goal to:
1437
- //
1438
- // // Vec<Vec<T>: Sized
1439
- //
1440
- // Clearly this table will have some solutions that don't
1441
- // apply to us. e.g., `Vec<Vec<u32>>: Sized` is a solution to
1442
- // this table, but that doesn't imply that `not {
1443
- // Vec<Vec<Vec<..>>>: Sized }` is false.
1444
- //
1445
- // This can be made to work -- we carry along the original
1446
- // selected goal when we establish links between tables, and
1447
- // we could use that to screen the resulting answers. (There
1448
- // are some further complications around the fact that
1449
- // selected goal may contain universally quantified free
1450
- // variables that have been inverted, as discussed in the
1451
- // prior paragraph above.) I just didn't feel like dealing
1452
- // with it yet.
1453
-
1454
- if infer. truncate_goal ( & inverted_subgoal) . is_some ( ) {
1455
- return None ;
1375
+ match infer. truncate_goal ( & inverted_subgoal) {
1376
+ Some ( _) => None ,
1377
+ None => Some ( infer. fully_canonicalize_goal ( & inverted_subgoal) ) ,
1456
1378
}
1457
-
1458
- return Some ( infer. fully_canonicalize_goal ( & inverted_subgoal) ) ;
1459
1379
}
1460
1380
1461
1381
/// Removes the subgoal at `subgoal_index` from the strand's
0 commit comments