Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It currently does union, intersection and set difference. It contains methods for checking subset and superset relationships. There are two sets of ops for the above: one unicode set and one 'Texas' parenthesized set. This is all a bit above and beyond the current spec, but quite close to what I envision for core.
- Loading branch information
Carl Masak
committed
Mar 19, 2010
1 parent
9affb78
commit c05da93
Showing
2 changed files
with
159 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
class Set does Associative { | ||
# We could use a hash here, but right now hash keys coerce to Str, | ||
# so instead let's use an array and &uniq for the time being. | ||
has @!elems; | ||
|
||
multi method new(@elems) { | ||
self.bless(self.CREATE, :elems( uniq @elems )); | ||
} | ||
multi method new(*@elems) { | ||
self.bless(self.CREATE, :elems( uniq @elems )); | ||
} | ||
multi method new(%elems) { | ||
self.bless(self.CREATE, :elems( %elems.keys )); | ||
} | ||
multi method new(Set $set) { | ||
$set; | ||
} | ||
|
||
sub contains(@array, $value) { | ||
for @array { | ||
if $value === $_ { | ||
return True; | ||
} | ||
} | ||
return False; | ||
} | ||
|
||
method keys() { @!elems } | ||
method values() { True xx +@!elems } | ||
method elems() { +@!elems } | ||
method exists($elem) { contains(@!elems, $elem) } | ||
|
||
method Num() { +self.elems } | ||
method Bool() { ?self.elems } | ||
|
||
multi method union(@otherset) { | ||
self.new((@!elems, @otherset)); | ||
} | ||
multi method union(%otherset) { | ||
self.union(%otherset.keys); | ||
} | ||
|
||
multi method intersection(@otherset) { | ||
self.new(grep { contains(@otherset, $_) }, @!elems); | ||
} | ||
multi method intersection(%otherset) { | ||
self.intersection(%otherset.keys); | ||
} | ||
|
||
multi method difference(%otherset) { | ||
self.difference(%otherset.keys); | ||
} | ||
multi method difference(@otherset) { | ||
self.new(grep { !contains(@otherset, $_) }, @!elems); | ||
} | ||
|
||
multi method subsetorequal(@otherset) { | ||
?contains(@otherset, all(@!elems)); | ||
} | ||
multi method subsetorequal(%otherset) { | ||
self.subsetorequal(%otherset.keys); | ||
} | ||
|
||
multi method supersetorequal(@otherset) { | ||
?contains(@!elems, all(@otherset)); | ||
} | ||
multi method supersetorequal(%otherset) { | ||
self.supersetorequal(%otherset.keys); | ||
} | ||
|
||
method equal($otherset) { | ||
+self == +$otherset && self.subsetorequal($otherset); | ||
} | ||
|
||
method subset($otherset) { | ||
+self < +Set.new($otherset) && self.subsetorequal($otherset); | ||
} | ||
|
||
method superset($otherset) { | ||
+self > +Set.new($otherset) && self.supersetorequal($otherset); | ||
} | ||
|
||
method perl() { | ||
'Set.new(' ~ join(', ', map { .perl }, @!elems) ~ ')'; | ||
} | ||
} | ||
|
||
multi sub infix:<∪>(Set $a, %b) { $a.union(%b) } | ||
multi sub infix:<∪>( %a, %b) { Set.new( %a).union(%b) } | ||
multi sub infix:<∪>( @a, %b) { Set.new(|@a).union(%b) } | ||
multi sub infix:<∪>( @a, @b) { Set.new(|@a).union(@b) } | ||
|
||
multi sub infix:<∩>(Set $a, %b) { $a.intersection(%b) } | ||
multi sub infix:<∩>( %a, %b) { Set.new( %a).intersection(%b) } | ||
multi sub infix:<∩>( @a, %b) { Set.new(|@a).intersection(%b) } | ||
multi sub infix:<∩>( @a, @b) { Set.new(|@a).intersection(@b) } | ||
|
||
multi sub infix:<∖>(Set $a, %b) { $a.difference(%b) } | ||
multi sub infix:<∖>( %a, %b) { Set.new( %a).difference(%b) } | ||
multi sub infix:<∖>( @a, %b) { Set.new(|@a).difference(%b) } | ||
multi sub infix:<∖>( @a, @b) { Set.new(|@a).difference(@b) } | ||
|
||
multi sub infix:<⊆>(Set $a, %b) { $a.subsetorequal(%b) } | ||
multi sub infix:<⊆>( %a, %b) { Set.new( %a).subsetorequal(%b) } | ||
multi sub infix:<⊆>( @a, %b) { Set.new(|@a).subsetorequal(%b) } | ||
multi sub infix:<⊆>( @a, @b) { Set.new(|@a).subsetorequal(@b) } | ||
|
||
multi sub infix:<⊇>(Set $a, %b) { $a.supersetorequal(%b) } | ||
multi sub infix:<⊇>( %a, %b) { Set.new( %a).supersetorequal(%b) } | ||
multi sub infix:<⊇>( @a, %b) { Set.new(|@a).supersetorequal(%b) } | ||
multi sub infix:<⊇>( @a, @b) { Set.new(|@a).supersetorequal(@b) } | ||
|
||
multi sub infix:<⊂>(Set $a, %b) { $a.subset(%b) } | ||
multi sub infix:<⊂>( %a, %b) { Set.new( %a).subset(%b) } | ||
multi sub infix:<⊂>( @a, %b) { Set.new(|@a).subset(%b) } | ||
multi sub infix:<⊂>( @a, @b) { Set.new(|@a).subset(@b) } | ||
|
||
multi sub infix:<⊃>(Set $a, %b) { $a.superset(%b) } | ||
multi sub infix:<⊃>( %a, %b) { Set.new( %a).superset(%b) } | ||
multi sub infix:<⊃>( @a, %b) { Set.new(|@a).superset(%b) } | ||
multi sub infix:<⊃>( @a, @b) { Set.new(|@a).superset(@b) } | ||
|
||
multi sub infix:<(|)>(Set $a, %b) { $a.union(%b) } | ||
multi sub infix:<(|)>( %a, %b) { Set.new( %a).union(%b) } | ||
multi sub infix:<(|)>( @a, %b) { Set.new(|@a).union(%b) } | ||
multi sub infix:<(|)>( @a, @b) { Set.new(|@a).union(@b) } | ||
|
||
multi sub infix:<(&)>(Set $a, %b) { $a.intersection(%b) } | ||
multi sub infix:<(&)>( %a, %b) { Set.new( %a).intersection(%b) } | ||
multi sub infix:<(&)>( @a, %b) { Set.new(|@a).intersection(%b) } | ||
multi sub infix:<(&)>( @a, @b) { Set.new(|@a).intersection(@b) } | ||
|
||
multi sub infix:<(-)>(Set $a, %b) { $a.difference(%b) } | ||
multi sub infix:<(-)>( %a, %b) { Set.new( %a).difference(%b) } | ||
multi sub infix:<(-)>( @a, %b) { Set.new(|@a).difference(%b) } | ||
multi sub infix:<(-)>( @a, @b) { Set.new(|@a).difference(@b) } | ||
|
||
multi sub infix:<(<=)>(Set $a, %b) { $a.subsetorequal(%b) } | ||
multi sub infix:<(<=)>( %a, %b) { Set.new( %a).subsetorequal(%b) } | ||
multi sub infix:<(<=)>( @a, %b) { Set.new(|@a).subsetorequal(%b) } | ||
multi sub infix:<(<=)>( @a, @b) { Set.new(|@a).subsetorequal(@b) } | ||
|
||
multi sub infix:«(>=)»(Set $a, %b) { $a.supersetorequal(%b) } | ||
multi sub infix:«(>=)»( %a, %b) { Set.new( %a).supersetorequal(%b) } | ||
multi sub infix:«(>=)»( @a, %b) { Set.new(|@a).supersetorequal(%b) } | ||
multi sub infix:«(>=)»( @a, @b) { Set.new(|@a).supersetorequal(@b) } | ||
|
||
multi sub infix:<(<)>(Set $a, %b) { $a.subset(%b) } | ||
multi sub infix:<(<)>( %a, %b) { Set.new( %a).subset(%b) } | ||
multi sub infix:<(<)>( @a, %b) { Set.new(|@a).subset(%b) } | ||
multi sub infix:<(<)>( @a, @b) { Set.new(|@a).subset(@b) } | ||
|
||
multi sub infix:«(>)»(Set $a, %b) { $a.superset(%b) } | ||
multi sub infix:«(>)»( %a, %b) { Set.new( %a).superset(%b) } | ||
multi sub infix:«(>)»( @a, %b) { Set.new(|@a).superset(%b) } | ||
multi sub infix:«(>)»( @a, @b) { Set.new(|@a).superset(@b) } | ||
|
||
# vim: ft=perl6 |