package DX::Step::ConsiderProposition;

use DX::Class;

with 'DX::Role::Step';

has proposition => (is => 'ro', isa => Proposition, required => 1);

sub apply_to {
  my ($self, $ss) = @_;
  my $hyp = $ss->current_hypothesis;
  trace consider => [
    statement => [
      [ symbol => 'consider' ],
      @{$self->proposition->for_deparse->[1]},
    ],
  ];
  my $old_scope = (my $old_hyp = $ss->current_hypothesis)->scope;
  my @old_locals = @{$old_scope->locals};
  my $top_level = $#old_locals;
  my $top = pop @old_locals;
  my $top_members = $top->members;
  my @new_names = grep !exists $top_members->{$_},
                    keys %{$self->proposition->introduced_names};
  my $new_scope = $old_scope->but(
    locals => [
      @old_locals,
      $top->but(members => {
        %{$top_members},
        map +($_ => DX::Value::Unset->new(
                      action_builder => DX::ActionBuilder::UnsetValue->new(
                        target_path => [ $top_level, $_ ],
                      )
                    )
        ), @new_names
      }),
    ],
    lex_map => {
      %{$old_scope->lex_map},
      map +($_ => [ $top_level, $_ ]), @new_names
    }
  );
  my $new_hyp = $old_hyp->but(scope => $new_scope);
  return $ss->but(
    current_hypothesis => $new_hyp,
    next_step => $self->proposition->resolve_for($new_scope)
  );
}

1;
