pervasive type constraints
[scpubgit/DX.git] / lib / DX / PropositionSequence.pm
CommitLineData
9eedd677 1package DX::PropositionSequence;
2
9eedd677 3use DX::Class;
4
a97779a1 5has members => (is => 'ro', isa => PropositionList, required => 1);
9eedd677 6
a97779a1 7has external_names => (is => 'ro', isa => HashRef[One], required => 1);
5f12a9d8 8
a97779a1 9has internal_names => (is => 'ro', isa => HashRef[One], required => 1);
5f12a9d8 10
9eedd677 11sub new_empty {
5f12a9d8 12 shift->new(
13 members => [],
14 external_names => {},
15 internal_names => {},
16 );
9eedd677 17}
18
5f12a9d8 19sub with_additional_proposition {
9eedd677 20 my ($self, $prop) = @_;
5f12a9d8 21 my %already_names = (
22 %{$self->external_names}, %{$self->internal_names}
23 );
24 my @fail;
25 if (
26 my @missing = grep !$already_names{$_}, sort keys %{$prop->required_names}
27 ) {
28 push @fail,
29 " variables ".join(' ', @missing)." required but not in scope";
30 }
31 if (
32 my @shadow = grep $already_names{$_}, keys %{$prop->introduced_names}
33 ) {
34 push @fail,
35 " new variables ".join(' ', @shadow)." are already in scope";
36 }
37 if (@fail) {
38 die join("\n", "Can't add call to ${\$prop->predicate}:", @fail, '');
39 }
40 $self->but(
41 members => [ @{$self->members}, $prop ],
42 internal_names => { %{$self->internal_names}, %{$prop->introduced_names} },
43 );
9eedd677 44}
45
461;