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);
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;
: ( is_solution_state => 1 )
),
on_exhaustion_step => undef,
+ on_solution_step => DX::Step::MarkAsSolution->new,
);
}
current_hypothesis => $first_alt->[0],
alternatives => \@rest_alt,
next_step => $first_alt->[1],
+ is_solution_step => 0,
);
}
--- /dev/null
+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;
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(