1 package DX::Step::ResolveProposition;
3 use DX::Step::EnterRecheck;
4 use DX::Step::Backtrack;
6 use Types::Standard qw(ArrayRef);
10 with 'DX::Role::Step';
12 has resolves => (is => 'lazy', init_arg => undef, builder => sub {
14 $self->resolution_space->proposition;
17 has resolution_space => (is => 'ro', isa => ResolutionSpace);
19 has current_resolution => (is => 'lazy', init_arg => undef, builder => sub {
21 $self->resolution_space->next_resolution;
24 has actions => (is => 'lazy', init_arg => undef, builder => sub {
26 $self->current_resolution->actions;
29 has depends_on => (is => 'lazy', init_arg => undef, builder => sub {
31 my $_expand_dep = sub {
32 my ($type, @path) = @{$_[0]};
34 ref() ? @{$_->value_path or return ()} : $_
36 return [ $type, @expanded ];
38 [ map $_expand_dep->($_),
39 @{$self->current_resolution->veracity_depends_on} ];
42 has alternative_step => (is => 'lazy', init_arg => undef, builder => sub {
44 my $rspace = $self->resolution_space->remaining_resolution_space;
45 return undef unless @{$rspace->members};
46 return $rspace->next_step;
50 my ($self, @actions) = @_;
51 $self->but(actions => [ @actions, @{$self->actions} ]);
54 sub but_with_dependencies_on {
55 my ($self, @deps) = @_;
56 $self->but(depends_on => [ @{$self->depends_on}, @deps ]);
60 my ($self, $old_ss) = @_;
61 trace resolve => [ statement => [
62 [ symbol => 'resolve' ],
65 [ symbol => 'proposition' ],
66 @{$self->resolves->for_deparse->[1]},
70 [ symbol => 'actions' ],
71 [ block => [ @{$self->actions} ] ],
75 [ symbol => 'depends_on' ],
78 (split '::', ${$_->[0]})[-1],
79 [ value_path => [ @{$_}[1..$#$_] ] ]
80 ], @{$self->depends_on}
86 if (my $prop = $old_ss->next_proposition) {
87 DX::Step::ConsiderProposition->new(
91 $old_ss->on_solution_step
94 my $ss = $old_ss->but(
97 [ $self->resolution_space, $old_ss ],
98 @{$old_ss->decisions_taken}
101 my $new_ss = $self->_apply_to_ss($ss);
102 return $ss->but(next_step => DX::Step::Backtrack->new) unless $new_ss;
107 my ($self, $old_ss) = @_;
108 my $old_hyp = $old_ss->current_hypothesis;
109 (my $hyp, my @recheck) = $old_hyp->with_resolution(
110 $self->resolves, $self->depends_on, $self->actions
112 return undef unless $hyp;
113 return $self->_recheck_for(
114 $old_ss->but(current_hypothesis => $hyp),
120 my ($self, $old_ss, @recheck) = @_;
122 return $old_ss unless @recheck;
124 my $ss = $old_ss->but(
125 next_step => DX::Step::EnterRecheck->new(
126 proposition_list => \@recheck,
127 on_completion_step => $old_ss->next_step,
128 on_failure_step => DX::Step::Backtrack->new,