query/solve/ensure
[scpubgit/DKit.git] / lib / DX / Solver.pm
index 6626840..753abe5 100644 (file)
@@ -19,10 +19,31 @@ has facts => (is => 'ro', default => sub { {} });
 has observation_policy => (is => 'ro');
 
 sub query {
-  my ($self, $vars, @terms) = @_;
+  my ($self, @terms) = @_;
+  $self->_solve({ allow_actions => 0 }, @terms);
+}
+
+sub solve {
+  my ($self, @terms) = @_;
+  $self->_solve({ allow_actions => 1 }, @terms);
+}
+
+sub ensure {
+  my ($self, @terms) = @_;
+  my $rs = $self->_solve({ allow_actions => 1 }, @terms);
+  my $r = $rs->next;
+  while ($r and $r->actions and my @ind = $r->independent_actions) {
+    $self->run_action($_) for @ind;
+    $rs = $self->_solve({ allow_actions => 1 }, @terms);
+    $r = $rs->next;
+  }
+  return $r;
+}
+
+sub _solve {
+  my ($self, $attrs, @terms) = @_;
   my $rule_set = $self->rule_set;
-  push @terms, map +[ materialize => $_ ], @$vars;
-  my $head = $rule_set->expand_and_link(undef, @terms);
+  my $head = $rule_set->expand_and_link(undef, @terms, [ 'materialize' ]);
   my $state = DX::State->new(
     next_op => $head,
     return_stack => [],
@@ -31,7 +52,8 @@ sub query {
     last_choice => [],
     facts => $self->facts,
     rule_set => $rule_set,
-  )->assign_vars(map +($_ => {}), @$vars);
+    %$attrs
+  );
   return DX::ResultStream->new(
     for_state => $state,
     ($self->observation_policy
@@ -42,6 +64,7 @@ sub query {
 
 sub run_action {
   my ($self, $action) = @_;
+  warn +(split('::', ref($action)))[-1]."\n";
   my @invalidate = $action->run;
   while (my ($type, $value) = splice @invalidate, 0, 2) {
     $self->facts->{$type}->remove_value($value);