add exhaustionstep and resumesearch concepts
[scpubgit/DX.git] / lib / DX / SearchState.pm
1 package DX::SearchState;
2
3 use DX::Step::Backtrack;
4 use DX::Step::ConsiderProposition;
5 use DX::Step::MarkAsSolution;
6 use DX::Class;
7
8 has current_hypothesis => (is => 'ro', isa => Hypothesis, required => 1);
9
10 has next_step => (is => 'ro', isa => Maybe[Step], required => 1);
11
12 has propositions => (is => 'ro', isa => PropositionSequence, required => 1);
13
14 has decisions_taken => (is => 'ro', isa => DecisionList, required => 1);
15
16 has is_solution_state => (is => 'ro', isa => Bool, required => 1);
17
18 has is_exhaustion_state => (is => 'ro', isa => Bool, required => 1);
19
20 has on_exhaustion_step => (is => 'ro', isa => Maybe[Step], required => 1);
21
22 has on_solution_step => (is => 'ro', isa => Maybe[Step], required => 1);
23
24 sub next_proposition {
25   my ($self) = @_;
26   my $hyp = $self->current_hypothesis;
27   $self->propositions->members->[
28     $hyp->resolved_propositions->resolved_count + 1
29   ];
30 }
31
32 sub new_for {
33   my ($class, $hyp, $props) = @_;
34   $class->new(
35     current_hypothesis => $hyp,
36     decisions_taken => [],
37     propositions => $props,
38     (@{$props->members}
39       ? (
40           next_step => DX::Step::ConsiderProposition->new(
41             proposition => $props->members->[0],
42           ),
43           is_solution_state => 0,
44         )
45       : ( next_step => DX::Step::MarkAsExhaustion->new, is_solution_state => 1 )
46     ),
47     is_exhaustion_state => 0,
48     on_exhaustion_step => DX::Step::MarkAsExhaustion->new,
49     on_solution_step => DX::Step::MarkAsSolution->new,
50   );
51 }
52
53 sub with_one_step {
54   my ($self) = @_;
55   return undef unless my $step = $self->next_step;
56   #trace step => $step;
57   return $step->apply_to($self);
58 }
59
60 sub force_backtrack {
61   my ($self) = @_;
62   return $self->but(
63     next_step => DX::Step::Backtrack->new,
64   )->with_one_step;
65 }
66
67 1;