06d198646f3a0f65cfb4ec8976787f0750863fb7
[scpubgit/DX.git] / lib / DX / Step / Backtrack.pm
1 package DX::Step::Backtrack;
2
3 use DX::DependencyMap;
4 use DX::Utils qw(format_deps);
5 use DX::Class;
6
7 with 'DX::Role::Step';
8
9 has resolution_space => (is => 'ro', isa => ResolutionSpace, required => 1);
10
11 sub apply_to {
12   my ($self, $ss) = @_;
13   my $rspace = $self->resolution_space;
14   trace backtrack => [ statement => [
15     [ symbol => 'backtrack' ],
16     [ statement => [
17       [ symbol => 'because' ],
18       format_deps($rspace->geometry_depends_on)
19     ] ]
20   ] ];
21   my $dmap = DX::DependencyMap->new_empty
22                               ->with_dependencies_for(
23                                   backtrack => $rspace->geometry_depends_on
24                                 );
25
26   foreach my $adj (@{$ss->decisions_taken}) {
27     my ($rspace_was, $ss_was) = @$adj;
28     $dmap = $dmap->with_dependencies_for(
29       backtrack => $rspace_was->geometry_depends_on
30     );
31     next unless @{$rspace_was->remaining_resolution_space->members};
32     trace rspace => [ statement => [
33       [ symbol => 'remaining' ],
34       @{$rspace_was->remaining_resolution_space->for_deparse->[1]}
35     ] ];
36     return $ss_was->but(
37       next_step => $rspace_was->remaining_resolution_space->next_step
38     );
39   }
40   return $ss->but(next_step => $ss->on_exhaustion_step);
41 }
42
43 1;