1with STRINGS_PACKAGE; use STRINGS_PACKAGE; 2with LATIN_FILE_NAMES; use LATIN_FILE_NAMES; 3with CONFIG; use CONFIG; 4with PREFACE; 5pragma Elaborate(PREFACE); 6package body WORD_PARAMETERS is 7 use TEXT_IO; 8 9 type HELP_TYPE is array (NATURAL range <>) of STRING(1..70); 10 BLANK_HELP_LINE : constant STRING(1..70) := (others => ' '); 11 NO_HELP : constant HELP_TYPE := (2..1 => BLANK_HELP_LINE); 12 13 14 type REPLY_TYPE is (N, Y); 15 package REPLY_TYPE_IO is new TEXT_IO.ENUMERATION_IO(REPLY_TYPE); 16 REPLY : array (BOOLEAN) of REPLY_TYPE := (N, Y); 17 MODE_OF_REPLY : array (REPLY_TYPE) of BOOLEAN := (FALSE, TRUE); 18 19 BLANK_INPUT : exception; 20 21 -- The default modes are set in the body so that they can be changed 22 -- with only this being recompiled, not the rest of the with'ing system 23 DEFAULT_MODE_ARRAY : constant MODE_ARRAY := ( 24 TRIM_OUTPUT => TRUE, 25 26 HAVE_OUTPUT_FILE => FALSE, 27 WRITE_OUTPUT_TO_FILE => FALSE, 28 29 DO_UNKNOWNS_ONLY => FALSE, 30 WRITE_UNKNOWNS_TO_FILE => FALSE, 31 32 IGNORE_UNKNOWN_NAMES => TRUE, 33 IGNORE_UNKNOWN_CAPS => TRUE, 34 DO_COMPOUNDS => TRUE, 35 DO_FIXES => TRUE, 36 DO_TRICKS => TRUE, 37 38 DO_DICTIONARY_FORMS => TRUE, 39 SHOW_AGE => FALSE, 40 SHOW_FREQUENCY => FALSE, 41 42 DO_EXAMPLES => FALSE, 43 DO_ONLY_MEANINGS => FALSE, 44 DO_STEMS_FOR_UNKNOWN => FALSE ); 45 46 BAD_MODE_FILE : exception; 47 48 49TRIM_OUTPUT_HELP : constant HELP_TYPE := ( 50 "This option instructs the program to remove from the output list of ", 51 "possible constructs those which are least likely. There is now a fair", 52 "amount of trimming, killing LOC and VOC plus removing Uncommon and ", 53 "non-classical (Archaic/Medieval) when more common results are found ", 54 "and this action is requested (turn it off in MDV (!) parameters). ", 55 "When a TRIM has been done, output is usually followed by asterix (*). ", 56 "The asterix may be missing depending on where the TRIM is done. ", 57 "There certainly is no absolute assurence that the items removed are ", 58 "not correct, just that they are statistically less likely. ", 59 "Note that poets are likely to employ unusual words and inflections for", 60 "various reasons. These may be trimmed out if this parameter in on. ", 61 "When in English mode, trim just reduces the output to the top six ", 62 "results, if there are that many. Asterix means there are more ", 63 " The default is Y(es) " ); 64 65 66HAVE_OUTPUT_FILE_HELP : constant HELP_TYPE := ( 67 "This option instructs the program to create a file which can hold the ", 68 "output for later study, otherwise the results are just displayed on ", 69 "the screen. The output file is named " & OUTPUT_FULL_NAME 70 & (39+OUTPUT_FULL_NAME'LENGTH..70 => ' '), 71 "This means that one run will necessarily overwrite a previous run, ", 72 "unless the previous results are renamed or copied to a file of another", 73 "name. This is available if the METHOD is INTERACTIVE, no parameters. ", 74 "The default is N(o), since this prevents the program from overwriting ", 75 "previous work unintentionally. Y(es) creates the output file. " ); 76 77WRITE_OUTPUT_TO_FILE_HELP : constant HELP_TYPE := ( 78 "This option instructs the program, when HAVE_OUTPUT_FILE is on, to ", 79 "write results to the file " & OUTPUT_FULL_NAME 80 & (27+OUTPUT_FULL_NAME'LENGTH..70 => ' '), 81 "This option may be turned on and off during running of the program, ", 82 "thereby capturing only certain desired results. If the option ", 83 "HAVE_OUTPUT_FILE is off, the user will not be given a chance to turn ", 84 "this one on. Only for INTERACTIVE running. Default is N(o). ", 85 "This works in English mode, but output in somewhat diffeent so far. " ); 86 87DO_UNKNOWNS_ONLY_HELP : constant HELP_TYPE := ( 88 "This option instructs the program to only output those words that it ", 89 "cannot resolve. Of course, it has to do processing on all words, but ", 90 "those that are found (with prefix/suffix, if that option in on) will ", 91 "be ignored. The purpose of this option is t allow a quick look to ", 92 "determine if the dictionary and process is going to do an acceptable ", 93 "job on the current text. It also allows the user to assemble a list ", 94 "of unknown words to look up manually, and perhaps augment the system ", 95 "dictionary. For those purposes, the system is usually run with the ", 96 "MINIMIZE_OUTPUT option, just producing a list. Another use is to run ", 97 "without MINIMIZE to an output file. This gives a list of the input ", 98 "text with the unknown words, by line. This functions as a spelling ", 99 "checker for Latin texts. The default is N(o). ", 100 "This does not work in English mode, but may in the future. " ); 101 102WRITE_UNKNOWNS_TO_FILE_HELP : constant HELP_TYPE := ( 103 "This option instructs the program to write all unresolved words to a ", 104 "UNKNOWNS file named " & UNKNOWNS_FULL_NAME 105 & (21+UNKNOWNS_FULL_NAME'LENGTH..70 => ' '), 106 "With this option on , the file of unknowns is written, even though ", 107 "the main output contains both known and unknown (unresolved) words. ", 108 "One may wish to save the unknowns for later analysis, testing, or to ", 109 "form the basis for dictionary additions. When this option is turned ", 110 "on, the UNKNOWNS file is written, destroying any file from a previous ", 111 "run. However, the write may be turned on and off during a single run ", 112 "without destroying the information written in that run. ", 113 "This option is for specialized use, so its default is N(o). ", 114 "This does not work in English mode, but may in the future. " ); 115 116IGNORE_UNKNOWN_NAMES_HELP : constant HELP_TYPE := ( 117 "This option instructs the program to assume that any capitalized word ", 118 "longer than three letters is a proper name. As no dictionary can be ", 119 "expected to account for many proper names, many such occur that would ", 120 "be called UNKNOWN. This contaminates the output in most cases, and ", 121 "it is often convenient to ignore these sperious UNKNOWN hits. This ", 122 "option implements that mode, and calls such words proper names. ", 123 "Any proper names that are in the dictionary are handled in the normal ", 124 "manner. The default is Y(es). " ); 125 126IGNORE_UNKNOWN_CAPS_HELP : constant HELP_TYPE := ( 127 "This option instructs the program to assume that any all caps word ", 128 "is a proper name or similar designation. This convention is often ", 129 "used to designate speakers in a discussion or play. No dictionary can", 130 "claim to be exaustive on proper names, so many such occur that would ", 131 "be called UNKNOWN. This contaminates the output in most cases, and ", 132 "it is often convenient to ignore these sperious UNKNOWN hits. This ", 133 "option implements that mode, and calls such words names. Any similar ", 134 "designations that are in the dictionary are handled in the normal ", 135 "manner, as are normal words in all caps. The default is Y(es). " ); 136 137DO_COMPOUNDS_HELP : constant HELP_TYPE := ( 138 "This option instructs the program to look ahead for the verb TO_BE (or", 139 "iri) when it finds a verb participle, with the expectation of finding ", 140 "a compound perfect tense or periphastic. This option can also be a ", 141 "trimming of the output, in that VPAR that do not fit (not NOM) will be", 142 "excluded, possible interpretations are lost. Default choice is Y(es).", 143 "This processing is turned off with the choice of N(o). " ); 144 145DO_FIXES_HELP : constant HELP_TYPE := ( 146 "This option instructs the program, when it is unable to find a proper ", 147 "match in the dictionary, to attach various prefixes and suffixes and ", 148 "try again. This effort is successful in about a quarter of the cases ", 149 "which would otherwise give UNKNOWN results, or so it seems in limited ", 150 "tests. For those cases in which a result is produced, about half give", 151 "easily interpreted output; many of the rest are etymologically true, ", 152 "but not necessarily obvious; about a tenth give entirely spurious ", 153 "derivations. The user must proceed with caution. ", 154 "The default choice is Y(es), since the results are generally useful. ", 155 "This processing can be turned off with the choice of N(o). " ); 156 157DO_TRICKS_HELP : constant HELP_TYPE := ( 158 "This option instructs the program, when it is unable to find a proper ", 159 "match in the dictionary, and after various prefixes and suffixes, to ", 160 "try every dirty Latin trick it can think of, mainly common letter ", 161 "replacements like cl -> cul, vul -> vol, ads -> ass, inp -> imp, etc. ", 162 "Together these tricks are useful, but may give false positives (>10%).", 163 "They provide for recognized varients in classical spelling. Most of ", 164 "the texts with which this program will be used have been well edited ", 165 "and standardized in spelling. Now, moreover, the dictionary is being", 166 "populated to such a state that the hit rate on tricks has fallen to a ", 167 "low level. It is very seldom productive, and it is always expensive. ", 168 "The only excuse for keeping it as default is that now the dictionary ", 169 "is quite extensive and misses are rare. Default is now Y(es). ") ; 170 171DO_DICTIONARY_FORMS_HELP : constant HELP_TYPE := ( 172 "This option instructs the program to output a line with the forms ", 173 "normally associated with a dictionary entry (NOM and GEN of a noun, ", 174 "the four principal parts of a verb, M-F-N NOM of an adjective, ...). ", 175 "This occurs when there is other output (i.e., not with UNKNOWNS_ONLY).", 176 "The default choice is N(o), but it can be turned on with a Y(es). " ); 177 178SHOW_AGE_HELP : constant HELP_TYPE := ( 179 "This option causes a flag, like '<Late>' to appear for inflection or ", 180 "form in the output. The AGE indicates when this word/inflection was ", 181 "in use, at least from indications is dictionary citations. It is ", 182 "just an indication, not controlling, useful when there are choices. ", 183 "No indication means that it is common throughout all periods. ", 184 "The default choice is Y(es), but it can be turned off with a N(o). " ); 185 186SHOW_FREQUENCY_HELP : constant HELP_TYPE := ( 187 "This option causes a flag, like '<rare>' to appear for inflection or ", 188 "form in the output. The FREQ is indicates the relative usage of the ", 189 "word or inflection, from indications is dictionary citations. It is ", 190 "just an indication, not controlling, useful when there are choices. ", 191 "No indication means that it is common throughout all periods. ", 192 "The default choice is Y(es), but it can be turned off with a N(o). " ); 193 194DO_EXAMPLES_HELP : constant HELP_TYPE := ( 195 "This option instructs the program to provide examples of usage of the ", 196 "cases/tenses/etc. that were constructed. The default choice is N(o). ", 197 "This produces lengthly output and is turned on with the choice Y(es). " ); 198 199DO_ONLY_MEANINGS_HELP : constant HELP_TYPE := ( 200 "This option instructs the program to only output the MEANING for a ", 201 "word, and omit the inflection details. This is primarily used in ", 202 "analyzing new dictionary material, comparing with the existing. ", 203 "However it may be of use for the translator who knows most all of ", 204 "the words and just needs a little reminder for a few. ", 205 "The default choice is N(o), but it can be turned on with a Y(es). " ); 206 207DO_STEMS_FOR_UNKNOWN_HELP : constant HELP_TYPE := ( 208 "This option instructs the program, when it is unable to find a proper ", 209 "match in the dictionary, and after various prefixes and suffixes, to ", 210 "list the dictionary entries around the unknown. This will likely ", 211 "catch a substantive for which only the ADJ stem appears in dictionary,", 212 "an ADJ for which there is only a N stem, etc. This option should ", 213 "probably only be used with individual UNKNOWN words, and off-line ", 214 "from full translations, therefore the default choice is N(o). ", 215 "This processing can be turned on with the choice of Y(es). " ); 216 217 218SAVE_PARAMETERS_HELP : constant HELP_TYPE := ( 219 "This option instructs the program, to save the current parameters, as ", 220 "just established by the user, in a file WORD.MOD. If such a file ", 221 "exists, the program will load those parameters at the start. If no ", 222 "such file can be found in the current subdirectory, the program will ", 223 "start with a default set of parameters. Since this parameter file is ", 224 "human-readable ASCII, it may also be created with a text editor. If ", 225 "the file found has been improperly created, is in the wrong format, or", 226 "otherwise uninterpretable by the program, it will be ignored and the ", 227 "default parameters used, until a proper parameter file in written by ", 228 "the program. Since one may want to make temporary changes during a ", 229 "run, but revert to the usual set, the default is N(o). " ); 230 231 procedure PUT(HELP : HELP_TYPE) is 232 begin 233 NEW_LINE; 234 for I in HELP'FIRST..HELP'LAST loop 235 PUT_LINE(HELP(I)); 236 end loop; 237 NEW_LINE; 238 end PUT; 239 240 procedure PUT_MODES is 241 use MODE_TYPE_IO; 242 use REPLY_TYPE_IO; 243 begin 244 if IS_OPEN(MODE_FILE) then 245 CLOSE(MODE_FILE); 246 end if; 247 CREATE(MODE_FILE, OUT_FILE, MODE_FULL_NAME); 248 for I in WORDS_MODE'RANGE loop 249 PUT(MODE_FILE, I); 250 SET_COL(MODE_FILE, 35); 251 PUT(MODE_FILE, REPLY(WORDS_MODE(I))); 252 NEW_LINE(MODE_FILE); 253 end loop; 254 CLOSE(MODE_FILE); 255 end PUT_MODES; 256 257 procedure GET_MODES is --(M : out MODE_ARRAY) is 258 use MODE_TYPE_IO; 259 use REPLY_TYPE_IO; 260 MO : MODE_TYPE; 261 REP : REPLY_TYPE; 262 begin 263 OPEN(MODE_FILE, IN_FILE, MODE_FULL_NAME); 264 while not END_OF_FILE(MODE_FILE) loop 265 GET(MODE_FILE, MO); 266 GET(MODE_FILE, REP); 267 WORDS_MODE(MO) := MODE_OF_REPLY(REP); 268 end loop; 269 CLOSE(MODE_FILE); 270 271 exception 272 when NAME_ERROR => 273 raise; 274 when others => 275 raise BAD_MODE_FILE; 276 end GET_MODES; 277 278 procedure INQUIRE(MO : MODE_TYPE; HELP : in HELP_TYPE := NO_HELP) is 279 use MODE_TYPE_IO; 280 use REPLY_TYPE_IO; 281 L1 : STRING(1..100) := (others => ' '); 282 LL : NATURAL; 283 R : REPLY_TYPE; 284 begin 285 PUT(MO); 286 PUT(" ? "); SET_COL(45); PUT("(Currently "); 287 PUT(REPLY(WORDS_MODE(MO))); PUT(" =>"); 288 GET_LINE(L1, LL); 289 if LL /= 0 then 290 if TRIM(L1(1..LL)) = "" then 291 PUT_LINE("Blank input, skipping the rest of CHANGE_PARAMETERS"); 292 raise BLANK_INPUT; 293 elsif L1(1) = '?' then 294 PUT(HELP); 295 INQUIRE(MO, HELP); 296 else 297 GET(L1(1..LL), R, LL); 298 WORDS_MODE(MO) := MODE_OF_REPLY(R); 299 end if; 300 end if; 301 NEW_LINE; 302 end INQUIRE; 303 304 305 procedure CHANGE_PARAMETERS is 306 L1 : STRING(1..100) := (others => ' '); 307 LL : NATURAL; 308 R : REPLY_TYPE; 309 310 begin 311 312 313 PUT_LINE("To set/change parameters reply Y/y or N/n. Return accepts current value."); 314 PUT_LINE("A '?' reply gives infomation/help on that parameter. A space skips the rest."); 315 NEW_LINE; 316 317 -- Interactive mode - lets you do things on unknown words 318 319 -- You can say it is a noun and then look at the endings 320 -- Or look all the endings and guess what part of speech 321 322 -- You can look at the dictionary items that are close to the word 323 -- There may be cases in which the stem is found but is not of right part 324 -- So maybe the word list is deficient and that root goes also to a ADJ 325 -- even if it is listed only for a N. 326 -- One can also look for ADV here with ending 'e', etc. 327 328 -- You can look up the word in a paper dictionary (with the help of ending) 329 -- And then enter the word into DICT.LOC, so it will hit next time 330 331 -- All unknowns could be recorded in a file for later reference 332 333 -- A '?' gives information (help) about the item in question 334 335 -- One can change the symbol that the main program uses for change and file 336 337 -- One can save the new parameters or let them revert to previous 338 -- There should be a basic set of parameters that one can always go to 339 340 -- There should be moods of translation, maybe to switch dictionaries 341 342 -- Maybe to turn on or off pre/suffix 343 -- Maybe to allow the user to look at just all the prefixes that match 344 345 INQUIRE(TRIM_OUTPUT, TRIM_OUTPUT_HELP); 346 347 348 INQUIRE(HAVE_OUTPUT_FILE, HAVE_OUTPUT_FILE_HELP); 349 350 351 if IS_OPEN(OUTPUT) and then not WORDS_MODE(HAVE_OUTPUT_FILE) then 352 CLOSE(OUTPUT); 353 WORDS_MODE(WRITE_OUTPUT_TO_FILE) := FALSE; 354 end if; 355 if not IS_OPEN(OUTPUT) and then WORDS_MODE(HAVE_OUTPUT_FILE) then 356 begin 357 CREATE(OUTPUT, OUT_FILE, OUTPUT_FULL_NAME); 358 exception 359 when others => 360 PUT_LINE("Cannot CREATE WORD.OUT - Check if it is in use elsewhere"); 361 end; 362 end if; 363 364 if WORDS_MODE(HAVE_OUTPUT_FILE) then 365 INQUIRE(WRITE_OUTPUT_TO_FILE, WRITE_OUTPUT_TO_FILE_HELP); 366 end if; 367 368 INQUIRE(DO_UNKNOWNS_ONLY, DO_UNKNOWNS_ONLY_HELP); 369 370 INQUIRE(WRITE_UNKNOWNS_TO_FILE, WRITE_UNKNOWNS_TO_FILE_HELP); 371 -- If there is an open file then OK 372 -- If not open and you now want to start writing to UNKNOWNS, the CREATE 373 if not IS_OPEN(UNKNOWNS) and then WORDS_MODE(WRITE_UNKNOWNS_TO_FILE) then 374 begin 375 CREATE(UNKNOWNS, OUT_FILE, UNKNOWNS_FULL_NAME); 376 exception 377 when others => 378 PUT_LINE("Cannot CREATE WORD.UNK - Check if it is in use elsewhere"); 379 end; 380 end if; 381 382 383 INQUIRE(IGNORE_UNKNOWN_NAMES, IGNORE_UNKNOWN_NAMES_HELP); 384 385 INQUIRE(IGNORE_UNKNOWN_CAPS, IGNORE_UNKNOWN_CAPS_HELP); 386 387 INQUIRE(DO_COMPOUNDS, DO_COMPOUNDS_HELP); 388 389 INQUIRE(DO_FIXES, DO_FIXES_HELP); 390 391 INQUIRE(DO_TRICKS, DO_TRICKS_HELP); 392 393 394 INQUIRE(DO_DICTIONARY_FORMS, DO_DICTIONARY_FORMS_HELP); 395 396 INQUIRE(SHOW_AGE, SHOW_AGE_HELP); 397 398 INQUIRE(SHOW_FREQUENCY, SHOW_FREQUENCY_HELP); 399 400 401 INQUIRE(DO_EXAMPLES, DO_EXAMPLES_HELP); 402 403 INQUIRE(DO_ONLY_MEANINGS, DO_ONLY_MEANINGS_HELP); 404 405 INQUIRE(DO_STEMS_FOR_UNKNOWN, DO_STEMS_FOR_UNKNOWN_HELP); 406 407 408 PUT("Do you wish to save this set of parameters? Y or N (Default) "); 409 PUT(" =>"); 410 GET_LINE(L1, LL); 411 if LL /= 0 then 412 if L1(1) = '?' then 413 PUT(SAVE_PARAMETERS_HELP); 414 PUT("Do you wish to save this set of parameters? Y or N (Default) "); 415 PUT(" =>"); 416 GET_LINE(L1, LL); 417 end if; 418 REPLY_TYPE_IO.GET(L1(1..LL), R, LL); 419 if MODE_OF_REPLY(R) then 420 PUT_MODES; 421 PUT_LINE("MODE_ARRAY saved in file " & MODE_FULL_NAME); 422 end if; 423 end if; 424 NEW_LINE; 425 426 exception 427 when BLANK_INPUT => 428 null; 429 when others => 430 PUT_LINE("Bad input - terminating CHANGE_PARAMETERS"); 431 432 end CHANGE_PARAMETERS; 433 434 435 436 procedure INITIALIZE_WORD_PARAMETERS is 437begin 438 WORDS_MODE := DEFAULT_MODE_ARRAY; 439--TEXT_IO.PUT_LINE("Initializing WORD_PARAMETERS"); 440 441 DO_MODE_FILE: 442 begin 443 -- Read the mode file 444 GET_MODES; --(WORDS_MODE); 445 PREFACE.PUT_LINE("MODE_FILE found - Using those modes and parameters"); 446 exception 447 -- If there is any problem 448 -- Put that the mode file is corrupted and the options are: 449 -- to proceed with default parameters 450 -- to set parameters with a CHANGE (SET) PARAMETERS and save 451 -- to examine the mode file with a text editor and try to repair it 452 when NAME_ERROR => 453 WORDS_MODE := DEFAULT_MODE_ARRAY; 454 when BAD_MODE_FILE => 455 PUT_LINE("MODE_FILE exists, but empty or corupted - Default modes used"); 456 PUT_LINE("You can set new parameters with CHANGE PARAMETERS and save."); 457 WORDS_MODE := DEFAULT_MODE_ARRAY; 458 when others => 459 PUT_LINE("MODE_FILE others ERROR"); 460 WORDS_MODE := DEFAULT_MODE_ARRAY; 461 end DO_MODE_FILE; 462 463 if ((METHOD = INTERACTIVE) or (METHOD = COMMAND_LINE_INPUT)) and then 464 (not TEXT_IO.IS_OPEN(OUTPUT)) and then 465 (WORDS_MODE(HAVE_OUTPUT_FILE)) then 466 TEXT_IO.CREATE(OUTPUT, TEXT_IO.OUT_FILE, OUTPUT_FULL_NAME); 467 --TEXT_IO.PUT_LINE("WORD.OUT Created at Initialization"); 468 PREFACE.PUT_LINE("WORD.OUT Created at Initialization"); 469 end if; 470 if not TEXT_IO.IS_OPEN(UNKNOWNS) and then WORDS_MODE(WRITE_UNKNOWNS_TO_FILE) then 471 TEXT_IO.CREATE(UNKNOWNS, TEXT_IO.OUT_FILE, UNKNOWNS_FULL_NAME); 472 PREFACE.PUT_LINE("WORD.UNK Created at Initialization"); 473 end if; 474end INITIALIZE_WORD_PARAMETERS; 475 476 477end WORD_PARAMETERS; 478