new Op::Predicate
[scpubgit/DKit.git] / lib / DX / Solver.pm
index 05523ec..0f23c54 100644 (file)
@@ -6,17 +6,23 @@ use DX::ResultStream;
 use List::Util qw(reduce);
 use Moo;
 
-has rule_set => (is => 'lazy', handles => [ 'add_rule' ], builder => sub {
-  DX::RuleSet->new
-});
+has rule_set => (
+  is => 'lazy',
+  handles => [ qw(add_predicate add_rule) ],
+  builder => sub {
+    DX::RuleSet->new
+  },
+);
 
 has facts => (is => 'ro', required => 1);
 
+has observation_policy => (is => 'ro');
+
 sub query {
   my ($self, $vars, @terms) = @_;
   my $rule_set = $self->rule_set;
-  my $head = reduce { $b->but(next => $a) }
-               reverse map $rule_set->expand(@$_), @terms;
+  push @terms, map +[ materialize => $_ ], @$vars;
+  my $head = $rule_set->expand_and_link(undef, @terms);
   my $state = DX::State->new(
     next_op => $head,
     return_stack => [],
@@ -27,8 +33,19 @@ sub query {
     rule_set => $rule_set,
   )->assign_vars(map +($_ => {}), @$vars);
   return DX::ResultStream->new(
-    for_state => $state
+    for_state => $state,
+    ($self->observation_policy
+      ? (observation_policy => $self->observation_policy)
+      : ()),
   );
 }
 
+sub run_action {
+  my ($self, $action) = @_;
+  my @invalidate = $action->run;
+  while (my ($type, $value) = splice @invalidate, 0, 2) {
+    $self->facts->{$type}->remove_value($value);
+  }
+}
+
 1;