1% MISSING33
2
3:- module(check_entry).
4
5
6getbug :-
7	writeln('\nCheck that you are in "module(check_entry).", then'),
8	writeln('to start the program type "test_check_entry.".\n').
9
10test_check_entry :-
11    open('/home/lp/ode/bugs/sepia/data/incorrect',write,WriteStream2),
12    setval(write_stream_2, WriteStream2),
13    open('/home/lp/ode/bugs/sepia/data/rubbish',write,WriteStream3),
14    setval(write_stream_3, WriteStream3),
15    open('/home/lp/ode/bugs/sepia/data/database',write,WriteStream4),
16    setval(write_stream_4, WriteStream4),
17    check_entry([bok, [aut,[69, 46, 89, 46, 32, 83, 104, 97, 112, 105, 114, 111]],
18      [key,[83, 104, 97, 112, 105, 114, 111]],
19      [yea,[49, 57, 56, 54]],
20      [tit, [65, 100, 118, 97, 110, 99, 101, 100, 32, 80, 114, 111, 103, 114, 97, 109, 109, 105, 110, 103, 32, 105, 110, 32, 80, 114, 111, 108, 111, 103]],
21      [pub,[65, 100, 100, 105, 115, 111, 110, 32, 87, 101, 115, 108, 101, 121]]]),
22    close(WriteStream2),
23    close(WriteStream3),
24    close(WriteStream4).
25
26
27:- lib(porting).
28:-set_all_strings_to_lists.
29
30:- lib(basic).
31:- lib(facts.
32:- lib(screen).
33
34
35bug :-
36	nl,
37	explanation.
38
39explanation :-
40writeln(' \n \
41Missing base clause for clean_val/2, therefore predicate always fails, \n \
42and the treatment of the bibliography entry is not finished. \n \
43 \n \
44The same program with the same bug appears in side13. \n \
45Here the test has been abstracted by hand. \n \
46 \n \
47GOAL:	 check_entry(...) \n \
48CORRECT: display correct bibliography entry \n \
49BUGGY:   no (more) solution \n \
50').
51
52% ============================================================================
53
54% --- test --- 5.7.89
55
56insert(Entry) :-
57	nl, writeln('Entry:'), writeln(Entry), nl.
58
59
60/*                         UPDATE OF THE DATABASE
61
62
63A)  interactive input help
64B)  input checker
65C)  erase/modify/add (Key)
66D)  translation of Scribe bibliography files into LOB files
67
68---------------
69
70A)  INTERACTIVE INPUT HELP
71
72build_file will help the user to build a file of future database entries
73which can be read by the input checker. For each document which shall be
74entered the user is asked for the mandatory or optional attributes with
75respect to the document's type.
76
77Representation of a document in the file:
78
79     [bok,[aut,"L. Sterling, E.Y. Shapiro"],
80          [tit,"The Art of Prolog - Advanced Programming Techniques"],
81          [key,"Sterling"],[yea,"1986"],
82          [pub,"MIT Press"],[ser,"Logic programming"],
83          [kyw,"logic programming"],[kyw,"prolog"],
84          [cop,"library","library"],
85          [cop,"library","mireille"]].
86
87*/
88
89% =============================================== main program ================
90
91build_file :-
92    clearpage,
93    get_answer('Please enter filename : ',Fname,2,5),
94    complete_filename(Fname,Filename),
95    open(Filename,write,10),		% open(Filename,10,w,2), what is the 2 for ??
96    setval(write_stream_1, WriteStream1),
97    build_file(Filename),
98    close(WriteStream1).
99
100build_file(Filename) :-
101    clearpage,
102    process_date,
103    process_file(Filename).
104
105process_file(Filename) :-
106    repeat,
107       cursor(2,5),
108       write('Document type :  '),
109       readln(Input),
110       checkinp_1(Input,CheckedInp),
111       process_doc(CheckedInp,Filename,4).
112
113process_doc(no,Filename,Line) :-
114    !,
115    clearpage,
116    cursor(3,5),
117    write('File '),
118    write(Filename),
119    write(' has been written.'),
120    nl,nl.
121
122process_doc(wronginp,Filename,Line) :-
123    NewL1 is Line - 2,
124    error_message('Wrong input.',NewL1,40,21),
125    fail.
126
127process_doc(DocType,Filename,Line) :-
128    prompted_atts(DocType,AttrList),
129    askfor_atts(AttrList,ValueList,Line,XLine),
130    write_entry([DocType|ValueList]),
131    clearpage,
132    fail.
133
134% askfor_atts will prompt the user to enter the values of the attributes
135
136askfor_atts([Attr],Res,ActLine,NewLine) :-
137    !,
138    askfor_att(Attr,Res,ActLine,NewLine).
139
140askfor_atts([Attr|AttrList],ValueList,ActLine,NewLine) :-
141    askfor_att(Attr,Res,ActLine,ActL),
142    askfor_atts(AttrList,ResList,ActL,NewLine),
143    conc(Res,ResList,ValueList).
144
145% Entry of (several) keywords: ResList = [[kyw,"logic"],[kyw,"Prolog"]]
146
147askfor_att([kyw,o],ResList,ActLine,NewLine) :-
148    !,
149    Line is ActLine + 1,
150    askfor_att_k(ResList,Line,NewLine).
151askfor_att([cop,o],ResList,ActLine,NewLine) :-
152    !,
153    Line is ActLine + 1,
154    askfor_att_c(ResList,Line,NewLine).
155askfor_att([Attr,R],Res,ActLine,NewLine) :-
156    !,
157    cap_attr_abbr(Attribute,Attr),
158    clearline(ActLine,5),
159    write(Attribute),
160    fill_blanks(Attribute,13),
161    write(' :  '),
162    receive(Attr,R,Res,ActLine,NewLine,22).
163
164askfor_att_k(ResList,ActLine,NewLine) :-
165    askfor_kyw(Res,ActLine,ActL),
166    process_kyw(Res,ResList,ActL,NewLine).
167
168process_kyw([],[],ActLine,ActLine) :-
169    !.
170
171process_kyw(Res,ResList,ActLine,NewLine) :-
172    askfor_att_k(Rlist,ActLine,NewLine),
173    conc(Res,Rlist,ResList).
174
175askfor_kyw(Res,ActLine,NewLine) :-
176    cap_attr_abbr(Attribute,kyw),
177    clearline(ActLine,5),
178    write(Attribute),
179    fill_blanks(Attribute,13),
180    write(' :  '),
181    receive(kyw,o,Res,ActLine,NewLine,22).
182
183% Entry of copies:
184% ResList = [[cop,"library","library"],[cop,"library","anna"]]
185
186
187askfor_att_c(ResList,ActLine,NewLine) :-
188    askfor_att([own,o],Res,ActLine,ActL),
189    process_cop(Res,ResList,ActL,NewLine).
190
191process_cop([],[],ActLine,ActLine) :- !.
192
193process_cop([[Attr,Owner]],ResList,ActLine,NewLine) :-
194    askfor_att([loc,m],[[loc,Location]],ActLine,ActL),
195    process_nxtcop(RList,ActL,NewLine),
196    conc([[cop,Owner,Location]],RList,ResList).
197
198process_nxtcop(ResList,ActLine,NewLine) :-
199    askfor_att([own,o],Own,ActLine,ActL),
200    process_own(Own,ResList,ActL,NewLine).
201
202process_own([],[],ActLine,ActLine) :-
203    !.
204
205process_own([own,Owner],ResList,ActLine,NewLine) :-
206    askfor_att([loc,m],[[loc,Location]],ActLine,ActL2),
207    process_nxtcop(RList,ActL2,NewLine),
208    conc([[cop,Owner,Location]],RList,ResList).
209
210% Entry of remaining attributes (which may have one value at most)
211
212
213
214
215% ---------------------
216% input check functions
217% ---------------------
218
219checkinp_1("",no) :- !.
220checkinp_1("no",no) :- !.
221checkinp_1("n",no) :- !.
222checkinp_1("e",no) :- !.
223checkinp_1("x",no) :- !.
224checkinp_1("exit",no) :- !.
225
226checkinp_1(X,Y) :-
227    name(Z,X),
228    type_abbr(Z,Y),
229    !.
230
231checkinp_1(X,Y) :-
232    name(Y,X),
233    type_abbr(_,Y),
234    !.
235
236checkinp_1(_,wronginp).
237
238
239checkinp_2(_,o,[],[],ActLine,ActLine) :-
240    !,
241    clearline(ActLine,5).
242checkinp_2(yea,m,[],Result,ActLine,ActLine) :-
243    !,
244    error_message('Attribute mandatory!',ActLine,40,22),
245    fail.
246checkinp_2(yea,R,Value,Result,ActLine,NewLine) :-
247    !,
248    str_to_int(Value,Int),
249    check_year(Int,Result,Value,R,ActLine,NewLine).
250checkinp_2(Attr,m,[],Res,ActLine,ActLine) :-
251    !,
252    error_message('Attribute mandatory!',ActLine,40,22),
253    fail.
254checkinp_2(Attr,R,Value,[[Attr,Value]],ActLine,NewLine) :-
255    check_length(Attr,Value),
256    !,
257    NewLine is ActLine + 1.
258checkinp_2(Attr,R,Value,Result,ActLine,ActLine) :-
259    !,
260    error_message('String too long!',ActLine,40,22),
261    fail.
262
263check_year(Int,[[yea,Result]],Result,R,ActLine,NewLine) :-
264    Int >= 1900,
265    Int =< 3000,
266    !,
267    NewLine is ActLine + 1.
268
269check_year(Int,Res,Result,R,ActLine,ActLine) :-
270    error_message('4 digits, please!',ActLine,40,22),
271    fail.
272
273
274check_length(Attr,Value) :-
275    len(Value,ActLength),
276    attr_len(Attr,MaxLength),
277    ActLength =< MaxLength.
278
279% --------------
280% subprocedures
281% --------------
282
283process_date :-
284    repeat,
285      (    get_answer('Please enter today`s date (DD.MM.YY) : ',Date,2,5),
286               check_date(Date),
287	       getval(write_stream_1, WriteStream1),
288               write(WriteStream1,Date),
289               writeln(WriteStream1,'. '),
290               clearpage
291      ;
292               error_message('Wrong format!',2,43,5),
293               fail
294      ).
295
296check_date(String) :-
297    up_to_char(46,String,Day,Rest),
298    up_to_char(46,Rest,Month,Year),
299    str_to_int(Day,IDay),
300    1 =< IDay,
301    IDay =< 31,
302    str_to_int(Month,IMonth),
303    1 =< IMonth,
304    IMonth =< 12,
305    str_to_int(Year,IYear),
306    0 =< IYear,
307    IYear =< 99.
308
309
310receive(Attr,R,Res,ActLine,NewLine,FromCol) :-
311    put_dot(Attr,ActLine,22),
312    readln(Value),
313    checkinp_2(Attr,R,Value,Res,ActLine,NewLine),
314    !.
315
316receive(Attr,R,Res,ActLine,NewLine,FromCol) :-
317    receive(Attr,R,Res,ActLine,NewLine,FromCol).
318
319write_entry(Entity) :-
320    getval(write_stream_1, WriteStream1),
321    write(WriteStream1,Entity),
322    writeln(WriteStream1,'. ').
323
324put_dot(Attr,Line,Col) :-
325    !,
326    attr_len(Attr,Length),
327    Col2 is Length + Col,
328    dot(Line,Col2),
329    cursor(Line,Col).
330
331dot(Line,Col) :-
332    Col =< 80,
333    !,
334    cursor(Line,Col),
335    write('.').
336
337dot(Line,Col).
338
339/* ------------------
340
341B)  INPUT CHECKER
342
343check_input will read new references from a file (written in a format like
344the output of build_file) and check whether there are values for all the
345mandatory attributes, whether the values are not too long, and whether there
346are entries in the database that are similar to the new one (i.e. have the
347same key). Correct references are directly inserted into the database.
348Incorrect references and those which are suspected to be already contained
349in the database are collected in a  file 'incorrect'. These references
350are presented to the moderator after the first check, s/he has the possibility
351to correct/reject them.
352
353*/
354
355check_input :-
356    clearpage,
357    get_answer('Please enter filename :  ',Input,4,10),
358    complete_filename(Input,Filename),
359    open(Filename,read,ReadStream1),
360    setval(read_stream_1, ReadStream1),
361    check_input(Filename),
362    close(ReadStream1).
363
364check_input(Filename) :-
365    open('/home/lp/ode/bugs/sepia/data/incorrect',write,WriteStream2),
366    setval(write_stream_2, WriteStream2),
367    open('/home/lp/ode/bugs/sepia/data/rubbish',write,WriteStream3),
368    setval(write_stream_3, WriteStream3),
369    open('/home/lp/ode/bugs/sepia/data/database',write,WriteStream4),
370    setval(write_stream_4, WriteStream4),
371    cursor(7,10),
372    write('checking file '),
373    write(Filename),
374    write(' ...'),
375    nl,nl,
376    getval(read_stream_1, ReadStream1),
377    read(ReadStream1,Date),
378    (    check_date(Date),
379            !
380    ;
381            write('Format of date is wrong / date is missing!'),
382            nl,
383            close(ReadStream1),
384            close(WriteStream2),
385            close(WriteStream3)
386    ),
387    assert(dat(Date)),
388    assert(double([])),
389    check_file,
390    retract(double(List1)),
391    close(WriteStream2),
392    close(WriteStream3),
393    !,
394    open('/home/lp/ode/bugs/sepia/data/incorrect',read,ReadStream2),
395    setval(read_stream_2, ReadStream2),
396    assert(double([])),
397    correct_entries,
398    close(ReadStream2),
399%  ---- test only -----
400%    close(WriteStream4),
401%  --------------------
402    retract(dat(Date)),
403    retract(double(List2)).
404
405
406% --------------------------------
407%        C H E C K   F I L E
408% --------------------------------
409
410check_file :-
411    repeat,
412       getval(read_stream_1, ReadStream1),
413       read(ReadStream1,Entry),
414       check_entry(Entry).
415
416check_entry(end_of_file) :- !.
417
418check_entry(Entry) :-
419    usable(Entry),
420    !,
421    clean(Entry,CEntry),
422    process_entry(CEntry).
423
424check_entry(Entry) :-
425    getval(write_stream_3, WriteStream3),
426    write(WriteStream3,Entry),
427    writeln(WriteStream3,'. '),
428    fail.
429
430process_entry(E) :-
431    E = [DocType|ValList],
432    member([key,Key],ValList),
433    write(Key),nl,
434    add_ide(E,Entry),
435    !,
436    proc_entry(Entry).
437
438process_entry(Entry) :-
439    write_errdoc(noide,Entry,[[key,m],[yea,m]]),
440    !,
441    fail.
442
443proc_entry(Entry) :-
444    double(Entry,Similars),
445    !,
446    first_double(Entry,N),
447    write_errdoc(double,Entry,[N,Similars]),
448    fail.
449
450proc_entry(Entry) :-
451    val_too_long(Entry,Attr),
452    !,
453    write_errdoc(toolong,Entry,Attr),
454    fail.
455
456proc_entry(Entry) :-
457    val_missing(Entry,Attr),
458    !,
459    write_errdoc(missing,Entry,Attr),
460    fail.
461
462proc_entry(Entry) :-
463    enter(Entry),
464    !,
465    fail.
466
467double(_,_) :- !, fail.
468double([DocType|ValList],Similars) :-
469    member([ide,Ide],ValList),
470    bagof(Result,
471          general_search([[ide,m,Ide]],[ide,aut,tit],[DocType],Result),
472          Similars).
473
474% check each attribute for a string that is too long
475val_too_long([DocType|ValList],TooLong) :-
476    too_long(ValList,TooLong).
477
478% check whether a mandatory attribute is missing
479val_missing([DocType|ValList],Attr) :-
480    mandatory_atts(DocType,AttList),
481    check_mand_atts(AttList,ValList,Attr).
482
483% add document identifier
484add_ide([DocType|ValList],[DocType|ComplList]) :-
485    generate_ide(ValList,Ide),
486    conc([[ide,Ide]],ValList,ComplList).
487
488generate_ide(ValList,Ide) :-
489    member([key,Key],ValList),
490    len(Key,Length),
491    Length =< 17,
492    first_nonabbr(Key,HeadKey),
493    member([yea,Year],ValList),
494    str_to_int(Year,Num),
495    Num >= 1900,
496    Num =< 3000,
497    ending(Year,EndYear),
498    conc(HeadKey,EndYear,Ide).
499
500% ---------------------------
501% process correct(ed) entries
502% ---------------------------
503
504enter([]) :- !.
505
506enter(Entry) :-
507    add_date(Entry,ComplEntry),
508    enter_doc(ComplEntry),
509    enter_copies(ComplEntry),
510    enter_kyws(ComplEntry).
511
512add_date([DT|List],[DT|ResList]) :-
513    dat(Date),
514    conc([[dat,Date]],List,ResList).
515
516enter_doc(ComplEntry) :-
517    build_docentry(ComplEntry,DocEntry),
518    insert_docentry(DocEntry).
519
520build_docentry([DocType|ValList],[DocType|CheckedList]) :-
521    rel_has_atts(DocType,AttList),
522    check_atts(AttList,ValList,CheckedList).
523
524enter_copies([DocType|ValList]) :-
525    member([ide,Ide],ValList),
526    dat(Date),
527    collect(cop,ValList,Copies),
528    insert_copies(DocType,Ide,Date,Copies).
529
530enter_kyws([DocType|ValList]) :-
531    member([ide,Ide],ValList),
532    collect(kyw,ValList,KywList),
533    insert_kyws(DocType,Ide,KywList).
534
535insert_docentry([DocType|ValList]) :-
536    conc_atom('insert_',DocType,ProcName),
537    strings_to_atoms_list(ValList,ValAtoms),
538    InsertProcess =.. [ProcName|[ValAtoms]],
539    call(InsertProcess).
540
541insert_copies(DocType,Ide,Date,[]) :- !.
542
543insert_copies(DocType,Ide,Date,[[Own,Loc]|CopList]) :-
544    name(DocType,DTString),
545    strings_to_atoms_list([Ide,DTString,Own,Loc,"-",Date],ValList),
546    InsertProcess =.. [insert_cop|[ValList]],
547    call(InsertProcess),
548    insert_copies(DocType,Ide,Date,CopList).
549
550insert_kyws(DocType,Ide,[]) :- !.
551
552insert_kyws(DocType,Ide,[Kyw|KywList]) :-
553    name(DocType,DTString),
554    strings_to_atoms_list([Ide,DTString,Kyw],ValList),
555    InsertProcess =.. [insert_kyw|[ValList]],
556    call(InsertProcess),
557    insert_kyws(DocType,Ide,KywList).
558
559/* ------ test procedures -----
560*/
561general_search(A,B,C,D) :-
562   !,
563   fail.
564/*
565general_search([[ide,m,Ide]],L1,L2,Result) :-
566   !,
567   write('Database search for ide = '),
568   write(Ide),
569   nl,
570   write('Please enter result: '),
571   read(Result),
572   nl,
573   (   Result = x,
574           !,
575           fail
576   ;
577       true
578   ).
579*/
580/*
581insert_art(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
582insert_bok(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
583insert_bol(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
584insert_con(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
585insert_inb(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
586insert_inc(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
587insert_inp(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
588insert_man(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
589insert_mas(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
590insert_mis(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
591insert_phd(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
592insert_pro(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
593insert_tec(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
594insert_unp(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
595insert_cop(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
596insert_kyw(List) :- getval(write_stream_4, WriteStream4),write(WriteStream4,List),writeln(WriteStream4,'. '),!.
597*/
598/*% ---------- end test procedures ------ */
599
600insert_art([Ide,Aut,Key,Tit,Jou,Vol,Num,Pag,Yea,Mon,Nte,Dat]) :-
601    insert(art(ide = ide, aut = Aut, key = Key, tit = Tit, jou = Jou,
602               vol = Vol, num = Num, pag = Pag, yea = Yea, mon = Mon,
603               nte = Nte, dat = Dat)),!.
604insert_art(List) :- write('                     Insert failed!'),nl.
605
606insert_bok([Ide,Aut,Key,Tit,Edr,Pub,Add,Edi,Ser,Vol,Num,How,Yea,Nte,Dat]) :-
607    insert(bok(ide = Ide, aut = Aut, key = Key, tit = Tit, edr = Edr,
608               pub = Pub, add = Add, edi = Edi, ser = Ser, vol = Vol,
609               num = Num, how = How, yea = Yea, nte = Nte, dat = Dat)),!.
610insert_bok(List) :- write('                     Insert failed!'),nl.
611
612insert_bol([Ide,Aut,Key,Tit,Pub,Add,How,Yea,Mon,Nte,Dat]) :-
613    insert(bol(ide = ide, aut = Aut, key = Key, tit = Tit, pub = Pub,
614               add = Add, how = How, yea = Yea, mon = Mon, nte = Nte,
615               dat = Dat)),!.
616insert_bol(List) :- write('                     Insert failed!'),nl.
617
618insert_con([Ide,Aut,Key,Tit,Org,Mee,Yea,Mon,Nte,Dat]) :-
619    insert(con(ide = Ide, aut = Aut, key = Key, tit = tit, org = Org,
620               mee = Mee, yea = Yea, mon = Mon, nte = Nte, dat = Dat)),!.
621insert_con(List) :- write('                     Insert failed!'),nl.
622
623insert_inb([Ide,Aut,Key,Tit,Bot,Cha,Pag,Edr,Pub,Add,Edi,Ser,Vol,Num,How,Yea,
624                  Nte,Dat]) :-
625    insert(inb(ide = Ide, aut = Aut, key = Key, tit = Tit, bot = Bot,
626               cha = Cha, pag = Pag, edr = Edr, pub = Pub, add = Add,
627               edi = Edi, ser = Ser, vol = Vol, num = Num, how = How,
628               yea = Yea, nte = Nte, dat = Dat)),!.
629insert_inb(List) :- write('                     Insert failed!'),nl.
630
631insert_inc([Ide,Aut,Key,Tit,Bot,Cha,Pag,Edr,Pub,Add,Ser,Vol,Num,Yea,Nte,
632                  Dat]) :-
633    insert(inc(ide = Ide, aut = Aut, key = Key, tit = Tit, bot = Bot,
634               cha = Cha, pag = Pag, edr = Edr, pub = Pub, add = Add,
635               ser = Ser, vol = Vol, num = Num, yea = Yea, nte = Nte,
636               dat = Dat)),!.
637insert_inc(List) :- write('                     Insert failed!'),nl.
638
639insert_inp([Ide,Aut,Key,Tit,Bot,Org,Pag,Edr,Pub,Add,Yea,Mon,Nte,Dat]) :-
640    insert(inp(ide = Ide, aut = Aut, key = Key, tit = Tit, bot = Bot,
641               org = Org, pag = Pag, edr = Edr, pub = Pub, add = Add,
642               yea = Yea, mon = Mon, nte = Nte, dat = Dat)),!.
643insert_inp(List) :- write('                     Insert failed!'),nl.
644
645insert_man([Ide,Aut,Key,Tit,Org,Add,Edi,Yea,Mon,Nte,Dat]) :-
646    insert(man(ide = Ide, aut = Aut, key = Key, tit = Tit, org = Org,
647               add = Add, edi = Edi, yea = Yea, mon = Mon, nte = Nte,
648               dat = Dat)),!.
649insert_man(List) :- write('                     Insert failed!'),nl.
650
651insert_mas([Ide,Aut,Key,Tit,Sch,Add,Yea,Mon,Nte,Dat]) :-
652    insert(mas(ide = Ide, aut = Aut, key = Key, tit = Tit, sch = Sch,
653               add = Add, yea = Yea, mon = Mon, nte = Nte, dat = Dat)),!.
654insert_mas(List) :- write('                     Insert failed!'),nl.
655
656insert_mis([Ide,Aut,Key,Tit,How,Yea,Mon,Nte,Dat]) :-
657    insert(mis(ide = Ide, aut = Aut, key = Key, tit = Tit, how = How,
658               yea = Yea, mon = Mon, nte = Nte, dat = Dat)),!.
659insert_mis(List) :- write('                     Insert failed!'),nl.
660
661insert_phd([Ide,Aut,Key,Tit,Sch,Add,Yea,Mon,Nte,Dat]) :-
662    insert(phd(ide = Ide, aut = Aut, key = Key, tit = Tit, sch = Sch,
663               add = Add, yea = Yea, mon = Mon, nte = Nte, dat = Dat)),!.
664insert_phd(List) :- write('                     Insert failed!'),nl.
665
666insert_pro([Ide,Key,Org,Tit,Bot,Edr,Pub,Add,Yea,Mon,Nte,Dat]) :-
667    insert(pro(ide = Ide, key = Key, org = Org, tit = Tit, bot = Bot,
668               edr = Edr, pub = Pub, add = Add, yea = yea, mon = Mon,
669               nte = Nte, dat = Dat)),!.
670insert_pro(List) :- write('                     Insert failed!'),nl.
671
672insert_tec([Ide,Aut,Key,Tit,Ins,Org,Add,Typ,Num,Yea,Mon,Nte,Dat]) :-
673    insert(tec(ide = Ide, aut = Aut, key = Key, tit = Tit, ins = Ins,
674               org = Org, add = Add, typ = Typ, num = Num, yea = Yea,
675               mon = Mon, nte = Nte, dat = Dat)),!.
676insert_tec(List) :- write('                     Insert failed!'),nl.
677
678insert_unp([Ide,Aut,Key,Tit,Yea,Mon,Nte,Dat]) :-
679    insert(unp(ide = Ide, aut = Aut, key = Key, tit = Tit, yea = Yea,
680               mon = Mon, nte = Nte, dat = Dat)),!.
681insert_unp(List) :- write('                     Insert failed!'),nl.
682
683insert_cop([Ide,DocType,Own,Loc,Llo,Dat]) :-
684    insert(cop(ide = Ide, doc = DocType, own = Own, loc = Loc,
685               llo = Llo, dat = Dat)),!.
686insert_cop(List) :- write('                     Insert failed!'),nl.
687
688insert_kyw([Ide,DocType,Kyw]) :-
689    insert(kyw(ide = Ide, doc = DocType, kyw = Kyw)),!.
690insert_kyw(List) :- write('                     Insert failed!'),nl.
691
692% --- collect complaints in 'incorrect' ---
693
694write_errdoc(Symptom,Entry,Bug) :-
695    getval(write_stream_2, WriteStream2),
696    write(WriteStream2,Symptom),
697    writeln(WriteStream2,'. '),
698    write(WriteStream2,Entry),
699    writeln(WriteStream2,'. '),
700    write(WriteStream2,Bug),
701    writeln(WriteStream2,'. ').
702
703
704% -----------------------------------------
705%       C O R R E C T   E N T R I E S
706% -----------------------------------------
707
708correct_entries :-
709    repeat,
710       read_comp(Complaint),
711       process_comp(Complaint).
712
713process_comp(end_of_file) :- !.
714
715process_comp([Symptom,Entry,Bug]) :-
716    correct_entry(Symptom,Entry,Bug,CorrectEntry),
717    enter(CorrectEntry),
718    fail.
719
720correct_entry(noide,[DocType|ValList],MissingL,CorrectEntry) :-
721    entry_display([DocType|ValList],Line),
722    NewLine is Line + 2,
723    correction(noide,MissingL,ResultL,NewLine),
724    del_all_atts(key,ValList,List1),
725    del_all_atts(yea,List1,List2),
726    conc(ResultL,List2,CList),
727    generate_ide(CList,Ide),
728    conc([[ide,Ide]],CList,CorrList),
729    check_and_correct([DocType|CorrList],CorrectEntry).
730correct_entry(missing,[DocType|ValList],Attr,[DocType|CorrectList]) :-
731    entry_display([DocType|ValList],Line),
732    NewLine is Line + 2,
733    correction(missing,Attr,Result,NewLine),
734    conc([Result],ValList,CList),
735    complete([DocType|CList],[DocType|CorrectList]).
736correct_entry(toolong,[DocType|ValList],Attr,[DocType|CorrectList]) :-
737    entry_display([DocType|ValList],Line),
738    NewLine is Line + 2,
739    correction(toolong,Attr,Result,NewLine),
740    replace_item(Result,ValList,CList1),
741    not_too_long([DocType|CList1],[DocType|CList2]),
742    complete([DocType|CList2],[DocType|CorrectList]).
743correct_entry(double,Entry,[f,Similars],CorrectEntry) :-
744    entry_display(Entry,Line),
745    ide_ending(Similars,End),
746    check_similars(Entry,Similars,CorrectEntry,End).
747correct_entry(double,Entry,[m,Similars],CorrectEntry) :-
748    double(Entry,RealSimilars),
749    entry_display(Entry,Line),
750    ide_ending(RealSimilars,End),
751    check_similars(Entry,RealSimilars,CorrectEntry,End).
752
753check_and_correct(Entry,CorrectEntry) :-
754    double(Entry,Similars),
755    !,
756    first_double(Entry,N),
757    correct_entry(double,Entry,[N,Similars],CorrectEntry).
758
759check_and_correct(Entry,CorrectEntry) :-
760    not_too_long(Entry,NTLEntry),
761    complete(NTLEntry,CorrectEntry).
762
763
764check_similars([DocType|ValList],[],[DocType|CorrectList],End) :-
765    !,
766    correct_ide(ValList,End,CList),
767    not_too_long([DocType|CList],[DocType|CList1]),
768    complete([DocType|Clist1],[DocType|CorrectList]).
769
770check_similars(Entry,[Similar|L],C,E) :-
771    clear_below(17),
772    cursor(17,1),
773    write('-----------------------------------------------------------------'),
774    m_display(Similar,19),
775    get_answer('Next similar entry (N) / reject entry (R) : ',Answer,23,5),
776    process_answer(Answer,Entry,L,C,E).
777
778process_answer("R",Entry,Similars,[],End) :- !.
779
780process_answer(Answer,Entry,Similars,CorrectEntry,End) :-
781    check_similars(Entry,Similars,CorrectEntry,End).
782
783complete([DocType|ValList],[DocType|CorrectList]) :-
784    val_missing([DocType|ValList],Attr),
785    !,
786    correct_entry(missing,[DocType|ValList],Attr,[DocType|CorrectList]).
787
788complete(Entry,Entry).
789
790not_too_long([DocType|ValList],[DocType|CorrectList]) :-
791    val_too_long([DocType|ValList],Attr),
792    !,
793    correct_entry(toolong,[DocType|ValList],Attr,[DocType|CorrectList]).
794
795not_too_long(Entry,Entry).
796
797read_comp(Input) :-
798    getval(read_stream_2, ReadStream2),
799    read(ReadStream2,Line1),
800    (    Line1 = end_of_file,
801            Input = Line1
802    ;
803            read(ReadStream2,Line2),
804            read(ReadStream2,Line3),
805            Input = [Line1,Line2,Line3]
806    ).
807
808correction(noide,MissingL,ResultL,Line) :-
809    print_line('Key/Year are incorrect!',Line,5),
810    NewL is Line + 1,
811    askfor_atts(MissingL,ResultL,NewL,NewLine).
812
813correction(missing,Attr,Result,Line) :-
814    print_line('Attribute missing!',Line,5),
815    NewL is Line + 1,
816    askfor_att([Attr,m],[Result],NewL,NewLine).
817
818correction(toolong,Attr,Result,Line) :-
819    print_line('Attribute too long!',Line,5),
820    NewL is Line + 1,
821    askfor_att([Attr,m],[Result],NewL,NewLine).
822
823% -------------------------------------
824%       S U B P R O C E D U R E S
825% -------------------------------------
826
827correct_ide(List,End,Result) :-
828    del([ide,Ide],List,List1),
829    conc(Ide,End,NewIde),
830    conc([[ide,NewIde]],List1,Result).
831
832ending(Year,EndYear) :-
833    last(Year,S,X),
834    last(S,T,Y),
835    conc([Y],[X],EndYear).
836
837entry_display([DocType|ValList],Line) :-
838    assert(doc(DocType)),
839    del_all_atts(kyw,ValList,List1),
840    del_all_atts(cop,List1,List2),
841    ordered([DocType|List2],[DocType|List3]),
842    strings_to_atoms_result(List3,List4),
843    standard_display(List4,Line),
844    retract(doc(DocType)).
845
846first_nonabbr([],"-").
847
848first_nonabbr(String,NonAbbr) :-
849    up_to_char(32,String,Str1,Str2),
850    !,
851    non_abbr(Str1,Str2,NonAbbr).
852
853first_nonabbr(String,String) :-
854    non_abbr(String,[],String).
855
856m_display([],L).
857
858m_display([[Attr,Val]|L],Line) :-
859    cap_attr_abbr(Attribute,Attr),
860    cursor(Line,5),
861    write(Attribute),
862    fill_blanks(Attribute,13),
863    write(' :  '),
864    name(AVal,Val),
865    write(AVal),
866    NewLine is Line + 1,
867    m_display(L,NewLine).
868
869non_abbr(Str,String,NonAbbr) :-
870    lastelem(Str,46),
871    !,
872    first_nonabbr(String,NonAbbr).
873
874non_abbr(Str,X,Str).
875
876too_long([],X) :-
877    !,
878    fail.
879
880too_long([[cop,Own,Loc]|L],own) :-
881    !,
882    len(Own,Length),
883    attr_len(own,Len),
884    Length > Len.
885
886too_long([[cop,Own,Loc]|L],loc) :-
887    !,
888    len(Loc,Length),
889    attr_len(loc,Len),
890    Length > Len.
891
892too_long([[Attr,Val]|L],Attr) :-
893    len(Val,Length),
894    attr_len(Attr,Len),
895    Length > Len,
896    !.
897
898too_long([X|L],Attr) :-
899    too_long(L,Attr).
900
901% check_mand_atts(AttrList,ValList,Attr) is true if ValList
902% does not contain a value for the mandatory attribute Attr
903
904check_mand_atts([],List,X) :-
905    !,
906    fail.
907
908check_mand_atts([Attr|L],ValList,Attr) :-
909    not(member([Attr,X],ValList)),
910    !.
911
912check_mand_atts([Attr|L],ValList,X) :-
913    check_mand_atts(L,ValList,X).
914
915% check_atts(AttList,ValList,CheckedList)
916% CheckedList = ValList + [Attr,"-"] for missing attribute Attr
917
918check_atts([],List,[]) :- !.
919
920check_atts([Attr|AList],ValList,[Val|CheckedList]) :-
921    member([Attr,Val],ValList),
922    !,
923    check_atts(AList,ValList,CheckedList).
924
925check_atts([Attr|AList],ValList,["-"|CheckedList]) :-
926    check_atts(AList,ValList,CheckedList).
927
928collect(cop,ValList,Copies) :-
929    bagof([Own,Loc],member([cop,Own,Loc],ValList),Copies),
930    !.
931
932collect(kyw,ValList,KywList) :-
933    bagof(Kyw,member([kyw,Kyw],ValList),KywList),
934    !.
935
936collect(X,Y,[]).
937
938% first_double
939
940first_double([DocType|ValList],f) :-
941    member([ide,Ide],ValList),
942    double(DoubleList),
943    not(member(Ide,DoubleList)),
944    !,
945    retract(double(DoubleList)),
946    conc([Ide],DoubleList,NewList),
947    assert(double(NewList)).
948
949first_double(Entry,m).
950
951% ide_ending computes the character that has to be concatenated to
952% the Document_Id of the actual entry to make it different from Similars
953
954ide_ending([SingleItem],"b") :- !.
955
956ide_ending(Similars,[End]) :-
957    max(Similars,Max),
958    End is Max + 1.
959
960max([],0).
961
962max([[[ide,Ide]|L]|List],Max) :-
963    max(List,M),
964    last(Ide,X,Last),
965    (    M >= Last,
966             !,
967             Max = M
968    ;
969             Max = Last
970    ).
971
972% strings_to_atoms_list transforms a list of strings into a list of atoms
973
974strings_to_atoms_list([],[]).
975
976strings_to_atoms_list([String|StringList],[Atom|AtomList]) :-
977    name(Atom,String),
978    strings_to_atoms_list(StringList,AtomList).
979
980% strings_to_atoms_result transforms the strings of a result list into atoms
981
982strings_to_atoms_result([],[]).
983
984strings_to_atoms_result([[Attr,String]|List],[[Attr,Atom]|AtomList]) :-
985    name(Atom,String),
986    strings_to_atoms_result(List,AtomList).
987
988% usable(Input) is true if Input can be interpreted as a document entry
989
990usable([Atom|List]) :-
991    doctype(Atom),
992    not(empty(List)),
993    atts_and_values(List).
994
995atts_and_values([]).
996atts_and_values([[Atom,Val]|L]) :-
997    attribute(Atom),
998    is_string(Val),
999    atts_and_values(L).
1000
1001atts_and_values([[cop,Val1,Val2]|L]) :-
1002    is_string(Val1),
1003    is_string(Val2),
1004    atts_and_values(L).
1005
1006% clean(Entry,CleanEntry):   * ? [ ] are removed, ' changed to ` in CleanEntry
1007
1008clean([DocType|ValList],[DocType|CleanList]) :-
1009    clean_vallist(ValList,CleanList).
1010
1011clean_vallist([],[]).
1012
1013clean_vallist([[Attr,Val]|Tail],[[Attr,CleanVal]|CleanTail]) :-
1014    clean_val(Val,CleanVal),
1015    clean_vallist(Tail,CleanTail).
1016
1017% fix: clean_val([],[]).
1018clean_val([42|Tail],CTail) :-
1019    !,
1020    clean_val(Tail,CTail).
1021
1022clean_val([63|Tail],CTail) :-
1023    !,
1024    clean_val(Tail,CTail).
1025
1026clean_val([91|Tail],CTail) :-
1027    !,
1028    clean_val(Tail,CTail).
1029
1030clean_val([93|Tail],CTail) :-
1031    !,
1032    clean_val(Tail,CTail).
1033
1034clean_val([39|Tail],[96|CTail]) :-
1035    !,
1036    clean_val(Tail,CTail).
1037
1038clean_val([X|Tail],[X|CTail]) :-
1039    clean_val(Tail,CTail).
1040
1041
1042/* ------------------
1043
1044D)  TRANSLATION OF SCRIBE BIBLIOGRAPHY FILES INTO LOB FILES
1045
1046*/
1047
1048translate_file :-
1049    clearpage,
1050    get_answer('Please enter name of Scribe file :  ',Inp,4,10),
1051    complete_filename(Inp,ScribeFile),
1052    open(ScribeFile,read,ReadStream3),
1053    setval(read_stream_3, ReadStream3),
1054    get_answer('Please enter name of LOB file :  ',Inp2,6,10),
1055    complete_filename(Inp2,LobFile),
1056    open(LobFile,write,WriteStream3),
1057    setval(write_stream_3, WriteStream3),
1058    transl_file,
1059    close(ReadStream3),
1060    close(WriteStream3).
1061
1062transl_file :-
1063    repeat,
1064        read_reference(Reference),
1065        transl_reference(Reference).
1066
1067transl_reference(end_of_file) :- !.
1068
1069transl_reference(Reference) :-
1070    transl_ref(Reference,Entry),
1071    getval(write_stream_3, WriteStream3),
1072    write(WriteStream3,Entry),
1073    writeln(WriteStream3,'. '),
1074    fail.
1075
1076transl_ref(Reference,[DocType|ValList]) :-
1077    retrieve_doctype(Reference,DocType,Rest),
1078    retrieve_vallist(Rest,ValList).
1079
1080retrieve_doctype([64|List],DocType,Rest) :-
1081    !,
1082    head_3(List,Type),
1083    transl_case(Type,DocType),
1084    up_to_char(44,List,X,Rest).
1085
1086retrieve_doctype([X|List],DocType,Rest) :-
1087    retrieve_doctype(List,DocType,Rest).
1088
1089retrieve_vallist(")",[]).
1090
1091retrieve_vallist(List,[[Attr,Val]|ValL]) :-
1092    retrieve_attrval(List,Attr,Val,Rest),
1093    retrieve_vallist(Rest,ValL).
1094
1095retrieve_attrval([X|List],Attr,Val,Rest) :-
1096   (   X < 65
1097   ;
1098       X > 90,
1099       X < 97
1100   ;
1101       X > 122
1102   ),
1103   !,
1104   retrieve_attrval(List,Attr,Val,Rest).
1105
1106retrieve_attrval(List,Attr,Value,Rest) :-
1107    head_3(List,Head),
1108    transl_attr(Head,Attr),
1109    up_to_char(34,List,X,Tail),
1110    up_to_char(34,Tail,Value,Rest).
1111
1112transl_attr("Not",nte) :- !.
1113transl_attr(X,A) :- transl_case(X,A).
1114
1115transl_case([C1,C2,C3],A) :-
1116    97 =< C1,
1117    C1 =< 122,
1118    !,
1119    name(A,[C1,C2,C3]).
1120
1121transl_case([C1,C2,C3],A) :-
1122    N1 is C1 + 32,
1123    name(A,[N1,C2,C3]).
1124
1125read_reference(Reference) :-
1126    read_ref(0,Reference).
1127
1128read_ref(X,Reference) :-
1129    getval(read_stream_3, ReadStream3),
1130    getc(ReadStream3,Y),
1131    read_ref_rest(X,Y,Reference).
1132
1133read_ref_rest(0,10,Reference) :-
1134    !,
1135    read_ref(0,Reference).
1136
1137read_ref_rest(41,10,[]) :- !.                 % end of reference
1138
1139read_ref_rest(X,Y,end_of_file) :-                 % EOF
1140    Y < 0,
1141    !.
1142
1143read_ref_rest(X,39,[96|Reference]) :-         % translates ' into `
1144    !,
1145    read_ref(96,Reference).
1146
1147read_ref_rest(X,42,Reference) :-              % deletes *
1148    !,
1149    read_ref(42,Reference).
1150
1151read_ref_rest(X,63,Reference) :-              % deletes ?
1152    !,
1153    read_ref(63,Reference).
1154
1155read_ref_rest(X,91,Reference) :-              % deletes [
1156    !,
1157    read_ref(91,Reference).
1158
1159read_ref_rest(X,93,Reference) :-              % deletes ]
1160    !,
1161    read_ref(93,Reference).
1162
1163read_ref_rest(X,Y,[Y|Reference]) :-
1164    !,
1165    read_ref(Y,Reference).
1166
1167
1168:- set_back_strings_to_strings.
1169