factor action execution out into solver method
[scpubgit/DKit.git] / lib / DX / Solver.pm
1 package DX::Solver;
2
3 use DX::RuleSet;
4 use DX::State;
5 use DX::ResultStream;
6 use List::Util qw(reduce);
7 use Moo;
8
9 has rule_set => (is => 'lazy', handles => [ 'add_rule' ], builder => sub {
10   DX::RuleSet->new
11 });
12
13 has facts => (is => 'ro', required => 1);
14
15 has observation_policy => (is => 'ro');
16
17 sub query {
18   my ($self, $vars, @terms) = @_;
19   my $rule_set = $self->rule_set;
20   push @terms, map +[ materialize => $_ ], @$vars;
21   my $head = $rule_set->expand_and_link(undef, @terms);
22   my $state = DX::State->new(
23     next_op => $head,
24     return_stack => [],
25     by_id => {},
26     scope => {},
27     last_choice => [],
28     facts => $self->facts,
29     rule_set => $rule_set,
30   )->assign_vars(map +($_ => {}), @$vars);
31   return DX::ResultStream->new(
32     for_state => $state,
33     ($self->observation_policy
34       ? (observation_policy => $self->observation_policy)
35       : ()),
36   );
37 }
38
39 sub run_action {
40   my ($self, $action) = @_;
41   my @invalidate = $action->run;
42   while (my ($type, $value) = splice @invalidate, 0, 2) {
43     $self->facts->{$type}->remove_value($value);
44   }
45 }
46
47 1;