types and deparsing and recalculation part working
[scpubgit/DX.git] / lib / DX / Hypothesis.pm
CommitLineData
9d759b64 1package DX::Hypothesis;
2
3e465d5d 3use DX::ActionPolicy::LockScope;
4use Types::Standard qw(ArrayRef);
9d759b64 5use DX::Class;
6
3e465d5d 7has scope => (is => 'ro', isa => Scope, required => 1);
9d759b64 8
3e465d5d 9has resolved_propositions => (
10 is => 'ro', isa => ResolvedPropositionSet, required => 1
11);
9d759b64 12
3e465d5d 13has outstanding_propositions => (
14 is => 'ro', isa => ArrayRef[Proposition], required => 1
15);
9d759b64 16
3e465d5d 17has actions => (
18 is => 'ro', isa => ArrayRef[Action], required => 1
19);
20
21has action_policy => (is => 'ro', isa => ActionPolicy, required => 1);
9d759b64 22
efad53c4 23sub head_proposition { shift->outstanding_propositions->[0] }
24
9d759b64 25sub with_actions {
26 my ($self, @actions) = @_;
27 my $hyp = $self;
28 foreach my $act (@actions) {
3e465d5d 29 return undef unless $self->action_policy->allows($act);
efad53c4 30 ($hyp, my @events) = $act->dry_run($hyp);
9d759b64 31 return undef unless $hyp;
32 $hyp = $hyp->but_recheck_for(@events);
33 return undef unless $hyp;
34 }
35 return $hyp;
36}
37
38sub but_recheck_for {
39 my ($self, @events) = @_;
40 my ($still_resolved, @recheck) = $self->resolved_propositions
41 ->but_expire_for(@events);
3e465d5d 42 return $self unless @recheck;
43
44 my $ap = DX::ActionPolicy::LockScope->new(
45 lock_to_depth => $self->scope->depth,
46 next_policy => $self->action_policy,
47 );
48
49 # we should probably be doing something about pruning the scope
50 # but that's completely pointless until we have rules
51
52 my $hyp = ref($self)->new(
53 scope => $self->scope,
54 resolved_propositions => DX::ResolvedPropositionSet->new_empty,
55 outstanding_propositions => \@recheck,
56 actions => [],
57 action_policy => $ap,
58 );
59
60 my $ss = DX::SearchState->new_for($hyp);
61
62 return undef unless my $sol_ss = $ss->find_solution;
63
64 my $sol_rps = $sol_ss->current_hypothesis->resolved_propositions;
65
66 my $rps = $still_resolved;
67
68 $rps = $rps->with_updated_dependencies_for(
69 $_, $sol_rps->dependencies_for($_)
70 ) for @recheck;
71
72 return $self->but(resolved_propositions => $rps);
9d759b64 73}
74
75sub resolve_head_dependent_on {
76 my ($self, $depends) = @_;
77 my ($first, @rest) = @{$self->outstanding_propositions};
78 $self->but(
79 resolved_propositions => $self->resolved_propositions
efad53c4 80 ->with_resolution_for(
81 $first,
82 $depends,
9d759b64 83 ),
efad53c4 84 outstanding_propositions => \@rest,
9d759b64 85 );
86}
87
881;