From: Matt S Trout Date: Sat, 23 Jul 2016 21:19:50 +0000 (+0000) Subject: tug firmly, and recursion pops out into iteration X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=7af7ed1e813a1fb1ee1818637ad92ce5d93453bc;p=scpubgit%2FDX.git tug firmly, and recursion pops out into iteration --- diff --git a/lib/DX/SearchState.pm b/lib/DX/SearchState.pm index 553b304..4715606 100644 --- a/lib/DX/SearchState.pm +++ b/lib/DX/SearchState.pm @@ -21,10 +21,10 @@ has on_exhaustion_step => (is => 'ro', isa => Maybe[Step], required => 1); has on_solution_step => (is => 'ro', isa => Maybe[Step], required => 1); sub next_proposition { - my ($self, $hyp) = @_; - $hyp ||= $self->current_hypothesis; + my ($self) = @_; + my $hyp = $self->current_hypothesis; $self->propositions->members->[ - $hyp->resolved_propositions->resolved_count + $hyp->resolved_propositions->resolved_count + 1 ]; } diff --git a/lib/DX/Step/EnterRecheck.pm b/lib/DX/Step/EnterRecheck.pm index 7134462..4d48553 100644 --- a/lib/DX/Step/EnterRecheck.pm +++ b/lib/DX/Step/EnterRecheck.pm @@ -1,6 +1,7 @@ package DX::Step::EnterRecheck; use DX::Step::CompleteRecheck; +use DX::Step::FailRecheck; use DX::Class; @@ -10,6 +11,8 @@ has proposition_list => (is => 'ro', required => 1); has on_completion_step => (is => 'ro', required => 1); +has on_failure_step => (is => 'ro', required => 1); + sub apply_to { my ($self, $old_ss) = @_; @@ -54,11 +57,13 @@ sub apply_to { proposition => $prop, ), is_solution_state => 0, - on_exhaustion_step => undef, on_solution_step => DX::Step::CompleteRecheck->new( resume_search_state => $old_ss->but(next_step => $next_step), was_recheck_for => $prop, ), + on_exhaustion_step => DX::Step::FailRecheck->new( + resume_search_state => $old_ss->but(next_step => $self->on_failure_step), + ), ); return $ss; diff --git a/lib/DX/Step/FailRecheck.pm b/lib/DX/Step/FailRecheck.pm new file mode 100644 index 0000000..f120f04 --- /dev/null +++ b/lib/DX/Step/FailRecheck.pm @@ -0,0 +1,14 @@ +package DX::Step::FailRecheck; + +use DX::Class; + +with 'DX::Role::Step'; + +has resume_search_state => (is => 'ro', required => 1); + +sub apply_to { + my ($self, $old_ss) = @_; + return $self->resume_search_state; +} + +1; diff --git a/lib/DX/Step/ResolveProposition.pm b/lib/DX/Step/ResolveProposition.pm index 95ed10d..cb236d8 100644 --- a/lib/DX/Step/ResolveProposition.pm +++ b/lib/DX/Step/ResolveProposition.pm @@ -1,6 +1,7 @@ package DX::Step::ResolveProposition; use DX::Step::EnterRecheck; +use DX::Step::Backtrack; use Types::Standard qw(ArrayRef); use DX::Utils qw(deparse); @@ -28,34 +29,30 @@ sub but_with_dependencies_on { } sub apply_to { - my ($self, $ss) = @_; - trace 'step.apply.old_hyp '.$self => $ss->current_hypothesis; - trace 'step.apply.actions '.$self => $self->actions; - my $new_ss = $self->_apply_to_ss($ss); - return $ss->but(next_step => DX::Step::Backtrack->new) unless $new_ss; - trace 'step.apply.new_hyp '.$self => $new_ss->current_hypothesis; + my ($self, $old_ss) = @_; my $ns = do { - if (my $prop = $new_ss->next_proposition) { + if (my $prop = $old_ss->next_proposition) { DX::Step::ConsiderProposition->new( proposition => $prop ) } else { - $new_ss->on_solution_step + $old_ss->on_solution_step } }; my $alt_step = $self->alternative_step; - return ( - $new_ss->but( - next_step => $ns, - ($alt_step - ? (alternatives => [ - [ $ss->current_hypothesis, $alt_step ], - @{$ss->alternatives} - ]) - : () - ), + my $ss = $old_ss->but( + next_step => $ns, + ($alt_step + ? (alternatives => [ + [ $old_ss->current_hypothesis, $alt_step ], + @{$old_ss->alternatives} + ]) + : () ), ); + my $new_ss = $self->_apply_to_ss($ss); + return $ss->but(next_step => DX::Step::Backtrack->new) unless $new_ss; + return $new_ss; } sub _apply_to_ss { @@ -79,22 +76,12 @@ sub _recheck_for { my $ss = $old_ss->but( next_step => DX::Step::EnterRecheck->new( proposition_list => \@recheck, - on_completion_step => DX::Step::MarkAsSolution->new, + on_completion_step => $old_ss->next_step, + on_failure_step => DX::Step::Backtrack->new, ), ); - my $sp = DX::SearchProcess->new( - current_search_state => $ss, - ); - - my $sol_sp = $sp->find_solution; - - unless ($sol_sp) { - trace 'step.recheck.fail' => 'argh'; - return undef; - } - - return $sol_sp->current_search_state->but(is_solution_state => 0); + return $ss; } 1;