/
set_proper_subset.pm
138 lines (128 loc) Β· 4.91 KB
/
set_proper_subset.pm
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
# This file implements the following set operators:
# (<) is a proper subset of (ASCII)
# β is a proper subset of
# β is NOT a proper subset of
# (>) is a proper superset of (ASCII)
# β is a proper superset of
# β
is NOT a proper superset of
proto sub infix:<<(<)>>($, $ --> Bool:D) is pure {*}
multi sub infix:<<(<)>>(Setty:D $a, Setty:D $b --> Bool:D) {
nqp::if(
nqp::eqaddr(nqp::decont($a),nqp::decont($b)),
False, # X is never a true subset of itself
nqp::if(
(my $braw := $b.RAW-HASH) && nqp::elems($braw),
nqp::if(
(my $araw := $a.RAW-HASH) && nqp::elems($araw),
nqp::if(
nqp::islt_i(nqp::elems($araw),nqp::elems($braw))
&& (my $iter := nqp::iterator($araw)),
nqp::stmts( # A has fewer elems than B
nqp::while(
$iter,
nqp::unless(
nqp::existskey($braw,nqp::iterkey_s(nqp::shift($iter))),
return False # elem in A doesn't exist in B
)
),
True # all elems in A exist in B
),
False # number of elems in B smaller or equal to A
),
True # no elems in A, and elems in B
),
False # can never have fewer elems in A than in B
)
)
}
multi sub infix:<<(<)>>(Setty:D $a, Mixy:D $b --> Bool:D) { $a.Mix (<) $b }
multi sub infix:<<(<)>>(Setty:D $a, Baggy:D $b --> Bool:D) { $a.Bag (<) $b }
multi sub infix:<<(<)>>(Setty:D $a, Any $b --> Bool:D) { $a (<) $b.Set }
multi sub infix:<<(<)>>(Mixy:D $a, Mixy:D $b --> Bool:D) {
Rakudo::QuantHash.MIX-IS-PROPER-SUBSET($a,$b)
}
multi sub infix:<<(<)>>(Mixy:D $a, Baggy:D $b --> Bool:D) {
Rakudo::QuantHash.MIX-IS-PROPER-SUBSET($a,$b)
}
multi sub infix:<<(<)>>(Mixy:D $a, Any $b --> Bool:D) { $a (<) $b.Mix }
multi sub infix:<<(<)>>(Baggy:D $a, Mixy:D $b --> Bool:D) {
Rakudo::QuantHash.MIX-IS-PROPER-SUBSET($a,$b)
}
multi sub infix:<<(<)>>(Baggy:D $a, Baggy:D $b --> Bool:D) {
nqp::if(
nqp::eqaddr(nqp::decont($a),nqp::decont($b)),
False, # never proper subset of self
nqp::if( # different objects
(my $araw := $a.RAW-HASH) && (my $iter := nqp::iterator($araw)),
nqp::if( # elements on left
(my $braw := $b.RAW-HASH) && nqp::elems($braw),
nqp::if( # elements on both sides
nqp::isle_i(nqp::elems($araw),nqp::elems($braw)),
nqp::stmts( # equal number of elements on either side
(my int $less = 0),
nqp::while(
$iter,
nqp::if(
(my $left := nqp::getattr(
nqp::iterval(nqp::shift($iter)),
Pair,
'$!value'
))
>
(my $right := nqp::getattr(
nqp::ifnull(
nqp::atkey($braw,nqp::iterkey_s($iter)),
BEGIN nqp::p6bindattrinvres( # virtual 0
nqp::create(Pair),Pair,'$!value',0)
),
Pair,
'$!value'
)),
(return False), # too many on left, we're done
nqp::unless($less,$less = $left < $right)
)
),
nqp::p6bool( # ok so far, must have lower total or fewer keys
$less || nqp::islt_i(nqp::elems($araw),nqp::elems($braw))
)
),
False # more keys on left
),
False # keys on left, no keys on right
),
nqp::p6bool( # no keys on left
($braw := $b.RAW-HASH) && nqp::elems($braw)
)
)
)
}
multi sub infix:<<(<)>>(Baggy:D $a, Any $b --> Bool:D) { $a (<) $b.Bag }
multi sub infix:<<(<)>>(Any $a, Mixy:D $b --> Bool:D) { $a.Mix (<) $b }
multi sub infix:<<(<)>>(Any $a, Baggy:D $b --> Bool:D) { $a.Bag (<) $b }
multi sub infix:<<(<)>>(Any $a, Any $b --> Bool:D) {
nqp::if(
nqp::eqaddr(nqp::decont($a),nqp::decont($b)),
False, # X is never a true subset of itself
$a.Set (<) $b.Set
)
}
multi sub infix:<<(<)>>(Failure $a, Any $b) { $a.throw }
multi sub infix:<<(<)>>(Any $a, Failure $b) { $b.throw }
# U+2282 SUBSET OF
my constant &infix:<β> := &infix:<<(<)>>;
# U+2284 NOT A SUBSET OF
only sub infix:<β>($a, $b --> Bool:D) is pure {
not $a (<) $b;
}
only sub infix:<<(>)>>(Any $a, Any $b --> Bool:D) {
$b (<) $a
}
# U+2283 SUPERSET OF
only sub infix:<β>($a, $b --> Bool:D) is pure {
$b (<) $a
}
# U+2285 NOT A SUPERSET OF
only sub infix:<β
>($a, $b --> Bool:D) is pure {
not $b (<) $a
}
# vim: ft=perl6 expandtab sw=4