can haz use strict
Matt S Trout [Sat, 5 Mar 2016 10:07:52 +0000 (10:07 +0000)]
lib/DX/Proposition.pm
lib/DX/PropositionSequence.pm
lib/DX/QueryState.pm
lib/DX/ShellSession.pm

index 154557a..aa6f060 100644 (file)
@@ -7,9 +7,9 @@ has predicate => (is => 'ro', isa => Str, required => 1);
 
 has args => (is => 'ro', isa => ArrayRef, required => 1);
 
-has introduces_names => (is => 'ro', isa => HashRef, required => 1);
+has introduced_names => (is => 'ro', isa => HashRef, required => 1);
 
-has requires_names => (is => 'ro', isa => HashRef, required => 1);
+has required_names => (is => 'ro', isa => HashRef, required => 1);
 
 sub resolve_for {
   my ($self, $scope) = @_;
index d884d96..2b4e8a4 100644 (file)
@@ -1,17 +1,47 @@
 package DX::PropositionSequence;
 
-use Types::Standard qw(ArrayRef);
+use Types::Standard qw(ArrayRef HashRef);
 use DX::Class;
 
 has members => (is => 'ro', isa => ArrayRef[Proposition], required => 1);
 
+has external_names => (is => 'ro', isa => HashRef, required => 1);
+
+has internal_names => (is => 'ro', isa => HashRef, required => 1);
+
 sub new_empty {
-  shift->new(members => []);
+  shift->new(
+    members => [],
+    external_names => {},
+    internal_names => {},
+  );
 }
 
-sub but_append_proposition {
+sub with_additional_proposition {
   my ($self, $prop) = @_;
-  $self->but(members => [ @{$self->members}, $prop ]);
+  my %already_names = (
+    %{$self->external_names}, %{$self->internal_names}
+  );
+  my @fail;
+  if (
+    my @missing = grep !$already_names{$_}, sort keys %{$prop->required_names}
+  ) {
+    push @fail,
+      "  variables ".join(' ', @missing)." required but not in scope";
+  }
+  if (
+    my @shadow = grep $already_names{$_}, keys %{$prop->introduced_names}
+  ) {
+    push @fail,
+      "  new variables ".join(' ', @shadow)." are already in scope";
+  }
+  if (@fail) {
+    die join("\n", "Can't add call to ${\$prop->predicate}:", @fail, '');
+  }
+  $self->but(
+    members => [ @{$self->members}, $prop ],
+    internal_names => { %{$self->internal_names}, %{$prop->introduced_names} },
+  );
 }
 
 1;
index dcc79c7..b15ac83 100644 (file)
@@ -27,7 +27,7 @@ has search_state => (
 
 sub new_search_state_for {
   my ($self, $prop_seq) = @_;
-  my @local_names = map { keys %{$_->introduces_names} }
+  my @local_names = map { keys %{$_->introduced_names} }
                       @{$prop_seq->members};
   my $scope = DX::Scope->new(
     predicates => $self->predicates,
@@ -60,7 +60,7 @@ sub new_search_state_for {
 sub with_additional_proposition {
   my ($self, $prop) = @_;
   my $prop_seq = $self->proposition_sequence
-                      ->but_append_proposition($prop);
+                      ->with_additional_proposition($prop);
   my $sol_ss = $self->new_search_state_for($prop_seq)
                     ->find_solution;
   die "No solution" unless $sol_ss;
index 13ebf78..adced53 100644 (file)
@@ -105,8 +105,8 @@ sub apply_predicate {
   my $prop = DX::Proposition->new(
     predicate => $pred,
     args => \@args,
-    introduces_names => $intro,
-    requires_names => $need,
+    introduced_names => $intro,
+    required_names => $need,
   );
   my $old_qstate = $self->shell_state->current_query_state;
   my $qstate = $old_qstate->with_additional_proposition($prop);