VulK wrote: > Dear All, > in a ticket (#21254) I recently created with Dylan Rupel I need to explore a > (possibly) infinite n-regular tree in a breath-first search.
Breath-first search = Search & pray? ;-) (Possibly infinite apnoea can't be healthy.) > The way it is > implemented right now is via iterators. I am writing to you to ask if there > is a preferred way to deal with user interaction and KeyboardInterrupt. > > At the moment the init function of :class:`ClusterAlgebra` calls > :meth:`reset_exploring_iterator` that creates an instance of :meth:`seeds` and > stores it in an internal var ``_sd_iter``. The methods that need to explore > the tree just call ``next`` on this iterator till they get the data they are > looking for. This process is potentially never ending. For this reason the > user may specify a maximum depth at which to stop. > > Since this iterator is computationally intense, it easy to imagine that > users will tend to start searching but change their mind in mid computation > and send an interrupt. This, unfortunately, leaves ``_sd_iter`` in a > corrupted state and all future calls to it will result in a StopIteration. > > At the moment we have a warning in the docstring of each method accessing > _sd_iter to explain that after sending a KeyboardInterrupt the user needs to > call :meth:`reset_exploring_iterator`. Do you think we should instead catch > the interrupt, reset the iterator and then raise it again like this? > > > @@ -1999,12 +1999,17 @@ class ClusterAlgebra(Parent): > sage: len(A.g_vectors_so_far()) > 14 > """ > - while self._explored_depth <= depth: > - try: > - seed = next(self._sd_iter) > - self._explored_depth = seed.depth() > - except StopIteration: > - break > + try: > + while self._explored_depth <= depth: > + try: > + seed = next(self._sd_iter) > + self._explored_depth = seed.depth() > + except StopIteration: > + break > + except KeyboardInterrupt: > + print("Got a KeyboardInterrupt, cleaning up before returning.") > + self.reset_exploring_iterator() > + raise KeyboardInterrupt > > The advantage of this is that the user does not have to remember an extra > (unnatural?) step. The drawback is that he/she looses any customization that > may have been made by a previous call to :meth:`reset_exploring_iterator`. > > > On a related topic. In the situation just described, the next exploration > will have to begin from the root of the tree resulting in a lot of wasted > effort. Is there any way around this? Sending a node of the tree back to the > iterator does not seem useful because of the breath-first search. Well, one usually implements checkpoints for such things (continually saving state to optionally resume later if interrupted). -leif -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at https://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/d/optout.