This file is indexed.

/usr/share/perl5/Set/Scalar.pm is in libset-scalar-perl 1.25-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
package Set::Scalar;

use strict;
# local $^W = 1;

use vars qw($VERSION @ISA);

$VERSION = '1.25';

@ISA = qw(Set::Scalar::Real Set::Scalar::Null Set::Scalar::Base);

use Set::Scalar::Base qw(_make_elements is_equal as_string_callback);
use Set::Scalar::Real;
use Set::Scalar::Null;
use Set::Scalar::Universe;

sub ELEMENT_SEPARATOR { " "    }
sub SET_FORMAT        { "(%s)" }

sub _insert_hook {
    my $self     = shift;

    if (@_) {
	my $elements = shift;

	$self->universe->_extend( $elements );

	$self->_insert_elements( $elements );
    }
}

sub _new_hook {
    my $self     = shift;
    my $elements = shift;

    $self->{ universe } = Set::Scalar::Universe->universe;

    $self->_insert( { _make_elements( @$elements ) } );
}

=pod

=head1 NAME

Set::Scalar - basic set operations

=head1 SYNOPSIS

    use Set::Scalar;
    $s = Set::Scalar->new;
    $s->insert('a', 'b');
    $s->delete('b');
    $t = Set::Scalar->new('x', 'y', $z);

=head1 DESCRIPTION

=head2 Creating

    $s = Set::Scalar->new;
    $s = Set::Scalar->new(@members);

    $t = $s->clone;
    $t = $s->copy;         # Clone of clone.
    $t = $s->empty_clone;  # Like clone() but with no members.

=head2 Modifying

    $s->insert(@members);
    $s->delete(@members);
    $s->invert(@members);  # Insert if hasn't, delete if has.

    $s->clear;  # Removes all the elements.

Note that clear() only releases the memory used by the set to
be reused by Perl; it will not reduce the overall memory use.

=head2 Displaying

    print $s, "\n";

The display format of a set is the members of the set separated by
spaces and enclosed in parentheses ().

You can even display recursive sets.

See L</"Customising Display"> for customising the set display.

=head2 Querying

Assuming a set C<$s>:

    @members  = $s->members;
    @elements = $s->elements;  # Alias for members.

    @$s  # Overloaded alias for members.

    $size = $s->size;  # The number of members.

    $s->has($m)        # Return true if has that member.
    $s->contains($m)   # Alias for has().

    if ($s->has($member)) { ... }

    $s->member($m)     # Returns the member if has that member.
    $s->element($m)    # Alias for member.

    $s->is_null        # Returns true if the set is empty.
    $s->is_empty       # Alias for is_null.

    $s->is_universal   # Returns true if the set is universal.

    $s->null           # The null set.
    $s->empty          # Alias for null.
    $s->universe       # The universe of the set.

=head2 Deriving

    $u = $s->union($t);
    $i = $s->intersection($t);
    $d = $s->difference($t);
    $e = $s->symmetric_difference($t);
    $v = $s->unique($t);
    $c = $s->complement;

These methods have operator overloads:

    $u = $s + $t;  # union
    $i = $s * $t;  # intersection
    $d = $s - $t;  # difference
    $e = $s % $t;  # symmetric_difference
    $v = $s / $t;  # unique
    $c = -$s;      # complement

Both the C<symmetric_difference> and C<unique> are symmetric on all
their arguments.  For two sets they are identical but for more than
two sets beware: C<symmetric_difference> returns true for elements
that are in an odd number (1, 3, 5, ...) of sets, C<unique> returns
true for elements that are in one set.

Some examples of the various set differences:

    set or difference                   value

    $a                                  (a b c d e)
    $b                                  (c d e f g)
    $c                                  (e f g h i)

    $a->difference($b)                  (a b)
    $a->symmetric_difference($b)        (a b f g)
    $a->unique($b)                      (a b f g)

    $b->difference($a)                  (f g)
    $b->symmetric_difference($a)        (a b f g)
    $b->unique($a)                      (a b f g)

    $a->difference($b, $c)              (a b)
    $a->symmetric_difference($b, $c)    (a b e h i)
    $a->unique($b, $c)                  (a b h i)

=head2 Comparing

    $eq = $s->is_equal($t);
    $dj = $s->is_disjoint($t);
    $pi = $s->is_properly_intersecting($t);
    $ps = $s->is_proper_subset($t);
    $pS = $s->is_proper_superset($t);
    $is = $s->is_subset($t);
    $iS = $s->is_superset($t);

    $cmp = $s->compare($t);

The C<compare> method returns a string from the following list:
"equal", "disjoint", "proper subset", "proper superset", "proper
intersect", and in future (once I get around implementing it),
"disjoint universes".

These methods have operator overloads:

    $eq = $s == $t;  # is_equal
    $dj = $s != $t;  # is_disjoint
    # No operator overload for is_properly_intersecting.
    $ps = $s < $t;   # is_proper_subset
    $pS = $s > $t;   # is_proper_superset
    $is = $s <= $t;  # is_subset
    $iS = $s >= $t;  # is_superset

    $cmp = $s <=> $t;

=head2 Boolean contexts

In Boolean contexts such as

    if ($set) { ... }
    while ($set1 && $set2) { ... }

the size of the C<$set> is tested, so empty sets test as false,
and non-empty sets as true.

=head2 Iterating

    while (defined(my $e = $s->each)) { ... }

This is more memory-friendly than

    for my $e ($s->elements) { ... }

which would first construct the full list of elements and then
walk through it: the C<$s-E<gt>each> handles one element at a time.

Analogously to using normal C<each(%hash)> in scalar context,
using C<$s-E<gt>each> has the following caveats:

=over 4

=item *

The elements are returned in (apparently) random order.
So don't expect any particular order.

=item *

When no more elements remain C<undef> is returned.  Since you may one
day have elements named C<0> don't test just like this

    while (my $e = $s->each) { ... }           # WRONG!

but instead like this

    while (defined(my $e = $s->each)) { ... }  # Right.

(An C<undef> as a set element doesn't really work, you get C<"">.)

=item *

There is one iterator per one set which is shared by many
element-accessing interfaces-- using the following will reset the
iterator: elements(), insert(), members(), size(), unique().  insert()
causes the iterator of the set being inserted (not the set being the
target of insertion) becoming reset.  unique() causes the iterators of
all the participant sets becoming reset.  B<The iterator getting reset
most probably causes an endless loop.>  So avoid doing that.

=item *

Modifying the set during the iteration may cause elements to be missed
or duplicated, or in the worst case, an endless loop; so don't do
that, either.

=back

=head2 Cartesian Product and Power Set

=over 4

=item *

Cartesian product is a product of two or more sets.  For two sets, it
is the set consisting of B<ordered pairs> of members from each set.
For example for the sets

  (a b)
  (c d e)

The Cartesian product of the above is the set

  ([a, c] [a, d] [a, e] [b, c] [b, d] [b, e])

The [,] notation is for the ordered pairs, which sets are are not.
This means two things: firstly, that [e, b] is B<not> in the above
Cartesian product, and secondly, [b, b] is a possibility:

  (a b)
  (b c e)

  ([a, b] [a, c] [a, e] [b, b] [b, c] [b, d])

For example:

  my $a = Set::Scalar->new(1..2);
  my $b = Set::Scalar->new(3..5);
  my $c = $a->cartesian_product($b);  # As an object method.
  my $d = Set::Scalar->cartesian_product($a, $b);  # As a class method.

The $c and $d will be of the same class as $a.  The members of $c and
$c in the above will be anonymous arrays (array references), not sets,
since sets wouldn't be able to represent the ordering or that a member
can be present more than once.  Also note that since the members of
the input sets are unordered, the ordered pairs themselves are
unlikely to be in any particular order.

If you don't want to construct the Cartesian product set, you can
construct an iterator and call it while it returns more members:

   my $iter = Set::Scalar->cartesian_product_iterator($a, $b, $c);
   while (my @m = $iter->()) {
     process(@m);
   }

=item *

Power set is the set of all the subsets of a set.  If the set has N
members, its power set has 2**N members.  For example for the set

    (a b c)

size 3, its power set is

    (() (a) (b) (c) (a b) (a c) (b c) (a b c))

size 8.  Note that since the elements of the power set are sets, they
are unordered, and therefore (b c) is equal to (c b).  For example:

    my $a = Set::Scalar->new(1..3);
    my $b = $a->power_set;               # As an object method.
    my $c = Set::Scalar->power_set($a);  # As a class method.

Even the empty set has a power set, of size one.

If you don't want to construct the power set, you can construct an
iterator and call it until it returns no more members:

   my $iter = Set::Scalar->power_set($a);
   my @m;
   do {
     @m = $iter->();
     process(@m);
   } while (@m);

=back

=head2 Customising Display

If you want to customise the display routine you will have to
modify the C<as_string> callback.  You can modify it either
for all sets by using C<as_string_callback()> as a class method:

    my $class_callback = sub { ... };

    Set::Scalar->as_string_callback($class_callback);

or for specific sets by using C<as_string_callback()> as an object
method:

    my $callback = sub  { ... };

    $s1->as_string_callback($callback);
    $s2->as_string_callback($callback);

The anonymous subroutine gets as its first (and only) argument the
set to display as a string.  For example to display the set C<$s>
as C<a-b-c-d-e> instead of C<(a b c d e)>

    $s->as_string_callback(sub{join("-",sort $_[0]->elements)});

If called without an argument, the current callback is returned.

If called as a class method with undef as the only argument, the
original callback (the one returning C<(a b c d e)>) for all the sets
is restored, or if called for a single set the callback is removed
(and the callback for all the sets will be used).

=head1 CAVEATS

The first priority of Set::Scalar is to be a convenient interface to sets.
While not designed to be slow or big, neither has it been designed to
be fast or compact.

Using references (or objects) as set members has not been extensively
tested.  The desired semantics are not always clear: what should
happen when the elements behind the references change? Especially
unclear is what should happen when the objects start having their
own stringification overloads.

=head1 SEE ALSO

Set::Bag for bags (multisets, counted sets), and Bit::Vector for fast
set operations (you have to take care of the element name to bit
number and back mappings yourself), or Set::Infinite for sets of
intervals, and many more.  CPAN is your friend.

=head1 AUTHOR

Jarkko Hietaniemi <jhi@iki.fi>

=head1 COPYRIGHT AND LICENSE

Copyright 2001,2002,2003,2004,2005,2007,2009 by Jarkko Hietaniemi

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;