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