home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / l / l217 / 2.ddi / PROGRAMS / GEOBASE.INC < prev    next >
Encoding:
Text File  |  1990-03-26  |  20.5 KB  |  685 lines

  1.  
  2. /*************************************************************************
  3.   SUPPORT PREDICATES - These are the clauses which support the
  4.   general system, including the parser and the menu system. Most of
  5.   the clauses involve list processing and are general enough to be
  6.   used in any system.
  7. *************************************************************************/
  8.  
  9. PREDICATES
  10.   write_list(INTEGER,STRINGLIST)    /* Write the list separated by spaces */
  11.   write_list2(STRINGLIST)                     /* Display an answer */
  12.   append(STRINGLIST,STRINGLIST,STRINGLIST)          /* Append two lists */
  13.   unik(STRINGLIST,STRINGLIST)        /* Eliminate duplicates in a list */
  14.   index(STRINGLIST,INTEGER,STRING)       /* Select an element from a list */
  15.  
  16. CLAUSES
  17.   index([X|_],1,X):- !.
  18.   index([_|L],N,X):- N>1,N1=N-1,index(L,N1,X).
  19.  
  20.   unik([],[]).
  21.   unik([H|T],L):-member(H,T),!,unik(T,L).
  22.   unik([H|T],[H|L]):-unik(T,L).
  23.  
  24.   append([],L,L).
  25.   append([Ah|At],B,[Ah|C]):-append(At,B,C).
  26.  
  27.  
  28.  
  29.   write_list(_,[]).
  30.   write_list(_,[X]):-!,write(X).
  31.   write_list(4,[H|T]):-!,write(H),nl,write_list(0,T).
  32.   write_list(3,[H|T]):-str_len(H,LEN),LEN>13,!,write(H),nl,write_list(0,T).
  33.   write_list(N,[H|T]):-str_len(H,LEN),LEN>13,!,N1=N+2,writef("%-27 ",H),write_list(N1,T).
  34.   write_list(N,[H|T]):-N1=N+1,writef("%-13 ",H),write_list(N1,T).
  35.  
  36.   write_list2([]).
  37.   write_list2([H|T]):-write(H,' '),write_list2(T).
  38.  
  39.  
  40. /*************************************************************************
  41.   Evaluating queries - This is the mechanism which reads a query, scans
  42.   the string and removes punctuation, parses the query and evaluates
  43.   it.  The number of solutions are also reported here.
  44. *************************************************************************/
  45.  
  46. DOMAINS
  47. /* Nine types of questions are recognized by the evaluator */
  48.   QUERY    =    q_e(ENT) ;
  49.         q_eaec(ENT,ASSOC,ENT,STRING) ;
  50.         q_eaq(ENT,ASSOC,ENT,QUERY) ;
  51.         q_sel(ENT,RELOP,ENT,REAL);
  52.         q_min(ENT,QUERY);
  53.         q_max(ENT,QUERY);
  54.         q_not(ENT,QUERY) ;
  55.         q_or(QUERY,QUERY) ;
  56.         q_and(QUERY,QUERY)
  57.  
  58. PREDICATES
  59. /* Input-output */
  60.   loop(STRING)            /* Main loop */
  61.   readquery(STRING)
  62.   write_unit(STRING)        /* Write the unit for an entity */
  63.   write_solutions(INTEGER)    /* Write the number of solutions */
  64.  
  65. /* Scanner */
  66.   scan(STRING,STRINGLIST)        /* Convert a string to a list of words */
  67.   filter(STRINGLIST,STRINGLIST)        /* Eliminate commas and periods    */
  68.  
  69. /* Parser */
  70.   pars(STRINGLIST,STRING,QUERY)
  71.  
  72. /* Evaluation */
  73.   eval(QUERY,STRING)
  74.  
  75.  
  76. CLAUSES
  77.   loop(STR):-    STR >< "",
  78.           scan(STR,LIST),               /* Returns a list of words(symbols)           */
  79.         filter(LIST,LIST1),           /* Removes punctuation and words to be ignored*/
  80.         pars(LIST1,E,Q),              /* Parses queries                            */
  81.         findall(A,eval(Q,A),L),
  82.         unik(L,L1),
  83.         write_list(0,L1),
  84.         write_unit(E),
  85.         listlen(L1,N),
  86.         write_solutions(N),
  87.         fail.
  88.  
  89.   loop(STR):-    STR >< "",readquery(L),loop(L).
  90.  
  91.   readquery(QUERY):-nl,nl,write("Query: "),readln(QUERY).
  92.  
  93.   scan(STR,[TOK|LIST]):-
  94.         fronttoken(STR,SYMB,STR1),!,
  95.         upper_lower(SYMB,TOK),
  96.         scan(STR1,LIST).
  97.   scan(_,[]).
  98.  
  99.   filter(["."|T],L):-    !,filter(T,L).
  100.   filter([","|T],L):-    !,filter(T,L).
  101.   filter(["?"|T],L):-    !,filter(T,L).
  102.   filter([H|T],L):-    ignore(H),!,filter(T,L).
  103.   filter([H|T],[H|L]):-    filter(T,L).
  104.   filter([],[]).
  105.  
  106.   write_unit(E):-unit(E,UNIT),!,write(' ',UNIT).
  107.   write_unit(_).
  108.  
  109.   write_solutions(0):-!,write("\nNo solutions").
  110.   write_solutions(1):-!.
  111.   write_solutions(N):-!,writef("\n% Solutions",N).
  112.  
  113. /*************************************************************************
  114.   ENTITY NAMES
  115. *************************************************************************/
  116.  
  117. PREDICATES
  118.   entn(STRING,STRING)        /* Convert an entity to singular form */
  119.   entity(STRING)        /* Get all entities */
  120.   ent_synonym(STRING,STRING)    /* Synonyms for entities */
  121.   ent_name(STRING,STRING)    /* Convert between an entity
  122.                    name and an internal entity name */
  123.  
  124. CLAUSES
  125.   ent_synonym(E,ENT):-synonym(E,ENT).
  126.   ent_synonym(E,E).
  127.  
  128.   ent_name(ENT,NAVN):-entn(E,NAVN),ent_synonym(E,ENT),entity(ENT).
  129.  
  130.   entn(E,N):-concat(E,"s",N).
  131.   entn(E,N):-free(E),bound(N),concat(X,"ies",N),concat(X,"y",E).
  132.   entn(E,E).
  133.  
  134.   entity(name):-!.
  135.   entity(continent):-!.
  136.   entity(X):-schema(X,_,_).
  137.  
  138.  
  139. /*************************************************************************
  140.   ERROR DETECTION -
  141.   Once the string has been converted to a list of words, the word
  142.   list can be checked against the language database to see if it
  143.   is a known word. Words which are not known are collected into a
  144.   list which the system reports on.
  145. *************************************************************************/
  146.  
  147. PREDICATES
  148.   error(STRINGLIST)
  149.   known_word(STRING)
  150.  
  151. CLAUSES
  152.   error(LIST):-    write(">> "),member(Y,LIST),not(known_word(Y)),!,
  153.         write("Unknown word: ",Y),nl.
  154.  
  155.   error(_):-    write("Sorry, the sentence can't be recognized").
  156.  
  157.   known_word(X):-str_real(X,_),!.  /*   Check for special case words    */
  158.   known_word("and"):-!.
  159.   known_word("or"):-!.
  160.   known_word("not"):-!.
  161.   known_word("all"):-!.
  162.   known_word("thousand"):-!.
  163.   known_word("million"):-!.
  164.   known_word(X):-minn(X),!.     /*  If not a special case word, check the */
  165.   known_word(X):-maxx(X),!.     /*  dynamic database for known words      */
  166.   known_word(X):-size(_,X),!.   /*  additional words.                     */
  167.   known_word(X):-ignore(X),!.
  168.   known_word(X):-unit(_,X),!.
  169.   known_word(X):-assoc(_,AL),member(X,AL),!.
  170.   known_word(X):-ent_name(_,X),!.
  171.   known_word(X):-entity(X),!.
  172.   known_word(X):-relop(L,_),member(X,L),!.
  173.   known_word(X):-entity(E),not(unit(E,_)),ent(E,X).
  174.  
  175. /*************************************************************************
  176.         PARSER
  177. *************************************************************************/
  178.  
  179. /*
  180.    PARSER SUPPORT -  Compound entities:
  181.    This is used by the parser to handle a compound entity (e.g.
  182.    New York).
  183. */
  184.  
  185. PREDICATES        
  186.   check(STRINGLIST)                          /* Check that the list is empty */
  187.   get_ent(STRINGLIST,STRINGLIST,STRING)            /* Get the compound entity      */
  188.   get_cmpent(STRINGLIST,STRINGLIST,STRING,STRING)  /* Get the first component      */
  189.   ent_end(STRINGLIST)                        /* Get the rest of the entity   */
  190.  
  191. CLAUSES
  192.   check([]).    
  193.  
  194.   get_ent([E|S],S,E):-ent_end(S),!.
  195.   get_ent(S1,S2,ENT):-get_cmpent(S1,S2," ",E1),frontchar(E1,_,E),ENT=E.
  196.  
  197.   get_cmpent([E|S],S,IND,ENT):-ent_end(S),concat(IND,E,ENT).
  198.   get_cmpent([E|S1],S2,IND,ENT):-
  199.         concat(IND,E,II),concat(II," ",III),
  200.         get_cmpent(S1,S2,III,ENT).
  201.  
  202.   ent_end([]).
  203.   ent_end(["and"|_]).
  204.   ent_end(["or"|_]).
  205.  
  206. /*
  207.   Here begins the parser. The first two parameters for the parsing
  208.   predicates are the inputlist and what remains of the list
  209.   after a part of a query is stripped off. In the last parameter, a
  210.   structure for the query is built up.
  211.  
  212.   This method is called "parsing by difference lists." Once you
  213.   understand how it works, you can easily add new sentence
  214.   constructions to the language.
  215. */
  216.  
  217. PREDICATES
  218.   s_rel(STRINGLIST,STRINGLIST,STRING)
  219.   s_unit(STRINGLIST,STRINGLIST,STRING)
  220.   s_val(STRINGLIST,STRINGLIST,REAL)
  221.  
  222. CLAUSES
  223.   s_rel(S1,S2,REL):-relop(RLIST,REL),append(RLIST,S2,S1).
  224.  
  225.   s_unit([UNIT|S],S,UNIT).
  226.   s_val([X,thousand|S],S,VAL):-    !,str_real(X,XX),VAL=1000*XX.
  227.   s_val([X,million|S],S,VAL):-    !,str_real(X,XX),VAL=1000000*XX.
  228.   s_val([X|S],S,VAL):-        str_real(X,VAL).
  229.  
  230.  
  231. PREDICATES
  232.   s_attr(STRINGLIST,STRINGLIST,STRING,QUERY)
  233.   s_minmax(STRINGLIST,STRINGLIST,STRING,QUERY)
  234.   s_rest(STRINGLIST,STRINGLIST,STRING,QUERY)
  235.   s_or(STRINGLIST,STRINGLIST,STRING,QUERY)
  236.   s_or1(STRINGLIST,STRINGLIST,STRING,QUERY,QUERY)
  237.   s_and(STRINGLIST,STRINGLIST,STRING,QUERY)
  238.   s_and1(STRINGLIST,STRINGLIST,STRING,QUERY,QUERY)
  239.   s_elem(STRINGLIST,STRINGLIST,STRING,QUERY)
  240.   s_assoc(STRINGLIST,STRINGLIST,STRING,QUERY)
  241.   s_assoc1(STRINGLIST,STRINGLIST,STRING,STRING,QUERY)
  242.   s_nest(STRINGLIST,STRINGLIST,STRING,QUERY)
  243.   get_assoc(STRINGLIST,STRINGLIST,STRING)
  244.  
  245. CLAUSES
  246.   pars(LIST,E,Q):-s_attr(LIST,OL,E,Q),check(OL),!.
  247.   pars(LIST,_,_):-error(LIST),fail.
  248.  
  249.   /* How big is the city new york -- BIG ENTITY CONSTANT */
  250.   s_attr([BIG,ENAME|S1],S2,E1,q_eaec(E1,A,E2,X)):-
  251.         ent_name(E2,ENAME),size(E2,BIG),
  252.         entitysize(E2,E1),schema(E1,A,E2),
  253.         get_ent(S1,S2,X),!.
  254.  
  255.   /* How big is new york -- BIG CONSTANT */
  256.   s_attr([BIG|S1],S2,E1,q_eaec(E1,A,E2,X)):-
  257.         get_ent(S1,S2,X),
  258.         size(E2,BIG),entitysize(E2,E1),
  259.         schema(E1,A,E2),ent(E2,X),!.
  260.  
  261.   /* How big is the biggest city -- BIG QUERY */
  262.   s_attr([BIG|S1],S2,E1,q_eaq(E1,A,E2,Q)):-
  263.         size(_,BIG),s_minmax(S1,S2,E2,Q),
  264.         size(E2,BIG),entitysize(E2,E1),
  265.         schema(E1,A,E2),!.
  266.  
  267.   s_attr(S1,S2,E,Q):-s_minmax(S1,S2,E,Q).
  268.  
  269. /* The smallest city -- MIN QUERY */
  270.   s_minmax([MIN|S1],S2,E,q_min(E,Q)):-minn(MIN),!,s_rest(S1,S2,E,Q).
  271.  
  272. /* The biggest city -- MAX QUERY */
  273.   s_minmax([MAX|S1],S2,E,q_max(E,Q)):-maxx(MAX),!,s_rest(S1,S2,E,Q).
  274.  
  275.   s_minmax(S1,S2,E,Q):-s_rest(S1,S2,E,Q).
  276.  
  277.  
  278. /* give me cities -- ENTITY */
  279.   s_rest([ENAME],[],E,q_e(E)):-!,ent_name(E,ENAME).
  280.  
  281.   s_rest([ENAME|S1],S2,E,Q):-ent_name(E,ENAME),s_or(S1,S2,E,Q).
  282.  
  283.  
  284. /* And has a higher priority than or */
  285.   s_or(S1,S2,E,Q):-s_and(S1,S3,E,Q1),s_or1(S3,S2,E,Q1,Q).
  286.   s_or1(["or",ENT|S1],S2,E,Q1,q_or(Q1,Q2)):-ent_name(E,ENT),!,s_or(S1,S2,E,Q2).
  287.   s_or1(["or"|S1],S2,E,Q1,q_or(Q1,Q2)):-!,s_or(S1,S2,E,Q2).
  288.   s_or1(S,S,_,Q,Q).
  289.  
  290.   s_and(S1,S2,E,Q):-s_elem(S1,S3,E,Q1),s_and1(S3,S2,E,Q1,Q).
  291.   s_and1(["and",ENT|S1],S2,E,Q1,q_and(Q1,Q2)):-ent_name(E,ENT),!,s_elem(S1,S2,E,Q2).
  292.   s_and1(["and"|S1],S2,E,Q1,q_and(Q1,Q2)):-!,s_elem(S1,S2,E,Q2).
  293.   s_and1(S,S,_,Q,Q).
  294.  
  295.  
  296. /* not QUERY */
  297.   s_elem(["not"|S1],S2,E,q_not(E,Q)):-!,s_assoc(S1,S2,E,Q).
  298.   s_elem(S1,S2,E,Q):-s_assoc(S1,S2,E,Q).
  299.  
  300.  
  301. /* ... longer than 1 thousand miles -- REL VAL UNIT */
  302.   s_assoc(S1,S4,E,q_sel(E,REL,ATTR,VAL)):-
  303.         s_rel(S1,S2,REL),s_val(S2,S3,VAL),
  304.         s_unit(S3,S4,UNIT),!,unit(ATTR,UNIT).
  305.  
  306. /* ... longer than 1 thousand -- REL VAL */
  307.   s_assoc(S1,S3,E,q_sel(E,REL,ATTR,VAL)):-
  308.         s_rel(S1,S2,REL),s_val(S2,S3,VAL),!,
  309.         entitysize(E,ATTR).
  310.  
  311.   s_assoc(S1,S3,E,Q):-
  312.         get_assoc(S1,S2,A),s_assoc1(S2,S3,E,A,Q).
  313.  
  314.  
  315. /* Before s_assoc1 is called ENT ASSOC is met */
  316.  
  317. /* ... the shortest river in texas -- MIN QUERY */
  318.   s_assoc1([MIN|S1],S2,E1,A,q_eaq(E1,A,E2,q_min(E2,Q))):-minn(MIN),!,
  319.         s_nest(S1,S2,E2,Q),schema(E1,A,E2).
  320.  
  321. /* ... the longest river in texas -- MAX QUERY */
  322.   s_assoc1([MAX|S1],S2,E1,A,q_eaq(E1,A,E2,q_max(E2,Q))):-maxx(MAX),!,
  323.         s_nest(S1,S2,E2,Q),schema(E1,A,E2).
  324.  
  325. /* ... with a population that is smaller than 1 million citizens --
  326.                                ENT REL VAL UNIT */
  327.   s_assoc1([ATTR|S1],S4,E,A,q_sel(E,REL,ATTR,VAL)):-
  328.     s_rel(S1,S2,REL),s_val(S2,S3,VAL),s_unit(S3,S4,UNIT1),!,
  329.     ent_name(E2,ATTR),schema(E,A,E2),unit(E2,UNIT),
  330.     UNIT=UNIT1,!.
  331.  
  332. /* ... with a population that are smaller than 1 million -- ENT REL VAL */
  333.   s_assoc1([ATTR|S1],S3,E,A,q_sel(E,REL,ATTR,VAL)):-
  334.     s_rel(S1,S2,REL),s_val(S2,S3,VAL),!,
  335.     ent_name(E2,ATTR),schema(E,A,E2),unit(E2,_).
  336.  
  337. /* ... that is smaller than 1 million citizens -- REL VAL UNIT */
  338.   s_assoc1(S1,S4,E,A,q_sel(E,REL,E2,VAL)):-
  339.     s_rel(S1,S2,REL),s_val(S2,S3,VAL),s_unit(S3,S4,UNIT1),!,
  340.     schema(E,A,E2),unit(E2,UNIT),
  341.     UNIT=UNIT1,!.
  342.  
  343. /* ... that is smaller than 1 million -- REL VAL */
  344.   s_assoc1(S1,S3,E,A,q_sel(E,REL,E2,VAL)):-
  345.     s_rel(S1,S2,REL),s_val(S2,S3,VAL),!,
  346.     schema(E,A,E2),unit(E2,_).
  347.  
  348. /* ... with a population on 1 million citizens -- ENT VAL UNIT */
  349.   s_assoc1([ATTR|S1],S3,E,A,q_sel(E,eq,ATTR,VAL)):-
  350.     s_val(S1,S2,VAL),s_unit(S2,S3,UNIT1),!,
  351.     ent_name(E2,ATTR),schema(E,A,E2),unit(E2,UNIT2),UNIT1=UNIT2,!.
  352.  
  353. /* ... with a population on 1 million -- ENT VAL */
  354.   s_assoc1([ATTR|S1],S2,E,A,q_sel(E,eq,ATTR,VAL)):-
  355.     s_val(S1,S2,VAL),
  356.     ent_name(E2,ATTR),schema(E,A,E2),unit(E2,_),!.
  357.  
  358. /* .. the state new york -- ENT CONST */
  359.   s_assoc1([ENAME|S1],S2,E1,A,q_eaec(E1,A,E2,X)):-
  360.         get_ent(S1,S2,X),ent_name(E2,ENAME),
  361.         not(unit(E2,_)),
  362.         schema(E1,A,E2),
  363.         ent(E2,X),!.
  364.  
  365.   s_assoc1(S1,S2,E1,A,q_eaq(E1,A,E2,Q)):-
  366.         s_nest(S1,S2,E2,Q),schema(E1,A,E2),!.
  367.  
  368. /* .. new york -- CONST */
  369.   s_assoc1(S1,S2,E1,A,q_eaec(E1,A,E2,X)):-
  370.         get_ent(S1,S2,X),schema(E1,A,E2),ent(E2,X),!.
  371.  
  372. /* Parse a nested query */
  373.   s_nest([ENAME|S1],S2,E,Q):-ent_name(E,ENAME),s_elem(S1,S2,E,Q).
  374.   s_nest([ENAME|S],S,E,q_e(E)):-ent_name(E,ENAME).
  375.  
  376. /* ... runs through texas -- ASSOC REST */
  377.   get_assoc(IL,OL,A):-append(ASL,OL,IL),assoc(A,ASL).
  378.  
  379. /*************************************************************************
  380.   EVALUATION OF QUESTIONS
  381. *************************************************************************/
  382.  
  383. PREDICATES  /* Support predicates for the parser */
  384.   sel_min(STRING,STRING,REAL,STRING,STRING,STRINGLIST)
  385.   sel_max(STRING,STRING,REAL,STRING,STRING,STRINGLIST)
  386.  
  387. CLAUSES
  388.   eval(q_min(ENT,TREE),ANS):-
  389.         findall(X,eval(TREE,X),L),
  390.         entitysize(ENT,ATTR),
  391.         sel_min(ENT,ATTR,99e99,"",ANS,L).
  392.  
  393.   eval(q_max(ENT,TREE),ANS):-
  394.         findall(X,eval(TREE,X),L),
  395.         entitysize(ENT,ATTR),
  396.         sel_max(ENT,ATTR,-1,"",ANS,L).
  397.  
  398.   eval(q_sel(E,gt,ATTR,VAL),ANS):-
  399.         schema(ATTR,ASSOC,E),
  400.         db(ATTR,ASSOC,E,SVAL2,ANS),
  401.         str_real(SVAL2,VAL2),
  402.         VAL2>VAL.
  403.  
  404.   eval(q_sel(E,lt,ATTR,VAL),ANS):-
  405.         schema(ATTR,ASSOC,E),
  406.         db(ATTR,ASSOC,E,SVAL2,ANS),
  407.         str_real(SVAL2,VAL2),
  408.         VAL2<VAL.
  409.  
  410.   eval(q_sel(E,eq,ATTR,VAL),ANS):-
  411.         schema(ATTR,ASSOC,E),
  412.         db(ATTR,ASSOC,E,SVAL,ANS),
  413.         str_real(SVAL,VAL).
  414.  
  415.   eval(q_not(E,TREE),ANS):-
  416.         findall(X,eval(TREE,X),L),
  417.         ent(E,ANS),
  418.         not(member(ANS,L)).
  419.  
  420.   eval(q_eaq(E1,A,E2,TREE),ANS):-
  421.         eval(TREE,VAL),db(E1,A,E2,ANS,VAL).
  422.  
  423.   eval(q_eaec(E1,A,E2,C),ANS):-db(E1,A,E2,ANS,C).
  424.  
  425.   eval(q_e(E),ANS):-    ent(E,ANS).
  426.  
  427.   eval(q_or(TREE,_),ANS):- eval(TREE,ANS).
  428.  
  429.   eval(q_or(_,TREE),ANS):- eval(TREE,ANS).
  430.  
  431.   eval(q_and(T1,T2),ANS):- eval(T1,ANS1),eval(T2,ANS),ANS=ANS1.
  432.  
  433.  
  434.   sel_min(_,_,_,RES,RES,[]).
  435.   sel_min(ENT,ATTR,MIN,_,RES,[H|T]):-schema(ATTR,ASSOC,ENT),
  436.     db(ATTR,ASSOC,ENT,VAL,H),
  437.     str_real(VAL,HH),MIN>HH,!,
  438.     sel_min(ENT,ATTR,HH,H,RES,T).
  439.   sel_min(ENT,ATTR,MIN,NAME,RES,[_|T]):-sel_min(ENT,ATTR,MIN,NAME,RES,T).
  440.  
  441.  
  442.   sel_max(_,_,_,RES,RES,[]).
  443.   sel_max(ENT,ATTR,MAX,_,RES,[H|T]):-
  444.     schema(ATTR,ASSOC,ENT),
  445.     db(ATTR,ASSOC,ENT,VAL,H),
  446.     str_real(VAL,HH),MAX<HH,!,
  447.     sel_max(ENT,ATTR,HH,H,RES,T).
  448.   sel_max(ENT,ATTR,MAX,NAME,RES,[_|T]):-sel_max(ENT,ATTR,MAX,NAME,RES,T).
  449.  
  450. /**************************************************************************
  451.   MAIN MENU - Here begins the user interface which demonstrates
  452.   how to process an action from a list of choices.
  453. **************************************************************************/
  454.  
  455. PREDICATES
  456. /* Main loop */
  457.   natlang
  458.   loaddba
  459.   savedba
  460.   mainmenu
  461.   proces(INTEGER)
  462.  
  463. /* View and update the language */
  464.   viewlang viewlang1(INTEGER)
  465.   updatelang updatelang1(INTEGER)
  466.  
  467. GOAL loaddba, natlang.
  468.  
  469. CLAUSES
  470.   natlang:-
  471.     makewindow(21,112,0,"",24,0,1,80),
  472.     write("ESC: Quit this menu -- Use arrow keys to select and hit RETURN to activate."),
  473.     makewindow(22,112,0,"",24,0,1,80),
  474.     write("Esc: Quit     F8: Last line    Ctrl S: Stop output    End: End of line"),
  475.     makewindow(2,7,7,"GEOBASE: Natural language interface to U.S. geography",0,0,24,80),
  476.     mainmenu.
  477.  
  478.   mainmenu:-    repeat,
  479.         menu(8,49,14,6,
  480.           [ "Tutorial",
  481.             "DOS Shell",
  482.             "Editor",
  483.             "───────────────────",
  484.             "Query the database",
  485.             "───────────────────",
  486.             "View the language",
  487.             "Update the language"]," Main Menu ",1,CHOICE),
  488.         proces(CHOICE),
  489.         CHOICE=0,!,
  490.         removewindow,removewindow.
  491.  
  492.   proces(0):-write("\nAre you sure you want to quit? (y/n): "),readchar(T),T='y'.
  493.   proces(1):-file_str("geobase.hlp",TXT),display(TXT),clearwindow,!.
  494.   proces(1):-write(">> geobase.hlp not in default directory\n").
  495.   proces(2):-makewindow(3,7,0,"",0,0,25,80),write("Type EXIT to return\n\n"),
  496.              system(""),!,removewindow.
  497.   proces(2):-write(">> command.com not accessible. press any key"),readchar(_),removewindow.
  498.   proces(3):-makewindow(3,7,112,"",9,5,15,75),edit("",_),removewindow.
  499.   proces(4).
  500.   proces(5):-readquery(L),loop(L).
  501.   proces(6).
  502.   proces(7):-viewlang.
  503.   proces(8):-updatelang.
  504.  
  505.   loaddba:-schema(_,_,_),!.  /* Database already loaded */
  506.   loaddba:-
  507.     existfile("geobase.lan"),existfile("geobase.dba"),
  508.     write("Loading database file - please wait\n"),
  509.     consult("geobase.lan",language),
  510.     consult("geobase.dba",data),!.
  511.   loaddba:-
  512.     write(">> geobase.dba not in default directory\n").
  513.  
  514.   savedba:-
  515.     write("Saving language definition - please wait\n"),
  516.     deletefile("geobase.bak"),
  517.     renamefile("geobase.lan","geobase.bak"),
  518.     save("geobase.lan",language).
  519.  
  520. /**************************************************************************
  521.    View and the language
  522. **************************************************************************/
  523.  
  524.   viewlang:-    repeat,
  525.         menu(5,40,14,10,
  526.           [ "1  Schema for the entity network",
  527.             "2  Names of entities",
  528.             "3  Synonyms for entities",
  529.             "4  Alternative names for associations",
  530.             "5  Words to ignore",
  531.             "6  Units for attributes",
  532.             "7  Alternatives for relation operators",
  533.             "8  Words stating minimums",
  534.             "9  Words stating maximum"
  535.           ]," Language ",1,CHOICE),
  536.         nl,viewlang1(CHOICE),CHOICE=0,!.
  537.  
  538.  
  539.   viewlang1(0).
  540.  
  541.   viewlang1(1):-
  542.     writef("%-12 %-8 %-12\n","Entity","Assoc","Entity"),
  543.     write("************ ******** ************\n"),
  544.     schema(E1,A,E2),writef("%-12 %-8 %-12\n",E1,A,E2),fail.
  545.     
  546.   viewlang1(1):-
  547.     write("\n\nPress any key to continue"),
  548.     readchar(_).    
  549.  
  550.   viewlang1(2):-
  551.     write("Entities\n********\n"),
  552.     findall(X,entity(X),L),unik(L,L1),write_list(0,L1),nl.
  553.     
  554.   viewlang1(2):-
  555.     write("\n\nPress any key to continue"),
  556.     readchar(_).    
  557.  
  558.   viewlang1(3):-
  559.     writef("%-15 %-15\n","Synonym","Entity"),
  560.     write("*************** ***************\n"),
  561.     synonym(E,S),writef("%-15 %-15\n",E,S),fail.
  562.     
  563.   viewlang1(3):-
  564.     write("\n\nPress any key to continue"),
  565.     readchar(_).    
  566.  
  567.   viewlang1(4):-
  568.     write("Associations\n************\n"),
  569.     assoc(X,L),
  570.     writef("%-8 ",X),write_list2(L),nl,fail.
  571.     
  572.   viewlang1(4):-
  573.     write("\n\nPress any key to continue"),
  574.     readchar(_).    
  575.  
  576.   viewlang1(5):-
  577.     write("Ignore\n******\n"),
  578.     findall(X,ignore(X),L),write_list(0,L),nl.
  579.     
  580.   viewlang1(5):-
  581.     write("\n\nPress any key to continue"),
  582.     readchar(_).    
  583.  
  584.   viewlang1(6):-
  585.     writef("%-15 %-15\n","entity","unit"),
  586.     write("*************** ***************\n"),
  587.     unit(E,U),writef("%-15 %-15\n",E,U),fail.
  588.     
  589.   viewlang1(6):-
  590.     write("\n\nPress any key to continue"),
  591.     readchar(_).    
  592.  
  593.   viewlang1(7):-
  594.     write("Names of relational operators\n*****************************\n"),
  595.     relop(LIST,REL),write(REL,": "),write_list2(LIST),nl,fail.
  596.     
  597.   viewlang1(7):-
  598.     write("\n\nPress any key to continue"),
  599.     readchar(_).    
  600.  
  601.   viewlang1(8):-
  602.     write("Minimum\n*******\n"),
  603.     findall(X,minn(X),L),write_list(0,L),nl.
  604.     
  605.   viewlang1(8):-
  606.     write("\n\nPress any key to continue"),
  607.     readchar(_).
  608.       
  609.   viewlang1(9):-
  610.     write("Maximum\n*******\n"),
  611.     findall(X,maxx(X),L),write_list(0,L),nl.
  612.     
  613.   viewlang1(9):-
  614.     write("\n\nPress any key to continue"),
  615.     readchar(_).    
  616.  
  617. /*************************************************************************
  618.    Update the language
  619. *************************************************************************/
  620.  
  621. DATABASE - updateflag
  622.   updated
  623.  
  624. PREDICATES
  625.   newignore
  626.   newsynonym
  627.   newassoc
  628.   getent(ENT)
  629.   getassoc(ASSOC)
  630.   reg_updated
  631.   save_if_updated
  632.  
  633. CLAUSES
  634.   updatelang:-    retractall(updated),
  635.           repeat,
  636.         menu(5,40,3,9,
  637.           [ "New Synonyms for entities",
  638.             "New Alternatives for associations",
  639.             "New Words to be ignored"
  640.           ],"Update Language",1,CHOICE),
  641.         nl,updatelang1(CHOICE),CHOICE=0,!,
  642.         save_if_updated.
  643.  
  644.   updatelang1(0).
  645.   updatelang1(1):-newsynonym.
  646.   updatelang1(2):-newassoc.
  647.   updatelang1(3):-newignore.
  648.  
  649.   newsynonym:-    getent(E),write("Synonym: "),
  650.         readln(SYNONYM),SYNONYM><"",
  651.         assert(synonym(SYNONYM,E)),
  652.         reg_updated,
  653.         newsynonym.
  654.  
  655.   newignore:-    write("Ignore:"),readln(IGNORE),IGNORE><"",
  656.         reg_updated,
  657.         assert(ignore(IGNORE)),newignore.
  658.  
  659.   newassoc:-
  660.         getassoc(ASSOC),
  661.         write("New form: "),
  662.         readln(FORM),FORM >< "",
  663.         scan(FORM,LIST),
  664.         reg_updated,
  665.         assert(assoc(ASSOC,LIST)),
  666.         newassoc.
  667.  
  668.   getassoc(A):-
  669.         findall(X,assoc(X,_),L),
  670.         unik(L,L1),
  671.         menu(11,30,7,7,L1,"Assoc",1,C),
  672.         index(L1,C,A).
  673.  
  674.   getent(E):-
  675.         findall(X,entity(X),L),
  676.         unik(L,L1),
  677.         menu(2,49,7,7,L1,"Entity",1,C),
  678.         index(L1,C,E).
  679.  
  680.   reg_updated:-updated,!.
  681.   reg_updated:-assert(updated).
  682.  
  683.   save_if_updated:-updated,!,savedba.
  684.   save_if_updated.
  685.