move to on_solution_step concept
Matt S Trout [Sat, 25 Jun 2016 01:57:13 +0000 (01:57 +0000)]
lib/DX/SearchState.pm
lib/DX/Step/Backtrack.pm
lib/DX/Step/MarkAsSolution.pm [new file with mode: 0644]
lib/DX/Step/Normal.pm

index a19a416..0702168 100644 (file)
@@ -3,6 +3,7 @@ package DX::SearchState;
 use Types::Standard qw(Maybe);
 use DX::Step::Backtrack;
 use DX::Step::InvokeNextPredicate;
+use DX::Step::MarkAsSolution;
 use DX::Class;
 
 has current_hypothesis => (is => 'ro', isa => Hypothesis, required => 1);
@@ -17,6 +18,8 @@ has is_solution_state => (is => 'ro', required => 1);
 
 has on_exhaustion_step => (is => 'ro', required => 1);
 
+has on_solution_step => (is => 'ro', required => 1);
+
 sub next_proposition {
   my ($self, $hyp) = @_;
   $hyp ||= $self->current_hypothesis;
@@ -41,6 +44,7 @@ sub new_for {
       : ( is_solution_state => 1 )
     ),
     on_exhaustion_step => undef,
+    on_solution_step => DX::Step::MarkAsSolution->new,
   );
 }
 
index 3306fc3..f211c73 100644 (file)
@@ -13,6 +13,7 @@ sub apply_to {
     current_hypothesis => $first_alt->[0],
     alternatives => \@rest_alt,
     next_step => $first_alt->[1],
+    is_solution_step => 0,
   );
 }
 
diff --git a/lib/DX/Step/MarkAsSolution.pm b/lib/DX/Step/MarkAsSolution.pm
new file mode 100644 (file)
index 0000000..e2fc7e3
--- /dev/null
@@ -0,0 +1,15 @@
+package DX::Step::MarkAsSolution;
+
+use DX::Class;
+
+with 'DX::Role::Step';
+
+sub apply_to {
+  my ($self, $ss) = @_;
+  $ss->but(
+    is_solution_state => 1,
+    next_step => DX::Step::Backtrack->new
+  );
+}
+
+1;
index e314088..68aae3a 100644 (file)
@@ -32,9 +32,15 @@ sub apply_to {
   my $new_hyp = $self->_apply_to_hyp($old_hyp);
   return $ss->but(next_step => DX::Step::Backtrack->new) unless $new_hyp;
   trace 'step.apply.new_hyp '.$self => $new_hyp;
-  my $ns = DX::Step::InvokeNextPredicate->new(
-    proposition => $ss->next_proposition($new_hyp)
-  );
+  my $ns = do {
+    if (my $prop = $ss->next_proposition($new_hyp)) {
+      DX::Step::InvokeNextPredicate->new(
+        proposition => $prop
+      )
+    } else {
+      $ss->on_solution_step
+    }
+  };
   my $alt_step = $self->alternative_step;
   return (
     $ss->but(