ba9d1258f3cc7705de15d261e03d10b79c72cdbf
[scpubgit/DX.git] / lib / DX / Step / EnterRecheck.pm
1 package DX::Step::EnterRecheck;
2
3 use DX::Step::CompleteRecheck;
4 use DX::Step::FailRecheck;
5
6 use DX::Class;
7
8 with 'DX::Role::Step';
9
10 has proposition_list => (
11   is => 'ro', isa => PropositionList, required => 1
12 );
13
14 has on_completion_step => (is => 'ro', isa => Step, required => 1);
15
16 has on_failure_step => (is => 'ro', isa => Maybe[Step], required => 1);
17
18 sub apply_to {
19   my ($self, $old_ss) = @_;
20
21   my ($prop, @rest) = @{$self->proposition_list};
22
23   trace recheck => [ statement => [
24     [ symbol => 'recheck' ],
25     @{$prop->for_deparse->[1]},
26     [ 'enter_block' ],
27   ] ];
28
29   my $old_hyp = $old_ss->current_hypothesis;
30
31   # we should probably be doing something about pruning the scope
32   # but that's completely pointless until we have rules (and also,
33   # the lock_to_depth arg needs to come from the proposition somehow)
34
35   my $ap = DX::ActionPolicy::LockScope->new(
36     lock_to_depth => $old_hyp->scope->depth,
37     next_policy => $old_hyp->action_policy,
38   );
39
40   my $hyp = ref($old_hyp)->new(
41     scope => $old_hyp->scope,
42     resolved_propositions => DX::ResolvedPropositionSet->new_empty,
43     actions => [],
44     action_applications => [],
45     action_policy => $ap,
46   );
47
48   my $pseq = DX::PropositionSequence->new(
49     members => [ $prop ],
50     external_names => {},
51     internal_names => {},
52   );
53
54   my $next_step = (@rest
55                     ? $self->but(proposition_list => \@rest)
56                     : $self->on_completion_step);
57
58   my $ss = DX::SearchState->new(
59     current_hypothesis => $hyp,
60     decisions_taken => [],
61     propositions => $pseq,
62     next_step => DX::Step::ConsiderProposition->new(
63                    proposition => $prop,
64                  ),
65     is_solution_state => 0,
66     is_exhaustion_state => 0,
67     on_solution_step => DX::Step::CompleteRecheck->new(
68       resume_search_state => $old_ss->but(next_step => $next_step),
69       was_recheck_for => $prop,
70     ),
71     on_exhaustion_step => DX::Step::FailRecheck->new(
72       resume_search_state => $old_ss->but(next_step => $self->on_failure_step),
73     ),
74   );
75
76   return $ss;
77 }
78
79 1;