package DX::Op::MemberOf;
use DX::ArrayStream;
+use DX::RefSet;
use Moo;
with 'DX::Role::Op';
has member_var => (is => 'ro', required => 1);
-has coll_name => (is => 'ro', required => 1);
+has coll_var => (is => 'ro', required => 1);
sub run {
my ($self, $state) = @_;
- my $member = $state->scope_var($self->member_var);
- die "member bound" if $member->is_bound;
- my $set = $state->facts->{$self->coll_name};
- my $stream = DX::ArrayStream->from_array(@{$set}{sort keys %$set});
- return $state->bind_stream_then($member, $stream, $self->next);
+ ($state, my %args) = $self->_expand_args($state,
+ member => $self->member_var,
+ of => $self->coll_var
+ );
+ my ($member, $of) = @args{qw(member of)};
+ my $type = $state->resolve_value($of);
+ my $set = ref($type) ? $type : $state->facts->{$type};
+ if ($member->is_bound) {
+ my $test = $state->resolve_value($member);
+ if (grep { $_ eq $test } $set->all) {
+ return $state->then($self->next);
+ }
+ return $state->backtrack;
+ }
+ my $ref_set = (
+ ref($type)
+ ? $set
+ : DX::RefSet->new(
+ target => $type, names => [ $set->key_list ],
+ )
+ );
+ return $state->then($self->next)
+ ->add_dependencies($member->id, $of->id)
+ ->bind_root_set($member->id, $ref_set)
}
1;