10248abdb0459a8d773c06744cf2afca96e68895
[scpubgit/DX.git] / lib / DX / SearchProcess.pm
1 package DX::SearchProcess;
2
3 use DX::SearchState;
4 use DX::Class;
5
6 has current_search_state => (
7   is => 'ro', isa => SearchState, required => 1,
8   handles => [ qw(
9     current_hypothesis next_step propositions alternatives
10   ) ],
11 );
12
13 sub new_for {
14   my ($class, $hyp, $props) = @_;
15   $class->new(
16     current_search_state => DX::SearchState->new(
17       current_hypothesis => $hyp,
18       alternatives => [],
19       next_step => DX::Step::InvokeNextPredicate->new(
20         proposition => $props->members->[0],
21       ),
22       propositions => $props,
23     ),
24   );
25 }
26
27 sub with_one_step {
28   my ($self) = @_;
29   my $new_ss = $self->current_search_state->with_one_step;
30   return undef unless $new_ss;
31   return $self->but(current_search_state => $new_ss);
32 }
33
34 sub find_solution {
35   my ($self) = @_;
36   my $state = $self->current_search_state;
37   while ($state and $state->next_proposition) {
38     $state = $state->with_one_step;
39   }
40   return undef unless $state;
41   trace 'search.solution.hyp' => $state->current_hypothesis;
42   return $self->but(current_search_state => $state);
43 }
44
45 sub force_backtrack {
46   my ($self) = @_;
47   my $new_ss = $self->current_search_state->force_backtrack;
48   return undef unless $new_ss;
49   return $self->but(current_search_state => $new_ss);
50 }
51
52 sub find_next_solution {
53   my ($self) = @_;
54   return undef unless my $bt = $self->force_backtrack;
55   return $bt->find_solution;
56 }
57
58 1;