line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Lingua::EN::Inflexion::Term; |
2
|
|
|
|
|
|
|
|
3
|
24
|
|
|
24
|
|
370
|
use 5.010; use warnings; use Carp; |
|
24
|
|
|
24
|
|
66
|
|
|
24
|
|
|
24
|
|
104
|
|
|
24
|
|
|
|
|
35
|
|
|
24
|
|
|
|
|
566
|
|
|
24
|
|
|
|
|
104
|
|
|
24
|
|
|
|
|
46
|
|
|
24
|
|
|
|
|
1295
|
|
4
|
24
|
|
|
24
|
|
9399
|
no if $] >= 5.018, warnings => "experimental::smartmatch"; |
|
24
|
|
|
|
|
292
|
|
|
24
|
|
|
|
|
120
|
|
5
|
|
|
|
|
|
|
|
6
|
24
|
|
|
24
|
|
8466
|
use Hash::Util 'fieldhash'; |
|
24
|
|
|
|
|
50892
|
|
|
24
|
|
|
|
|
129
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
fieldhash my %term_of; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# Inside-out constructor... |
11
|
|
|
|
|
|
|
sub new { |
12
|
25086
|
|
|
25086
|
0
|
45162
|
my ($class, $term) = @_; |
13
|
|
|
|
|
|
|
|
14
|
25086
|
|
|
|
|
34607
|
my $object = bless do{ \my $scalar }, $class; |
|
25086
|
|
|
|
|
55311
|
|
15
|
|
|
|
|
|
|
|
16
|
25086
|
|
33
|
|
|
143396
|
$term_of{$object} = $term // croak "Missing arg to $class ctor"; |
17
|
|
|
|
|
|
|
|
18
|
25086
|
|
|
|
|
105948
|
return $object; |
19
|
|
|
|
|
|
|
} |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# Replicate casing... |
22
|
|
|
|
|
|
|
my $encase = sub { |
23
|
|
|
|
|
|
|
my ($original, $target) = @_; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# Special case for 'I' <-> 'we'... |
26
|
|
|
|
|
|
|
return $target if $original =~ /\A(?:I|we)\Z/i; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Construct word-by-word case transformations... |
29
|
|
|
|
|
|
|
my @transforms |
30
|
|
|
|
|
|
|
= map { /\A[[:lower:][:^alpha:]]+\Z/ ? sub { lc shift } |
31
|
|
|
|
|
|
|
: /\A[[:upper:]][[:lower:][:^alpha:]]+\Z/ ? sub { ucfirst lc shift } |
32
|
|
|
|
|
|
|
: /\A[[:upper:][:^alpha:]]+\Z/ ? sub { uc shift } |
33
|
|
|
|
|
|
|
: sub { shift } |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
split /\s+/, $original; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
if (!@transforms) { |
38
|
|
|
|
|
|
|
@transforms = sub {shift}; |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Apply to target... |
42
|
|
|
|
|
|
|
$target =~ s{(\S+)} |
43
|
|
|
|
|
|
|
{ my $transform = @transforms > 1 ? shift @transforms : $transforms[0]; |
44
|
|
|
|
|
|
|
$transform->($1); |
45
|
|
|
|
|
|
|
}xmseg; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
return $target; |
48
|
|
|
|
|
|
|
}; |
49
|
|
|
|
|
|
|
|
50
|
0
|
|
|
0
|
0
|
0
|
# Report part-of-speech... |
51
|
0
|
|
|
0
|
0
|
0
|
sub is_noun { 0 } |
52
|
0
|
|
|
0
|
0
|
0
|
sub is_verb { 0 } |
53
|
|
|
|
|
|
|
sub is_adj { 0 } |
54
|
|
|
|
|
|
|
|
55
|
0
|
|
|
0
|
0
|
0
|
# Default classical/unassimilated mode does nothing... |
56
|
0
|
|
|
0
|
0
|
0
|
sub classical { return shift; } |
57
|
|
|
|
|
|
|
sub unassimilated { return shift->classical; } |
58
|
|
|
|
|
|
|
|
59
|
24
|
|
|
24
|
|
39878
|
# Coerce to original... |
|
24
|
|
|
|
|
50
|
|
|
24
|
|
|
|
|
6235
|
|
60
|
|
|
|
|
|
|
use Scalar::Util qw< refaddr blessed >; |
61
|
0
|
|
|
0
|
|
0
|
use overload ( |
62
|
0
|
|
|
0
|
|
0
|
q[qr] => sub { return shift->as_regex(); }, |
63
|
0
|
|
|
0
|
|
0
|
q[""] => sub { return "$term_of{shift()}"; }, |
64
|
2
|
|
|
2
|
|
18
|
q[0+] => sub { return refaddr(shift); }, |
65
|
0
|
|
|
0
|
|
0
|
q[bool] => sub { return 1; }, |
66
|
0
|
|
|
0
|
|
0
|
q[${}] => sub { croak "Can't coerce ", ref(shift), ' object to scalar reference'; }, |
67
|
0
|
|
|
0
|
|
0
|
q[@{}] => sub { croak "Can't coerce ", ref(shift), ' object to array reference'; }, |
68
|
0
|
|
|
0
|
|
0
|
q[%{}] => sub { croak "Can't coerce ", ref(shift), ' object to hash reference'; }, |
69
|
0
|
|
|
0
|
|
0
|
q[&{}] => sub { croak "Can't coerce ", ref(shift), ' object to subroutine reference'; }, |
70
|
|
|
|
|
|
|
q[*{}] => sub { croak "Can't coerce ", ref(shift), ' object to typeglob reference'; }, |
71
|
|
|
|
|
|
|
|
72
|
141
|
|
|
141
|
|
276
|
q[~~] => sub { |
73
|
|
|
|
|
|
|
my ($term, $other_arg) = @_; |
74
|
|
|
|
|
|
|
|
75
|
141
|
100
|
66
|
|
|
654
|
# Handle TERM ~~ TERM... |
76
|
47
|
|
66
|
|
|
127
|
if (blessed($other_arg) && $other_arg->isa(__PACKAGE__)) { |
77
|
|
|
|
|
|
|
return lc($term->singular) eq lc($other_arg->singular) |
78
|
|
|
|
|
|
|
|| lc($term->plural) eq lc($other_arg->plural) |
79
|
|
|
|
|
|
|
|| lc($term->classical->plural) eq lc($other_arg->classical->plural); |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# Otherwise just smartmatch against TERM as regex.... |
83
|
94
|
|
|
|
|
223
|
else { |
84
|
|
|
|
|
|
|
return $other_arg ~~ $term->as_regex; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
}, |
87
|
|
|
|
|
|
|
|
88
|
24
|
|
|
|
|
340
|
|
89
|
24
|
|
|
24
|
|
18866
|
fallback => 1, |
|
24
|
|
|
|
|
17237
|
|
90
|
|
|
|
|
|
|
); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# Treat as regex... |
93
|
94
|
|
|
94
|
0
|
175
|
sub as_regex { |
94
|
94
|
|
|
|
|
151
|
my ($self) = @_; |
95
|
94
|
|
|
|
|
233
|
my %seen; |
|
212
|
|
|
|
|
487
|
|
|
282
|
|
|
|
|
963
|
|
96
|
|
|
|
|
|
|
my $pattern = join '|', map { quotemeta } reverse sort grep { !$seen{$_}++ } |
97
|
94
|
|
|
|
|
3366
|
($self->singular, $self->plural, $self->classical->plural); |
98
|
|
|
|
|
|
|
return qr{$pattern}i; |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
package Lingua::EN::Inflexion::Noun; |
103
|
|
|
|
|
|
|
our @ISA = 'Lingua::EN::Inflexion::Term'; |
104
|
24
|
|
|
24
|
|
34255
|
|
|
24
|
|
|
|
|
101
|
|
|
24
|
|
|
|
|
7888
|
|
105
|
24
|
|
|
24
|
|
9026
|
use Lingua::EN::Inflexion::Nouns; |
|
24
|
|
|
|
|
62
|
|
|
24
|
|
|
|
|
23448
|
|
106
|
|
|
|
|
|
|
use Lingua::EN::Inflexion::Indefinite; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# Report number of the noun... |
109
|
2978
|
|
|
2978
|
|
5366
|
sub is_plural { |
110
|
2978
|
|
|
|
|
9175
|
my ($self) = @_; |
111
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Nouns::is_plural( $term_of{$self} ); |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
2405
|
|
|
2405
|
|
3989
|
sub is_singular { |
115
|
2405
|
|
|
|
|
6055
|
my ($self) = @_; |
116
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Nouns::is_singular( $term_of{$self} ); |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
0
|
|
|
0
|
|
0
|
# Report part-of-speech... |
120
|
|
|
|
|
|
|
sub is_noun { 1 } |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# Return plural and singular forms of the noun... |
123
|
6019
|
|
|
6019
|
|
10568
|
sub plural { |
124
|
|
|
|
|
|
|
my ($self) = @_; |
125
|
|
|
|
|
|
|
return $encase->( |
126
|
6019
|
|
|
|
|
18910
|
$term_of{$self}, |
127
|
|
|
|
|
|
|
Lingua::EN::Inflexion::Nouns::convert_to_modern_plural( $term_of{$self} ) |
128
|
|
|
|
|
|
|
); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
11771
|
|
|
11771
|
|
138074
|
sub singular { |
132
|
|
|
|
|
|
|
my ($self) = @_; |
133
|
|
|
|
|
|
|
return $encase->( |
134
|
11771
|
|
|
|
|
39850
|
$term_of{$self}, |
135
|
|
|
|
|
|
|
Lingua::EN::Inflexion::Nouns::convert_to_singular( $term_of{$self} ) |
136
|
|
|
|
|
|
|
); |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
0
|
|
|
0
|
|
0
|
sub indef_article { |
140
|
|
|
|
|
|
|
my ($self) = @_; |
141
|
0
|
|
|
|
|
0
|
|
142
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Indefinite::select_indefinite_article($self->singular); |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
956
|
|
|
956
|
|
3062
|
sub indefinite { |
146
|
956
|
|
100
|
|
|
2817
|
my ($self, $count) = @_; |
147
|
|
|
|
|
|
|
$count //= 1; |
148
|
956
|
100
|
|
|
|
2221
|
|
149
|
478
|
|
|
|
|
1165
|
if ($count == 1 ) { |
150
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Indefinite::prepend_indefinite_article($self->singular); |
151
|
|
|
|
|
|
|
} |
152
|
478
|
|
|
|
|
1496
|
else { |
153
|
|
|
|
|
|
|
return "$count " . $self->plural; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Conversions to ordinal and cardinal numbers (with module loaded on demand)... |
159
|
|
|
|
|
|
|
my $num2word = sub { |
160
|
|
|
|
|
|
|
state $load = require Lingua::EN::Nums2Words && Lingua::EN::Nums2Words::set_case('lower'); |
161
|
|
|
|
|
|
|
Lingua::EN::Nums2Words::num2word(@_); |
162
|
|
|
|
|
|
|
}; |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
my $num2word_short_ordinal = sub { |
165
|
|
|
|
|
|
|
state $load = require Lingua::EN::Nums2Words && Lingua::EN::Nums2Words::set_case('lower'); |
166
|
|
|
|
|
|
|
Lingua::EN::Nums2Words::num2word_short_ordinal(@_); |
167
|
|
|
|
|
|
|
}; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
my $num2word_ordinal = sub { |
170
|
|
|
|
|
|
|
state $load = require Lingua::EN::Nums2Words && Lingua::EN::Nums2Words::set_case('lower'); |
171
|
|
|
|
|
|
|
Lingua::EN::Nums2Words::num2word_ordinal(@_); |
172
|
|
|
|
|
|
|
}; |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# These words may need an "and" before them... |
175
|
|
|
|
|
|
|
my $LAST_WORD = qr{ |
176
|
|
|
|
|
|
|
one | two | three | four | five | six | seven | eight | nine | ten |
177
|
|
|
|
|
|
|
| eleven | twelve | teen | ty |
178
|
|
|
|
|
|
|
| first | second | third | [rfxnhe]th |
179
|
|
|
|
|
|
|
}x; |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# These words may need an "and" after them... |
182
|
|
|
|
|
|
|
my $POWER_WORD = qr{ |
183
|
|
|
|
|
|
|
hundred | thousand | \S+illion |
184
|
|
|
|
|
|
|
}x; |
185
|
|
|
|
|
|
|
|
186
|
2
|
|
|
2
|
|
10
|
sub cardinal { |
187
|
2
|
|
|
|
|
6
|
my $value = $term_of{ shift() }; |
188
|
|
|
|
|
|
|
my $max_trans = shift(); |
189
|
|
|
|
|
|
|
|
190
|
2
|
|
|
|
|
417
|
# Load the necessary module, and compensate for its persnicketiness... |
191
|
0
|
|
|
0
|
|
0
|
state $load = require Lingua::EN::Words2Nums; |
192
|
|
|
|
|
|
|
local $SIG{__WARN__} = sub{}; |
193
|
|
|
|
|
|
|
|
194
|
0
|
|
0
|
|
|
0
|
# Make sure we have a number... |
195
|
|
|
|
|
|
|
$value = Lingua::EN::Words2Nums::words2nums($value) // $value; |
196
|
|
|
|
|
|
|
|
197
|
0
|
0
|
0
|
|
|
0
|
# If it's above threshold, return it as a number... |
198
|
|
|
|
|
|
|
return $value |
199
|
|
|
|
|
|
|
if defined $max_trans && $value >= $max_trans; |
200
|
|
|
|
|
|
|
|
201
|
0
|
|
|
|
|
0
|
# Otherwise, convert it to words... |
202
|
|
|
|
|
|
|
my $words = $num2word->($value); |
203
|
|
|
|
|
|
|
|
204
|
0
|
0
|
|
|
|
0
|
# Correct for proper English pronunciation... |
205
|
0
|
|
|
|
|
0
|
if ($value > 100) { |
206
|
0
|
|
|
|
|
0
|
$words =~ s{ ($POWER_WORD) \s+ (\S*$LAST_WORD) \b } {$1 and $2}gx; |
207
|
0
|
|
|
|
|
0
|
$words =~ s{ (?
|
208
|
|
|
|
|
|
|
$words =~ s{ ^ ([^,]+),([^,]+) $ } {$1$2}x; |
209
|
|
|
|
|
|
|
} |
210
|
0
|
|
|
|
|
0
|
|
211
|
|
|
|
|
|
|
return $words; |
212
|
|
|
|
|
|
|
} |
213
|
|
|
|
|
|
|
|
214
|
0
|
|
|
0
|
|
0
|
sub ordinal { |
215
|
0
|
|
|
|
|
0
|
my $value = $term_of{ shift() }; |
216
|
|
|
|
|
|
|
my $max_trans = shift(); |
217
|
|
|
|
|
|
|
|
218
|
0
|
|
|
|
|
0
|
# Load the necessary module, and compensate for its persnicketiness... |
219
|
0
|
|
|
0
|
|
0
|
state $load = require Lingua::EN::Words2Nums; |
220
|
|
|
|
|
|
|
local $SIG{__WARN__} = sub{}; |
221
|
|
|
|
|
|
|
|
222
|
0
|
|
0
|
|
|
0
|
# Make sure we have a number... |
223
|
|
|
|
|
|
|
$value = Lingua::EN::Words2Nums::words2nums($value) // $value; |
224
|
|
|
|
|
|
|
|
225
|
0
|
0
|
0
|
|
|
0
|
# If it's above threshold, return it as a number... |
226
|
|
|
|
|
|
|
return $num2word_short_ordinal->($value) |
227
|
|
|
|
|
|
|
if defined $max_trans && $value >= $max_trans; |
228
|
|
|
|
|
|
|
|
229
|
0
|
|
|
|
|
0
|
# Otherwise, convert it to words... |
230
|
|
|
|
|
|
|
my $words = $num2word_ordinal->( $value ); |
231
|
|
|
|
|
|
|
|
232
|
0
|
0
|
|
|
|
0
|
# Correct for proper English pronunciation... |
233
|
0
|
|
|
|
|
0
|
if ($value > 100) { |
234
|
0
|
|
|
|
|
0
|
$words =~ s{ ($POWER_WORD) \s+ (\S*$LAST_WORD) \b } {$1 and $2}gx; |
235
|
0
|
|
|
|
|
0
|
$words =~ s{ (?
|
236
|
|
|
|
|
|
|
$words =~ s{ ^ ([^,]+),([^,]+) $ } {$1$2}x; |
237
|
|
|
|
|
|
|
} |
238
|
0
|
|
|
|
|
0
|
|
239
|
|
|
|
|
|
|
return $words; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
|
243
|
4951
|
|
|
4951
|
|
13011
|
# Return a classical version of the term... |
244
|
|
|
|
|
|
|
sub classical { Lingua::EN::Inflexion::Noun::Classical->new(shift) } |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
package Lingua::EN::Inflexion::Noun::Classical; |
248
|
|
|
|
|
|
|
our @ISA = 'Lingua::EN::Inflexion::Noun'; |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
# Inside-out ctor expects a base-class object to clone... |
251
|
4951
|
|
|
4951
|
|
9597
|
sub new { |
252
|
|
|
|
|
|
|
my ($class, $orig_object) = @_; |
253
|
4951
|
|
|
|
|
7106
|
|
|
4951
|
|
|
|
|
9911
|
|
254
|
|
|
|
|
|
|
my $new_object = bless do{ \my $scalar }, $class; |
255
|
4951
|
|
|
|
|
11319
|
|
256
|
|
|
|
|
|
|
$term_of{$new_object} = $orig_object->singular; |
257
|
4951
|
|
|
|
|
20587
|
|
258
|
|
|
|
|
|
|
return $new_object; |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
0
|
|
|
0
|
|
0
|
# Already a classical noun, so this is now idempotent... |
262
|
|
|
|
|
|
|
sub classical { return shift } |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
# Classical plurals are different... |
265
|
4779
|
|
|
4779
|
|
9076
|
sub plural { |
266
|
|
|
|
|
|
|
my ($self) = @_; |
267
|
|
|
|
|
|
|
return $encase->( |
268
|
4779
|
|
|
|
|
15399
|
$term_of{$self}, |
269
|
|
|
|
|
|
|
Lingua::EN::Inflexion::Nouns::convert_to_classical_plural($term_of{$self}) |
270
|
|
|
|
|
|
|
); |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
package Lingua::EN::Inflexion::Verb; |
274
|
|
|
|
|
|
|
our @ISA = 'Lingua::EN::Inflexion::Term'; |
275
|
24
|
|
|
24
|
|
16798
|
|
|
24
|
|
|
|
|
110
|
|
|
24
|
|
|
|
|
30603
|
|
276
|
|
|
|
|
|
|
use Lingua::EN::Inflexion::Verbs; |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
# Utility sub that adjusts final consonants when they need to be doubled in inflexions... |
279
|
|
|
|
|
|
|
my $truncate = sub { |
280
|
|
|
|
|
|
|
my ($term) = @_; |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
# Apply the first relevant transform... |
283
|
|
|
|
|
|
|
$term =~ s{ ie \Z }{y}x |
284
|
|
|
|
|
|
|
or $term =~ s{ ue \Z }{u}x |
285
|
|
|
|
|
|
|
or $term =~ s{ ([auy])e \Z }{$1}x |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
or $term =~ s{ ski \Z }{ski}x |
288
|
|
|
|
|
|
|
or $term =~ s{ [^b]i \Z }{}x |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
or $term =~ s{ ([^e])e \Z }{$1}x |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
or $term =~ m{ er \Z }x |
293
|
|
|
|
|
|
|
or $term =~ s{ (.[bdghklmnprstz][o]([n])) \Z }{$1}x |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
or $term =~ s{ ([^aeiou][aeiouy]([bcdlgmnprstv])) \Z }{$1$2}x |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
or $term =~ s{ e \Z }{}x; |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
return $term; |
300
|
|
|
|
|
|
|
}; |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
# Report status of verb... |
303
|
212
|
|
|
212
|
|
362
|
sub is_plural { |
304
|
212
|
|
|
|
|
561
|
my ($self) = @_; |
305
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Verbs::is_plural( $term_of{$self} ); |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
214
|
|
|
214
|
|
348
|
sub is_singular { |
309
|
214
|
|
|
|
|
736
|
my ($self) = @_; |
310
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Verbs::is_singular( $term_of{$self} ); |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
0
|
|
|
0
|
|
0
|
sub is_present { |
314
|
0
|
|
|
|
|
0
|
my ($self) = @_; |
315
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Verbs::is_present( $term_of{$self} ); |
316
|
|
|
|
|
|
|
} |
317
|
|
|
|
|
|
|
|
318
|
0
|
|
|
0
|
|
0
|
sub is_past { |
319
|
0
|
|
|
|
|
0
|
my ($self) = @_; |
320
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Verbs::is_past( $term_of{$self} ); |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
|
323
|
0
|
|
|
0
|
|
0
|
sub is_pres_part { |
324
|
0
|
|
|
|
|
0
|
my ($self) = @_; |
325
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Verbs::is_pres_part( $term_of{$self} ); |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
0
|
|
|
0
|
|
0
|
sub is_past_part { |
329
|
0
|
|
|
|
|
0
|
my ($self) = @_; |
330
|
|
|
|
|
|
|
return Lingua::EN::Inflexion::Verbs::is_past_part( $term_of{$self} ); |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
0
|
|
|
0
|
|
0
|
# Report part-of-speech... |
334
|
|
|
|
|
|
|
sub is_verb { 1 } |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# Conversions... |
338
|
|
|
|
|
|
|
|
339
|
532
|
|
|
532
|
|
35552
|
sub singular { |
340
|
|
|
|
|
|
|
my ($self) = @_; |
341
|
|
|
|
|
|
|
|
342
|
532
|
|
|
|
|
1530
|
# Is it a known inflexion??? |
343
|
|
|
|
|
|
|
my $inflexion = Lingua::EN::Inflexion::Verbs::convert_to_singular( $term_of{$self} ); |
344
|
|
|
|
|
|
|
|
345
|
532
|
50
|
|
|
|
1662
|
# Return with case-following... |
346
|
|
|
|
|
|
|
return $encase->( $term_of{$self}, $inflexion eq '_' ? $term_of{$self} : $inflexion ); |
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
|
349
|
3664
|
|
|
3664
|
|
5450
|
sub plural { |
350
|
|
|
|
|
|
|
my ($self) = @_; |
351
|
|
|
|
|
|
|
|
352
|
3664
|
|
|
|
|
9358
|
# Is it a known inflexion??? |
353
|
|
|
|
|
|
|
my $inflexion = Lingua::EN::Inflexion::Verbs::convert_to_plural( $term_of{$self} ); |
354
|
|
|
|
|
|
|
|
355
|
3664
|
100
|
|
|
|
11238
|
# Return with case-following... |
356
|
|
|
|
|
|
|
return $encase->( $term_of{$self}, $inflexion eq '_' ? $term_of{$self} : $inflexion ); |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
1024
|
|
|
1024
|
|
107783
|
sub past { |
360
|
1024
|
|
|
|
|
1833
|
my ($self) = @_; |
361
|
1024
|
|
|
|
|
1931
|
my $term = $term_of{$self}; |
362
|
|
|
|
|
|
|
my $root = $self->plural; |
363
|
|
|
|
|
|
|
|
364
|
1024
|
|
|
|
|
2551
|
# Is it a known inflexion??? |
365
|
|
|
|
|
|
|
my $inflexion = Lingua::EN::Inflexion::Verbs::convert_to_past( $term ); |
366
|
1024
|
100
|
|
|
|
2168
|
|
367
|
48
|
|
|
|
|
107
|
if ($inflexion eq '_') { |
368
|
|
|
|
|
|
|
$inflexion = Lingua::EN::Inflexion::Verbs::convert_to_past( $root ); |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
1024
|
100
|
|
|
|
1733
|
# Otherwise use the standard pattern... |
372
|
48
|
|
|
|
|
101
|
if ($inflexion eq '_') { |
373
|
|
|
|
|
|
|
$inflexion = $truncate->($root) . 'ed'; |
374
|
|
|
|
|
|
|
} |
375
|
|
|
|
|
|
|
|
376
|
1024
|
|
|
|
|
1724
|
# Return with case-following... |
377
|
|
|
|
|
|
|
return $encase->( $term, $inflexion ); |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
1023
|
|
|
1023
|
|
108321
|
sub pres_part { |
381
|
1023
|
|
|
|
|
1871
|
my ($self) = @_; |
382
|
1023
|
|
|
|
|
2072
|
my $term = $term_of{$self}; |
383
|
|
|
|
|
|
|
my $root = $self->plural; |
384
|
|
|
|
|
|
|
|
385
|
1023
|
|
|
|
|
2672
|
# Is it a known inflexion??? |
386
|
|
|
|
|
|
|
my $inflexion = Lingua::EN::Inflexion::Verbs::convert_to_pres_part( $root ); |
387
|
|
|
|
|
|
|
|
388
|
1023
|
100
|
|
|
|
2035
|
# Otherwise use the standard pattern... |
389
|
48
|
|
|
|
|
96
|
if ($inflexion eq '_') { |
390
|
|
|
|
|
|
|
$inflexion = $truncate->($root) . 'ing'; |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
1023
|
|
|
|
|
1637
|
# Return with case-following... |
394
|
|
|
|
|
|
|
return $encase->( $term, $inflexion ); |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
1082
|
|
|
1082
|
|
107502
|
sub past_part { |
398
|
1082
|
|
|
|
|
2075
|
my ($self) = @_; |
399
|
1082
|
|
|
|
|
2078
|
my $term = $term_of{$self}; |
400
|
|
|
|
|
|
|
my $root = $self->plural; |
401
|
|
|
|
|
|
|
|
402
|
1082
|
|
|
|
|
2765
|
# Is it a known inflexion??? |
403
|
|
|
|
|
|
|
my $inflexion = Lingua::EN::Inflexion::Verbs::convert_to_past_part( $root ); |
404
|
|
|
|
|
|
|
|
405
|
1082
|
100
|
|
|
|
2194
|
# Otherwise use the standard pattern... |
406
|
48
|
|
|
|
|
101
|
if ($inflexion eq '_') { |
407
|
|
|
|
|
|
|
$inflexion = $truncate->($root) . 'ed'; |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
|
410
|
1082
|
|
|
|
|
1674
|
# Return with case-following... |
411
|
|
|
|
|
|
|
return $encase->( $term, $inflexion ); |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
|
414
|
0
|
|
|
0
|
|
0
|
sub indefinite { |
415
|
0
|
|
0
|
|
|
0
|
my ($self, $count) = @_; |
416
|
|
|
|
|
|
|
$count //= 1; |
417
|
0
|
0
|
|
|
|
0
|
|
418
|
|
|
|
|
|
|
return $count == 1 ? $self->singular |
419
|
|
|
|
|
|
|
: $self->plural; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
package Lingua::EN::Inflexion::Adjective; |
424
|
|
|
|
|
|
|
our @ISA = 'Lingua::EN::Inflexion::Term'; |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
# Load adjective tables, always taking first option... |
427
|
|
|
|
|
|
|
my @adjectives = ( |
428
|
|
|
|
|
|
|
# Determiners... |
429
|
|
|
|
|
|
|
'a' => 'some', |
430
|
|
|
|
|
|
|
'an' => 'some', |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
# Demonstratives... |
433
|
|
|
|
|
|
|
'that' => 'those', |
434
|
|
|
|
|
|
|
'this' => 'these', |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# Possessives... |
437
|
|
|
|
|
|
|
'my' => 'our', |
438
|
|
|
|
|
|
|
'your' => 'your', |
439
|
|
|
|
|
|
|
'their' => 'their', |
440
|
|
|
|
|
|
|
'her' => 'their', |
441
|
|
|
|
|
|
|
'his' => 'their', |
442
|
|
|
|
|
|
|
'its' => 'their', |
443
|
|
|
|
|
|
|
); |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
my (%adj_plural_of, %adj_singular_of, %adj_is_plural, %adj_is_singular); |
446
|
|
|
|
|
|
|
while (my ($sing, $plur) = splice @adjectives, 0, 2) { |
447
|
|
|
|
|
|
|
$adj_is_singular{$sing} = 1; |
448
|
|
|
|
|
|
|
$adj_singular_of{$plur} //= $sing; |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
$adj_is_plural{$plur} = 1; |
451
|
|
|
|
|
|
|
$adj_plural_of{$sing} //= $plur; |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
|
455
|
0
|
|
|
0
|
|
0
|
# Report part-of-speech... |
456
|
|
|
|
|
|
|
sub is_adj { 1 } |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
# Report number of adjective... |
460
|
18
|
|
|
18
|
|
38
|
sub is_plural { |
461
|
18
|
|
|
|
|
43
|
my ($self) = @_; |
462
|
|
|
|
|
|
|
my $term = $term_of{$self}; |
463
|
18
|
|
66
|
|
|
179
|
return $adj_is_plural{$term} || $adj_is_plural{lc $term} |
464
|
|
|
|
|
|
|
|| !$adj_is_singular{$term} && !$adj_is_singular{lc $term}; |
465
|
|
|
|
|
|
|
} |
466
|
|
|
|
|
|
|
|
467
|
22
|
|
|
22
|
|
53
|
sub is_singular { |
468
|
22
|
|
|
|
|
56
|
my ($self) = @_; |
469
|
|
|
|
|
|
|
my $term = $term_of{$self}; |
470
|
22
|
|
66
|
|
|
253
|
return $adj_is_singular{$term} || $adj_is_singular{lc $term} |
471
|
|
|
|
|
|
|
|| !$adj_is_plural{$term} && !$adj_is_plural{lc $term}; |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
# Conversions... |
476
|
|
|
|
|
|
|
|
477
|
18
|
|
|
18
|
|
46
|
sub singular { |
478
|
18
|
|
|
|
|
37
|
my ($self) = @_; |
479
|
18
|
|
|
|
|
37
|
my $term = $term_of{$self}; |
480
|
|
|
|
|
|
|
my $singular = $term;; |
481
|
|
|
|
|
|
|
|
482
|
18
|
100
|
|
|
|
79
|
# Is it a possessive form??? |
483
|
6
|
|
|
|
|
17
|
if ($term =~ m{ \A (.*) 's? \Z }ixms) { |
484
|
|
|
|
|
|
|
$singular = Lingua::EN::Inflexion::Noun->new($1)->singular . q{'s}; |
485
|
|
|
|
|
|
|
} |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
# Otherwise, it's either a known inflexion, or uninflected... |
488
|
12
|
|
66
|
|
|
66
|
else { |
|
|
|
66
|
|
|
|
|
489
|
|
|
|
|
|
|
$singular = $adj_singular_of{$term} // $adj_singular_of{lc $term} // $term; |
490
|
|
|
|
|
|
|
} |
491
|
18
|
|
|
|
|
61
|
|
492
|
|
|
|
|
|
|
return $encase->($term, $singular); |
493
|
|
|
|
|
|
|
} |
494
|
|
|
|
|
|
|
|
495
|
22
|
|
|
22
|
|
56
|
sub plural { |
496
|
22
|
|
|
|
|
56
|
my ($self) = @_; |
497
|
22
|
|
|
|
|
48
|
my $term = $term_of{$self}; |
498
|
|
|
|
|
|
|
my $plural = $term;; |
499
|
|
|
|
|
|
|
|
500
|
22
|
100
|
|
|
|
104
|
# Is it a possessive form??? |
501
|
6
|
|
|
|
|
28
|
if ($term =~ m{ \A (.*) 's? \Z }ixms) { |
502
|
6
|
|
|
|
|
48
|
$plural = Lingua::EN::Inflexion::Noun->new($1)->plural . q{'s}; |
503
|
|
|
|
|
|
|
$plural =~ s{ s's \Z }{s'}xms |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
# Otherwise, it's either a known inflexion, or uninflected... |
507
|
16
|
|
66
|
|
|
103
|
else { |
|
|
|
66
|
|
|
|
|
508
|
|
|
|
|
|
|
$plural = $adj_plural_of{$term} // $adj_plural_of{lc $term} // $term; |
509
|
|
|
|
|
|
|
} |
510
|
22
|
|
|
|
|
64
|
|
511
|
|
|
|
|
|
|
return $encase->($term, $plural); |
512
|
|
|
|
|
|
|
} |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
1; # Magic true value required at end of module |
516
|
|
|
|
|
|
|
__END__ |