package DX::Proposition;

use DX::Step::ConsiderProposition;

use DX::Class;

has predicate => (is => 'ro', isa => Str, required => 1);

has args => (is => 'ro', isa => ArrayRef[Str|Value], required => 1);

has introduced_names => (is => 'ro', isa => HashRef[One], required => 1);

has required_names => (is => 'ro', isa => HashRef[One], required => 1);

sub for_deparse {
  my ($self) = @_;
  [ statement => [
    [ symbol => $self->predicate ],
    map {
      ref($_)
        ? $_
        : [ symbol => $self->introduced_names->{$_} ? "?$_" : $_ ]
    } @{$self->args}
  ] ];
}

sub resolve_for {
  my ($self, $scope) = @_;
  my $predicate = $scope->lookup_predicate($self->predicate);
  my @args = map { ref($_) ? $_ : $scope->lookup($_) } @{$self->args};
  #if (my $step = $scope->known_facts->resolution_step_for($predicate, @args)) {
  #  return $step;
  #}
  return $predicate->resolution_step_for($self, @args);
}

sub consider_step {
  my ($self) = @_;
  DX::Step::ConsiderProposition->new(proposition => $self);
}

1;
