6300b23698126923dca548e80e9a1bc3a63d8c9f
[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 => (
10   is => 'lazy',
11   handles => [ qw(add_predicate add_rule) ],
12   builder => sub {
13     DX::RuleSet->new
14   },
15 );
16
17 has facts => (is => 'ro', default => sub { {} });
18
19 has observation_policy => (is => 'ro');
20
21 sub query {
22   my ($self, @terms) = @_;
23   my $rule_set = $self->rule_set;
24   my $head = $rule_set->expand_and_link(undef, @terms, [ 'materialize' ]);
25   my $state = DX::State->new(
26     next_op => $head,
27     return_stack => [],
28     by_id => {},
29     scope => {},
30     last_choice => [],
31     facts => $self->facts,
32     rule_set => $rule_set,
33   );
34   return DX::ResultStream->new(
35     for_state => $state,
36     ($self->observation_policy
37       ? (observation_policy => $self->observation_policy)
38       : ()),
39   );
40 }
41
42 sub run_action {
43   my ($self, $action) = @_;
44   my @invalidate = $action->run;
45   while (my ($type, $value) = splice @invalidate, 0, 2) {
46     $self->facts->{$type}->remove_value($value);
47   }
48 }
49
50 1;