1% LOOP57
2:- module(yoyo3).
3
4:- dynamic already_seen/1.
5
6:- lib(porting, yoyo3).
7:- set_all_strings_to_lists.	% this has to be done before compiling the files!
8
9:- lib(basic, yoyo3).
10:- lib(facts, yoyo3).
11:- lib(screen, yoyo3).
12:- set_flag(print_depth, 10000).
13
14:- op(400, xfy, '.').
15:- op(400, xfy, and).
16
17
18getbug :-
19	writeln('\nCheck that you are in "module(yoyo3).", then'),
20	writeln('to start the program type "check_input."\n and enter "Foo" (once) and "1986" (many times)\n').
21
22bug :-
23	nl,
24	explanation.
25
26explanation :-
27writeln('There is no clause treating the case that there is no similar entry, \n\
28causing backtracking to the place where an input is requested. \n\
29\n\
30GOAL:	 check_input, filename "bib4_list" \n\
31CORRECT: ask for the missing key, display complete entry \n\
32BUGGY:   endless loop (failure-driven). \n').
33
34
35% ============================================================================
36
37% --- test --- 5.7.89
38
39insert(Entry) :-
40	nl, writeln('Entry:'), writeln(Entry), nl.
41
42double(_,_) :- !, fail.
43double([DocType|ValList],Similars) :-
44    member([ide,Ide],ValList),
45    bagof(Result,
46          general_search([[ide,m,Ide]],[ide,aut,tit],[DocType],Result),
47          Similars).
48
49/*                         UPDATE OF THE DATABASE
50
51
52A)  interactive input help
53B)  input checker
54C)  erase/modify/add (Key)
55D)  transformation of findecrc files into LOB files
56
57---------------
58
59A)  INTERACTIVE INPUT HELP
60
61build_file will help the user to build a file of future database entries
62which can be read by the input checker. For each document which shall be
63entered the user is asked for the mandatory or optional attributes with
64respect to the document's type.
65
66Representation of a document in the file:
67
68     [bok,[aut,"L. Sterling, E.Y. Shapiro"],
69          [tit,"The Art of Prolog - Advanced Programming Techniques"],
70          [key,"Sterling"],[yea,"1986"],
71          [pub,"MIT Press"],[ser,"Logic programming"],
72          [kyw,"logic programming"],[kyw,"prolog"],
73          [cop,"library","library"],
74          [cop,"library","mireille"]].
75
76*/
77
78% ---------------
79% test procedures
80% ---------------
81
82existing_name(Filename) :- !,fail.
83
84% =============================================== main program ================
85
86build_file :-
87    clearpage,
88%    get_answer('Please enter filename :  ',Input,4,10),
89%    complete_filename(Input,Filename),
90    lob_build_lib_name(bib4_list, Filename), % for testing
91    open(Filename,write,bibfile),
92    build_file(Filename),
93    close(bibfile).
94
95build_file(Filename) :-
96    existing_name(Filename),
97    !,
98    error_message('Filename already exists!',2,5,5),
99    readln(X),
100    clearpage,
101    build_file.
102build_file(Filename) :-
103    clearpage,
104    process_date,
105    process_file(Filename).
106
107process_file(Filename) :-
108    cursor(2,5),
109    write('Document type :  '),
110    readln(Input),
111    checkinp_1(Input,CheckedInp),
112    !,
113    process_doc(CheckedInp,Filename,4).
114
115process_doc(no,Filename,Line) :-
116    !,
117    clearpage,
118    cursor(3,5),
119    write('File '),
120    write(Filename),
121    write(' has been written.'),
122    nl,nl.
123process_doc(wronginp,Filename,Line) :-
124    NewL1 is Line - 2,
125    error_message('Wrong input.',NewL1,40,21),
126    process_file(Filename).
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    process_file(Filename).
133
134% askfor_atts will prompt the user to enter the values of the attributes
135
136askfor_atts([Attr],Res,ActLine,NewLine) :-
137    askfor_att(Attr,Res,ActLine,NewLine).
138askfor_atts([Attr|AttrList],ValueList,ActLine,NewLine) :-
139    askfor_att(Attr,Res,ActLine,ActL),
140    askfor_atts(AttrList,ResList,ActL,NewLine),
141    conc(Res,ResList,ValueList).
142
143askfor_att([kyw,o],ResList,ActLine,NewLine) :-
144    Line is ActLine + 1,
145    askfor_att_k([kyw,o],ResList,Line,NewLine).
146askfor_att([cop,o],ResList,ActLine,NewLine) :-
147    Line is ActLine + 1,
148    askfor_att_c([cop,o],ResList,Line,NewLine).
149askfor_att([Attr,R],Res,ActLine,NewLine) :-
150    cap_attr_abbr(Attribute,Attr),
151    clearline(ActLine,5),
152    write(Attribute),
153    fill_blanks(Attribute,13),
154    write(' :  '),
155    receive(Attr,R,Res,ActLine,NewLine,22).
156
157% Entry of (several) keywords: ResList = [[kyw,"logic"],[kyw,"Prolog"]]
158
159askfor_att_k([kyw,o],ResList,ActLine,NewLine) :-
160    askfor_kyw(Res,ActLine,ActL),
161    process_kyw(Res,ResList,ActL,NewLine).
162
163process_kyw([],[],ActLine,ActLine) :-
164    !.
165process_kyw(Res,ResList,ActLine,NewLine) :-
166    askfor_att_k([kyw,o],Rlist,ActLine,NewLine),
167    conc(Res,Rlist,ResList).
168
169askfor_kyw(Res,ActLine,NewLine) :-
170    cap_attr_abbr(Attribute,kyw),
171    clearline(ActLine,5),
172    write(Attribute),
173    fill_blanks(Attribute,13),
174    write(' :  '),
175    receive(kyw,o,Res,ActLine,NewLine,22).
176
177% Entry of copies:
178% ResList = [[cop,"library","library"],[cop,"library","anna"]]
179
180askfor_att_c([cop,o],ResList,ActLine,NewLine) :-
181    askfor_att([own,o],Res,ActLine,ActL),
182    process_cop(Res,ResList,ActL,NewLine).
183
184process_cop([],[],ActLine,ActLine).
185process_cop([[Attr,Owner]],ResList,ActLine,NewLine) :-
186    askfor_att([loc,m],[[loc,Location]],ActLine,ActL),
187    process_nxtcop(RList,ActL,NewLine),
188    conc([[cop,Owner,Location]],RList,ResList).
189
190process_nxtcop(ResList,ActLine,NewLine) :-
191    askfor_att([own,o],Own,ActLine,ActL),
192    process_own(Own,ResList,ActL,NewLine).
193
194process_own([],[],ActLine,ActLine) :-
195    !.
196process_own([own,Owner],ResList,ActLine,NewLine) :-
197    askfor_att([loc,m],[[loc,Location]],ActLine,ActL2),
198    process_nxtcop(RList,ActL2,NewLine),
199    conc([[cop,Owner,Location]],RList,ResList).
200
201
202% ---------------------
203% input check functions
204% ---------------------
205
206checkinp_1("",no).
207checkinp_1("no",no).
208checkinp_1("n",no).
209checkinp_1("e",no).
210checkinp_1("x",no).
211checkinp_1("exit",no).
212checkinp_1(X,Y) :-
213    name(Z,X),
214    type_abbr(Z,Y).
215checkinp_1(X,Y) :-
216    name(Y,X),
217    type_abbr(_,Y).
218checkinp_1(_,wronginp).
219
220checkinp_2(_,o,[],[],ActLine,ActLine) :-
221    !,
222    clearline(ActLine,5).
223checkinp_2(yea,m,[],Result,ActLine,ActLine) :-
224    !,
225    error_message('Attribute mandatory!',ActLine,40,22),
226    fail.
227checkinp_2(yea,R,Value,Result,ActLine,NewLine) :-
228    !,
229    str_to_int(Value,Int),
230    check_year(Int,Result,Value,R,ActLine,NewLine).
231checkinp_2(Attr,m,[],Res,ActLine,ActLine) :-
232    !,
233    error_message('Attribute mandatory!',ActLine,40,22),
234    fail.
235checkinp_2(Attr,R,Value,[[Attr,Value]],ActLine,NewLine) :-
236    check_length(Attr,Value),
237    !,
238    NewLine is ActLine + 1.
239checkinp_2(Attr,R,Value,Result,ActLine,ActLine) :-
240    !,
241    error_message('String too long!',ActLine,40,22),
242    fail.
243
244check_year(Int,[[yea,Result]],Result,R,ActLine,NewLine) :-
245    Int >= 1900,
246    Int =< 3000,
247    !,
248    NewLine is ActLine + 1.
249check_year(Int,Res,Result,R,ActLine,ActLine) :-
250    error_message('4 digits, please!',ActLine,40,22),
251    fail.
252
253check_length(Attr,Value) :-
254    len(Value,ActLength),
255    attr_len(Attr,MaxLength),
256    ActLength =< MaxLength.
257
258% --------------
259% error messages
260% --------------
261
262error_message(Message,Line,Col,BackCol) :-
263    clearline(Line,Col),
264    write('    ** '),
265%   write('*** error: '),
266    write(Message),
267    write(' **'),
268    readln(X),
269    clearline(Line,BackCol).
270
271
272% --------------
273% subprocedures
274% --------------
275
276process_date :-
277    repeat,
278      (    get_answer('Please enter today`s date (DD.MM.YY) : ',Date,2,5),
279               check_date(Date),
280               write(bibfile,Date),
281               writeln(bibfile,'. '),
282               clearpage
283      ;
284               error_message('Wrong format!',2,43,5),
285               fail
286      ).
287
288check_date(String) :-
289    up_to_char(46,String,Day,Rest),
290    up_to_char(46,Rest,Month,Year),
291    str_to_int(Day,IDay),
292    1 =< IDay,
293    IDay =< 31,
294    str_to_int(Month,IMonth),
295    1 =< IMonth,
296    IMonth =< 12,
297    str_to_int(Year,IYear),
298    0 =< IYear,
299    IYear =< 99.
300
301
302receive(Attr,R,Res,ActLine,NewLine,FromCol) :-
303    put_dot(Attr,ActLine,22),
304    readln(Value),
305    checkinp_2(Attr,R,Value,Res,ActLine,NewLine).
306receive(Attr,R,Res,ActLine,NewLine,FromCol) :-
307    receive(Attr,R,Res,ActLine,NewLine,FromCol).
308
309write_entry(Entity) :-
310    write(bibfile,Entity),
311    writeln(bibfile,'. ').
312
313put_dot(Attr,Line,Col) :-
314    attr_len(Attr,Length),
315    Col2 is Length + Col + 2,
316    dot(Line,Col2),
317    cursor(Line,Col).
318
319dot(Line,Col) :-
320    Col =< 80,
321    !,
322    cursor(Line,Col),
323    write('.').
324dot(Line,Col).
325
326
327/*
328
329------------------
330
331B)  INPUT CHECKER
332
333check_input will read new references from a file (written in a format like
334the output of build_file) and check whether there are values for all the
335mandatory attributes, whether the values are not too long, and whether there
336are entries in the database that are similar to the new one (i.e. have the
337same key). Correct references are directly inserted into the database.
338Incorrect references and those which are suspected to be already contained
339in the database are collected in a  file 'documents.err'. These references
340are presented to the moderator after the first check, s/he has the possibility
341to correct/reject them.
342
343*/
344
345check_input :-
346    clearpage,
347%    get_answer('Please enter filename :  ',Input,4,10),
348%    complete_filename(Input,Filename),
349    lob_build_lib_name(bib4_list, Filename), % for testing
350    open(Filename,read,bibinput),
351    check_input(Filename),
352    close(bibinput).
353
354% check_input(Filename) :-
355%     not(existing_name(Filename)),
356%     !,
357%     error_message('Filename does not exists!',2,5,5),
358%     readln(X),
359%     clearpage,
360%     check_input.
361
362check_input(Filename) :-
363    lob_build_lib_name('documents.err', Filename),
364    open(Filename, write, errout),
365    read(bibinput,Date),
366    assert(dat(Date)),
367    check_file,
368    close(errout),
369    !,
370    open(Filename,read,errin),
371    correct_entries,
372    close(errin),
373    retract(dat(Date)).
374
375
376% --------------------------------
377%        C H E C K   F I L E
378% --------------------------------
379
380check_file :-
381    read(bibinput,Entry),
382    process_entry(Entry).
383
384process_entry(end_of_file) :- !.
385process_entry(E) :-
386    add_ide(E,Entry),
387    !,
388    proc_entry(Entry).
389process_entry(Entry) :-
390    write_errdoc(noide,Entry,[[key,m],[yea,m]]),
391    check_file.
392
393proc_entry(Entry) :-
394    double(Entry,Similars),
395    write_errdoc(double,Entry,Similars),
396    check_file.
397proc_entry(Entry) :-
398    val_too_long(Entry,Attr),
399    write_errdoc(toolong,Entry,Attr),
400    check_file.
401proc_entry(Entry) :-
402    val_missing(Entry,Attr),
403    write_errdoc(missing,Entry,Attr),
404    check_file.
405proc_entry(Entry) :-
406    enter(Entry),
407    check_file.
408
409% check each attribute for a string that is too long
410val_too_long([DocType|ValList],TooLong) :-
411    too_long(ValList,TooLong).
412
413% check whether a mandatory attribute is missing
414val_missing([DocType|ValList],Attr) :-
415    mandatory_atts(DocType,AttList),
416    check_mand_atts(AttList,ValList,Attr).
417
418% add document identifier
419add_ide([DocType|ValList],[DocType|ComplList]) :-
420    generate_ide(ValList,Ide),
421    conc([[ide,Ide]],ValList,ComplList).
422
423generate_ide(ValList,Ide) :-
424    member([key,Key],ValList),
425    len(Key,Length),
426    Length =< 17,
427    first_nonabbr(Key,HeadKey),
428    member([yea,Year],ValList),
429    str_to_int(Year,Num),
430    Num >= 1900,
431    Num =< 3000,
432    ending(Year,EndYear),
433    conc(HeadKey,EndYear,Ide).
434
435% ---------------------------
436% process correct(ed) entries
437% ---------------------------
438
439enter([]).
440enter(Entry) :-
441    add_date(Entry,ComplEntry),
442    enter_doc(ComplEntry).
443%    enter_copies(ComplEntry),
444%    enter_kyws(ComplEntry).
445
446add_date([DT|List],[DT|ResList]) :-
447    dat(Date),
448    conc([[dat,Date]],List,ResList).
449
450enter_doc(ComplEntry) :-
451    build_docentry(ComplEntry,DocEntry),
452    insert_docentry(DocEntry).
453
454build_docentry([DocType|ValList],[DocType|CheckedList]) :-
455    rel_has_atts(DocType,AttList),
456    check_atts(AttList,ValList,CheckedList).
457
458enter_copies([DocType|ValList]) :-
459    member([ide,Ide],ValList),
460    dat(Date),
461    collect(cop,ValList,Copies),
462    insert_copies(DocType,Ide,Date,Copies).
463
464enter_kyws([DocType|ValList]) :-
465    member([ide,Ide],ValList),
466    collect(kyw,ValList,KywList),
467    insert_kyws(DocType,Ide,KywList).
468
469insert_docentry([DocType|ValList]) :-
470    conc_atom('insert_',DocType,ProcName),
471    strings_to_atoms_list(ValList,ValAtoms),
472    InsertProcess =.. [ProcName|[ValAtoms]],
473    call(InsertProcess).
474
475insert_copies(DocType,Ide,Date,[]).
476insert_copies(DocType,Ide,Date,[[Own,Loc]|CopList]) :-
477    name(DocType,DTString),
478    strings_to_atoms_list([Ide,DTString,Own,Loc,"-",Date],ValList),
479    InsertProcess =.. [insert_cop|[ValList]],
480    call(InsertProcess),
481    insert_copies(DocType,Ide,Date,CopList).
482
483insert_kyws(DocType,Ide,[]).
484insert_kyws(DocType,Ide,[Kyw|KywList]) :-
485    name(DocType,DTString),
486    strings_to_atoms_list([Ide,DTString,Kyw],ValList),
487    InsertProcess =.. [insert_kyw|[ValList]],
488    call(InsertProcess),
489    insert_kyws(DocType,Ide,KywList).
490
491% ------ test procedures -----
492
493general_search([[ide,m,Ide]],L1,L2,Result) :-
494   nl,nl,
495   write('Database search for ide = '),
496   write(Ide),
497   nl,
498   write('Please enter result: '),
499   read(Result),
500   nl,
501   (   Result = x,
502           !,
503           fail
504   ;
505       true
506   ).
507
508insert_art(List) :- write(List),nl,assert(ins(List)).
509insert_bok(List) :- write(List),nl,assert(ins(List)).
510insert_bol(List) :- write(List),nl,assert(ins(List)).
511insert_con(List) :- write(List),nl,assert(ins(List)).
512insert_inb(List) :- write(List),nl,assert(ins(List)).
513insert_inc(List) :- write(List),nl,assert(ins(List)).
514insert_inp(List) :- write(List),nl,assert(ins(List)).
515insert_man(List) :- write(List),nl,assert(ins(List)).
516insert_mas(List) :- write(List),nl,assert(ins(List)).
517insert_mis(List) :- write(List),nl,assert(ins(List)).
518insert_phd(List) :- write(List),nl,assert(ins(List)).
519insert_pro(List) :- write(List),nl,assert(ins(List)).
520insert_tec(List) :- write(List),nl,assert(ins(List)).
521insert_unp(List) :- write(List),nl,assert(ins(List)).
522insert_cop(List) :- write(List),nl,assert(ins(List)).
523insert_kyw(List) :- write(List),nl,assert(ins(List)).
524
525% ---------- end test procedures ------
526
527/*
528
529insert_art([Ide,Aut,Tit,Jou,Vol,Num,Pag,Yea,Mon,Nte,Dat]) :-
530    insert(art(ide = ide, aut = Aut, tit = Tit, jou = Jou, vol = Vol,
531               num = Num, pag = Pag, yea = Yea, mon = Mon, nte = Nte,
532               dat = Dat)).
533
534insert_bok([Ide,Aut,Tit,Edr,Pub,Add,Edi,Ser,Vol,Num,How,Yea,Nte,Dat]) :-
535    insert(bok(ide = Ide, aut = Aut, tit = Tit, edr = Edr, pub = Pub,
536               add = Add, edi = Edi, ser = Ser, vol = Vol, num = Num,
537               how = How, yea = Yea, nte = Nte, dat = Dat)).
538
539insert_bol([Ide,Aut,Tit,Pub,Add,How,Yea,Mon,Nte,Dat]) :-
540    insert(bol(ide = ide, aut = Aut, tit = Tit, pub = Pub, add = Add,
541               how = How, yea = Yea, mon = Mon, nte = Nte, dat = Dat)).
542
543insert_con([Ide,Aut,Tit,Org,Mee,Yea,Mon,Nte,Dat]) :-
544    insert(con(ide = Ide, aut = Aut, tit = tit, org = Org, mee = Mee,
545               yea = Yea, mon = Mon, nte = Nte, dat = Dat)).
546
547insert_inb([Ide,Aut,Tit,Bot,Cha,Pag,Edr,Pub,Add,Edi,Ser,Vol,Num,How,Yea,
548                  Nte,Dat]) :-
549    insert(inb(ide = Ide, aut = Aut, tit = Tit, bot = Bot, cha = Cha,
550               pag = Pag, edr = Edr, pub = Pub, add = Add, edi = Edi,
551               ser = Ser, vol = Vol, num = Num, how = How, yea = Yea,
552               nte = Nte, dat = Dat)).
553
554insert_inc([Ide,Aut,Tit,Bot,Cha,Pag,Edr,Pub,Add,Ser,Vol,Num,Yea,Nte,Dat]) :-
555    insert(inc(ide = Ide, aut = Aut, tit = Tit, bot = Bot, cha = Cha,
556               pag = Pag, edr = Edr, pub = Pub, add = Add, ser = Ser,
557               vol = Vol, num = Num, yea = Yea, nte = Nte, dat = Dat)).
558
559insert_inp([Ide,Aut,Tit,Bot,Org,Pag,Edr,Pub,Add,Yea,Mon,Nte,Dat]) :-
560    insert(inp(ide = Ide, aut = Aut, tit = Tit, bot = Bot, org = Org,
561               pag = Pag, edr = Edr, pub = Pub, add = Add, yea = Yea,
562               mon = Mon, nte = Nte, dat = Dat)).
563
564insert_man([Ide,Aut,Tit,Org,Add,Edi,Yea,Mon,Nte,Dat]) :-
565    insert(man(ide = Ide, aut = Aut, tit = Tit, org = Org, add = Add,
566               yea = Yea, mon = Mon, nte = Nte, dat = Dat)).
567
568insert_mas([Ide,Aut,Tit,Sch,Add,Yea,Mon,Nte,Dat]) :-
569    insert(mas(ide = Ide, aut = Aut, tit = Tit, sch = Sch, add = Add,
570               yea = Yea, mon = Mon, nte = Nte, dat = Dat)).
571
572insert_mis([Ide,Aut,Tit,How,Yea,Mon,Nte,Dat]) :-
573    insert(mis(ide = Ide, aut = Aut, tit = Tit, how = How, yea = Yea,
574               mon = Mon, nte = Nte, dat = Dat)).
575
576insert_phd([Ide,Aut,Tit,Sch,Add,Yea,Mon,Nte,Dat]) :-
577    insert(phd(ide = Ide, aut = Aut, tit = Tit, sch = Sch, add = Add,
578               yea = Yea, mon = Mon, nte = Nte, dat = Dat)).
579
580insert_pro([Ide,org,Tit,Bot,Edr,Pub,Add,Yea,Mon,Nte,Dat]) :-
581    insert(pro(ide = Ide, org = Org, tit = Tit, bot = Bot, edr = Edr,
582               pub = Pub, add = Add, yea = yea, mon = Mon, nte = Nte,
583               dat = Dat)).
584
585insert_tec([Ide,Aut,Tit,Ins,Org,Add,Typ,Num,Yea,Mon,Nte,Dat]) :-
586    insert(tec(ide = Ide, aut = Aut, tit = Tit, ins = Ins, org = Org,
587               add = Add, typ = Typ, num = Num, yea = Yea, mon = Mon,
588               nte = Nte, dat = Dat)).
589
590insert_unp([Ide,Aut,Tit,Yea,Mon,Nte,Dat]) :-
591    insert(unp(ide = Ide, aut = Aut, tit = Tit, yea = Yea, mon = Mon,
592               nte = Nte, dat = Dat)).
593
594insert_cop([Ide,DocType,Own,Loc,Llo,Dat]) :-
595    insert(cop(ide = Ide, doc = DocType, own = Own, loc = Loc,
596               llo = Llo, dat = Dat)).
597
598insert_kyw([Ide,DocType,Kyw]) :-
599    insert(kyw(ide = Ide, doc = DocType, kyw = Kyw)).
600
601*/
602
603% -------------------------
604% process incorrect entries
605% -------------------------
606
607write_errdoc(Symptom,Entry,Bug) :-
608    write(errout,Symptom),
609    writeln(errout,'. '),
610    write(errout,Entry),
611    writeln(errout,'. '),
612    write(errout,Bug),
613    writeln(errout,'. ').
614
615
616% -----------------------------------------
617%       C O R R E C T   E N T R I E S
618% -----------------------------------------
619
620correct_entries :-
621    read_comp(Complaint),
622    process_comp(Complaint).
623
624process_comp(end_of_file) :- !.
625process_comp([Symptom,Entry,Bug]) :-
626    correct_entry(Symptom,Entry,Bug,CorrectEntry),
627    enter(CorrectEntry),
628    correct_entries.
629
630correct_entry(noide,[DocType|ValList],MissingL,CorrectEntry) :-
631    entry_display([DocType|ValList],Line),
632    NewLine is Line + 2,
633    correction(noide,MissingL,ResultL,NewLine),
634    conc(ResultL,ValList,CList),
635    generate_ide(CList,Ide),
636    conc([[ide,Ide]],CList,CorrList),
637    check_double([DocType|CorrList],ResEntry),
638    (    ResEntry = [],
639             CorrectEntry = []
640    ;
641             not_too_long(ResEntry,NTLEntry),
642             complete(NTLEntry,CorrectEntry)
643    ).
644correct_entry(missing,[DocType|ValList],Attr,[DocType|CorrectList]) :-
645    entry_display([DocType|ValList],Line),
646    NewLine is Line + 2,
647    correction(missing,Attr,Result,NewLine),
648    conc([Result],ValList,CList),
649    complete([DocType|CList],[DocType|CorrectList]).
650correct_entry(toolong,[DocType|ValList],Attr,[DocType|CorrectList]) :-
651    entry_display([DocType|ValList],Line),
652    NewLine is Line + 2,
653    correction(toolong,Attr,Result,NewLine),
654    replace(Result,ValList,CList1),
655    not_too_long([DocType|CList1],[DocType|CList2]),
656    complete([DocType|CList2],[DocType|CorrectList]).
657correct_entry(double,Entry,Similars,CorrectEntry) :-
658    entry_display(Entry,Line),
659    ide_ending(Similars,End),
660    check_double_4(Entry,Similars,CorrectEntry,End).
661
662check_double(Entry,CorrectEntry) :-
663    double(Entry,Similars),
664    correct_entry(double,Entry,Similars,CorrectEntry).
665% fix: add second clause for check_double treating the case
666%      that there is no similar entry:
667%      check_doubleEn(try, Entry).
668
669check_double_4([DocType|ValList],[],[DocType|CorrectList],End) :-
670    clear_below(20),
671    cursor(22,5),
672    write('Reference will be entered into the database'),
673    correct_ide(ValList,End,CList),
674    not_too_long([DocType|CList],[DocType|CList1]),
675    complete([DocType|Clist1],[DocType|CorrectList]).
676check_double_4(Entry,[Similar|L],C,E) :-
677    clear_below(20),
678    write('-----------------------------------------------------------------'),
679    m_display(Similar),
680    get_answer('Next similar entry (N) / reject entry (R) : ',Answer,24,5),
681    process_answer(Answer,Entry,L,C,E).
682
683process_answer("R",Entry,Similars,[],End).
684process_answer(Answer,Entry,Similars,CorrectEntry,End) :-
685    check_double_4(Entry,Similars,CorrectEntry,End).
686
687complete([DocType|ValList],[DocType|CorrectList]) :-
688    val_missing([DocType|ValList],Attr),
689    !,
690    correct_entry(missing,[DocType|ValList],Attr,[DocType|CorrectList]).
691complete(Entry,Entry).
692
693not_too_long([DocType|ValList],[DocType|CorrectList]) :-
694    val_too_long([DocType|ValList],Attr),
695    !,
696    correct_entry(toolong,[DocType|ValList],Attr,[DocType|CorrectList]).
697not_too_long(Entry,Entry).
698
699read_comp(Input) :-
700    read(errin,Line1),
701    (    Line1 = end_of_file,
702            Input = Line1
703    ;
704            read(errin,Line2),
705            read(errin,Line3),
706            Input = [Line1,Line2,Line3]
707    ).
708
709correction(noide,MissingL,ResultL,Line) :-
710    print_line('Key/Year were incorrect!',Line,5),
711    NewL is Line + 1,
712    askfor_atts(MissingL,ResultL,NewL,NewLine).
713correction(missing,Attr,Result,Line) :-
714    print_line('Attribute missing!',Line,5),
715    NewL is Line + 1,
716    askfor_att([Attr,m],[Result],NewL,NewLine).
717correction(toolong,Attr,Result,Line) :-
718    print_line('Attribute too long!',Line,5),
719    NewL is Line + 1,
720    askfor_att([Attr,m],[Result],NewL,NewLine).
721
722% -------------------------------------
723%       S U B P R O C E D U R E S
724% -------------------------------------
725
726correct_ide(List,End,Result) :-
727    del([ide,Ide],List,List1),
728    conc(Ide,End,NewIde),
729    conc([[ide,NewIde]],List1,Result).
730
731ending(Year,EndYear) :-
732    last(Year,S,X),
733    last(S,T,Y),
734    conc([Y],[X],EndYear).
735
736entry_display([DocType|ValList],Line) :-
737    assert(doc(DocType)),
738    del_all_atts(kyw,ValList,List1),
739    del_all_atts(cop,List1,List2),
740    ordered([DocType|List2],[DocType|List3]),
741    strings_to_atoms_result(List3,List4),
742    standard_display(List4,Line),
743    retract(doc(DocType)).
744
745first_nonabbr([],"-").
746first_nonabbr(String,NonAbbr) :-
747    up_to_char(32,String,Str1,Str2),
748    non_abbr(Str1,Str2,NonAbbr).
749first_nonabbr(String,String) :-
750    non_abbr(String,[],String).
751
752m_display([],L).
753m_display([[Attr|Val]|L],Line) :-
754    cap_attr_abbr(Attribute,Attr),
755    cursor(Line,5),
756    write(Attribute),
757    fill_blanks(Attribute,13),
758    write(' :  '),
759    name(AVal,Val),
760    write(AVal),
761    NewLine is Line + 1,
762    m_display(L,NewLine).
763
764non_abbr(Str,String,NonAbbr) :-
765    lastelem(Str,46),
766    first_nonabbr(String,NonAbbr).
767non_abbr(Str,X,Str).
768
769too_long([],X) :-
770    !,
771    fail.
772too_long([[cop,Own,Loc]|L],own) :-
773    len(Own,Length),
774    attr_len(own,Len),
775    Length > Len.
776too_long([[cop,Own,Loc]|L],loc) :-
777    len(Loc,Length),
778    attr_len(loc,Len),
779    Length > Len.
780too_long([[Attr,Val]|L],Attr) :-
781    len(Val,Length),
782    attr_len(Attr,Len),
783    Length > Len.
784too_long([X|L],Attr) :-
785    too_long(L,Attr).
786
787% check_mand_atts(AttrList,ValList,Attr) is true if ValList
788% does not contain a value for the mandatory attribute Attr
789
790check_mand_atts([],List,X) :-
791    !,
792    fail.
793check_mand_atts([Attr|L],ValList,Attr) :-
794    not(member([Attr,X],ValList)).
795check_mand_atts([Attr|L],ValList,X) :-
796    check_mand_atts(L,ValList,X).
797
798% check_atts(AttList,ValList,CheckedList)
799% CheckedList = ValList + [Attr,"-"] for missing attribute Attr
800
801check_atts([],List,[]).
802check_atts([Attr|AList],ValList,[Val|CheckedList]) :-
803    member([Attr,Val],ValList),
804    !,
805    check_atts(AList,ValList,CheckedList).
806check_atts([Attr|AList],ValList,["-"|CheckedList]) :-
807    check_atts(AList,ValList,CheckedList).
808
809collect(cop,ValList,Copies) :-
810    bagof([Own,Loc],member([cop,Own,Loc],ValList),Copies).
811collect(kyw,ValList,KywList) :-
812    bagof(Kyw,member([kyw,Kyw],ValList),KywList).
813collect(X,Y,[]).
814
815complete_filename(Str,CompName) :-
816    atom_string(Atom, Str),
817    lob_build_lib_name(Atom, CompName).
818%    conc("/home/lp/ode/demo/loop/",Str,CompStr),
819%    name(CompName,CompStr).
820
821
822% strings_to_atoms_list transforms a list of strings into a list of atoms
823
824strings_to_atoms_list([],[]).
825strings_to_atoms_list([String|StringList],[Atom|AtomList]) :-
826    name(Atom,String),
827    strings_to_atoms_list(StringList,AtomList).
828
829% strings_to_atoms_result transforms the strings of a result list into atoms
830
831strings_to_atoms_result([],[]).
832strings_to_atoms_result([[Attr,String]|List],[[Attr,Atom]|AtomList]) :-
833    name(Atom,String),
834    strings_to_atoms_result(List,AtomList).
835
836:- set_back_strings_to_strings.
837
838