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