@@ -1136,93 +1136,93 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
1136
1136
( AnswerMode :: Ambiguous , _) => true ,
1137
1137
}
1138
1138
} ;
1139
- // N.B. If we try to pursue a strand and it's found to be ambiguous,
1140
- // we know that isn't part of a cycle.
1141
1139
if forest. tables [ table]
1142
1140
. strands_mut ( )
1143
- . any ( |s| strand_is_participating ( s) )
1141
+ . all ( |s| ! strand_is_participating ( s) )
1144
1142
{
1145
- let clock = self . stack . top ( ) . clock ;
1146
- let cyclic_minimums = self . stack . top ( ) . cyclic_minimums ;
1147
- if cyclic_minimums. positive >= clock && cyclic_minimums. negative >= clock {
1148
- debug ! ( "cycle with no new answers" ) ;
1149
-
1150
- if cyclic_minimums. negative < TimeStamp :: MAX {
1151
- // This is a negative cycle.
1152
- self . unwind_stack ( ) ;
1153
- return Err ( RootSearchFail :: NegativeCycle ) ;
1143
+ // If no strands are participating, then that means they are all
1144
+ // ambiguous and we are in complete mode.
1145
+ debug ! ( "All strands would return ambiguous answers." ) ;
1146
+ match self . forest . tables [ table] . answer_mode {
1147
+ AnswerMode :: Complete => {
1148
+ debug ! ( "Allowing ambiguous answers." ) ;
1149
+ self . forest . tables [ table] . answer_mode = AnswerMode :: Ambiguous ;
1150
+ return Err ( RootSearchFail :: QuantumExceeded ) ;
1151
+ }
1152
+ AnswerMode :: Ambiguous => {
1153
+ unreachable ! ( ) ;
1154
1154
}
1155
+ }
1156
+ }
1155
1157
1156
- // If all the things that we recursively depend on have
1157
- // positive dependencies on things below us in the stack,
1158
- // then no more answers are forthcoming. We can clear all
1159
- // the strands for those things recursively.
1160
- let table = self . stack . top ( ) . table ;
1161
- let cyclic_strands =
1162
- self . forest . tables [ table] . drain_strands ( strand_is_participating) ;
1163
- self . clear_strands_after_cycle ( cyclic_strands) ;
1158
+ let clock = self . stack . top ( ) . clock ;
1159
+ let cyclic_minimums = self . stack . top ( ) . cyclic_minimums ;
1160
+ if cyclic_minimums. positive >= clock && cyclic_minimums. negative >= clock {
1161
+ debug ! ( "cycle with no new answers" ) ;
1164
1162
1165
- // Now we yield with `QuantumExceeded`
1163
+ if cyclic_minimums. negative < TimeStamp :: MAX {
1164
+ // This is a negative cycle.
1166
1165
self . unwind_stack ( ) ;
1167
- return Err ( RootSearchFail :: QuantumExceeded ) ;
1168
- } else {
1169
- debug ! ( "table part of a cycle" ) ;
1166
+ return Err ( RootSearchFail :: NegativeCycle ) ;
1167
+ }
1170
1168
1171
- // This table resulted in a positive cycle, so we have
1172
- // to check what this means for the subgoal containing
1173
- // this strand
1174
- let caller_strand = match self . stack . pop_and_borrow_caller_strand ( ) {
1175
- Some ( s ) => s ,
1176
- None => {
1177
- panic ! ( "nothing on the stack but cyclic result" ) ;
1178
- }
1179
- } ;
1169
+ // If all the things that we recursively depend on have
1170
+ // positive dependencies on things below us in the stack,
1171
+ // then no more answers are forthcoming. We can clear all
1172
+ // the strands for those things recursively.
1173
+ let table = self . stack . top ( ) . table ;
1174
+ // N.B. If we try to pursue a strand and it's found to be ambiguous,
1175
+ // we know that isn't part of a cycle.
1176
+ let cyclic_strands = self . forest . tables [ table ] . drain_strands ( strand_is_participating ) ;
1177
+ self . clear_strands_after_cycle ( cyclic_strands ) ;
1180
1178
1181
- // We can't take this because we might need it later to clear the cycle
1182
- let caller_selected_subgoal = caller_strand. selected_subgoal . as_ref ( ) . unwrap ( ) ;
1183
- match caller_strand. ex_clause . subgoals [ caller_selected_subgoal. subgoal_index ] {
1184
- Literal :: Positive ( _) => {
1185
- self . stack
1186
- . top ( )
1187
- . cyclic_minimums
1188
- . take_minimums ( & cyclic_minimums) ;
1189
- }
1190
- Literal :: Negative ( _) => {
1191
- // We depend on `not(subgoal)`. For us to continue,
1192
- // `subgoal` must be completely evaluated. Therefore,
1193
- // we depend (negatively) on the minimum link of
1194
- // `subgoal` as a whole -- it doesn't matter whether
1195
- // it's pos or neg.
1196
- let mins = Minimums {
1197
- positive : self . stack . top ( ) . clock ,
1198
- negative : cyclic_minimums. minimum_of_pos_and_neg ( ) ,
1199
- } ;
1200
- self . stack . top ( ) . cyclic_minimums . take_minimums ( & mins) ;
1201
- }
1202
- }
1179
+ // Now we yield with `QuantumExceeded`
1180
+ self . unwind_stack ( ) ;
1181
+ return Err ( RootSearchFail :: QuantumExceeded ) ;
1182
+ } else {
1183
+ debug ! ( "table part of a cycle" ) ;
1203
1184
1204
- // We can't pursue this strand anymore, so push it back onto the table
1205
- let active_strand = self . stack . top ( ) . active_strand . take ( ) . unwrap ( ) ;
1206
- let table = self . stack . top ( ) . table ;
1207
- let canonical_active_strand =
1208
- Forest :: canonicalize_strand ( self . context , active_strand) ;
1209
- self . forest . tables [ table] . enqueue_strand ( canonical_active_strand) ;
1185
+ // This table resulted in a positive cycle, so we have
1186
+ // to check what this means for the subgoal containing
1187
+ // this strand
1188
+ let caller_strand = match self . stack . pop_and_borrow_caller_strand ( ) {
1189
+ Some ( s) => s,
1190
+ None => {
1191
+ panic ! ( "nothing on the stack but cyclic result" ) ;
1192
+ }
1193
+ } ;
1210
1194
1211
- // The strand isn't active, but the table is, so just continue
1212
- return Ok ( ( ) ) ;
1195
+ // We can't take this because we might need it later to clear the cycle
1196
+ let caller_selected_subgoal = caller_strand. selected_subgoal . as_ref ( ) . unwrap ( ) ;
1197
+ match caller_strand. ex_clause . subgoals [ caller_selected_subgoal. subgoal_index ] {
1198
+ Literal :: Positive ( _) => {
1199
+ self . stack
1200
+ . top ( )
1201
+ . cyclic_minimums
1202
+ . take_minimums ( & cyclic_minimums) ;
1203
+ }
1204
+ Literal :: Negative ( _) => {
1205
+ // We depend on `not(subgoal)`. For us to continue,
1206
+ // `subgoal` must be completely evaluated. Therefore,
1207
+ // we depend (negatively) on the minimum link of
1208
+ // `subgoal` as a whole -- it doesn't matter whether
1209
+ // it's pos or neg.
1210
+ let mins = Minimums {
1211
+ positive : self . stack . top ( ) . clock ,
1212
+ negative : cyclic_minimums. minimum_of_pos_and_neg ( ) ,
1213
+ } ;
1214
+ self . stack . top ( ) . cyclic_minimums . take_minimums ( & mins) ;
1215
+ }
1213
1216
}
1214
- }
1215
1217
1216
- debug ! ( "All strands would return ambiguous answers." ) ;
1217
- match self . forest . tables [ table] . answer_mode {
1218
- AnswerMode :: Complete => {
1219
- debug ! ( "Allowing ambiguous answers." ) ;
1220
- self . forest . tables [ table] . answer_mode = AnswerMode :: Ambiguous ;
1221
- return Err ( RootSearchFail :: QuantumExceeded ) ;
1222
- }
1223
- AnswerMode :: Ambiguous => {
1224
- panic ! ( ) ;
1225
- }
1218
+ // We can't pursue this strand anymore, so push it back onto the table
1219
+ let active_strand = self . stack . top ( ) . active_strand . take ( ) . unwrap ( ) ;
1220
+ let table = self . stack . top ( ) . table ;
1221
+ let canonical_active_strand = Forest :: canonicalize_strand ( self . context , active_strand) ;
1222
+ self . forest . tables [ table] . enqueue_strand ( canonical_active_strand) ;
1223
+
1224
+ // The strand isn't active, but the table is, so just continue
1225
+ return Ok ( ( ) ) ;
1226
1226
}
1227
1227
}
1228
1228
0 commit comments