fn pursue_positive_subgoal(
        &mut self,
        depth: StackIndex,
        mut strand: Strand<'_, C, impl Context>,
        selected_subgoal: &SelectedSubgoal<C>,
    ) -> StrandResult<C, ()> {
        let table = self.stack[depth].table;
        let SelectedSubgoal {
            subgoal_index,
            subgoal_table,
            answer_index,
            ref universe_map,
        } = *selected_subgoal;

        match self.ensure_answer_recursively(subgoal_table, answer_index) {
            Ok(EnsureSuccess::AnswerAvailable) => {
                // The given answer is available; we'll process it below.
            }
            Ok(EnsureSuccess::Coinductive) => {
                // This is a co-inductive cycle. That is, this table
                // appears somewhere higher on the stack, and has now
                // recursively requested an answer for itself. That
                // means that our subgoal is unconditionally true, so
                // we can drop it and pursue the next thing.
                assert!(
                    self.tables[table].coinductive_goal
                        && self.tables[subgoal_table].coinductive_goal
                );
                let Strand {
                    infer,
                    mut ex_clause,
                    selected_subgoal: _,
                } = strand;
                ex_clause.subgoals.remove(subgoal_index);
                return self.pursue_strand_recursively(
                    depth,
                    Strand {
                        infer,
                        ex_clause,
                        selected_subgoal: None,
                    },
                );
            }
            Err(RecursiveSearchFail::NoMoreSolutions) => {
                info!("pursue_positive_subgoal: no more solutions");
                return Err(StrandFail::NoSolution);
            }
            Err(RecursiveSearchFail::QuantumExceeded) => {
                // We'll have to revisit this strand later
                info!("pursue_positive_subgoal: quantum exceeded");
                self.tables[table].push_strand(Self::canonicalize_strand(strand));
                return Err(StrandFail::QuantumExceeded);
            }
            Err(RecursiveSearchFail::Cycle(minimums)) => {
                info!(
                    "pursue_positive_subgoal: cycle with minimums {:?}",
                    minimums
                );
                let canonical_strand = Self::canonicalize_strand(strand);
                return Err(StrandFail::Cycle(canonical_strand, minimums));
            }
        }

        // Whichever way this particular answer turns out, there may
        // yet be *more* answers. Enqueue that alternative for later.
        self.push_strand_pursuing_next_answer(depth, &mut strand, selected_subgoal);

        // OK, let's follow *this* answer and see where it leads.
        let Strand {
            infer,
            mut ex_clause,
            selected_subgoal: _,
        } = strand;
        let subgoal = match ex_clause.subgoals.remove(subgoal_index) {
            Literal::Positive(g) => g,
            Literal::Negative(g) => panic!(
                "pursue_positive_subgoal invoked with negative selected literal: {:?}",
                g
            ),
        };

        let table_goal = &CO::map_goal_from_canonical(&universe_map,
                                                     &CO::canonical(&self.tables[subgoal_table].table_goal));
        let answer_subst =
            &CO::map_subst_from_canonical(&universe_map, &self.answer(subgoal_table, answer_index).subst);
        match infer.apply_answer_subst(ex_clause, &subgoal, table_goal, answer_subst) {
            Ok(mut ex_clause) => {
                // If the answer had delayed literals, we have to
                // ensure that `ex_clause` is also delayed. This is
                // the SLG FACTOR operation, though NFTD just makes it
                // part of computing the SLG resolvent.
                {
                    let answer = self.answer(subgoal_table, answer_index);
                    if !answer.delayed_literals.is_empty() {
                        ex_clause.delayed_literals.push(DelayedLiteral::Positive(
                            subgoal_table,
                            infer.sink_answer_subset(&answer.subst),
                        ));
                    }
                }

                // Apply answer abstraction.
                let ex_clause = self.truncate_returned(ex_clause, &mut *infer);

                self.pursue_strand_recursively(
                    depth,
                    Strand {
                        infer,
                        ex_clause,
                        selected_subgoal: None,
                    },
                )
            }

            // This answer led nowhere. Give up for now, but of course
            // there may still be other strands to pursue, so return
            // `QuantumExceeded`.
            Err(NoSolution) => {
                info!("pursue_positive_subgoal: answer not unifiable -> NoSolution");
                Err(StrandFail::NoSolution)
            }
        }
    }
/// Invoked when we have selected a positive literal, created its
/// table, and selected a particular answer index N we are looking
/// for. Searches for that answer. If we find one, we can do two things:
///
/// - create a new strand with the same selected subgoal, but searching for the
///   answer with index N+1
/// - use the answer to resolve our selected literal and select the next subgoal
///   in this strand to pursue
///
/// When an answer is found, that corresponds to *Positive Return*
/// from the NFTD paper.
Invoked when we have selected a positive literal, created its
table, and selected a particular answer index N we are looking
for. Searches for that answer. If we find one, we can do two things.

create a new strand with the same selected subgoal, but searching for the
answer with index N+1
use the answer to resolve our selected literal and select the next subgoal
in this strand to pursue

When an answer is found, that corresponds to *Positive Return
from the NFTD paper.
Invoked when we have selected a positive literal created its table and selected a particular answer index N we are looking for . Searches for that answer . If we find one we can do two things . create a new strand with the same selected subgoal but searching for the answer with index N + 1 use the answer to resolve our selected literal and select the next subgoal in this strand to pursue When an answer is found that corresponds to * Positive Return from the NFTD paper .
fn pursue_positive_subgoal(
        &mut self,
        depth: StackIndex,
        mut strand: Strand<'_, C, impl Context>,
        selected_subgoal: &SelectedSubgoal<C>,
    ) -> StrandResult<C, ()> {
        let table = self.stack[depth].table;
        let SelectedSubgoal {
            subgoal_index,
            subgoal_table,
            answer_index,
            ref universe_map,
        } = *selected_subgoal;
        match self.ensure_answer_recursively(subgoal_table, answer_index) {
            Ok(EnsureSuccess::AnswerAvailable) => {
                // The given answer is available; we'll process it below.
            }
            Ok(EnsureSuccess::Coinductive) => {
                // This is a co-inductive cycle. That is, this table
                // appears somewhere higher on the stack, and has now
                // recursively requested an answer for itself. That
                // means that our subgoal is unconditionally true, so
                // we can drop it and pursue the next thing.
                assert!(
                    self.tables[table].coinductive_goal
                        && self.tables[subgoal_table].coinductive_goal
                );
                let Strand {
                    infer,
                    mut ex_clause,
                    selected_subgoal: _,
                } = strand;
                ex_clause.subgoals.remove(subgoal_index);
                return self.pursue_strand_recursively(
                    depth,
                    Strand {
                        infer,
                        ex_clause,
                        selected_subgoal: None,
                    },
                );
            }
            Err(RecursiveSearchFail::NoMoreSolutions) => {
                info!("pursue_positive_subgoal: no more solutions");
                return Err(StrandFail::NoSolution);
            }
            Err(RecursiveSearchFail::QuantumExceeded) => {
                // We'll have to revisit this strand later
                info!("pursue_positive_subgoal: quantum exceeded");
                self.tables[table].push_strand(Self::canonicalize_strand(strand));
                return Err(StrandFail::QuantumExceeded);
            }
            Err(RecursiveSearchFail::Cycle(minimums)) => {
                info!(
                    "pursue_positive_subgoal: cycle with minimums {:?}",
                    minimums
                );
                let canonical_strand = Self::canonicalize_strand(strand);
                return Err(StrandFail::Cycle(canonical_strand, minimums));
            }
        }
        // Whichever way this particular answer turns out, there may
        // yet be *more* answers. Enqueue that alternative for later.
        self.push_strand_pursuing_next_answer(depth, &mut strand, selected_subgoal);
        // OK, let's follow *this* answer and see where it leads.
        let Strand {
            infer,
            mut ex_clause,
            selected_subgoal: _,
        } = strand;
        let subgoal = match ex_clause.subgoals.remove(subgoal_index) {
            Literal::Positive(g) => g,
            Literal::Negative(g) => panic!(
                "pursue_positive_subgoal invoked with negative selected literal: {:?}",
                g
            ),
        };
        let table_goal = &CO::map_goal_from_canonical(&universe_map,
                                                     &CO::canonical(&self.tables[subgoal_table].table_goal));
        let answer_subst =
            &CO::map_subst_from_canonical(&universe_map, &self.answer(subgoal_table, answer_index).subst);
        match infer.apply_answer_subst(ex_clause, &subgoal, table_goal, answer_subst) {
            Ok(mut ex_clause) => {
                // If the answer had delayed literals, we have to
                // ensure that `ex_clause` is also delayed. This is
                // the SLG FACTOR operation, though NFTD just makes it
                // part of computing the SLG resolvent.
                {
                    let answer = self.answer(subgoal_table, answer_index);
                    if !answer.delayed_literals.is_empty() {
                        ex_clause.delayed_literals.push(DelayedLiteral::Positive(
                            subgoal_table,
                            infer.sink_answer_subset(&answer.subst),
                        ));
                    }
                }
                // Apply answer abstraction.
                let ex_clause = self.truncate_returned(ex_clause, &mut *infer);
                self.pursue_strand_recursively(
                    depth,
                    Strand {
                        infer,
                        ex_clause,
                        selected_subgoal: None,
                    },
                )
            }
            // This answer led nowhere. Give up for now, but of course
            // there may still be other strands to pursue, so return
            // `QuantumExceeded`.
            Err(NoSolution) => {
                info!("pursue_positive_subgoal: answer not unifiable -> NoSolution");
                Err(StrandFail::NoSolution)
            }
        }
    }
fn pursue_positive_subgoal ( & mut self , depth : StackIndex , mut strand : Strand < ' _ , C , impl Context > , selected_subgoal : & SelectedSubgoal < C > , ) -> StrandResult < C , ( ) > { let table = self . stack [ depth ] . table ; let SelectedSubgoal { subgoal_index , subgoal_table , answer_index , ref universe_map , } = * selected_subgoal ; match self . ensure_answer_recursively ( subgoal_table , answer_index ) { Ok ( EnsureSuccess :: AnswerAvailable ) => { // The given answer is available; we'll process it below. } Ok ( EnsureSuccess :: Coinductive ) => { // This is a co-inductive cycle. That is, this table // appears somewhere higher on the stack, and has now // recursively requested an answer for itself. That // means that our subgoal is unconditionally true, so // we can drop it and pursue the next thing. assert ! ( self tables [ table ] coinductive_goal self tables [ subgoal_table ] coinductive_goal ) ; let Strand { infer , mut ex_clause , selected_subgoal : _ , } = strand ; ex_clause . subgoals . remove ( subgoal_index ) ; return self . pursue_strand_recursively ( depth , Strand { infer , ex_clause , selected_subgoal : None , } , ) ; } Err ( RecursiveSearchFail :: NoMoreSolutions ) => { info ! ( " " ) ; return Err ( StrandFail :: NoSolution ) ; } Err ( RecursiveSearchFail :: QuantumExceeded ) => { // We'll have to revisit this strand later info ! ( " " ) ; self . tables [ table ] . push_strand ( Self :: canonicalize_strand ( strand ) ) ; return Err ( StrandFail :: QuantumExceeded ) ; } Err ( RecursiveSearchFail :: Cycle ( minimums ) ) => { info ! ( " " minimums ) ; let canonical_strand = Self :: canonicalize_strand ( strand ) ; return Err ( StrandFail :: Cycle ( canonical_strand , minimums ) ) ; } } // Whichever way this particular answer turns out, there may // yet be *more* answers. Enqueue that alternative for later. self . push_strand_pursuing_next_answer ( depth , & mut strand , selected_subgoal ) ; // OK, let's follow *this* answer and see where it leads. let Strand { infer , mut ex_clause , selected_subgoal : _ , } = strand ; let subgoal = match ex_clause . subgoals . remove ( subgoal_index ) { Literal :: Positive ( g ) => g , Literal :: Negative ( g ) => panic ! ( " " g ) , } ; let table_goal = & CO :: map_goal_from_canonical ( & universe_map , & CO :: canonical ( & self . tables [ subgoal_table ] . table_goal ) ) ; let answer_subst = & CO :: map_subst_from_canonical ( & universe_map , & self . answer ( subgoal_table , answer_index ) . subst ) ; match infer . apply_answer_subst ( ex_clause , & subgoal , table_goal , answer_subst ) { Ok ( mut ex_clause ) => { // If the answer had delayed literals, we have to // ensure that `ex_clause` is also delayed. This is // the SLG FACTOR operation, though NFTD just makes it // part of computing the SLG resolvent. { let answer = self . answer ( subgoal_table , answer_index ) ; if ! answer . delayed_literals . is_empty ( ) { ex_clause . delayed_literals . push ( DelayedLiteral :: Positive ( subgoal_table , infer . sink_answer_subset ( & answer . subst ) , ) ) ; } } // Apply answer abstraction. let ex_clause = self . truncate_returned ( ex_clause , & mut * infer ) ; self . pursue_strand_recursively ( depth , Strand { infer , ex_clause , selected_subgoal : None , } , ) } // This answer led nowhere. Give up for now, but of course // there may still be other strands to pursue, so return // `QuantumExceeded`. Err ( NoSolution ) => { info ! ( " " ) ; Err ( StrandFail :: NoSolution ) } } }
Invoked when we have selected a positive literal, created its
table, and selected a particular answer index N we are looking
for.
Invoked when we have selected a positive literal created its table and selected a particular answer index N we are looking for .
&mut self
depth
StackIndex
strand
Strand<'_, C, impl Context>
selected_subgoal
&SelectedSubgoal<C>
&mut self
depth
StackIndex
strand
Strand<'_, C, impl Context>
selected_subgoal
&SelectedSubgoal<C>