notes about actions being disallowed
[scpubgit/DX.git] / lib / DX / Step / ResolveProposition.pm
1 package DX::Step::ResolveProposition;
2
3 use DX::Step::EnterRecheck;
4 use DX::Step::CompleteResolution;
5 use DX::Step::Backtrack;
6
7 use DX::Utils qw(expand_deps);
8
9 use DX::Class;
10
11 with 'DX::Role::Step';
12
13 has resolution_space => (is => 'ro', isa => ResolutionSpace);
14
15 sub but_first {
16   my ($self, @actions) = @_;
17   $self->but(actions => [ @actions, @{$self->actions} ]);
18 }
19
20 sub but_with_dependencies_on {
21   my ($self, @deps) = @_;
22   $self->but(depends_on => [ @{$self->depends_on}, @deps ]);
23 }
24
25 sub apply_to {
26   my ($self, $old_ss) = @_;
27   my $rspace = $self->resolution_space;
28   my $prop = $rspace->proposition;
29   my $res = $rspace->next_resolution;
30   my $vdeps = $res->veracity_depends_on;
31   trace resolve => [ statement => [
32     [ symbol => 'resolve' ],
33     [ block => [
34       [ statement => [
35         [ symbol => 'proposition' ],
36         @{$prop->for_deparse->[1]},
37       ] ],
38       (@{$res->actions}
39         ? [ statement => [
40             [ symbol => 'actions' ],
41             [ block => $res->actions ],
42           ] ]
43         : ()),
44       [ statement => [
45         [ symbol => 'depends_on' ],
46         [ block => [
47           map [ statement => [
48             [ symbol => (split '::', ${$_->[0]})[-1] ],
49             [ value_path => [ @{$_}[1..$#$_] ] ]
50           ] ], @{$vdeps}
51         ] ],
52       ] ],
53     ] ]
54   ] ];
55   my $old_hyp = $old_ss->current_hypothesis;
56   (my $hyp, my @recheck) = $old_hyp->with_resolution(
57     $prop, $vdeps, $res->actions
58   );
59   # Failure to have a $hyp here means an action was disallowed by policy
60   # or failed - unsure if "failed" should be permitted and unsure if policy
61   # checks belong in with_resolution
62   unless ($hyp) {
63     return $old_ss->but(
64       next_step
65         => $rspace->remaining_resolution_space->next_step
66     );
67   }
68   my $next_step = DX::Step::CompleteResolution->new(
69     original_search_state => $old_ss,
70     resolution_space => $rspace,
71   );
72   unless (@recheck) {
73     return $old_ss->but(next_step => $next_step, current_hypothesis => $hyp);
74   }
75   return $old_ss->but(
76     current_hypothesis => $hyp,
77     next_step => DX::Step::EnterRecheck->new(
78       proposition_list => \@recheck,
79       on_completion_step => $next_step,
80       resolution_space => $rspace,
81     ),
82   );
83 }
84
85 1;