record all adjustments, even those without alternatives
Matt S Trout [Mon, 13 Feb 2017 21:20:38 +0000 (21:20 +0000)]
lib/DX/SearchProcess.pm
lib/DX/SearchState.pm
lib/DX/Step/Backtrack.pm
lib/DX/Step/ResolveProposition.pm

index 4e44db1..e2ec2d5 100644 (file)
@@ -37,7 +37,9 @@ sub find_solution {
 sub force_backtrack {
   my ($self) = @_;
   my $new_ss = $self->current_search_state->force_backtrack;
-  return undef unless $new_ss;
+  # XXX infinite loop without the next line and I'm unsure why we don't
+  # get a loop-ending undef from elsewhere if the backtrack failed
+  return undef unless $new_ss->next_step;
   return $self->but(current_search_state => $new_ss);
 }
 
index eea032c..0a306c9 100644 (file)
@@ -57,8 +57,6 @@ sub with_one_step {
 
 sub force_backtrack {
   my ($self) = @_;
-  my ($first_alt, @rest_alt) = @{$self->adjustments_made};
-  return undef unless $first_alt;
   return $self->but(
     next_step => DX::Step::Backtrack->new,
   )->with_one_step;
index f145351..047b693 100644 (file)
@@ -6,9 +6,13 @@ with 'DX::Role::Step';
 
 sub apply_to {
   my ($self, $ss) = @_;
-  my ($first_alt, @rest_alt) = @{$ss->adjustments_made};
-  return $ss->but(next_step => $ss->on_exhaustion_step) unless $first_alt;
-  return $first_alt->[1]->but(next_step => $first_alt->[0]->alternative_step);
+  foreach my $adj (@{$ss->adjustments_made}) {
+    my ($step_was, $ss_was) = @$adj;
+    if (my $alt = $step_was->alternative_step) {
+      return $ss_was->but(next_step => $alt);
+    }
+  }
+  return $ss->but(next_step => $ss->on_exhaustion_step);
 }
 
 1;
index d738ac1..6f91b9b 100644 (file)
@@ -55,7 +55,7 @@ sub apply_to {
   my $alt_step = $self->alternative_step;
   my $ss = $old_ss->but(
     next_step => $ns,
-    ($alt_step
+    (@{$self->actions}
       ? (adjustments_made => [
           [ $self, $old_ss ],
           @{$old_ss->adjustments_made}