| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Coy; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | BEGIN | 
| 4 |  |  |  |  |  |  | { | 
| 5 | 1 |  |  | 1 |  | 6 | require Exporter; | 
| 6 | 1 |  |  |  |  | 16 | @ISA = ('Exporter'); | 
| 7 | 1 |  |  |  |  | 3 | @EXPORT = qw(transcend enlighten); | 
| 8 | 1 |  |  |  |  | 4 | $VERSION = '0.06'; | 
| 9 |  |  |  |  |  |  |  | 
| 10 | 1 |  |  |  |  | 4 | my $USER_CONFIG_FILE = "$ENV{HOME}/.coyrc"; | 
| 11 |  |  |  |  |  |  |  | 
| 12 | 1 |  |  | 1 |  | 1109 | use Carp (); | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 63 |  | 
| 13 |  |  |  |  |  |  |  | 
| 14 | 0 |  |  | 0 | 0 | 0 | sub transcend { &Carp::croak } | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 0 |  |  | 0 | 0 | 0 | sub enlighten { &Carp::carp } | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | # THE REAL WORK STARTS HERE | 
| 19 |  |  |  |  |  |  |  | 
| 20 | 1 |  |  | 1 |  | 1349 | use Lingua::EN::Inflect qw(PL_N PL_V NO inflect NUM A PART_PRES NUMWORDS); | 
|  | 1 |  |  |  |  | 22371 |  | 
|  | 1 |  |  |  |  | 187 |  | 
| 21 | 1 |  |  | 1 |  | 579 | use Lingua::EN::Hyphenate; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 1103 |  | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | sub random | 
| 24 |  |  |  |  |  |  | { | 
| 25 | 0 |  |  | 0 | 0 | 0 | for (1..100) | 
| 26 |  |  |  |  |  |  | { | 
| 27 | 0 |  |  |  |  | 0 | my $choice = $_[int rand @_]; | 
| 28 | 0 | 0 |  |  |  | 0 | my $selection = (ref($choice) eq 'CODE') | 
| 29 |  |  |  |  |  |  | ? $choice->() | 
| 30 |  |  |  |  |  |  | : $choice; | 
| 31 | 0 | 0 |  |  |  | 0 | return $selection if defined $selection; | 
| 32 |  |  |  |  |  |  | } | 
| 33 | 0 |  |  |  |  | 0 | die "couldn't randomize: " . join(", ", @_) . "at " . (caller)[2]; | 
| 34 |  |  |  |  |  |  | } | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | sub syl_count | 
| 37 |  |  |  |  |  |  | { | 
| 38 | 0 |  |  | 0 | 0 | 0 | my $count = 0; | 
| 39 | 0 |  |  |  |  | 0 | my $word; | 
| 40 | 0 |  |  |  |  | 0 | foreach $word (split / /, $_[0]) | 
| 41 |  |  |  |  |  |  | { | 
| 42 | 0 | 0 |  |  |  | 0 | $word =~ /^\d+$/ and $word = NUMWORDS($word); | 
| 43 | 0 |  |  |  |  | 0 | my @syllables = syllables($word); | 
| 44 | 0 |  |  |  |  | 0 | $count += @syllables; | 
| 45 |  |  |  |  |  |  | } | 
| 46 | 0 |  |  |  |  | 0 | return $count; | 
| 47 |  |  |  |  |  |  | } | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | # Personages | 
| 50 |  |  |  |  |  |  |  | 
| 51 | 1 |  |  |  |  | 9 | @Coy::personage = ( "The Jade Emperor", "Master Po", "Mumon", | 
| 52 |  |  |  |  |  |  | "The Seventh Sage", "the Master", "Alan Watts", | 
| 53 |  |  |  |  |  |  | "Tor Kin Tun", "Tom See", "Or Wunt", | 
| 54 |  |  |  |  |  |  | "Homer Simpson", "Lao Tse", "The Buddha", | 
| 55 |  |  |  |  |  |  | "Gautama", "Swordmaster Mushashi", "Con Wei", | 
| 56 |  |  |  |  |  |  | "Joshu", "Bankei", "Ryokan", "Ryonen", "Eshun", | 
| 57 |  |  |  |  |  |  | ); | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | # EXCLAMATIONS | 
| 61 |  |  |  |  |  |  |  | 
| 62 | 1 |  |  |  |  | 2 | my @exclamation = ( 'Oh!', 'See!', ' Look!' ); | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | # LOCATIONS | 
| 66 |  |  |  |  |  |  |  | 
| 67 | 1 |  |  |  |  | 3 | my @aquatic    = qw( pond  river  pool  dam  stream  lake ); | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | sub Aquatic::atRandom | 
| 70 | 0 |  |  | 0 |  | 0 | { random | 
| 71 |  |  |  |  |  |  | "in the " . random(@aquatic), | 
| 72 |  |  |  |  |  |  | "in " . A(random @aquatic) | 
| 73 |  |  |  |  |  |  | ; | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | sub Exoaquatic::atRandom | 
| 77 | 0 |  |  | 0 |  | 0 | { random | 
| 78 |  |  |  |  |  |  | "out of the " . random(@aquatic), | 
| 79 |  |  |  |  |  |  | "from " . A(random @aquatic) | 
| 80 |  |  |  |  |  |  | ; | 
| 81 |  |  |  |  |  |  | } | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | sub Suraquatic::atRandom | 
| 84 | 0 |  |  | 0 |  | 0 | { random | 
| 85 |  |  |  |  |  |  | "on the " . random(@aquatic), | 
| 86 |  |  |  |  |  |  | "on " . A(random @aquatic) | 
| 87 |  |  |  |  |  |  | ; | 
| 88 |  |  |  |  |  |  | } | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | sub Aerial::atRandom | 
| 91 | 0 |  |  | 0 |  | 0 | { random | 
| 92 |  |  |  |  |  |  | "over the " . random(@aquatic), | 
| 93 |  |  |  |  |  |  | "above the " . random(@aquatic), | 
| 94 |  |  |  |  |  |  | "over " . random(@Coy::place), | 
| 95 |  |  |  |  |  |  | "above " . random(@Coy::place), | 
| 96 |  |  |  |  |  |  | "near " . random(@Coy::place) | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | sub Arborial::atRandom | 
| 100 | 0 |  |  | 0 |  | 0 | { random | 
| 101 |  |  |  |  |  |  | "in " . A(random @Coy::tree), | 
| 102 |  |  |  |  |  |  | "in the branches of " . A(random @Coy::tree), | 
| 103 |  |  |  |  |  |  | "in " . A(random @Coy::tree, @Coy::fruit_tree) . " tree", | 
| 104 |  |  |  |  |  |  | "in the branches of " . A(random @Coy::tree, @Coy::fruit_tree) . " tree"; | 
| 105 |  |  |  |  |  |  | } | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | sub Terrestrial::atRandom | 
| 108 | 0 |  |  | 0 |  | 0 | { random | 
| 109 |  |  |  |  |  |  | "under " . A(random @Coy::tree) . random(" tree", ""), | 
| 110 |  |  |  |  |  |  | "near " . random(@Coy::place), | 
| 111 |  |  |  |  |  |  | "beside " . A(random @aquatic); | 
| 112 |  |  |  |  |  |  | } | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | # DIRECTIONS | 
| 116 |  |  |  |  |  |  |  | 
| 117 | 1 |  |  |  |  | 4 | my @horizontalNS = qw( north south ); | 
| 118 | 1 |  |  |  |  | 27 | my @horizontalEW = qw( east west ); | 
| 119 | 1 |  |  |  |  | 3 | my @vertical    = qw( up upwards down downwards ); | 
| 120 | 1 |  |  |  |  | 2 | my @general_dir = qw( away ); | 
| 121 | 1 |  |  |  |  | 2 | my @to_dir_prep    = ( "towards" ); | 
| 122 | 1 |  |  |  |  | 1 | my @from_dir_prep    = ( "away from", ); | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | sub Horizontal::atRandom | 
| 125 | 0 |  |  | 0 |  | 0 | { my $compass = random | 
| 126 |  |  |  |  |  |  | @horizontalNS, | 
| 127 |  |  |  |  |  |  | @horizontalEW, | 
| 128 |  |  |  |  |  |  | random(@horizontalNS).'-'.random(@horizontalEW) | 
| 129 |  |  |  |  |  |  | ; | 
| 130 | 0 |  |  |  |  | 0 | return random | 
| 131 |  |  |  |  |  |  | ($compass x 8, | 
| 132 |  |  |  |  |  |  | @general_dir), | 
| 133 |  |  |  |  |  |  | random(@to_dir_prep)." the ".$compass, | 
| 134 |  |  |  |  |  |  | random(@to_dir_prep, @from_dir_prep)." ".random(@Coy::place); | 
| 135 |  |  |  |  |  |  | } | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | sub Any::atRandom | 
| 138 | 0 |  |  | 0 |  | 0 | { my $compass = random | 
| 139 |  |  |  |  |  |  | @horizontalNS, | 
| 140 |  |  |  |  |  |  | @horizontalEW, | 
| 141 |  |  |  |  |  |  | random(@horizontalNS).'-'.random(@horizontalEW) | 
| 142 |  |  |  |  |  |  | ; | 
| 143 | 0 |  |  |  |  | 0 | return random | 
| 144 |  |  |  |  |  |  | $compass, | 
| 145 |  |  |  |  |  |  | @general_dir, | 
| 146 |  |  |  |  |  |  | random(@to_dir_prep)." the ".$compass, | 
| 147 |  |  |  |  |  |  | random(@to_dir_prep, @from_dir_prep)." ".random(@Coy::place); | 
| 148 | 0 |  |  |  |  | 0 | @vertical; | 
| 149 |  |  |  |  |  |  | } | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | # DATABASE | 
| 152 |  |  |  |  |  |  |  | 
| 153 | 1 |  |  |  |  | 1 | $Coy::agent = {}; | 
| 154 | 1 |  |  |  |  | 2 | $Coy::agent_categories = {}; | 
| 155 | 1 |  |  |  |  | 1 | @Coy::nouns = (); | 
| 156 | 1 |  |  |  |  | 2 | $Coy::associations = ""; | 
| 157 | 1 |  |  |  |  | 1 | my $nonassoc = 0; | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | sub tree | 
| 160 |  |  |  |  |  |  | { | 
| 161 | 1 |  |  | 1 | 0 | 3 | push @Coy::tree, @_; | 
| 162 | 1 |  |  |  |  | 1 | 1; | 
| 163 |  |  |  |  |  |  | } | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | sub fruit_tree | 
| 166 |  |  |  |  |  |  | { | 
| 167 | 1 |  |  | 1 | 0 | 2 | push @Coy::fruit_tree, @_; | 
| 168 | 1 |  |  |  |  | 2 | 1; | 
| 169 |  |  |  |  |  |  | } | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | sub place | 
| 172 |  |  |  |  |  |  | { | 
| 173 | 1 |  |  | 1 | 0 | 4 | push @Coy::place, @_; | 
| 174 | 1 |  |  |  |  | 6 | 1; | 
| 175 |  |  |  |  |  |  | } | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | sub personage | 
| 178 |  |  |  |  |  |  | { | 
| 179 | 0 |  |  | 0 | 0 | 0 | push @Coy::personage, @_; | 
| 180 | 0 |  |  |  |  | 0 | 1; | 
| 181 |  |  |  |  |  |  | } | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | sub noun | 
| 184 |  |  |  |  |  |  | { | 
| 185 | 1 |  |  | 1 | 0 | 2 | my $hashref = shift; | 
| 186 | 1 | 50 |  |  |  | 4 | Carp::croak "Usage: noun " unless ref($hashref) eq 'HASH'; | 
| 187 | 1 |  |  |  |  | 14 | $Coy::agent = { %$Coy::agent, %$hashref }; | 
| 188 |  |  |  |  |  |  | # print STDERR "Added ", scalar keys %$hashref, " to agent\n"; | 
| 189 | 1 |  |  |  |  | 3 | 1; | 
| 190 |  |  |  |  |  |  | } | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | sub categories | 
| 193 |  |  |  |  |  |  | { | 
| 194 | 1 |  |  | 1 | 0 | 2 | my $hashref = shift; | 
| 195 | 1 | 50 |  |  |  | 3 | Carp::croak "Usage: categories " unless ref($hashref) eq 'HASH'; | 
| 196 | 1 |  |  |  |  | 4 | $Coy::agent_categories = { %$Coy::agent_categories, %$hashref }; | 
| 197 |  |  |  |  |  |  | # print STDERR "Added ", scalar keys %$hashref, " to agent_categories\n"; | 
| 198 | 1 |  |  |  |  | 2 | 1; | 
| 199 |  |  |  |  |  |  | } | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | sub syllable_counter | 
| 202 |  |  |  |  |  |  | { | 
| 203 | 1 |  |  | 1 | 0 | 1 | my $sub = shift; | 
| 204 | 1 | 50 |  |  |  | 9 | $sub = \&$sub unless ref $sub; | 
| 205 | 1 |  |  | 1 |  | 6 | no strict; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 1647 |  | 
| 206 | 1 |  |  |  |  | 4 | undef &syllables; | 
| 207 | 1 |  |  | 1 |  | 6 | local $SIG{__WARN__} = sub {}; | 
|  | 1 |  |  |  |  | 5 |  | 
| 208 | 1 |  |  |  |  | 13 | *syllables = $sub; | 
| 209 |  |  |  |  |  |  | } | 
| 210 |  |  |  |  |  |  |  | 
| 211 | 1 |  |  |  |  | 20 | my @count_prob = ((0)x1,(1)x90,(2)x40,(3..5)x2,(6..12)x1); | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | sub get_Noun_Verb | 
| 214 |  |  |  |  |  |  | { | 
| 215 | 0 |  |  | 0 | 0 | 0 | my ($count, $sound, $noun_only) = @_; | 
| 216 | 0 |  |  |  |  | 0 | my ($noun, $verb, $min, $max); | 
| 217 | 0 |  |  |  |  | 0 | my $tries = 0; | 
| 218 | 0 |  |  |  |  | 0 | $nonassoc = 0; | 
| 219 | 0 |  |  |  |  | 0 | while (++$tries) | 
| 220 |  |  |  |  |  |  | { | 
| 221 | 0 |  |  |  |  | 0 | $noun  = random @Coy::nouns; | 
| 222 | 0 | 0 |  |  |  | 0 | return $noun if $noun_only; | 
| 223 | 0 |  |  |  |  | 0 | my @verbs = keys %{$Coy::agent->{$noun}{act}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 224 |  |  |  |  |  |  | # print STDERR "noun = $noun\n"; | 
| 225 |  |  |  |  |  |  | # print STDERR "verbs = @verbs\n"; | 
| 226 | 0 | 0 | 0 |  |  | 0 | push @verbs, @{$Coy::agent->{$noun}{sound}} | 
|  | 0 |  |  |  |  | 0 |  | 
| 227 |  |  |  |  |  |  | if $sound && $Coy::agent->{$noun}{sound}; | 
| 228 | 0 |  |  |  |  | 0 | $verb = random @verbs; | 
| 229 |  |  |  |  |  |  | # print STDERR "[trying $noun/$verb for $count"; | 
| 230 |  |  |  |  |  |  | # print STDERR " (non-assoc)" if $nonassoc; | 
| 231 |  |  |  |  |  |  | # print STDERR "]\n"; | 
| 232 | 0 | 0 |  |  |  | 0 | if ($tries>20) { $nonassoc = 1 } | 
|  | 0 |  |  |  |  | 0 |  | 
| 233 | 0 | 0 | 0 |  |  | 0 | if ($Coy::associations && !$nonassoc) | 
| 234 |  |  |  |  |  |  | { | 
| 235 | 0 |  | 0 |  |  | 0 | my $assoc = | 
| 236 |  |  |  |  |  |  | $Coy::agent->{$noun}{act}{$verb}{associations}||""; | 
| 237 |  |  |  |  |  |  | # print "$noun/$verb: [$assoc]->[$Coy::associations]\n"; | 
| 238 | 0 | 0 | 0 |  |  | 0 | next unless $assoc && ($assoc =~ /$Coy::associations/i); | 
| 239 |  |  |  |  |  |  | # print "[$assoc]\n"; | 
| 240 |  |  |  |  |  |  | } | 
| 241 | 0 | 0 |  |  |  | 0 | if ($tries>50) | 
| 242 |  |  |  |  |  |  | { | 
| 243 | 0 |  | 0 |  |  | 0 | $_[0] = $Coy::agent->{$noun}{act}{$verb}{minimum} | 
| 244 |  |  |  |  |  |  | || $Coy::agent->{$noun}{minimum}; | 
| 245 | 0 |  |  |  |  | 0 | last; | 
| 246 |  |  |  |  |  |  | } | 
| 247 | 0 |  |  |  |  | 0 | $min = $Coy::agent->{$noun}{act}{$verb}{minimum}; | 
| 248 | 0 | 0 | 0 |  |  | 0 | $min = $Coy::agent->{$noun}{minimum} | 
|  |  |  | 0 |  |  |  |  | 
| 249 |  |  |  |  |  |  | if !defined ($min) || defined($Coy::agent->{$noun}{minimum}) | 
| 250 |  |  |  |  |  |  | && $min < $Coy::agent->{$noun}{minimum}; | 
| 251 | 0 |  |  |  |  | 0 | $max = $Coy::agent->{$noun}{act}{$verb}{maximum}; | 
| 252 | 0 | 0 | 0 |  |  | 0 | $max = $Coy::agent->{$noun}{maximum} | 
|  |  |  | 0 |  |  |  |  | 
| 253 |  |  |  |  |  |  | if !defined ($max) || defined($Coy::agent->{$noun}{maximum}) | 
| 254 |  |  |  |  |  |  | && $max > $Coy::agent->{$noun}{maximum}; | 
| 255 |  |  |  |  |  |  | # print STDERR "trying $noun/$verb [$min<=$count<=$max]\n"; | 
| 256 | 0 | 0 | 0 |  |  | 0 | last unless (defined($min) && $count < $min || | 
|  |  |  | 0 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
| 257 |  |  |  |  |  |  | defined($max) && $count > $max); | 
| 258 |  |  |  |  |  |  | } | 
| 259 |  |  |  |  |  |  |  | 
| 260 |  |  |  |  |  |  | # print STDERR "[accepted $noun/$verb]\n"; | 
| 261 | 0 |  |  |  |  | 0 | return ($noun, $verb, PART_PRES($verb), | 
| 262 |  |  |  |  |  |  | $Coy::agent->{$noun}{act}{$verb}{non_adjectival}); | 
| 263 |  |  |  |  |  |  | } | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | sub Noun | 
| 266 |  |  |  |  |  |  | { | 
| 267 | 0 |  |  | 0 | 0 | 0 | my $count = random @count_prob; | 
| 268 | 0 |  |  |  |  | 0 | my ($noun,@verb)  = get_Noun_Verb($count,'SOUND','NOUN_ONLY'); | 
| 269 | 0 | 0 |  |  |  | 0 | return $noun if $Coy::agent->{$noun}{personage};; | 
| 270 | 0 |  |  |  |  | 0 | return inflect "NO($noun,$count)"; | 
| 271 |  |  |  |  |  |  | } | 
| 272 |  |  |  |  |  |  |  | 
| 273 |  |  |  |  |  |  | sub Noun_Verb | 
| 274 |  |  |  |  |  |  | { | 
| 275 | 0 |  |  | 0 | 0 | 0 | my $count = random @count_prob; | 
| 276 | 0 |  |  |  |  | 0 | my ($noun,@verb)  = get_Noun_Verb($count,'SOUND'); | 
| 277 | 0 |  |  |  |  | 0 | my $verb = random @verb[0..1]; | 
| 278 | 0 | 0 |  |  |  | 0 | return inflect "$noun PL_V($verb,$count)" if $Coy::agent->{$noun}{personage}; | 
| 279 | 0 |  |  |  |  | 0 | return inflect "NO($noun,$count) PL_V($verb,$count)"; | 
| 280 |  |  |  |  |  |  | } | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | sub Participle_Noun | 
| 283 |  |  |  |  |  |  | { | 
| 284 | 0 |  |  | 0 | 0 | 0 | my $count = random @count_prob; | 
| 285 | 0 |  |  |  |  | 0 | my ($noun,$verb,$participle,$non_adjectival)  = | 
| 286 |  |  |  |  |  |  | get_Noun_Verb($count,'SOUND'); | 
| 287 | 0 | 0 | 0 |  |  | 0 | return if $non_adjectival or $Coy::agent->{$noun}{personage}; | 
| 288 | 0 |  |  |  |  | 0 | return inflect "NO($participle $noun,$count)"; | 
| 289 |  |  |  |  |  |  | } | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | sub Noun_Location | 
| 292 |  |  |  |  |  |  | { | 
| 293 | 0 |  |  | 0 | 0 | 0 | my $count = random @count_prob; | 
| 294 | 0 |  |  |  |  | 0 | my ($noun,@verb)  = get_Noun_Verb($count,'NOUN_ONLY'); | 
| 295 | 0 |  |  |  |  | 0 | my $verb = random @verb[0..1]; | 
| 296 | 0 | 0 |  |  |  | 0 | return undef unless $Coy::agent->{$noun}{act}{$verb[0]}{location}; | 
| 297 | 0 |  |  |  |  | 0 | my $location = $Coy::agent->{$noun}{act}{$verb[0]}{location}->atRandom(); | 
| 298 | 0 | 0 |  |  |  | 0 | return inflect "$noun $location" if $Coy::agent->{$noun}{personage}; | 
| 299 | 0 |  |  |  |  | 0 | return inflect "NO($noun,$count) $location"; | 
| 300 |  |  |  |  |  |  | } | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | sub Noun_Verb_Location | 
| 303 |  |  |  |  |  |  | { | 
| 304 | 0 |  |  | 0 | 0 | 0 | my $count = random @count_prob; | 
| 305 | 0 |  |  |  |  | 0 | my ($noun,@verb)  = get_Noun_Verb($count); | 
| 306 | 0 |  |  |  |  | 0 | my $verb = random @verb[0..1]; | 
| 307 | 0 | 0 |  |  |  | 0 | return undef unless $Coy::agent->{$noun}{act}{$verb[0]}{location}; | 
| 308 | 0 |  |  |  |  | 0 | my $location = $Coy::agent->{$noun}{act}{$verb[0]}{location}->atRandom(); | 
| 309 | 0 | 0 |  |  |  | 0 | return inflect "$noun PL_V($verb,$count) $location" | 
| 310 |  |  |  |  |  |  | if $Coy::agent->{$noun}{personage}; | 
| 311 | 0 |  |  |  |  | 0 | return inflect "NO($noun,$count) PL_V($verb,$count) $location"; | 
| 312 |  |  |  |  |  |  | } | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | sub Noun_Verb_Direction | 
| 315 |  |  |  |  |  |  | { | 
| 316 | 0 |  |  | 0 | 0 | 0 | my $count = random @count_prob; | 
| 317 | 0 |  |  |  |  | 0 | my ($noun,@verb)  = get_Noun_Verb($count); | 
| 318 | 0 |  |  |  |  | 0 | my $verb = random @verb[0..1]; | 
| 319 | 0 | 0 |  |  |  | 0 | return undef unless $Coy::agent->{$noun}{act}{$verb[0]}{direction}; | 
| 320 | 0 |  |  |  |  | 0 | my $direction = $Coy::agent->{$noun}{act}{$verb[0]}{direction}->atRandom(); | 
| 321 | 0 | 0 |  |  |  | 0 | return inflect "$noun PL_V($verb,$count) $direction" | 
| 322 |  |  |  |  |  |  | if $Coy::agent->{$noun}{personage}; | 
| 323 | 0 |  |  |  |  | 0 | return inflect "NO($noun,$count) PL_V($verb,$count) $direction"; | 
| 324 |  |  |  |  |  |  | } | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | sub expand_synonyms | 
| 327 |  |  |  |  |  |  | { | 
| 328 | 1 |  |  | 1 | 0 | 3 | foreach my $noun ( @Coy::nouns ) | 
| 329 |  |  |  |  |  |  | { | 
| 330 | 43 |  |  |  |  | 41 | my %act = %{$Coy::agent->{$noun}{act}}; | 
|  | 43 |  |  |  |  | 254 |  | 
| 331 | 43 |  |  |  |  | 126 | foreach my $verb ( keys %act ) | 
| 332 |  |  |  |  |  |  | { | 
| 333 | 451 | 100 |  |  |  | 917 | if (exists $act{$verb}{synonyms}) | 
| 334 |  |  |  |  |  |  | { | 
| 335 | 183 |  |  |  |  | 163 | foreach my $syn ( @{$act{$verb}{synonyms}} ) | 
|  | 183 |  |  |  |  | 272 |  | 
| 336 |  |  |  |  |  |  | { | 
| 337 | 480 |  |  |  |  | 1322 | $Coy::agent->{$noun}{act}{$syn} | 
| 338 |  |  |  |  |  |  | = $act{$verb}; | 
| 339 |  |  |  |  |  |  | } | 
| 340 |  |  |  |  |  |  | } | 
| 341 |  |  |  |  |  |  | } | 
| 342 |  |  |  |  |  |  | } | 
| 343 |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | sub expand_categories | 
| 346 |  |  |  |  |  |  | { | 
| 347 | 1 |  |  | 1 | 0 | 3 | foreach my $noun ( @Coy::nouns ) | 
| 348 |  |  |  |  |  |  | { | 
| 349 | 23 | 50 |  |  |  | 45 | my $categories = $Coy::agent->{$noun}{category} or next; | 
| 350 | 23 |  |  |  |  | 23 | my %generic_acts = (); | 
| 351 | 23 |  |  |  |  | 27 | foreach my $category ( @$categories ) | 
| 352 |  |  |  |  |  |  | { | 
| 353 | 29 | 50 |  |  |  | 51 | next unless $Coy::agent_categories->{$category}; | 
| 354 | 29 | 50 |  |  |  | 135 | %generic_acts = | 
| 355 | 29 |  |  |  |  | 19 | ( %{$Coy::agent_categories->{$category}{act}||{}}, | 
| 356 |  |  |  |  |  |  | %generic_acts ); | 
| 357 |  |  |  |  |  |  | } | 
| 358 |  |  |  |  |  |  | # print STDERR "expanding $noun with", keys(%generic_acts), "\n"; | 
| 359 | 23 | 100 |  |  |  | 120 | %{$Coy::agent->{$noun}{act}} = | 
|  | 23 |  |  |  |  | 72 |  | 
| 360 | 23 |  |  |  |  | 40 | ( %generic_acts, %{$Coy::agent->{$noun}{act}||{}} ); | 
| 361 |  |  |  |  |  |  | } | 
| 362 | 1 |  |  |  |  | 3 | foreach my $noun ( @Coy::personage ) | 
| 363 |  |  |  |  |  |  | { | 
| 364 | 20 |  |  |  |  | 30 | push @Coy::nouns, $noun; | 
| 365 | 20 |  |  |  |  | 63 | $Coy::agent->{$noun}{category} = [ "Human" ]; | 
| 366 | 20 |  |  |  |  | 39 | $Coy::agent->{$noun}{maximum} = 1; | 
| 367 | 20 |  |  |  |  | 29 | $Coy::agent->{$noun}{minimum} = 1; | 
| 368 | 20 |  |  |  |  | 25 | $Coy::agent->{$noun}{personage} = 1; | 
| 369 | 20 |  | 50 |  |  | 73 | $Coy::agent->{$noun}{act} =  $Coy::agent_categories->{Human}{act}||{}; | 
| 370 |  |  |  |  |  |  | } | 
| 371 |  |  |  |  |  |  | } | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | sub Generate | 
| 374 |  |  |  |  |  |  | { | 
| 375 |  |  |  |  |  |  | local $_ =  random | 
| 376 |  |  |  |  |  |  | ( | 
| 377 | 0 |  |  | 0 |  |  | (sub { Noun }) x 1, | 
| 378 | 0 |  |  | 0 |  |  | (sub { Noun_Location }) x 6, | 
| 379 | 0 |  |  | 0 |  |  | (sub { Noun_Verb }) x 3, | 
| 380 | 0 |  |  | 0 |  |  | (sub { Noun_Verb_Direction }) x 13, | 
| 381 | 0 |  |  | 0 |  |  | (sub { Noun_Verb_Location }) x 13, | 
| 382 | 0 |  |  | 0 | 0 |  | (sub { Participle_Noun }) x 5, | 
|  | 0 |  |  | 0 |  |  |  | 
| 383 |  |  |  |  |  |  | ); | 
| 384 |  |  |  |  |  |  | ; | 
| 385 |  |  |  |  |  |  |  | 
| 386 | 0 |  |  |  |  |  | s/^1(?= )/a/; | 
| 387 | 0 |  |  |  |  |  | s/^2(?= )/random "a pair of", "two"/e; | 
|  | 0 |  |  |  |  |  |  | 
| 388 | 0 |  |  |  |  |  | s/^(\d+)(?= )/NUMWORDS($1)/e; | 
|  | 0 |  |  |  |  |  |  | 
| 389 | 0 | 0 |  |  |  |  | $Coy::associations = "" unless $nonassoc; | 
| 390 | 0 |  |  |  |  |  | return ucfirst $_; | 
| 391 |  |  |  |  |  |  | } | 
| 392 |  |  |  |  |  |  |  | 
| 393 |  |  |  |  |  |  | sub Generate_Sized | 
| 394 |  |  |  |  |  |  | { | 
| 395 | 0 |  |  | 0 | 0 |  | my ($size) = @_; | 
| 396 | 0 |  |  |  |  |  | my $fulltext = ""; | 
| 397 | 0 |  |  |  |  |  | my $fullcount = 0; | 
| 398 | 0 |  |  |  |  |  | while ($fullcount != $size) | 
| 399 |  |  |  |  |  |  | { | 
| 400 | 0 |  |  |  |  |  | my $text = Generate; | 
| 401 | 0 |  |  |  |  |  | my $count = $fullcount + syl_count($text); | 
| 402 | 0 | 0 | 0 |  |  |  | if ($count < $size-1 || $count == $size) | 
| 403 |  |  |  |  |  |  | { | 
| 404 | 0 | 0 |  |  |  |  | $fulltext .= ($fulltext?". ":"").$text; | 
| 405 | 0 |  |  |  |  |  | $fullcount = $count; | 
| 406 |  |  |  |  |  |  | } | 
| 407 |  |  |  |  |  |  | } | 
| 408 | 0 |  |  |  |  |  | return $fulltext; | 
| 409 |  |  |  |  |  |  | } | 
| 410 |  |  |  |  |  |  |  | 
| 411 | 1 |  |  | 1 |  | 876 | use Text::Wrap; | 
|  | 1 |  |  |  |  | 2877 |  | 
|  | 1 |  |  |  |  | 1384 |  | 
| 412 |  |  |  |  |  |  |  | 
| 413 |  |  |  |  |  |  | sub with_haiku | 
| 414 |  |  |  |  |  |  | { | 
| 415 | 0 |  |  | 0 | 0 |  | my $message = join("",@_); | 
| 416 | 0 |  |  |  |  |  | my $file = "Mysterious Compiler"; | 
| 417 | 0 |  |  |  |  |  | my $line = "???"; | 
| 418 | 0 | 0 |  |  |  |  | if ($message =~ s/(.*)at\s(\S+)\sline\s(\d+.*?)\s*\Z/$1/s) | 
|  |  | 0 |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | { | 
| 420 | 0 |  | 0 |  |  |  | $file = $2||$file; | 
| 421 | 0 |  | 0 |  |  |  | $line = $3||$line; | 
| 422 |  |  |  |  |  |  | } | 
| 423 |  |  |  |  |  |  | elsif ($message =~ s/(.*)File\s'([^']+)';\s+Line\s+(\d+.*)/$1/s) | 
| 424 |  |  |  |  |  |  | { | 
| 425 | 0 |  | 0 |  |  |  | $file = $2||$file; | 
| 426 | 0 |  | 0 |  |  |  | $line = $3||$line; | 
| 427 | 0 |  |  |  |  |  | chomp $line; | 
| 428 | 0 |  |  |  |  |  | $file =~ s/^.*://; | 
| 429 |  |  |  |  |  |  | } | 
| 430 |  |  |  |  |  |  |  | 
| 431 | 0 |  |  |  |  |  | associate($message); | 
| 432 |  |  |  |  |  |  |  | 
| 433 | 0 |  |  |  |  |  | my @words = (); | 
| 434 | 0 |  |  |  |  |  | foreach my $word (split /\s+/, Generate_Sized(17)) | 
| 435 |  |  |  |  |  |  | { | 
| 436 | 0 |  |  |  |  |  | push @words, [$word, syl_count($word)]; | 
| 437 |  |  |  |  |  |  | } | 
| 438 |  |  |  |  |  |  |  | 
| 439 | 0 |  |  |  |  |  | my $haiku = ""; | 
| 440 | 0 |  |  |  |  |  | my $count = 0; | 
| 441 | 0 |  |  |  |  |  | while ($count<5) | 
| 442 |  |  |  |  |  |  | { | 
| 443 | 0 |  |  |  |  |  | my $word = shift @words; | 
| 444 | 0 |  |  |  |  |  | $haiku .= "$word->[0] "; | 
| 445 | 0 |  |  |  |  |  | $count+=$word->[1]; | 
| 446 |  |  |  |  |  |  | } | 
| 447 | 0 |  |  |  |  |  | $haiku .= "\n\t"; | 
| 448 | 0 |  |  |  |  |  | while ($count<12) | 
| 449 |  |  |  |  |  |  | { | 
| 450 | 0 |  |  |  |  |  | my $word = shift @words; | 
| 451 | 0 |  |  |  |  |  | $haiku .= "$word->[0] "; | 
| 452 | 0 |  |  |  |  |  | $count+=$word->[1]; | 
| 453 |  |  |  |  |  |  | } | 
| 454 | 0 |  |  |  |  |  | $haiku .= "\n\t"; | 
| 455 | 0 |  |  |  |  |  | $haiku .= join(" ",map {$_->[0]} @words) . "."; | 
|  | 0 |  |  |  |  |  |  | 
| 456 |  |  |  |  |  |  |  | 
| 457 |  |  |  |  |  |  |  | 
| 458 | 0 |  |  |  |  |  | $message = wrap("\t\t","\t\t",$message); | 
| 459 | 0 |  |  |  |  |  | $message =~ s/\t\t//; | 
| 460 |  |  |  |  |  |  |  | 
| 461 | 0 |  |  |  |  |  | my @book = ('Analects of %s', | 
| 462 |  |  |  |  |  |  | 'Sayings of %s', | 
| 463 |  |  |  |  |  |  | 'The Wisdom of %s', | 
| 464 |  |  |  |  |  |  | '"%s Speaks"', | 
| 465 |  |  |  |  |  |  | '"The Way of %s"', | 
| 466 |  |  |  |  |  |  | ); | 
| 467 |  |  |  |  |  |  |  | 
| 468 | 0 |  |  |  |  |  | my $book = sprintf(random(@book),$file); | 
| 469 |  |  |  |  |  |  |  | 
| 470 | 0 |  |  |  |  |  | $where = wrap("\t\t\t","\t\t\t ","($book: line $line)"); | 
| 471 | 0 |  |  |  |  |  | $where =~ s/\t\t\t//; | 
| 472 |  |  |  |  |  |  |  | 
| 473 |  |  |  |  |  |  |  | 
| 474 | 0 |  |  |  |  |  | my $personage = ucfirst random @Coy::personage; | 
| 475 |  |  |  |  |  |  |  | 
| 476 | 0 |  |  |  |  |  | return < | 
| 477 |  |  |  |  |  |  |  | 
| 478 |  |  |  |  |  |  | ----- | 
| 479 |  |  |  |  |  |  | $haiku | 
| 480 |  |  |  |  |  |  | ----- | 
| 481 |  |  |  |  |  |  |  | 
| 482 |  |  |  |  |  |  | ${personage}'s commentary... | 
| 483 |  |  |  |  |  |  |  | 
| 484 |  |  |  |  |  |  | $message | 
| 485 |  |  |  |  |  |  |  | 
| 486 |  |  |  |  |  |  | $where | 
| 487 |  |  |  |  |  |  | MU | 
| 488 |  |  |  |  |  |  | } | 
| 489 |  |  |  |  |  |  |  | 
| 490 |  |  |  |  |  |  | sub associate | 
| 491 |  |  |  |  |  |  | { | 
| 492 | 0 |  |  | 0 | 0 |  | %Coy::associations = (); | 
| 493 | 0 |  |  |  |  |  | my ($message) = @_; | 
| 494 | 0 |  |  |  |  |  | $message =~ s/[^A-Za-z]+/ /g; | 
| 495 | 0 |  |  |  |  |  | my @words = split /\s+/, $message; | 
| 496 | 0 |  |  |  |  |  | $Coy::associations = join "|", grep {$_} @words; | 
|  | 0 |  |  |  |  |  |  | 
| 497 |  |  |  |  |  |  | # $Coy::associations = qr/$Coy::associations/; | 
| 498 |  |  |  |  |  |  | } | 
| 499 |  |  |  |  |  |  |  | 
| 500 |  |  |  |  |  |  | # LOAD STANDARD DATA | 
| 501 |  |  |  |  |  |  |  | 
| 502 | 1 |  |  |  |  | 3 | syllable_counter "Lingua::EN::Hyphenate::syllables"; | 
| 503 |  |  |  |  |  |  |  | 
| 504 | 1 |  |  |  |  | 82 | noun | 
| 505 |  |  |  |  |  |  | { | 
| 506 |  |  |  |  |  |  | duck => | 
| 507 |  |  |  |  |  |  | { | 
| 508 |  |  |  |  |  |  | category => [ Bird ], | 
| 509 |  |  |  |  |  |  | act => | 
| 510 |  |  |  |  |  |  | { | 
| 511 |  |  |  |  |  |  | swims => | 
| 512 |  |  |  |  |  |  | { | 
| 513 |  |  |  |  |  |  | location => Suraquatic, | 
| 514 |  |  |  |  |  |  | direction => Horizontal, | 
| 515 |  |  |  |  |  |  | }, | 
| 516 |  |  |  |  |  |  | }, | 
| 517 |  |  |  |  |  |  | sound => [ "quacks", ] | 
| 518 |  |  |  |  |  |  | }, | 
| 519 |  |  |  |  |  |  | swallow => | 
| 520 |  |  |  |  |  |  | { | 
| 521 |  |  |  |  |  |  | category => [ Bird ], | 
| 522 |  |  |  |  |  |  | act => { swoops => { location => Aerial, } }, | 
| 523 |  |  |  |  |  |  | }, | 
| 524 |  |  |  |  |  |  | raven	   => { category => [ Bird ] }, | 
| 525 |  |  |  |  |  |  | thrush	   => { category => [ Bird ], sound => [ "sings" ]}, | 
| 526 |  |  |  |  |  |  | songbird   => { category => [ Bird ], sound => [ "sings" ]}, | 
| 527 |  |  |  |  |  |  | lark       => { category => [ Bird ], sound => [ "sings" ]}, | 
| 528 |  |  |  |  |  |  | gannet	   => { category => [ Bird ] }, | 
| 529 |  |  |  |  |  |  | dove	   => { category => [ Bird ], sound => [ "coos" ] }, | 
| 530 |  |  |  |  |  |  | kingfisher => { category => [ Bird ] }, | 
| 531 |  |  |  |  |  |  | woodpecker => { category => [ Bird ] }, | 
| 532 |  |  |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | 'carp'	   => { category => [ Fish ] }, | 
| 534 |  |  |  |  |  |  | goldfish   => { category => [ Fish ] }, | 
| 535 |  |  |  |  |  |  | salmon     => { category => [ Fish, Leaper ] }, | 
| 536 |  |  |  |  |  |  | pike       => { category => [ Fish, Leaper ] }, | 
| 537 |  |  |  |  |  |  | trout      => { category => [ Fish, Leaper ] }, | 
| 538 |  |  |  |  |  |  |  | 
| 539 |  |  |  |  |  |  | fox => | 
| 540 |  |  |  |  |  |  | { | 
| 541 |  |  |  |  |  |  | category => [ Animal, Hunter ], | 
| 542 |  |  |  |  |  |  | sound    => [ "barks" ], | 
| 543 |  |  |  |  |  |  | act => | 
| 544 |  |  |  |  |  |  | { | 
| 545 |  |  |  |  |  |  | trots => { location => Terrestrial }, | 
| 546 |  |  |  |  |  |  | }, | 
| 547 |  |  |  |  |  |  | }, | 
| 548 |  |  |  |  |  |  | bear => | 
| 549 |  |  |  |  |  |  | { | 
| 550 |  |  |  |  |  |  | category => [ Animal ], | 
| 551 |  |  |  |  |  |  | sound    => [ "howls" ], | 
| 552 |  |  |  |  |  |  | act      => | 
| 553 |  |  |  |  |  |  | { | 
| 554 |  |  |  |  |  |  | fishes => { location => Aquatic }, | 
| 555 |  |  |  |  |  |  | }, | 
| 556 |  |  |  |  |  |  | }, | 
| 557 |  |  |  |  |  |  | wolf => | 
| 558 |  |  |  |  |  |  | { | 
| 559 |  |  |  |  |  |  | category => [ Animal, Hunter ], | 
| 560 |  |  |  |  |  |  | sound    => [ "howls" ], | 
| 561 |  |  |  |  |  |  | }, | 
| 562 |  |  |  |  |  |  | cat => | 
| 563 |  |  |  |  |  |  | { | 
| 564 |  |  |  |  |  |  | category => [ Animal, Hunter ], | 
| 565 |  |  |  |  |  |  | sound    => [ "purrs", "yowls" ], | 
| 566 |  |  |  |  |  |  | act => | 
| 567 |  |  |  |  |  |  | { | 
| 568 |  |  |  |  |  |  | washes   => { location => Terrestrial }, | 
| 569 |  |  |  |  |  |  | sits     => { location => Terrestrial }, | 
| 570 |  |  |  |  |  |  | }, | 
| 571 |  |  |  |  |  |  | }, | 
| 572 |  |  |  |  |  |  | rabbit => | 
| 573 |  |  |  |  |  |  | { | 
| 574 |  |  |  |  |  |  | category => [ Animal ], | 
| 575 |  |  |  |  |  |  | act => | 
| 576 |  |  |  |  |  |  | { | 
| 577 |  |  |  |  |  |  | sniffs   => { location => Terrestrial }, | 
| 578 |  |  |  |  |  |  | grazes   => { location => Terrestrial }, | 
| 579 |  |  |  |  |  |  | }, | 
| 580 |  |  |  |  |  |  | }, | 
| 581 |  |  |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | "young girl" => | 
| 583 |  |  |  |  |  |  | { | 
| 584 |  |  |  |  |  |  | category => [ Human ], | 
| 585 |  |  |  |  |  |  | act => | 
| 586 |  |  |  |  |  |  | { | 
| 587 |  |  |  |  |  |  | skips => | 
| 588 |  |  |  |  |  |  | { | 
| 589 |  |  |  |  |  |  | location => Terrestrial, | 
| 590 |  |  |  |  |  |  | non_adjectival => 1, | 
| 591 |  |  |  |  |  |  | } | 
| 592 |  |  |  |  |  |  | }, | 
| 593 |  |  |  |  |  |  | }, | 
| 594 |  |  |  |  |  |  | "old man" => | 
| 595 |  |  |  |  |  |  | { | 
| 596 |  |  |  |  |  |  | category => [ Human ], | 
| 597 |  |  |  |  |  |  | act => | 
| 598 |  |  |  |  |  |  | { | 
| 599 |  |  |  |  |  |  | swims => | 
| 600 |  |  |  |  |  |  | { | 
| 601 |  |  |  |  |  |  | location => Aquatic, | 
| 602 |  |  |  |  |  |  | non_adjectival => 1, | 
| 603 |  |  |  |  |  |  | } | 
| 604 |  |  |  |  |  |  | }, | 
| 605 |  |  |  |  |  |  | }, | 
| 606 |  |  |  |  |  |  | lover => | 
| 607 |  |  |  |  |  |  | { | 
| 608 |  |  |  |  |  |  | category => [ Human ], | 
| 609 |  |  |  |  |  |  | minimum  => 2, | 
| 610 |  |  |  |  |  |  | maximum  => 2, | 
| 611 |  |  |  |  |  |  | act => | 
| 612 |  |  |  |  |  |  | { | 
| 613 |  |  |  |  |  |  | kisses => { location => Terrestrial, }, | 
| 614 |  |  |  |  |  |  | cuddles => { location => Terrestrial, }, | 
| 615 |  |  |  |  |  |  | touch => { location => Terrestrial, }, | 
| 616 |  |  |  |  |  |  | whisper => { location => Terrestrial, }, | 
| 617 |  |  |  |  |  |  | dance => { location => Terrestrial, }, | 
| 618 |  |  |  |  |  |  | }, | 
| 619 |  |  |  |  |  |  | }, | 
| 620 |  |  |  |  |  |  | }; | 
| 621 |  |  |  |  |  |  |  | 
| 622 | 1 |  |  |  |  | 51 | categories | 
| 623 |  |  |  |  |  |  | { | 
| 624 |  |  |  |  |  |  | Human => | 
| 625 |  |  |  |  |  |  | { | 
| 626 |  |  |  |  |  |  | act => | 
| 627 |  |  |  |  |  |  | { | 
| 628 |  |  |  |  |  |  | dies => | 
| 629 |  |  |  |  |  |  | { | 
| 630 |  |  |  |  |  |  | associations => "die depart exit", | 
| 631 |  |  |  |  |  |  | location => Terrestrial, | 
| 632 |  |  |  |  |  |  | }, | 
| 633 |  |  |  |  |  |  | quarrels => | 
| 634 |  |  |  |  |  |  | { | 
| 635 |  |  |  |  |  |  | associations => "argument", | 
| 636 |  |  |  |  |  |  | location => Terrestrial, | 
| 637 |  |  |  |  |  |  | minimum => 2, | 
| 638 |  |  |  |  |  |  | synonyms => [qw(bickers argues banters fights)], | 
| 639 |  |  |  |  |  |  | }, | 
| 640 |  |  |  |  |  |  | contends => | 
| 641 |  |  |  |  |  |  | { | 
| 642 |  |  |  |  |  |  | associations => "argument", | 
| 643 |  |  |  |  |  |  | location => Terrestrial, | 
| 644 |  |  |  |  |  |  | minimum => 2, | 
| 645 |  |  |  |  |  |  | synonyms => [qw(debates)], | 
| 646 |  |  |  |  |  |  | non_adjectival => 1, | 
| 647 |  |  |  |  |  |  | }, | 
| 648 |  |  |  |  |  |  | sits => | 
| 649 |  |  |  |  |  |  | { | 
| 650 |  |  |  |  |  |  | associations => "rest static stop", | 
| 651 |  |  |  |  |  |  | location => Terrestrial, | 
| 652 |  |  |  |  |  |  | non_adjectival => 1, | 
| 653 |  |  |  |  |  |  | }, | 
| 654 |  |  |  |  |  |  | meets => | 
| 655 |  |  |  |  |  |  | { | 
| 656 |  |  |  |  |  |  | associations => "join together", | 
| 657 |  |  |  |  |  |  | location => Terrestrial, | 
| 658 |  |  |  |  |  |  | minimum => 2, | 
| 659 |  |  |  |  |  |  | non_adjectival => 1, | 
| 660 |  |  |  |  |  |  | synonyms => [qw(encounters)], | 
| 661 |  |  |  |  |  |  | }, | 
| 662 |  |  |  |  |  |  | laughs => | 
| 663 |  |  |  |  |  |  | { | 
| 664 |  |  |  |  |  |  | associations => "happy", | 
| 665 |  |  |  |  |  |  | location => Terrestrial, | 
| 666 |  |  |  |  |  |  | non_adjectival => 1, | 
| 667 |  |  |  |  |  |  | }, | 
| 668 |  |  |  |  |  |  | parts => | 
| 669 |  |  |  |  |  |  | { | 
| 670 |  |  |  |  |  |  | associations => "leave left miss", | 
| 671 |  |  |  |  |  |  | location => Terrestrial, | 
| 672 |  |  |  |  |  |  | minimum => 2, | 
| 673 |  |  |  |  |  |  | }, | 
| 674 |  |  |  |  |  |  | departs => | 
| 675 |  |  |  |  |  |  | { | 
| 676 |  |  |  |  |  |  | associations => "leave left miss", | 
| 677 |  |  |  |  |  |  | location => Terrestrial, | 
| 678 |  |  |  |  |  |  | }, | 
| 679 |  |  |  |  |  |  | weeps => | 
| 680 |  |  |  |  |  |  | { | 
| 681 |  |  |  |  |  |  | associations => "NEG", | 
| 682 |  |  |  |  |  |  | location => Terrestrial, | 
| 683 |  |  |  |  |  |  | }, | 
| 684 |  |  |  |  |  |  | sighs => | 
| 685 |  |  |  |  |  |  | { | 
| 686 |  |  |  |  |  |  | associations => "NEG", | 
| 687 |  |  |  |  |  |  | location => Terrestrial, | 
| 688 |  |  |  |  |  |  | }, | 
| 689 |  |  |  |  |  |  | embraces => | 
| 690 |  |  |  |  |  |  | { | 
| 691 |  |  |  |  |  |  | associations => "join together with", | 
| 692 |  |  |  |  |  |  | location => Terrestrial, | 
| 693 |  |  |  |  |  |  | minimum => 2, | 
| 694 |  |  |  |  |  |  | maximum => 2, | 
| 695 |  |  |  |  |  |  | }, | 
| 696 |  |  |  |  |  |  | }, | 
| 697 |  |  |  |  |  |  | }, | 
| 698 |  |  |  |  |  |  | Animal => | 
| 699 |  |  |  |  |  |  | { | 
| 700 |  |  |  |  |  |  | act => | 
| 701 |  |  |  |  |  |  | { | 
| 702 |  |  |  |  |  |  | sits => | 
| 703 |  |  |  |  |  |  | { | 
| 704 |  |  |  |  |  |  | associations => "static", | 
| 705 |  |  |  |  |  |  | location => Terrestrial, | 
| 706 |  |  |  |  |  |  | }, | 
| 707 |  |  |  |  |  |  | walks => | 
| 708 |  |  |  |  |  |  | { | 
| 709 |  |  |  |  |  |  | associations => "gone", | 
| 710 |  |  |  |  |  |  | location => Terrestrial, | 
| 711 |  |  |  |  |  |  | non_adjectival => 1, | 
| 712 |  |  |  |  |  |  | }, | 
| 713 |  |  |  |  |  |  | watches => | 
| 714 |  |  |  |  |  |  | { | 
| 715 |  |  |  |  |  |  | associations => "see", | 
| 716 |  |  |  |  |  |  | location => Terrestrial, | 
| 717 |  |  |  |  |  |  | non_adjectival => 1, | 
| 718 |  |  |  |  |  |  | }, | 
| 719 |  |  |  |  |  |  | waits => | 
| 720 |  |  |  |  |  |  | { | 
| 721 |  |  |  |  |  |  | associations => "wait", | 
| 722 |  |  |  |  |  |  | location => Terrestrial, | 
| 723 |  |  |  |  |  |  | non_adjectival => 1, | 
| 724 |  |  |  |  |  |  | }, | 
| 725 |  |  |  |  |  |  | eats => | 
| 726 |  |  |  |  |  |  | { | 
| 727 |  |  |  |  |  |  | associations => 'eat consume use', | 
| 728 |  |  |  |  |  |  | location => Terrestrial, | 
| 729 |  |  |  |  |  |  | non_adjectival => 1, | 
| 730 |  |  |  |  |  |  | } | 
| 731 |  |  |  |  |  |  | }, | 
| 732 |  |  |  |  |  |  | }, | 
| 733 |  |  |  |  |  |  |  | 
| 734 |  |  |  |  |  |  | Hunter => | 
| 735 |  |  |  |  |  |  | { | 
| 736 |  |  |  |  |  |  | act => | 
| 737 |  |  |  |  |  |  | { | 
| 738 |  |  |  |  |  |  | crouches => { location => Terrestrial }, | 
| 739 |  |  |  |  |  |  | prowls   => { location => Terrestrial }, | 
| 740 |  |  |  |  |  |  | stalks   => { location => Terrestrial }, | 
| 741 |  |  |  |  |  |  | leaps    => { location => Terrestrial }, | 
| 742 |  |  |  |  |  |  | }, | 
| 743 |  |  |  |  |  |  | }, | 
| 744 |  |  |  |  |  |  | Fish => | 
| 745 |  |  |  |  |  |  | { | 
| 746 |  |  |  |  |  |  | act => | 
| 747 |  |  |  |  |  |  | { | 
| 748 |  |  |  |  |  |  | darts => | 
| 749 |  |  |  |  |  |  | { | 
| 750 |  |  |  |  |  |  | location => Aquatic, | 
| 751 |  |  |  |  |  |  | }, | 
| 752 |  |  |  |  |  |  | swims => | 
| 753 |  |  |  |  |  |  | { | 
| 754 |  |  |  |  |  |  | location => Aquatic, | 
| 755 |  |  |  |  |  |  | non_adjectival => 1, | 
| 756 |  |  |  |  |  |  | }, | 
| 757 |  |  |  |  |  |  | }, | 
| 758 |  |  |  |  |  |  | }, | 
| 759 |  |  |  |  |  |  | Leaper => | 
| 760 |  |  |  |  |  |  | { | 
| 761 |  |  |  |  |  |  | act => { leaps => { location => Exoaquatic } }, | 
| 762 |  |  |  |  |  |  | }, | 
| 763 |  |  |  |  |  |  | Bird => | 
| 764 |  |  |  |  |  |  | { | 
| 765 |  |  |  |  |  |  | act => | 
| 766 |  |  |  |  |  |  | { | 
| 767 |  |  |  |  |  |  | flies => | 
| 768 |  |  |  |  |  |  | { | 
| 769 |  |  |  |  |  |  | location => Aerial, | 
| 770 |  |  |  |  |  |  | direction => Any, | 
| 771 |  |  |  |  |  |  | }, | 
| 772 |  |  |  |  |  |  | nests => | 
| 773 |  |  |  |  |  |  | { | 
| 774 |  |  |  |  |  |  | location => Arborial, | 
| 775 |  |  |  |  |  |  | }, | 
| 776 |  |  |  |  |  |  | }, | 
| 777 |  |  |  |  |  |  | }, | 
| 778 |  |  |  |  |  |  | }; | 
| 779 |  |  |  |  |  |  |  | 
| 780 | 1 |  |  |  |  | 4 | tree qw( oak elm willow maple she-oak ); | 
| 781 |  |  |  |  |  |  |  | 
| 782 | 1 |  |  |  |  | 3 | fruit_tree qw( cherry apple lemon ); | 
| 783 |  |  |  |  |  |  |  | 
| 784 | 1 |  |  |  |  | 2 | place ( "Mount Fuji", "a temple",  "the Emperor's palace", | 
| 785 |  |  |  |  |  |  | "a dojo", "the Shaolin temple", "a farmer's cottage", | 
| 786 |  |  |  |  |  |  | "the village", "the town square", "the harbor", | 
| 787 |  |  |  |  |  |  | "Bill Clinton's office", "a monastry", "the market-place", | 
| 788 |  |  |  |  |  |  | ); | 
| 789 |  |  |  |  |  |  |  | 
| 790 |  |  |  |  |  |  |  | 
| 791 |  |  |  |  |  |  | # LOAD USER-DEFINED DATA | 
| 792 |  |  |  |  |  |  |  | 
| 793 | 1 | 50 |  |  |  | 20 | if (-f $USER_CONFIG_FILE) | 
| 794 |  |  |  |  |  |  | { | 
| 795 | 1 |  |  | 1 |  | 11 | no strict; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 118 |  | 
| 796 | 0 |  |  |  |  | 0 | do $USER_CONFIG_FILE; | 
| 797 |  |  |  |  |  |  | } | 
| 798 |  |  |  |  |  |  |  | 
| 799 | 1 |  |  |  |  | 6 | @Coy::nouns = keys %$Coy::agent; | 
| 800 |  |  |  |  |  |  |  | 
| 801 | 1 |  |  |  |  | 4 | expand_categories; | 
| 802 | 1 |  |  |  |  | 3 | expand_synonyms; | 
| 803 |  |  |  |  |  |  |  | 
| 804 |  |  |  |  |  |  | # print STDERR "Nouns: ", scalar @Coy::nouns, "\n"; | 
| 805 |  |  |  |  |  |  |  | 
| 806 |  |  |  |  |  |  | } | 
| 807 |  |  |  |  |  |  |  | 
| 808 |  |  |  |  |  |  | # AND FINALLY, INSTALL IT ALL... | 
| 809 |  |  |  |  |  |  |  | 
| 810 |  |  |  |  |  |  | my $nested = -1; | 
| 811 |  |  |  |  |  |  |  | 
| 812 |  |  |  |  |  |  | $SIG{__WARN__} = sub | 
| 813 |  |  |  |  |  |  | { | 
| 814 |  |  |  |  |  |  | local $SIG{__WARN__}; | 
| 815 |  |  |  |  |  |  | $nested++; | 
| 816 |  |  |  |  |  |  | warn with_haiku(@_) unless $nested; | 
| 817 |  |  |  |  |  |  | warn @_ if $nested; | 
| 818 |  |  |  |  |  |  | $nested--; | 
| 819 |  |  |  |  |  |  | }; | 
| 820 |  |  |  |  |  |  |  | 
| 821 |  |  |  |  |  |  | $SIG{__DIE__}  = sub | 
| 822 |  |  |  |  |  |  | { | 
| 823 |  |  |  |  |  |  | local $SIG{__DIE__}; | 
| 824 |  |  |  |  |  |  | $nested++; | 
| 825 |  |  |  |  |  |  | die with_haiku(@_) unless $nested; | 
| 826 |  |  |  |  |  |  | die @_ if $nested; | 
| 827 |  |  |  |  |  |  | $nested--; | 
| 828 |  |  |  |  |  |  | }; | 
| 829 |  |  |  |  |  |  |  | 
| 830 |  |  |  |  |  |  | 1; | 
| 831 |  |  |  |  |  |  |  | 
| 832 |  |  |  |  |  |  |  | 
| 833 |  |  |  |  |  |  | __END__ |