fn complete_pop(
        &mut self,
        completed_goal_depth: StackIndex,
        minimums: &mut Minimums,
    ) -> ExplorationResult {
        debug!(
            "complete_pop(completed_goal_depth={:?}, minimums={:?}",
            completed_goal_depth,
            minimums
        );

        let completed_dfn = self.stack[completed_goal_depth].dfn;
        let popped_goals = self.stack.pop_until(completed_goal_depth);
        let mut new_clauses = vec![];
        for popped_goal in popped_goals.into_iter().rev() {
            let StackEntry {
                table: popped_table,
                link: popped_link,
                ..
            } = popped_goal;

            // None of the goals we pop should depend on anything
            // below the completed goal on the stack.
            assert!(
                popped_link.positive >= completed_dfn,
                "popped table {:?} with position link {:?} where completed_dfn = {:?}",
                popped_table,
                popped_link.positive,
                completed_dfn
            );

            // None of the popped goals should have negative dependencies.
            assert!(
                popped_link.negative == DepthFirstNumber::MAX,
                "popped table {:?} with negative link {:?} where completed_dfn = {:?}",
                popped_table,
                popped_link.negative,
                completed_dfn
            );

            // Take the list of negative goals. We will be updating those.
            let negatives = self.tables[popped_table].mark_complete();

            if self.tables[popped_table].is_not_satisfiable() {
                // If the set of answers is EMPTY, then this goal has
                // definitely FAILED. We can therefore go through the
                // list of clauses blocked negatively on this popped goal
                // and let them proceed.
                let unblocked = negatives.into_iter().map(|pending| {
                    let PendingExClause {
                        goal_depth,
                        subst,
                        selected_goal,
                        delayed_literals,
                        constraints,
                        subgoals,
                    } = self.infer.instantiate_canonical(&pending);
                    mem::drop(selected_goal); // don't need it
                    (
                        goal_depth,
                        ExClause {
                            subst,
                            delayed_literals,
                            constraints,
                            subgoals,
                        },
                    )
                });
                new_clauses.extend(unblocked);
            } else if self.tables[popped_table].is_satisfiable() {
                // We have a definitive answer. We can just
                // abandon the list of negative clauses then,
                // since they are all failed paths.
                //
                // DIVERGENCE: If we introduced subgoal abstraction
                // along negative paths,
            } else {
                // Otherwise, if we do not have a *definitive*
                // answer, then it is not yet known whether this
                // goal has succeeded or failed.  We must therefore
                // go through the list of clauses blocked
                // negatively on this popped goal and convert them
                // into DELAYED clauses.
                let delayed = Self::delay_negatives(&mut self.infer, popped_table, negatives);
                new_clauses.extend(delayed);
            }
        }

        *minimums = Minimums {
            positive: DepthFirstNumber::MAX,
            negative: DepthFirstNumber::MAX,
        };
        for (goal_depth, ex_clause) in new_clauses {
            self.new_clause(goal_depth, ex_clause, minimums)?;
        }
        Ok(FullyExplored)
    }
/// Code to cover the sub-case of `complete` in which all of the
/// goals that we depend upon lie atop us in the stack. Since all
/// of *them* are completely evaluated, we are done. For example,
/// imagine that we have this prolog program:
///
/// ```notrust
/// s :- p.
/// p :- s.
/// ```
///
/// We would first push `s` onto the stack of goals with DFN 0,
/// then `p` with DFN 1. When we finish exploring `p`, we would
/// invoke `complete`, but it would have a *positive link* on
/// `s`. This means that the `link.positive` for `q` would be
/// 0, which is higher than `q`'s DFN of 1. Therefore, we would do nothing.
/// But then we would invoke `complete` on `s` -- and the link for `s` is 0
/// as is its DFN. In that case, this `if` is true.
Code to cover the sub-case of `complete` in which all of the
goals that we depend upon lie atop us in the stack. Since all
of *them* are completely evaluated, we are done. For example,
imagine that we have this prolog program.



We would first push `s` onto the stack of goals with DFN 0,
then `p` with DFN 1.
Code to cover the sub - case of ` complete ` in which all of the goals that we depend upon lie atop us in the stack . Since all of * them * are completely evaluated we are done . For example imagine that we have this prolog program . We would first push ` s ` onto the stack of goals with DFN 0 then ` p ` with DFN 1 .
fn complete_pop(
        &mut self,
        completed_goal_depth: StackIndex,
        minimums: &mut Minimums,
    ) -> ExplorationResult {
        debug!(
            "complete_pop(completed_goal_depth={:?}, minimums={:?}",
            completed_goal_depth,
            minimums
        );
        let completed_dfn = self.stack[completed_goal_depth].dfn;
        let popped_goals = self.stack.pop_until(completed_goal_depth);
        let mut new_clauses = vec![];
        for popped_goal in popped_goals.into_iter().rev() {
            let StackEntry {
                table: popped_table,
                link: popped_link,
                ..
            } = popped_goal;
            // None of the goals we pop should depend on anything
            // below the completed goal on the stack.
            assert!(
                popped_link.positive >= completed_dfn,
                "popped table {:?} with position link {:?} where completed_dfn = {:?}",
                popped_table,
                popped_link.positive,
                completed_dfn
            );
            // None of the popped goals should have negative dependencies.
            assert!(
                popped_link.negative == DepthFirstNumber::MAX,
                "popped table {:?} with negative link {:?} where completed_dfn = {:?}",
                popped_table,
                popped_link.negative,
                completed_dfn
            );
            // Take the list of negative goals. We will be updating those.
            let negatives = self.tables[popped_table].mark_complete();
            if self.tables[popped_table].is_not_satisfiable() {
                // If the set of answers is EMPTY, then this goal has
                // definitely FAILED. We can therefore go through the
                // list of clauses blocked negatively on this popped goal
                // and let them proceed.
                let unblocked = negatives.into_iter().map(|pending| {
                    let PendingExClause {
                        goal_depth,
                        subst,
                        selected_goal,
                        delayed_literals,
                        constraints,
                        subgoals,
                    } = self.infer.instantiate_canonical(&pending);
                    mem::drop(selected_goal); // don't need it
                    (
                        goal_depth,
                        ExClause {
                            subst,
                            delayed_literals,
                            constraints,
                            subgoals,
                        },
                    )
                });
                new_clauses.extend(unblocked);
            } else if self.tables[popped_table].is_satisfiable() {
                // We have a definitive answer. We can just
                // abandon the list of negative clauses then,
                // since they are all failed paths.
                //
                // DIVERGENCE: If we introduced subgoal abstraction
                // along negative paths,
            } else {
                // Otherwise, if we do not have a *definitive*
                // answer, then it is not yet known whether this
                // goal has succeeded or failed.  We must therefore
                // go through the list of clauses blocked
                // negatively on this popped goal and convert them
                // into DELAYED clauses.
                let delayed = Self::delay_negatives(&mut self.infer, popped_table, negatives);
                new_clauses.extend(delayed);
            }
        }
        *minimums = Minimums {
            positive: DepthFirstNumber::MAX,
            negative: DepthFirstNumber::MAX,
        };
        for (goal_depth, ex_clause) in new_clauses {
            self.new_clause(goal_depth, ex_clause, minimums)?;
        }
        Ok(FullyExplored)
    }
fn complete_pop ( & mut self , completed_goal_depth : StackIndex , minimums : & mut Minimums , ) -> ExplorationResult { debug ! ( " " completed_goal_depth minimums ) ; let completed_dfn = self . stack [ completed_goal_depth ] . dfn ; let popped_goals = self . stack . pop_until ( completed_goal_depth ) ; let mut new_clauses = vec ! [ ] ; for popped_goal in popped_goals . into_iter ( ) . rev ( ) { let StackEntry { table : popped_table , link : popped_link , .. } = popped_goal ; // None of the goals we pop should depend on anything // below the completed goal on the stack. assert ! ( popped_link positive completed_dfn " " popped_table popped_link positive completed_dfn ) ; // None of the popped goals should have negative dependencies. assert ! ( popped_link negative DepthFirstNumber MAX " " popped_table popped_link negative completed_dfn ) ; // Take the list of negative goals. We will be updating those. let negatives = self . tables [ popped_table ] . mark_complete ( ) ; if self . tables [ popped_table ] . is_not_satisfiable ( ) { // If the set of answers is EMPTY, then this goal has // definitely FAILED. We can therefore go through the // list of clauses blocked negatively on this popped goal // and let them proceed. let unblocked = negatives . into_iter ( ) . map ( | pending | { let PendingExClause { goal_depth , subst , selected_goal , delayed_literals , constraints , subgoals , } = self . infer . instantiate_canonical ( & pending ) ; mem :: drop ( selected_goal ) ; // don't need it ( goal_depth , ExClause { subst , delayed_literals , constraints , subgoals , } , ) } ) ; new_clauses . extend ( unblocked ) ; } else if self . tables [ popped_table ] . is_satisfiable ( ) { // We have a definitive answer. We can just // abandon the list of negative clauses then, // since they are all failed paths. // // DIVERGENCE: If we introduced subgoal abstraction // along negative paths, } else { // Otherwise, if we do not have a *definitive* // answer, then it is not yet known whether this // goal has succeeded or failed.  We must therefore // go through the list of clauses blocked // negatively on this popped goal and convert them // into DELAYED clauses. let delayed = Self :: delay_negatives ( & mut self . infer , popped_table , negatives ) ; new_clauses . extend ( delayed ) ; } } * minimums = Minimums { positive : DepthFirstNumber :: MAX , negative : DepthFirstNumber :: MAX , } ; for ( goal_depth , ex_clause ) in new_clauses { self . new_clause ( goal_depth , ex_clause , minimums ) ? ; } Ok ( FullyExplored ) }
Code to cover the sub-case of `complete` in which all of the
goals that we depend upon lie atop us in the stack.
Code to cover the sub - case of ` complete ` in which all of the goals that we depend upon lie atop us in the stack .
&mut self
completed_goal_depth
StackIndex
minimums
&mut Minimums