have with_actions return the recheck list
[scpubgit/DX.git] / lib / DX / Hypothesis.pm
CommitLineData
9d759b64 1package DX::Hypothesis;
2
3e465d5d 3use DX::ActionPolicy::LockScope;
4use Types::Standard qw(ArrayRef);
4016201b 5use DX::Utils qw(deparse);
9d759b64 6use DX::Class;
7
3e465d5d 8has scope => (is => 'ro', isa => Scope, required => 1);
9d759b64 9
3e465d5d 10has resolved_propositions => (
11 is => 'ro', isa => ResolvedPropositionSet, required => 1
12);
9d759b64 13
3e465d5d 14has actions => (
15 is => 'ro', isa => ArrayRef[Action], required => 1
16);
17
e442aff8 18has action_applications => (
19 is => 'ro', isa => ArrayRef[Action], required => 1
20);
21
3e465d5d 22has action_policy => (is => 'ro', isa => ActionPolicy, required => 1);
9d759b64 23
24sub with_actions {
25 my ($self, @actions) = @_;
26 my $hyp = $self;
9e8ed9ae 27 my @events;
9d759b64 28 foreach my $act (@actions) {
3e465d5d 29 return undef unless $self->action_policy->allows($act);
9e8ed9ae 30 ($hyp, my @these_events) = $act->dry_run($hyp);
9d759b64 31 return undef unless $hyp;
9e8ed9ae 32 push @events, @these_events;
9d759b64 33 }
ea0dbc2a 34 my ($still_resolved, @recheck) = $hyp->resolved_propositions
35 ->but_expire_for(@events);
36 return (
37 $hyp->but(resolved_propositions => $still_resolved),
38 @recheck
39 );
9d759b64 40}
41
42sub but_recheck_for {
ea0dbc2a 43 my ($self, @recheck) = @_;
3e465d5d 44
45 my $ap = DX::ActionPolicy::LockScope->new(
46 lock_to_depth => $self->scope->depth,
47 next_policy => $self->action_policy,
48 );
49
50 # we should probably be doing something about pruning the scope
51 # but that's completely pointless until we have rules
52
53 my $hyp = ref($self)->new(
54 scope => $self->scope,
55 resolved_propositions => DX::ResolvedPropositionSet->new_empty,
3e465d5d 56 actions => [],
e442aff8 57 action_applications => [],
3e465d5d 58 action_policy => $ap,
59 );
60
1350f664 61 my $pseq = DX::PropositionSequence->new(
62 members => \@recheck,
63 external_names => {},
64 internal_names => {},
65 );
66
bcee3a69 67 trace 'step.recheck.hyp' => $hyp;
68
8c16d3c9 69 my $ss = DX::SearchProcess->new_for($hyp, $pseq);
3e465d5d 70
2d4e0113 71 my $sol_ss = $ss->find_solution;
72
73 unless ($sol_ss) {
74 trace 'step.recheck.fail' => 'argh';
75 return undef;
76 }
3e465d5d 77
78 my $sol_rps = $sol_ss->current_hypothesis->resolved_propositions;
79
ea0dbc2a 80 my $rps = $self->resolved_propositions;
3e465d5d 81
82 $rps = $rps->with_updated_dependencies_for(
83 $_, $sol_rps->dependencies_for($_)
84 ) for @recheck;
85
bcee3a69 86 trace 'step.recheck.done' => 'yay';
87
3e465d5d 88 return $self->but(resolved_propositions => $rps);
9d759b64 89}
90
5787d20d 91sub with_resolution {
cdca8723 92 my ($self, $prop, $depends, $actions) = @_;
ea0dbc2a 93 (my $hyp, my @recheck) = $self->with_actions(@$actions);
cdca8723 94 return undef unless $hyp;
ea0dbc2a 95 if (@recheck) {
96 $hyp = $hyp->but_recheck_for(@recheck);
97 return undef unless $hyp;
98 }
cdca8723 99 $hyp->but(
9d759b64 100 resolved_propositions => $self->resolved_propositions
efad53c4 101 ->with_resolution_for(
5787d20d 102 $prop,
efad53c4 103 $depends,
9d759b64 104 ),
9d759b64 105 );
106}
107
1081;