add propositions method to searchstate
[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 outstanding_propositions => (
15 is => 'ro', isa => ArrayRef[Proposition], required => 1
16);
9d759b64 17
3e465d5d 18has actions => (
19 is => 'ro', isa => ArrayRef[Action], required => 1
20);
21
e442aff8 22has action_applications => (
23 is => 'ro', isa => ArrayRef[Action], required => 1
24);
25
3e465d5d 26has action_policy => (is => 'ro', isa => ActionPolicy, required => 1);
9d759b64 27
efad53c4 28sub head_proposition { shift->outstanding_propositions->[0] }
29
9d759b64 30sub with_actions {
31 my ($self, @actions) = @_;
32 my $hyp = $self;
33 foreach my $act (@actions) {
3e465d5d 34 return undef unless $self->action_policy->allows($act);
efad53c4 35 ($hyp, my @events) = $act->dry_run($hyp);
9d759b64 36 return undef unless $hyp;
37 $hyp = $hyp->but_recheck_for(@events);
38 return undef unless $hyp;
39 }
40 return $hyp;
41}
42
43sub but_recheck_for {
44 my ($self, @events) = @_;
45 my ($still_resolved, @recheck) = $self->resolved_propositions
46 ->but_expire_for(@events);
3e465d5d 47 return $self unless @recheck;
48
49 my $ap = DX::ActionPolicy::LockScope->new(
50 lock_to_depth => $self->scope->depth,
51 next_policy => $self->action_policy,
52 );
53
54 # we should probably be doing something about pruning the scope
55 # but that's completely pointless until we have rules
56
57 my $hyp = ref($self)->new(
58 scope => $self->scope,
59 resolved_propositions => DX::ResolvedPropositionSet->new_empty,
60 outstanding_propositions => \@recheck,
61 actions => [],
e442aff8 62 action_applications => [],
3e465d5d 63 action_policy => $ap,
64 );
65
1350f664 66 my $pseq = DX::PropositionSequence->new(
67 members => \@recheck,
68 external_names => {},
69 internal_names => {},
70 );
71
bcee3a69 72 trace 'step.recheck.hyp' => $hyp;
73
1350f664 74 my $ss = DX::SearchState->new_for($hyp, $pseq);
3e465d5d 75
2d4e0113 76 my $sol_ss = $ss->find_solution;
77
78 unless ($sol_ss) {
79 trace 'step.recheck.fail' => 'argh';
80 return undef;
81 }
3e465d5d 82
83 my $sol_rps = $sol_ss->current_hypothesis->resolved_propositions;
84
85 my $rps = $still_resolved;
86
87 $rps = $rps->with_updated_dependencies_for(
88 $_, $sol_rps->dependencies_for($_)
89 ) for @recheck;
90
bcee3a69 91 trace 'step.recheck.done' => 'yay';
92
3e465d5d 93 return $self->but(resolved_propositions => $rps);
9d759b64 94}
95
96sub resolve_head_dependent_on {
97 my ($self, $depends) = @_;
98 my ($first, @rest) = @{$self->outstanding_propositions};
99 $self->but(
100 resolved_propositions => $self->resolved_propositions
efad53c4 101 ->with_resolution_for(
102 $first,
103 $depends,
9d759b64 104 ),
efad53c4 105 outstanding_propositions => \@rest,
9d759b64 106 );
107}
108
1091;