format aperture in backtrack trace
[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 compact_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     [ 'enter_block' ]
17   ] ];
18   trace backtrack => [ word_and_body => [
19     'failure_dependencies',
20     format_deps($rspace->geometry_depends_on)
21   ] ];
22   my $dmap = DX::DependencyMap->new_empty
23                               ->with_dependencies_for(
24                                   backtrack => $rspace->geometry_depends_on
25                                 );
26   DECISION: foreach my $adj (@{$ss->decisions_taken}) {
27     my ($rspace_was, $ss_was) = @$adj;
28     trace backtrack => [ statement => [
29       [ symbol => 'decision' ],
30       [ pairs => [
31         [ for => $rspace_was->proposition, ],
32         [ aperture => [ block => [
33             map [ statement => [
34               [ symbol => (split '::', ${$_->[0]})[-1] ],
35               [ value_path => [ @{$_}[1..$#$_] ] ],
36             ] ], @{$rspace_was->aperture}
37           ] ] ]
38       ] ]
39     ] ];
40     foreach my $event (@{$rspace_was->aperture}) {
41       if ($dmap->dependents_of($event)) {
42         my $remain = $rspace_was->remaining_resolution_space;
43         if (@{$remain->members}) {
44           trace backtrack => [ statement => [
45             [ symbol => 'found_alternative' ]
46           ] ];
47           trace backtrack => [ 'leave_block' ];
48           return $ss_was->but(
49             next_step => $remain->with_geometry_dependencies(
50                                   $dmap->dependencies_for('backtrack')
51                                )->next_step
52           );
53         }
54         $dmap = $dmap->with_dependencies_for(
55           backtrack => $rspace_was->geometry_depends_on
56         );
57         trace backtrack => [ word_and_body => [
58           'failure_dependencies',
59           format_deps(compact_deps($dmap->dependencies_for('backtrack')))
60         ] ];
61         next DECISION;
62       }
63     }
64     trace backtrack => [ statement => [ [ symbol => 'non_relevant' ] ] ];
65   }
66   trace backtrack => [ statement => [ [ symbol => 'exhaustion' ] ] ];
67   trace backtrack => [ 'leave_block' ];
68   return $ss->but(
69     next_step
70       => $ss->on_exhaustion_step->but(
71            exhaustion_depends_on => $dmap->dependencies_for('backtrack')
72          )
73   );
74 }
75
76 1;