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