package Lingua::EN::Conjugate; use Data::Dumper; @ISA = qw( Exporter ); @EXPORT_OK = qw( conjugate @tenses @pron ); use warnings; use strict; use diagnostics; use vars qw( $VERSION %irreg @pron @tenses %conj ); $VERSION = '0.1'; @pron = qw(I you we he she it they); @tenses = qw( present present_prog past past_prog perfect past_perfect perfect_prog past_perfect_prog modal modal_prog modal_perf modal_perf_prog conjunctive_present imperative ); while () { chomp; my ($verb, $simp, $part) = split /\t/, $_; $verb =~ s/\(.*//; $simp =~ s/\/.*//; $part =~ s/\/.*//; ($verb, $simp, $part) = map {s/ +$//; $_} ($verb, $simp, $part); $irreg{$verb} = {past=>$simp, part=>$part}; #print "$verb, $simp, $part\n"; } sub conjugate { my %params = @_; #print Dumper \%params; my $inf = defined $params{verb}? $params{verb} : warn "must define a verb!!\n", return; my $modal = defined $params{modal}? $params{modal} : 'will'; my @conjs = (); my ($part, $past, $gerund); my $stem = $inf; if ($stem=~/[bcdfghjklmnpqrstvwxyz][aeiou][bcdfghjklmnpqrstv]$/) { #if the word ends in CVC pattern (but final consonant is not w,x,y, or z) # and if the stress is not on the penultimate syllable, then double # the final consonant. # # works for stop, sit, spit, refer, begin, admit, etc. # but breaks for visit, happen, enter, etc. $stem =~ s/(\w)$/$1$1/; } $part = $past = $stem . 'ed' ; $part =~ s/([bcdfghjklmnpqrstvwxyz])eed$/$1ed/; $part =~ s/([bcdfghjklmnpqrstvwxyz])yed$/$1ied/; $gerund = $stem . 'ing'; $gerund =~ s/([bcdfghjklmnpqrstvwxyz])eing$/$1ing/; if ($inf eq 'be') { $gerund = 'being'; } if (defined $irreg{$inf} ) { $part = $irreg{$inf}{part}; $past = $irreg{$inf}{past}; } #print "$inf, $past, $part\n"; my %conj = ( present => {(map {$_ => $_ . " $inf"} qw(I you we they)) , (map {$_ => $_ . " ${inf}s"} qw(he she it)) }, present_prog => {(map {$_ => $_ . " am $gerund"} qw(I)), (map {$_ => $_ . " are $gerund"} qw(you we they)) , (map {$_ => $_ . " is $gerund"} qw(he she it)) }, past => {map {$_ => $_ . " $past"} @pron}, past_prog => {(map {$_ => $_ . " were $gerund"} qw(you we they)) , (map {$_ => $_ . " was $gerund"} qw(I he she it)) }, perfect => {(map {$_ => $_ . " have $part"} qw(I you we they)), (map {$_ => $_ . " has $part"} qw(he she it))}, past_perfect => {map {$_ => $_ . " had $part"} @pron}, perfect_prog => {(map {$_ => $_ . " have been $gerund"} qw(I you we they)), (map {$_ => $_ . " has been $gerund"} qw(he she it))}, past_perfect_prog=>{map {$_ => $_ . " had been $gerund"} @pron}, modal => {map {$_ => $_ . " $modal $inf"} @pron}, modal_prog => {map {$_ => $_ . " $modal be $gerund"} @pron}, modal_perf => {map {$_ => $_ . " $modal have $part"} @pron}, modal_perf_prog => {map {$_ => $_ . " $modal have been $gerund"} @pron}, conjunctive_present => {map {$_ => $_ ." $inf"} @pron}, imperative => { "you"=> "$inf", "we"=>"let's $inf" }, ); if ($inf eq 'be') { $conj{present} = { (map {$_ => $_ . " am"} qw(I)), (map {$_ => $_ . " are"} qw(you we they)) , (map {$_ => $_ . " is"} qw(he she it)) }; $conj{past} = { (map {$_ => $_ . " were"} qw(you we they)) , (map {$_ => $_ . " was"} qw(I he she it)) }; } if (ref $params{pronoun} or ref $params{tense} or !defined $params{pronoun} or !defined $params{tense}) { my $ret = {}; my @t = ref $params{tense}? @{$params{tense}} : defined $params{tense}? $params{tense} : @tenses; for my $t (@t) { #print "$t: \n"; #print Dumper $conj{$t}; #print "\n"; my @p = ref $params{pronoun} ? grep {defined $conj{$t}{$_}} @{$params{pronoun}} : defined $params{pronoun}? $params{pronoun} : grep {defined $conj{$t}{$_}} @pron ; for my $p (@p) { next unless defined $conj{$t}{$p}; $ret->{$t}{$p} = $conj{$t}{$p}; } } if (wantarray) { my @return = (); for my $t (keys %{ $ret }) { for my $p (keys %{ $ret->{$t} }) { push @return, $ret->{$t}{$p}; } } return @return; } else {return $ret} } return $conj{$params{tense}}{$params{pronoun}}; } "true"; =head1 NAME Lingua::EN::Conjugate - Conjugation of English verbs =head1 SYNOPSIS use Lingua::EN::Conjugate qw( conjugate ); use Data::Dumper; # scalar context with tense and pronoun defined as scalars, #returns a scalar my $walk = conjugate( 'verb'=>'walk', 'tense'=>'perfect_prog', 'pronoun'=>'he' ); print $walk . "\n"; # scalar context with tense and pronoun undefined or defined #as array refs, returns a hashref my $go = conjugate( 'verb'=>'go', 'tense'=>[qw(past modal_perf)], 'modal'=>'might not' ) ; print Dumper($go); # array context, returns an array of conjugated forms my @be = conjugate( 'verb'=>'be', 'pronoun'=>[qw(I we)], 'tense'=>'past_prog' ); print join("\n", @be); =head1 DESCRIPTION This module conjugates English verbs. Thanks to Susan Jones for the list of irregular verbs and an explanation of English verb tenses: http://www2.gsu.edu/~wwwesl/egw/grlists.htm. present -> we drive present_prog -> we are driving past -> we drove past_prog -> we were driving perfect -> we have driven past_perfect -> we had driven perfect_prog -> we have been driving past_perfect_prog -> we had been driving modal -> we will drive modal_prog -> we will be driving modal_perf -> we will have driven modal_perf_prog -> we will have been driving conjunctive_present -> we drive imperative -> let's drive note that the "future tense" is called "modal" here, with "will" as the default. You could substitute any of (shall / can / can't / could / must) as the modal verb, and it would still make sense. See http://www.englishclub.com/grammar/verbs-modals_can.htm. I'm not quite sure what to do with "Be able to" asa modal verb. =head2 EXPORT None by default. You can export the following functions and variables: conjugate @tenses @pronouns =head1 BUGS I've tried to implement double-consonants for -ed and -ing ("admitted", "stopping" etc.) The rules for doing so are here: http://www.english-zone.com/spelling/doubles.html. However, the xception to the rule is when thestress is on the penultimate syllable, such as "visit", "open", etc. So I need a list of words ending in CVC, with the stress on the next to the last syllable, to get the spelling right. =head1 HISTORY =over 4 =item 0.1 Original version -- no guarantees. =back =head1 AUTHOR Russ Graham, russgraham@gmail.com =head1 SEE ALSO perl(1). =cut __DATA__ awake awoke awoken be was, were been bear bore born beat beat beat become became become begin began begun bend bent bent beset beset beset bet bet bet bid bid/bade bid/bidden bind bound bound bite bit bitten bleed bled bled blow blew blown break broke broken breed bred bred bring brought brought broadcast broadcast broadcast build built built burn burned/burnt burned/burnt burst burst burst buy bought bought cast cast cast catch caught caught choose chose chosen cling clung clung come came come cost cost cost creep crept crept cut cut cut deal dealt dealt dig dug dug dive dived/dove dived do did done draw drew drawn dream dreamed/dreamt dreamed/dreamt drive drove driven drink drank drunk eat ate eaten fall fell fallen feed fed fed feel felt felt fight fought fought find found found fit fit fit flee fled fled fling flung flung fly flew flown forbid forbade forbidden forget forgot forgotten forego (forgo) forewent foregone forgive forgave forgiven forsake forsook forsaken freeze froze frozen get got gotten give gave given go went gone grind ground ground grow grew grown hang hung hung hear heard heard hide hid hidden hit hit hit hold held held hurt hurt hurt keep kept kept kneel knelt knelt knit knit knit know knew know lay laid laid lead led led leap leaped/lept leaped/lept learn learned/learnt learned/learnt leave left left lend lent lent let let let lie lay lain light lighted/lit lighted lose lost lost make made made mean meant meant meet met met misspell misspelled/misspelt misspelled/misspelt mistake mistook mistaken mow mowed mowed/mown overcome overcame overcome overdo overdid overdone overtake overtook overtaken overthrow overthrew overthrown pay paid paid plead pled pled prove proved proved/proven put put put quit quit quit read read read rid rid rid ride rode ridden ring rang rung rise rose risen run ran run saw sawed sawed/sawn say said said see saw seen seek sought sought sell sold sold send sent sent set set set sew sewed sewed/sewn shake shook shaken shave shaved shaved/shaven shear shore shorn shed shed shed shine shone shone shoe shoed shoed/shod shoot shot shot show showed showed/shown shrink shrank shrunk shut shut shut sing sang sung sink sank sunk sit sat sat sleep slept slept slay slew slain slide slid slid sling slung slung slit slit slit smite smote smitten sow sowed sowed/sown speak spoke spoken speed sped sped spend spent spent spill spilled/spilt spilled/spilt spin spun spun spit spit/spat spit split split split spread spread spread spring sprang/sprung sprung stand stood stood steal stole stolen stick stuck stuck sting stung stung stink stank stunk stride strod stridden strike struck struck string strung strung strive strove striven swear swore sworn sweep swept swept swell swelled swelled/swollen swim swam swum swing swung swung take took taken teach taught taught tear tore torn tell told told think thought thought thrive thrived/throve thrived throw threw thrown thrust thrust thrust tread trod trodden understand understood understood uphold upheld upheld upset upset upset wake woke woken wear wore worn weave weaved/wove weaved/woven wed wed wed weep wept wept wind wound wound win won won withhold withheld withheld withstand withstood withstood wring wrung wrung write wrote written