From c05da93cc378a188c6dcc800c00d06e9b8f3eb74 Mon Sep 17 00:00:00 2001 From: Carl Masak Date: Fri, 19 Mar 2010 15:55:03 +0100 Subject: [PATCH] [Set.pm] new class in core 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. --- build/Makefile.in | 1 + src/core/Set.pm | 158 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/core/Set.pm diff --git a/build/Makefile.in b/build/Makefile.in index 4964305c892..d1f79f440d8 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -172,6 +172,7 @@ CORE_SOURCES = \ src/core/Any-num.pm \ src/core/Any-str.pm \ src/core/Seq.pm \ + src/core/Set.pm \ src/core/Array.pm \ src/core/Int.pm \ src/core/Iterable.pm \ diff --git a/src/core/Set.pm b/src/core/Set.pm new file mode 100644 index 00000000000..cba7efe6c23 --- /dev/null +++ b/src/core/Set.pm @@ -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