rspace tracing
[scpubgit/DX.git] / lib / DX / Step / ResolveProposition.pm
CommitLineData
a3104d41 1package DX::Step::ResolveProposition;
9d759b64 2
614f3d93 3use DX::Step::EnterRecheck;
7af7ed1e 4use DX::Step::Backtrack;
614f3d93 5
3e465d5d 6use Types::Standard qw(ArrayRef);
c99dbb05 7use DX::Utils qw(expand_deps);
614f3d93 8
9d759b64 9use DX::Class;
10
3e465d5d 11with 'DX::Role::Step';
9d759b64 12
29daa554 13has resolves => (is => 'lazy', init_arg => undef, builder => sub {
14 my ($self) = @_;
15 $self->resolution_space->proposition;
16});
9d759b64 17
839c0018 18has resolution_space => (is => 'ro', isa => ResolutionSpace);
3e465d5d 19
839c0018 20has current_resolution => (is => 'lazy', init_arg => undef, builder => sub {
21 my ($self) = @_;
22 $self->resolution_space->next_resolution;
23});
24
25has actions => (is => 'lazy', init_arg => undef, builder => sub {
26 my ($self) = @_;
27 $self->current_resolution->actions;
28});
29
30has depends_on => (is => 'lazy', init_arg => undef, builder => sub {
31 my ($self) = @_;
c99dbb05 32 expand_deps($self->current_resolution->veracity_depends_on);
839c0018 33});
ccf0d4fe 34
839c0018 35has alternative_step => (is => 'lazy', init_arg => undef, builder => sub {
36 my ($self) = @_;
37 my $rspace = $self->resolution_space->remaining_resolution_space;
38 return undef unless @{$rspace->members};
29daa554 39 return $rspace->next_step;
839c0018 40});
9d759b64 41
4aeeab1e 42sub but_first {
43 my ($self, @actions) = @_;
44 $self->but(actions => [ @actions, @{$self->actions} ]);
45}
46
0498469a 47sub but_with_dependencies_on {
48 my ($self, @deps) = @_;
49 $self->but(depends_on => [ @{$self->depends_on}, @deps ]);
50}
51
9d759b64 52sub apply_to {
7af7ed1e 53 my ($self, $old_ss) = @_;
5b6cab1b 54 trace resolve => [ statement => [
55 [ symbol => 'resolve' ],
56 [ block => [
57 [ statement => [
58 [ symbol => 'proposition' ],
59 @{$self->resolves->for_deparse->[1]},
60 ] ],
61 (@{$self->actions}
62 ? [ statement => [
63 [ symbol => 'actions' ],
c99dbb05 64 [ block => $self->actions ],
5b6cab1b 65 ] ]
66 : ()),
93de8fb0 67 [ statement => [
68 [ symbol => 'depends_on' ],
69 [ pairs => [
70 map [
71 (split '::', ${$_->[0]})[-1],
72 [ value_path => [ @{$_}[1..$#$_] ] ]
73 ], @{$self->depends_on}
74 ] ],
75 ] ],
5b6cab1b 76 ] ]
77 ] ];
1dcbfaf8 78 my $ns = do {
7af7ed1e 79 if (my $prop = $old_ss->next_proposition) {
86dbedb6 80 DX::Step::ConsiderProposition->new(
1dcbfaf8 81 proposition => $prop
82 )
83 } else {
7af7ed1e 84 $old_ss->on_solution_step
1dcbfaf8 85 }
86 };
7af7ed1e 87 my $ss = $old_ss->but(
88 next_step => $ns,
1c02730b 89 decisions_taken => [
90 [ $self->resolution_space, $old_ss ],
91 @{$old_ss->decisions_taken}
92 ],
f696251f 93 );
7af7ed1e 94 my $new_ss = $self->_apply_to_ss($ss);
95 return $ss->but(next_step => DX::Step::Backtrack->new) unless $new_ss;
96 return $new_ss;
9d759b64 97}
98
2ac94761 99sub _apply_to_ss {
100 my ($self, $old_ss) = @_;
101 my $old_hyp = $old_ss->current_hypothesis;
77065529 102 (my $hyp, my @recheck) = $old_hyp->with_resolution(
cdca8723 103 $self->resolves, $self->depends_on, $self->actions
104 );
2ac94761 105 return undef unless $hyp;
106 return $self->_recheck_for(
107 $old_ss->but(current_hypothesis => $hyp),
108 @recheck
109 );
04844099 110}
111
2ac94761 112sub _recheck_for {
113 my ($self, $old_ss, @recheck) = @_;
49e9aea0 114
31753090 115 return $old_ss unless @recheck;
2ac94761 116
614f3d93 117 my $ss = $old_ss->but(
118 next_step => DX::Step::EnterRecheck->new(
31753090 119 proposition_list => \@recheck,
7af7ed1e 120 on_completion_step => $old_ss->next_step,
121 on_failure_step => DX::Step::Backtrack->new,
614f3d93 122 ),
310662b5 123 );
124
7af7ed1e 125 return $ss;
9d759b64 126}
127
1281;