code: def solve_step(self):
          
          self.solve_begun = True
          if self.status != SolverStatus.unsolved:
              return
  
          if self.pr:
              self.pr.header("SOLVE #%d (%d fails so far)...",
                             self.solve_count + 1, self.num_fails)
  
          phase = self._pop_phase()
  
          if phase.status == SolverStatus.failed:  # a previously failed phase
              self.pr("discarded failed phase, fetching previous unsolved phase...")
              self.failed_phase_list.append(phase)
              phase = self._pop_phase()
  
          if phase.status == SolverStatus.exhausted:
              self.pr.subheader("SPLITTING:")
              phase, next_phase = phase.split()
              self._push_phase(next_phase)
              if self.pr:
                  self.pr("new phase: %s", phase)
  
          new_phase = phase.solve()
          self.solve_count += 1
  
          if new_phase.status == SolverStatus.failed:
              self.pr.subheader("FAILED:")
              self._push_phase(new_phase)
              if self.pr and len(self.phase_stack) == 1:
                  self.pr.header("FAIL: there is no solution")
  
          elif new_phase.status == SolverStatus.solved:
              # solved, but there may be cyclic dependencies
              self.pr.subheader("SOLVED:")
              final_phase = new_phase.finalise()
              self._push_phase(final_phase)
  
              if self.pr:
                  if final_phase.status == SolverStatus.cyclic:
                      self.pr.header("FAIL: a cycle was detected")
                  else:
                      self.pr.header("SUCCESS")
  
          else:
              self.pr.subheader("EXHAUSTED:")
              assert(new_phase.status == SolverStatus.exhausted)
              self._push_phase(new_phase)
docs: Perform a single solve step.